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.