aboutsummaryrefslogtreecommitdiff
path: root/cmd/bootefi.c
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@openbsd.org>2018-06-15 23:47:12 +0200
committerAlexander Graf <agraf@suse.de>2018-07-25 14:57:43 +0200
commitdc500c369486fbe04000fd325c46bb309e4a1827 (patch)
treec0536188ca6d92a2534040d00526d7e3d4f69a78 /cmd/bootefi.c
parent907ee2945e78c66aaefabaabada4d092fd8e3d58 (diff)
downloadu-boot-dc500c369486fbe04000fd325c46bb309e4a1827.zip
u-boot-dc500c369486fbe04000fd325c46bb309e4a1827.tar.gz
u-boot-dc500c369486fbe04000fd325c46bb309e4a1827.tar.bz2
efi_loader: ARM: run EFI payloads non-secure
If desired (and possible) switch into HYP mode or non-secure SVC mode before calling the entry point of an EFI application. This allows U-Boot to provide a usable PSCI implementation and makes it possible to boot kernels into hypervisor mode using an EFI bootloader. Based on diffs from Heinrich Schuchardt and Alexander Graf. Signed-off-by: Mark Kettenis <kettenis@openbsd.org> [agraf: Fix indentation] Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'cmd/bootefi.c')
-rw-r--r--cmd/bootefi.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index cd755b6..c8c2564 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -20,6 +20,11 @@
#include <asm-generic/unaligned.h>
#include <linux/linkage.h>
+#ifdef CONFIG_ARMV7_NONSEC
+#include <asm/armv7.h>
+#include <asm/secure.h>
+#endif
+
DECLARE_GLOBAL_DATA_PTR;
#define OBJ_LIST_NOT_INITIALIZED 1
@@ -194,6 +199,18 @@ static efi_status_t efi_run_in_el2(EFIAPI efi_status_t (*entry)(
}
#endif
+#ifdef CONFIG_ARMV7_NONSEC
+static efi_status_t efi_run_in_hyp(EFIAPI efi_status_t (*entry)(
+ efi_handle_t image_handle, struct efi_system_table *st),
+ efi_handle_t image_handle, struct efi_system_table *st)
+{
+ /* Enable caches again */
+ dcache_enable();
+
+ return efi_do_enter(image_handle, st, entry);
+}
+#endif
+
/* Carve out DT reserved memory ranges */
static efi_status_t efi_carve_out_dt_rsv(void *fdt)
{
@@ -350,6 +367,22 @@ static efi_status_t do_bootefi_exec(void *efi,
}
#endif
+#ifdef CONFIG_ARMV7_NONSEC
+ if (armv7_boot_nonsec()) {
+ dcache_disable(); /* flush cache before switch to HYP */
+
+ armv7_init_nonsec();
+ secure_ram_addr(_do_nonsec_entry)(
+ efi_run_in_hyp,
+ (uintptr_t)entry,
+ (uintptr_t)loaded_image_info_obj.handle,
+ (uintptr_t)&systab);
+
+ /* Should never reach here, efi exits with longjmp */
+ while (1) { }
+ }
+#endif
+
ret = efi_do_enter(loaded_image_info_obj.handle, &systab, entry);
exit: