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