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