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 <bootm.h> 12 #include <cpu_func.h> 13 #include <log.h> 14 #include <setjmp.h> 15 #include <asm/armv7.h> 16 #include <asm/secure.h> 17 18 /** 19 * entry_non_secure() - entry point when switching to non-secure mode 20 * 21 * When switching to non-secure mode switch_to_non_secure_mode() calls this 22 * function passing a jump buffer. We use this jump buffer to restore the 23 * original stack and register state. 24 * 25 * @non_secure_jmp: jump buffer for restoring stack and registers 26 */ entry_non_secure(jmp_buf non_secure_jmp)27static void entry_non_secure(jmp_buf non_secure_jmp) 28 { 29 dcache_enable(); 30 debug("Reached non-secure mode\n"); 31 32 /* Restore stack and registers saved in switch_to_non_secure_mode() */ 33 longjmp(non_secure_jmp, 1); 34 } 35 36 /** 37 * switch_to_non_secure_mode() - switch to non-secure mode 38 * 39 * Operating systems may expect to run in non-secure mode. Here we check if 40 * we are running in secure mode and switch to non-secure mode if necessary. 41 */ switch_to_non_secure_mode(void)42void switch_to_non_secure_mode(void) 43 { 44 static bool is_nonsec; 45 jmp_buf non_secure_jmp; 46 47 if (armv7_boot_nonsec() && !is_nonsec) { 48 if (setjmp(non_secure_jmp)) 49 return; 50 dcache_disable(); /* flush cache before switch to HYP */ 51 armv7_init_nonsec(); 52 is_nonsec = true; 53 secure_ram_addr(_do_nonsec_entry)(entry_non_secure, 54 (uintptr_t)&non_secure_jmp, 55 0, 0); 56 } 57 } 58