summaryrefslogtreecommitdiff
path: root/arch/x86/lib/bootm.c
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-03-25 17:34:34 -0400
committerTom Rini <trini@konsulko.com>2023-03-25 17:34:34 -0400
commitfde439219ff53a46bdd5dff69e049ccd4be57310 (patch)
tree423643707fad940e0845cbebf74d545b05b3d336 /arch/x86/lib/bootm.c
parent4b635046b5e92e419fbd1bf93e5b0ef86dbcadc2 (diff)
parent93e3364804ffd4a5d4a0df9c750a1859f9fe298b (diff)
Merge tag 'efi-next-20230325' of https://source.denx.de/u-boot/custodians/u-boot-efi into next
Pull request for efi-next-20230325 Documenation: * add man-page for efi command UEFI: * Let EFI app call ExitBootServices() before legacy booting kernel * Support zboot and bootm in the EFI app * Let efi command show configuration tables * Support booting a 64-bit kernel from 64-bit EFI app * Allocate device-tree copy from high memory * simplify efi_str_to_u16()
Diffstat (limited to 'arch/x86/lib/bootm.c')
-rw-r--r--arch/x86/lib/bootm.c43
1 files changed, 35 insertions, 8 deletions
diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c
index 873e2bc176f..61cb7bc6116 100644
--- a/arch/x86/lib/bootm.c
+++ b/arch/x86/lib/bootm.c
@@ -10,6 +10,7 @@
#include <common.h>
#include <bootstage.h>
#include <command.h>
+#include <efi.h>
#include <hang.h>
#include <log.h>
#include <asm/global_data.h>
@@ -149,26 +150,52 @@ error:
return 1;
}
-int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
+int boot_linux_kernel(ulong setup_base, ulong entry, bool image_64bit)
{
bootm_announce_and_cleanup();
#ifdef CONFIG_SYS_COREBOOT
timestamp_add_now(TS_U_BOOT_START_KERNEL);
#endif
+
+ /*
+ * Exit EFI boot services just before jumping, after all console
+ * output, since the console won't be available afterwards.
+ */
+ if (IS_ENABLED(CONFIG_EFI_APP)) {
+ int ret;
+
+ ret = efi_store_memory_map(efi_get_priv());
+ if (ret)
+ return ret;
+ printf("Exiting EFI boot services\n");
+ ret = efi_call_exit_boot_services();
+ if (ret)
+ return ret;
+ }
+
if (image_64bit) {
if (!cpu_has_64bit()) {
puts("Cannot boot 64-bit kernel on 32-bit machine\n");
return -EFAULT;
}
- /* At present 64-bit U-Boot does not support booting a
+ /*
+ * At present 64-bit U-Boot only supports booting a 64-bit
* kernel.
- * TODO(sjg@chromium.org): Support booting both 32-bit and
- * 64-bit kernels from 64-bit U-Boot.
+ *
+ * TODO(sjg@chromium.org): Support booting 32-bit kernels from
+ * 64-bit U-Boot
*/
-#if !CONFIG_IS_ENABLED(X86_64)
- return cpu_jump_to_64bit(setup_base, load_address);
-#endif
+ if (CONFIG_IS_ENABLED(X86_64)) {
+ typedef void (*h_func)(ulong zero, ulong setup);
+ h_func func;
+
+ /* jump to Linux with rdi=0, rsi=setup_base */
+ func = (h_func)entry;
+ func(0, setup_base);
+ } else {
+ return cpu_jump_to_64bit(setup_base, entry);
+ }
} else {
/*
* Set %ebx, %ebp, and %edi to 0, %esi to point to the
@@ -190,7 +217,7 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
"movl $0, %%ebp\n"
"cli\n"
"jmp *%[kernel_entry]\n"
- :: [kernel_entry]"a"(load_address),
+ :: [kernel_entry]"a"(entry),
[boot_params] "S"(setup_base),
"b"(0), "D"(0)
);