1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Switch to non-secure mode 4 * 5 * Copyright (c) 2018 Heinrich Schuchardt 6 * 7 * This module contains the ARMv7 specific code required for leaving the 8 * secure mode before booting an operating system. 9 */ 10 11 #include <common.h> 12 #include <bootm.h> 13 #include <asm/armv7.h> 14 #include <asm/secure.h> 15 #include <asm/setjmp.h> 16 17 /** 18 * entry_non_secure() - entry point when switching to non-secure mode 19 * 20 * When switching to non-secure mode switch_to_non_secure_mode() calls this 21 * function passing a jump buffer. We use this jump buffer to restore the 22 * original stack and register state. 23 * 24 * @non_secure_jmp: jump buffer for restoring stack and registers 25 */ 26 static void entry_non_secure(struct jmp_buf_data *non_secure_jmp) 27 { 28 dcache_enable(); 29 debug("Reached non-secure mode\n"); 30 31 /* Restore stack and registers saved in switch_to_non_secure_mode() */ 32 longjmp(non_secure_jmp, 1); 33 } 34 35 /** 36 * switch_to_non_secure_mode() - switch to non-secure mode 37 * 38 * Operating systems may expect to run in non-secure mode. Here we check if 39 * we are running in secure mode and switch to non-secure mode if necessary. 40 */ 41 void switch_to_non_secure_mode(void) 42 { 43 static bool is_nonsec; 44 struct jmp_buf_data non_secure_jmp; 45 46 if (armv7_boot_nonsec() && !is_nonsec) { 47 if (setjmp(&non_secure_jmp)) 48 return; 49 dcache_disable(); /* flush cache before switch to HYP */ 50 armv7_init_nonsec(); 51 is_nonsec = true; 52 secure_ram_addr(_do_nonsec_entry)(entry_non_secure, 53 (uintptr_t)&non_secure_jmp, 54 0, 0); 55 } 56 } 57