x86: Allow booting a kernel from the EFI app
[platform/kernel/u-boot.git] / arch / x86 / lib / bootm.c
index 07d8f1f..57cba5c 100644 (file)
@@ -8,8 +8,11 @@
  */
 
 #include <common.h>
+#include <bootstage.h>
 #include <command.h>
 #include <hang.h>
+#include <log.h>
+#include <asm/global_data.h>
 #include <dm/device.h>
 #include <dm/root.h>
 #include <errno.h>
@@ -33,7 +36,7 @@ void bootm_announce_and_cleanup(void)
        printf("\nStarting kernel ...\n\n");
 
 #ifdef CONFIG_SYS_COREBOOT
-       timestamp_add_now(TS_U_BOOT_START_KERNEL);
+       timestamp_add_now(TS_START_KERNEL);
 #endif
        bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
 #if CONFIG_IS_ENABLED(BOOTSTAGE_REPORT)
@@ -51,7 +54,7 @@ void bootm_announce_and_cleanup(void)
 #if defined(CONFIG_OF_LIBFDT) && !defined(CONFIG_OF_NO_KERNEL)
 int arch_fixup_memory_node(void *blob)
 {
-       bd_t    *bd = gd->bd;
+       struct bd_info  *bd = gd->bd;
        int bank;
        u64 start[CONFIG_NR_DRAM_BANKS];
        u64 size[CONFIG_NR_DRAM_BANKS];
@@ -134,7 +137,7 @@ static int boot_prep_linux(bootm_headers_t *images)
        printf("Setup at %#08lx\n", images->ep);
        ret = setup_zimage((void *)images->ep, cmd_line_dest,
                        0, images->rd_start,
-                       images->rd_end - images->rd_start);
+                       images->rd_end - images->rd_start, 0);
 
        if (ret) {
                printf("## Setting up boot parameters failed ...\n");
@@ -176,10 +179,14 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
                * U-Boot is setting them up that way for itself in
                * arch/i386/cpu/cpu.c.
                *
-               * Note that we cannot currently boot a kernel while running as
-               * an EFI application. Please use the payload option for that.
+               * Note: this is incomplete for EFI kernels!
+               *
+               * This can boot a kernel while running as an EFI application,
+               * but if the kernel requires EFI support then that support needs
+               * to be enabled first (see EFI_LOADER). Also the EFI information
+               * must enabled with setup_efi_info(). See setup_zimage() for
+               * how this is done with the stub.
                */
-#ifndef CONFIG_EFI_APP
                __asm__ __volatile__ (
                "movl $0, %%ebp\n"
                "cli\n"
@@ -188,7 +195,6 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
                [boot_params] "S"(setup_base),
                "b"(0), "D"(0)
                );
-#endif
        }
 
        /* We can't get to here */
@@ -205,8 +211,8 @@ static int boot_jump_linux(bootm_headers_t *images)
                                 images->os.arch == IH_ARCH_X86_64);
 }
 
-int do_bootm_linux(int flag, int argc, char * const argv[],
-               bootm_headers_t *images)
+int do_bootm_linux(int flag, int argc, char *const argv[],
+                  bootm_headers_t *images)
 {
        /* No need for those on x86 */
        if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE)
@@ -220,3 +226,21 @@ int do_bootm_linux(int flag, int argc, char * const argv[],
 
        return boot_jump_linux(images);
 }
+
+static ulong get_sp(void)
+{
+       ulong ret;
+
+#if CONFIG_IS_ENABLED(X86_64)
+       ret = gd->start_addr_sp;
+#else
+       asm("mov %%esp, %0" : "=r"(ret) : );
+#endif
+
+       return ret;
+}
+
+void arch_lmb_reserve(struct lmb *lmb)
+{
+       arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096);
+}