I suspect that at some point in the future we'll have to bite the
bullet and call into EFI runtime services on amd64 as well.  The diff
below paves the road by passing the necessary information from our
bootloader to the kernel.

There is a potential issue with this diff.  The EFI memory map is
stored into the bootloader "heap" which is allocated with the
EfiLoaderData attribute.  Memory allocated with that attribute is
treated as Free/Available by the kernel.  So this data may be
overwritten and the kernel would need to move it somewhere safe early
in the boot process.  It's not clear to me how early though?  Can
somebody who is more familiar with the amd64 and kernel and how it
uses physical memory during early bootstrap shed some light on this?


Index: arch/amd64/stand/efiboot/efiboot.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/efiboot.c,v
retrieving revision 1.30
diff -u -p -r1.30 efiboot.c
--- arch/amd64/stand/efiboot/efiboot.c  6 Jul 2018 07:55:50 -0000       1.30
+++ arch/amd64/stand/efiboot/efiboot.c  6 Aug 2018 21:22:33 -0000
@@ -279,6 +279,7 @@ efi_device_path_ncmp(EFI_DEVICE_PATH *dp
  * Memory
  ***********************************************************************/
 bios_memmap_t           bios_memmap[64];
+bios_efiinfo_t          bios_efiinfo;
 
 static void
 efi_heap_init(void)
@@ -335,6 +336,9 @@ efi_memprobe_internal(void)
        cnvmem = extmem = 0;
        bios_memmap[0].type = BIOS_MAP_END;
 
+       if (bios_efiinfo.mmap_start != 0)
+               free((void *)bios_efiinfo.mmap_start, bios_efiinfo.mmap_size);
+
        siz = 0;
        status = EFI_CALL(BS->GetMemoryMap, &siz, NULL, &mapkey, &mmsiz,
            &mmver);
@@ -400,7 +404,11 @@ efi_memprobe_internal(void)
                    bm->addr / 1024 == extmem + 1024)
                        extmem += bm->size / 1024;
        }
-       free(mm0, siz);
+
+       bios_efiinfo.mmap_desc_ver = mmver;
+       bios_efiinfo.mmap_desc_size = mmsiz;
+       bios_efiinfo.mmap_size = siz;
+       bios_efiinfo.mmap_start = (uintptr_t)mm0;
 }
 
 /***********************************************************************
@@ -733,22 +741,21 @@ efi_makebootargs(void)
        EFI_STATUS               status;
        EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
                                *gopi;
-       bios_efiinfo_t           ei;
+       bios_efiinfo_t          *ei = &bios_efiinfo;
        int                      curmode;
        UINTN                    sz, gopsiz, bestsiz = 0;
 
-       memset(&ei, 0, sizeof(ei));
        /*
         * ACPI, BIOS configuration table
         */
        for (i = 0; i < ST->NumberOfTableEntries; i++) {
                if (efi_guidcmp(&acpi_guid,
                    &ST->ConfigurationTable[i].VendorGuid) == 0)
-                       ei.config_acpi = (intptr_t)
+                       ei->config_acpi = (uintptr_t)
                            ST->ConfigurationTable[i].VendorTable;
                else if (efi_guidcmp(&smbios_guid,
                    &ST->ConfigurationTable[i].VendorGuid) == 0)
-                       ei.config_smbios = (intptr_t)
+                       ei->config_smbios = (uintptr_t)
                            ST->ConfigurationTable[i].VendorTable;
        }
 
@@ -781,35 +788,44 @@ efi_makebootargs(void)
                gopi = gop->Mode->Info;
                switch (gopi->PixelFormat) {
                case PixelBlueGreenRedReserved8BitPerColor:
-                       ei.fb_red_mask      = 0x00ff0000;
-                       ei.fb_green_mask    = 0x0000ff00;
-                       ei.fb_blue_mask     = 0x000000ff;
-                       ei.fb_reserved_mask = 0xff000000;
+                       ei->fb_red_mask      = 0x00ff0000;
+                       ei->fb_green_mask    = 0x0000ff00;
+                       ei->fb_blue_mask     = 0x000000ff;
+                       ei->fb_reserved_mask = 0xff000000;
                        break;
                case PixelRedGreenBlueReserved8BitPerColor:
-                       ei.fb_red_mask      = 0x000000ff;
-                       ei.fb_green_mask    = 0x0000ff00;
-                       ei.fb_blue_mask     = 0x00ff0000;
-                       ei.fb_reserved_mask = 0xff000000;
+                       ei->fb_red_mask      = 0x000000ff;
+                       ei->fb_green_mask    = 0x0000ff00;
+                       ei->fb_blue_mask     = 0x00ff0000;
+                       ei->fb_reserved_mask = 0xff000000;
                        break;
                case PixelBitMask:
-                       ei.fb_red_mask = gopi->PixelInformation.RedMask;
-                       ei.fb_green_mask = gopi->PixelInformation.GreenMask;
-                       ei.fb_blue_mask = gopi->PixelInformation.BlueMask;
-                       ei.fb_reserved_mask =
+                       ei->fb_red_mask = gopi->PixelInformation.RedMask;
+                       ei->fb_green_mask = gopi->PixelInformation.GreenMask;
+                       ei->fb_blue_mask = gopi->PixelInformation.BlueMask;
+                       ei->fb_reserved_mask =
                            gopi->PixelInformation.ReservedMask;
                        break;
                default:
                        break;
                }
-               ei.fb_addr = gop->Mode->FrameBufferBase;
-               ei.fb_size = gop->Mode->FrameBufferSize;
-               ei.fb_height = gopi->VerticalResolution;
-               ei.fb_width = gopi->HorizontalResolution;
-               ei.fb_pixpsl = gopi->PixelsPerScanLine;
+               ei->fb_addr = gop->Mode->FrameBufferBase;
+               ei->fb_size = gop->Mode->FrameBufferSize;
+               ei->fb_height = gopi->VerticalResolution;
+               ei->fb_width = gopi->HorizontalResolution;
+               ei->fb_pixpsl = gopi->PixelsPerScanLine;
        }
 
-       addbootarg(BOOTARG_EFIINFO, sizeof(ei), &ei);
+       /*
+        * EFI system table
+        */
+       ei->system_table = (uintptr_t)ST;
+
+#ifdef __amd64__
+       ei->flags |= BEI_64BIT;
+#endif
+
+       addbootarg(BOOTARG_EFIINFO, sizeof(bios_efiinfo), &bios_efiinfo);
 }
 
 void
Index: arch/amd64/include/biosvar.h
===================================================================
RCS file: /cvs/src/sys/arch/amd64/include/biosvar.h,v
retrieving revision 1.25
diff -u -p -r1.25 biosvar.h
--- arch/amd64/include/biosvar.h        6 Feb 2018 01:09:17 -0000       1.25
+++ arch/amd64/include/biosvar.h        6 Aug 2018 21:22:33 -0000
@@ -204,6 +204,13 @@ typedef struct _bios_efiinfo {
        uint32_t        fb_green_mask;
        uint32_t        fb_blue_mask;
        uint32_t        fb_reserved_mask;
+       uint32_t        flags;
+#define BEI_64BIT      0x00000001      /* 64-bit EFI implementation */
+       uint32_t        mmap_desc_ver;
+       uint32_t        mmap_desc_size;
+       uint32_t        mmap_size;
+       uint64_t        mmap_start;
+       uint64_t        system_table;
 } __packed bios_efiinfo_t;
 
 #define        BOOTARG_UCODE 12

Reply via email to