[U-Boot] [PATCH 3/5] efi_loader: AArch64: Run EFI payloads in EL2 if U-Boot runs in EL3

Alexander Graf agraf at suse.de
Fri May 13 14:21:33 CEST 2016


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 <agraf at 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 d3a2331..79dbd15 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! */
 #ifdef DEBUG_EFI
 	printf("%s:%d Jumping to 0x%lx\n", __func__, __LINE__, (long)entry);
-- 
1.8.5.6



More information about the U-Boot mailing list