summaryrefslogtreecommitdiff
path: root/cmd/bootefi.c
diff options
context:
space:
mode:
authorAlison Wang <b18965@freescale.com>2016-11-10 10:49:03 +0800
committerYork Sun <york.sun@nxp.com>2016-11-22 11:40:24 -0800
commitec6617c39741adc6c54952564579e32c3c09c66f (patch)
tree2c65fb7ab999e39eb6acc0be8890eced30c950a1 /cmd/bootefi.c
parent95e74a3df75bf01eaf69f5c28f9aa2db6568e901 (diff)
armv8: Support loading 32-bit OS in AArch32 execution state
To support loading a 32-bit OS, the execution state will change from AArch64 to AArch32 when jumping to kernel. The architecture information will be got through checking FIT image, then U-Boot will load 32-bit OS or 64-bit OS automatically. Signed-off-by: Ebony Zhu <ebony.zhu@nxp.com> Signed-off-by: Alison Wang <alison.wang@nxp.com> Signed-off-by: Chenhui Zhao <chenhui.zhao@nxp.com> Reviewed-by: York Sun <york.sun@nxp.com>
Diffstat (limited to 'cmd/bootefi.c')
-rw-r--r--cmd/bootefi.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index ca411702ba..97a0fc9c7c 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -141,6 +141,18 @@ static void *copy_fdt(void *fdt)
return new_fdt;
}
+#ifdef CONFIG_ARM64
+static unsigned long efi_run_in_el2(ulong (*entry)(void *image_handle,
+ struct efi_system_table *st), void *image_handle,
+ struct efi_system_table *st)
+{
+ /* Enable caches again */
+ dcache_enable();
+
+ return entry(image_handle, st);
+}
+#endif
+
/*
* Load an EFI payload into a newly allocated piece of memory, register all
* EFI objects it would want to access and jump to it.
@@ -231,9 +243,14 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt)
if (current_el() == 3) {
smp_kick_all_cpus();
dcache_disable(); /* flush cache before switch to EL2 */
- armv8_switch_to_el2();
- /* Enable caches again */
- dcache_enable();
+
+ /* Move into EL2 and keep running there */
+ armv8_switch_to_el2((ulong)entry, (ulong)&loaded_image_info,
+ (ulong)&systab, (ulong)efi_run_in_el2,
+ ES_TO_AARCH64);
+
+ /* Should never reach here, efi exits with longjmp */
+ while (1) { }
}
#endif