I've successfully booted the machine with the following changes:

--- sys/arch/amd64/stand/efiboot/efiboot.c    2016-06-10 12:36:06.000000000
-0600
+++ sys/arch/amd64/stand/efiboot/efiboot.c    2016-12-28 15:57:36.728002168
-0600
@@ -137,12 +137,16 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TA
 void
 efi_cleanup(void)
 {
+      int         retry;
     EFI_STATUS     status;

-    efi_memprobe_internal();    /* sync the current map */
-    status = EFI_CALL(BS->ExitBootServices, IH, mmap_key);
-    if (status != EFI_SUCCESS)
-        panic("ExitBootServices");
+    /* retry once in case of failure */
+    for (retry = 1; retry == 0; retry--) {
+        efi_memprobe_internal();    /* sync the current map */
+        status = EFI_CALL(BS->ExitBootServices, IH, mmap_key);
+        if (status != EFI_SUCCESS && retry == 0)
+            panic("ExitBootServices failed (%d)\n", status);
+    }
 }

 /***********************************************************************


--- sys/arch/amd64/stand/libsa/exec_i386.c    2015-11-26 04:52:40.000000000
-0600
+++ sys/arch/amd64/stand/libsa/exec_i386.c    2016-12-28 15:30:42.201644481
-0600
@@ -116,6 +116,27 @@ run_loadfile(u_long *marks, int howto)
     sr_clear_keys();
 #endif

+    entry = marks[MARK_ENTRY] & 0x0fffffff;
+
+#ifdef EFIBOOT
+    /* Move the loaded kernel image to the usual place */
+    delta = DEFAULT_KERNEL_ADDRESS - efi_loadaddr;
+    memcpy((void *)marks[MARK_START] + delta, (void *)marks[MARK_START],
+        marks[MARK_END] - marks[MARK_START]);
+    for (i = 0; i < MARK_MAX; i++)
+        marks[i] += delta;
+    entry += delta;
+#endif
+
+    printf("entry point at 0x%lx [%x, %x, %x, %x]\n", entry,
+        ((int *)entry)[0], ((int *)entry)[1],
+        ((int *)entry)[2], ((int *)entry)[3]);
+
+#ifdef EFIBOOT
+    /* Sync the memory map and call ExitBootServices() */
+    efi_cleanup();
+#endif
+
     /* Pass memory map to the kernel */
     mem_pass();

@@ -129,34 +150,12 @@ run_loadfile(u_long *marks, int howto)
     makebootargs(av, &ac);
 #endif

-    entry = marks[MARK_ENTRY] & 0x0fffffff;
-
-    printf("entry point at 0x%lx [%x, %x, %x, %x]\n", entry,
-        ((int *)entry)[0], ((int *)entry)[1],
-        ((int *)entry)[2], ((int *)entry)[3]);
-#ifndef EFIBOOT
-    /* stack and the gung is ok at this point, so, no need for asm setup */
-    (*(startfuncp)entry)(howto, bootdev, BOOTARG_APIVER, marks[MARK_END],
-        extmem, cnvmem, ac, (int)av);
-#else
-    /*
-     * Move the loaded kernel image to the usual place after calling
-     * ExitBootServices().
-     */
-    delta = DEFAULT_KERNEL_ADDRESS - efi_loadaddr;
-    efi_cleanup();
-    memcpy((void *)marks[MARK_START] + delta, (void *)marks[MARK_START],
-        marks[MARK_END] - marks[MARK_START]);
-    for (i = 0; i < MARK_MAX; i++)
-        marks[i] += delta;
-    entry += delta;
-#ifdef __amd64__
+#if defined(EFIBOOT) && defined(__amd64__)
     (*run_i386)((u_long)run_i386, entry, howto, bootdev, BOOTARG_APIVER,
         marks[MARK_END], extmem, cnvmem, ac, (intptr_t)av);
 #else
     (*(startfuncp)entry)(howto, bootdev, BOOTARG_APIVER, marks[MARK_END],
         extmem, cnvmem, ac, (int)av);
 #endif
-#endif
     /* not reached */
 }

I diffed my changes against the 6.0 version of the files, but I tested
applying them against both 6.0 and the most current versions and there were
no conflicts either way.

Oh before I forget, while I was reading through the code I noticed what
appears to be a typo in sys/arch/amd64/stand/efiboot/eficall.h:

#define EFI_CALL(...)   \
    _efi_call_fn(__VA_ARGS__, _call_9, _call_8, _call_7, _call_6, _call_5, \
            _call_4, _call_3, _call_2, _call_1, _call_1)(__VA_ARGS__)
#endif

It looks like the second instance of _call_1 should be _call_0 (which is
defined earlier), unless I am totally misreading this.

Reply via email to