On Mon, Aug 06, 2018 at 11:38:28PM +0200, Mark Kettenis wrote:
> 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?
> 

That's probably me, but I'm a bit backed up at the moment. I'll take a
look this weekend.

-ml

> 
> 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