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.