From 0f15f6b02825b042ddc1d753f62cf87f30b1fe12 Mon Sep 17 00:00:00 2001 From: Peter Hoyes Date: Thu, 19 May 2022 09:02:32 +0100 Subject: [PATCH 9/9] armv8: Enable icache when switching exception levels in bootefi bootefi calls the function switch_to_non_secure_mode before calling the UEFI payload to handle the case where U-Boot is running at EL3. For AArch64, the UEFI specification states that: The core will be configured as follows: * MMU enabled * Instruction and data caches enabled These requirements should be followed when switching exception levels for EFI applications. This function already disables and re-enables the data cache prior to switching exception levels, but omits the instruction cache, meaning the function returns with the instruction cache disabled at the new exception level. Fix this by calling icache_disable prior to switching exception levels and icache_enable afterwards. Issue-Id: SCM-4641 Signed-off-by: Peter Hoyes Upstream-Status: Inappropriate [other] Implementation pending further discussion Change-Id: I678cd5ba39b56e124ab7854608289cd14651ce65 --- arch/arm/cpu/armv8/exception_level.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/cpu/armv8/exception_level.c b/arch/arm/cpu/armv8/exception_level.c index 4aad1550f4..0a3e5428e7 100644 --- a/arch/arm/cpu/armv8/exception_level.c +++ b/arch/arm/cpu/armv8/exception_level.c @@ -27,6 +27,7 @@ static void entry_non_secure(struct jmp_buf_data *non_secure_jmp) { dcache_enable(); + icache_enable(); debug("Reached non-secure mode\n"); /* Restore stack and registers saved in switch_to_non_secure_mode() */ @@ -61,6 +62,7 @@ void switch_to_non_secure_mode(void) if (setjmp(&non_secure_jmp)) return; dcache_disable(); /* flush cache before switch to EL2 */ + icache_disable(); /* Move into EL2 and keep running there */ armv8_switch_to_el2((uintptr_t)&non_secure_jmp, 0, 0, 0, (uintptr_t)entry_non_secure, ES_TO_AARCH64); @@ -68,6 +70,7 @@ void switch_to_non_secure_mode(void) if (setjmp(&non_secure_jmp)) return; dcache_disable(); /* flush cache before switch to EL1 */ + icache_disable(); /* Move into EL1 and keep running there */ armv8_switch_to_el1((uintptr_t)&non_secure_jmp, 0, 0, 0, (uintptr_t)entry_non_secure, ES_TO_AARCH64); -- 2.25.1