diff options
author | Mark Kettenis <kettenis@openbsd.org> | 2018-06-15 23:47:12 +0200 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2018-07-25 14:57:43 +0200 |
commit | dc500c369486fbe04000fd325c46bb309e4a1827 (patch) | |
tree | c0536188ca6d92a2534040d00526d7e3d4f69a78 /cmd/bootefi.c | |
parent | 907ee2945e78c66aaefabaabada4d092fd8e3d58 (diff) |
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.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/cmd/bootefi.c b/cmd/bootefi.c index cd755b6bf4..c8c2564512 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: |