| From c7301588a3aec9ebf36749da601d0d6e3d807bfc Mon Sep 17 00:00:00 2001 |
| From: Peter Hoyes <Peter.Hoyes@arm.com> |
| Date: Thu, 19 May 2022 09:02:32 +0100 |
| Subject: [PATCH] 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 <Peter.Hoyes@arm.com> |
| 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); |