Index: sys/boot/efi/loader/arch/amd64/elf64_freebsd.c =================================================================== --- sys/boot/efi/loader/arch/amd64/elf64_freebsd.c (revision 291207) +++ sys/boot/efi/loader/arch/amd64/elf64_freebsd.c (working copy) @@ -174,13 +174,6 @@ if (err != 0) return(err); - status = BS->ExitBootServices(IH, efi_mapkey); - if (EFI_ERROR(status)) { - printf("%s: ExitBootServices() returned 0x%lx\n", __func__, - (long)status); - return (EINVAL); - } - dev_cleanup(); trampoline(trampstack, efi_copy_finish, kernend, modulep, PT4, Index: sys/boot/efi/loader/arch/arm/exec.c =================================================================== --- sys/boot/efi/loader/arch/arm/exec.c (revision 291070) +++ sys/boot/efi/loader/arch/arm/exec.c (working copy) @@ -82,13 +82,6 @@ printf("modulep: %#x\n", modulep); printf("relocation_offset %llx\n", __elfN(relocation_offset)); - status = BS->ExitBootServices(IH, efi_mapkey); - if (EFI_ERROR(status)) { - printf("%s: ExitBootServices() returned 0x%lx\n", __func__, - (long)status); - return (EINVAL); - } - dev_cleanup(); (*entry)((void *)modulep); Index: sys/boot/efi/loader/arch/arm64/exec.c =================================================================== --- sys/boot/efi/loader/arch/arm64/exec.c (revision 291236) +++ sys/boot/efi/loader/arch/arm64/exec.c (working copy) @@ -118,13 +118,6 @@ if (err != 0) return (err); - status = BS->ExitBootServices(IH, efi_mapkey); - if (EFI_ERROR(status)) { - printf("%s: ExitBootServices() returned 0x%lx\n", __func__, - (long)status); - return (EINVAL); - } - /* Clean D-cache under kernel area and invalidate whole I-cache */ clean_addr = efi_translate(fp->f_addr); clean_size = efi_translate(kernendp) - clean_addr; Index: sys/boot/efi/loader/bootinfo.c =================================================================== --- sys/boot/efi/loader/bootinfo.c (revision 291070) +++ sys/boot/efi/loader/bootinfo.c (working copy) @@ -55,8 +55,6 @@ #include #endif -UINTN efi_mapkey; - static const char howto_switches[] = "aCdrgDmphsv"; static int howto_masks[] = { RB_ASKNAME, RB_CDROM, RB_KDB, RB_DFLTROOT, RB_GDB, RB_MULTIPLE, @@ -234,6 +232,47 @@ } static int +bi_add_efi_data_and_exit(struct preloaded_file *kfp, + struct efi_map_header *efihdr, size_t efisz, EFI_MEMORY_DESCRIPTOR *mm, + UINTN sz) +{ + UINTN efi_mapkey; + UINTN mmsz; + UINT32 mmver; + EFI_STATUS status; + uint8_t retry = 2; + + if((kfp == NULL) || (efihdr == NULL) || (mm == NULL)) + return (EINVAL); + + while (retry > 0) { + status = BS->GetMemoryMap(&sz, mm, &efi_mapkey, &mmsz, &mmver); + if (EFI_ERROR(status)) { + printf("%s: GetMemoryMap() returned 0x%lx\n", __func__, + (long)status); + return (EINVAL); + } + status = BS->ExitBootServices(IH, efi_mapkey); + if (EFI_ERROR(status)) { + /* Map key is incorrect, retry */ + printf("%s: ExitBootServices() returned 0x%lx\n", + __func__, (long)status); + } + else { + efihdr->memory_size = sz; + efihdr->descriptor_size = mmsz; + efihdr->descriptor_version = mmver; + file_addmetadata(kfp, MODINFOMD_EFI_MAP, efisz + sz, + efihdr); + return (0); + } + retry--; + } + + return (EINVAL); +} + +static int bi_load_efi_data(struct preloaded_file *kfp) { EFI_MEMORY_DESCRIPTOR *mm; @@ -240,6 +279,7 @@ EFI_PHYSICAL_ADDRESS addr; EFI_STATUS status; size_t efisz; + UINTN efi_mapkey; UINTN mmsz, pages, sz; UINT32 mmver; struct efi_map_header *efihdr; @@ -294,20 +334,8 @@ efihdr = (struct efi_map_header *)addr; mm = (void *)((uint8_t *)efihdr + efisz); sz = (EFI_PAGE_SIZE * pages) - efisz; - status = BS->GetMemoryMap(&sz, mm, &efi_mapkey, &mmsz, &mmver); - if (EFI_ERROR(status)) { - printf("%s: GetMemoryMap() returned 0x%lx\n", __func__, - (long)status); - return (EINVAL); - } - efihdr->memory_size = sz; - efihdr->descriptor_size = mmsz; - efihdr->descriptor_version = mmver; - - file_addmetadata(kfp, MODINFOMD_EFI_MAP, efisz + sz, efihdr); - - return (0); + return (bi_add_efi_data_and_exit(kfp, efihdr, efisz, mm, sz)); } /* Index: sys/boot/efi/loader/loader_efi.h =================================================================== --- sys/boot/efi/loader/loader_efi.h (revision 291070) +++ sys/boot/efi/loader/loader_efi.h (working copy) @@ -44,8 +44,6 @@ ssize_t efi_readin(const int fd, vm_offset_t dest, const size_t len); void * efi_translate(vm_offset_t ptr); -extern UINTN efi_mapkey; - void efi_copy_finish(void); #endif /* _LOADER_EFI_COPY_H_ */