Some boards decided not to run ATF or other secure firmware in EL3, so
they instead run U-Boot there. The uEFI spec doesn't know what EL3 is
though - it only knows about EL2 and EL1. So if we see that we're running
in EL3, let's get into EL2 to make payloads happy.

Signed-off-by: Alexander Graf <ag...@suse.de>
---
 arch/arm/include/asm/armv8/mmu.h | 19 ++++++++++++-------
 cmd/bootefi.c                    | 11 +++++++++++
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h
index 0d08ed3..876a2b2 100644
--- a/arch/arm/include/asm/armv8/mmu.h
+++ b/arch/arm/include/asm/armv8/mmu.h
@@ -116,19 +116,24 @@
 static inline void set_ttbr_tcr_mair(int el, u64 table, u64 tcr, u64 attr)
 {
        asm volatile("dsb sy");
-       if (el == 1) {
+       switch (el) {
+       case 1:
                asm volatile("msr ttbr0_el1, %0" : : "r" (table) : "memory");
                asm volatile("msr tcr_el1, %0" : : "r" (tcr) : "memory");
                asm volatile("msr mair_el1, %0" : : "r" (attr) : "memory");
-       } else if (el == 2) {
-               asm volatile("msr ttbr0_el2, %0" : : "r" (table) : "memory");
-               asm volatile("msr tcr_el2, %0" : : "r" (tcr) : "memory");
-               asm volatile("msr mair_el2, %0" : : "r" (attr) : "memory");
-       } else if (el == 3) {
+               break;
+       case 3:
                asm volatile("msr ttbr0_el3, %0" : : "r" (table) : "memory");
                asm volatile("msr tcr_el3, %0" : : "r" (tcr) : "memory");
                asm volatile("msr mair_el3, %0" : : "r" (attr) : "memory");
-       } else {
+
+               /* We may switch to EL2 later, so set those too; fall through */
+       case 2:
+               asm volatile("msr ttbr0_el2, %0" : : "r" (table) : "memory");
+               asm volatile("msr tcr_el2, %0" : : "r" (tcr) : "memory");
+               asm volatile("msr mair_el2, %0" : : "r" (attr) : "memory");
+               break;
+       default:
                hang();
        }
        asm volatile("isb");
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 2169065..edd0980 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -205,6 +205,17 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt)
                loaded_image_info.device_handle = nethandle;
 #endif
 
+#ifdef CONFIG_ARM64
+       /* On AArch64 we need to make sure we call our payload in < EL3 */
+       if (current_el() == 3) {
+               smp_kick_all_cpus();
+               dcache_disable();       /* flush cache before switch to EL2 */
+               armv8_switch_to_el2();
+               /* Enable caches again */
+               set_sctlr(get_sctlr() | (CR_C|CR_M));
+       }
+#endif
+
        /* Call our payload! */
        debug("%s:%d Jumping to 0x%lx\n", __func__, __LINE__, (long)entry);
 
-- 
1.8.5.6

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to