blob: a4bc746e3094c32101d6b441a3808acba9d62983 [file] [log] [blame]
Andrew Geisslerfc7e7972023-09-11 08:24:07 -04001From c7301588a3aec9ebf36749da601d0d6e3d807bfc Mon Sep 17 00:00:00 2001
Brad Bishopbec4ebc2022-08-03 09:55:16 -04002From: Peter Hoyes <Peter.Hoyes@arm.com>
3Date: Thu, 19 May 2022 09:02:32 +0100
Andrew Geisslerfc7e7972023-09-11 08:24:07 -04004Subject: [PATCH] armv8: Enable icache when switching exception levels in
Brad Bishopbec4ebc2022-08-03 09:55:16 -04005 bootefi
6
7bootefi calls the function switch_to_non_secure_mode before calling the
8UEFI payload to handle the case where U-Boot is running at EL3.
9
10For AArch64, the UEFI specification states that:
11 The core will be configured as follows:
12 * MMU enabled
13 * Instruction and data caches enabled
14
15These requirements should be followed when switching exception levels
16for EFI applications.
17
18This function already disables and re-enables the data cache prior to
19switching exception levels, but omits the instruction cache, meaning
20the function returns with the instruction cache disabled at the new
21exception level. Fix this by calling icache_disable prior to switching
22exception levels and icache_enable afterwards.
23
24Issue-Id: SCM-4641
25Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
26Upstream-Status: Inappropriate [other]
27 Implementation pending further discussion
28Change-Id: I678cd5ba39b56e124ab7854608289cd14651ce65
Andrew Geisslerfc7e7972023-09-11 08:24:07 -040029
Brad Bishopbec4ebc2022-08-03 09:55:16 -040030---
31 arch/arm/cpu/armv8/exception_level.c | 3 +++
32 1 file changed, 3 insertions(+)
33
34diff --git a/arch/arm/cpu/armv8/exception_level.c b/arch/arm/cpu/armv8/exception_level.c
35index 4aad1550f4..0a3e5428e7 100644
36--- a/arch/arm/cpu/armv8/exception_level.c
37+++ b/arch/arm/cpu/armv8/exception_level.c
38@@ -27,6 +27,7 @@
39 static void entry_non_secure(struct jmp_buf_data *non_secure_jmp)
40 {
41 dcache_enable();
42+ icache_enable();
43 debug("Reached non-secure mode\n");
44
45 /* Restore stack and registers saved in switch_to_non_secure_mode() */
46@@ -61,6 +62,7 @@ void switch_to_non_secure_mode(void)
47 if (setjmp(&non_secure_jmp))
48 return;
49 dcache_disable(); /* flush cache before switch to EL2 */
50+ icache_disable();
51 /* Move into EL2 and keep running there */
52 armv8_switch_to_el2((uintptr_t)&non_secure_jmp, 0, 0, 0,
53 (uintptr_t)entry_non_secure, ES_TO_AARCH64);
54@@ -68,6 +70,7 @@ void switch_to_non_secure_mode(void)
55 if (setjmp(&non_secure_jmp))
56 return;
57 dcache_disable(); /* flush cache before switch to EL1 */
58+ icache_disable();
59 /* Move into EL1 and keep running there */
60 armv8_switch_to_el1((uintptr_t)&non_secure_jmp, 0, 0, 0,
61 (uintptr_t)entry_non_secure, ES_TO_AARCH64);