Let the EFI bootloader make a copy of the EFI System Resource Table (ESRT)
authorkettenis <kettenis@openbsd.org>
Mon, 2 Jan 2023 22:41:17 +0000 (22:41 +0000)
committerkettenis <kettenis@openbsd.org>
Mon, 2 Jan 2023 22:41:17 +0000 (22:41 +0000)
and pass it to the kernel.

ok jca@, patrick@

sys/arch/amd64/include/biosvar.h
sys/arch/amd64/stand/efiboot/conf.c
sys/arch/amd64/stand/efiboot/efiboot.c
sys/stand/efi/include/efiapi.h

index 1abd944..7a59d45 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: biosvar.h,v 1.29 2022/11/29 21:41:39 guenther Exp $   */
+/*     $OpenBSD: biosvar.h,v 1.30 2023/01/02 22:41:17 kettenis Exp $   */
 
 /*
  * Copyright (c) 1997-1999 Michael Shalayeff
@@ -218,11 +218,13 @@ typedef struct _bios_efiinfo {
        uint32_t        fb_reserved_mask;
        uint32_t        flags;
 #define BEI_64BIT      0x00000001      /* 64-bit EFI implementation */
+#define BEI_ESRT       0x00000002      /* ESRT table */
        uint32_t        mmap_desc_ver;
        uint32_t        mmap_desc_size;
        uint32_t        mmap_size;
        uint64_t        mmap_start;
        uint64_t        system_table;
+       uint64_t        config_esrt;
 } __packed bios_efiinfo_t;
 
 #define        BOOTARG_UCODE 12
index 4859ce0..81f2ece 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: conf.c,v 1.39 2022/08/12 20:18:58 stsp Exp $  */
+/*     $OpenBSD: conf.c,v 1.40 2023/01/02 22:41:17 kettenis Exp $      */
 
 /*
  * Copyright (c) 1996 Michael Shalayeff
@@ -40,7 +40,7 @@
 #include "efidev.h"
 #include "efipxe.h"
 
-const char version[] = "3.62";
+const char version[] = "3.63";
 
 #ifdef EFI_DEBUG
 int    debug = 0;
index 3115508..95cf92d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: efiboot.c,v 1.40 2022/07/11 19:45:02 kettenis Exp $   */
+/*     $OpenBSD: efiboot.c,v 1.41 2023/01/02 22:41:17 kettenis Exp $   */
 
 /*
  * Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
@@ -831,6 +831,7 @@ efi_com_putc(dev_t dev, int c)
  */
 static EFI_GUID                         acpi_guid = ACPI_20_TABLE_GUID;
 static EFI_GUID                         smbios_guid = SMBIOS_TABLE_GUID;
+static EFI_GUID                         esrt_guid = EFI_SYSTEM_RESOURCE_TABLE_GUID;
 static int                      gopmode = -1;
 
 #define        efi_guidcmp(_a, _b)     memcmp((_a), (_b), sizeof(EFI_GUID))
@@ -870,6 +871,34 @@ efi_makebootargs(void)
                    &ST->ConfigurationTable[i].VendorGuid) == 0)
                        ei->config_smbios = (uintptr_t)
                            ST->ConfigurationTable[i].VendorTable;
+               else if (efi_guidcmp(&esrt_guid,
+                   &ST->ConfigurationTable[i].VendorGuid) == 0)
+                       ei->config_esrt = (uintptr_t)
+                           ST->ConfigurationTable[i].VendorTable;
+       }
+
+       /*
+        * Need to copy ESRT because call to ExitBootServices() frees memory of
+        * type EfiBootServicesData in which ESRT resides.
+        */
+       if (ei->config_esrt != 0) {
+               EFI_SYSTEM_RESOURCE_TABLE *esrt =
+                   (EFI_SYSTEM_RESOURCE_TABLE *)ei->config_esrt;
+               size_t esrt_size = sizeof(*esrt) +
+                   esrt->FwResourceCount * sizeof(EFI_SYSTEM_RESOURCE_ENTRY);
+               void *esrt_copy;
+
+               /*
+                * Using EfiRuntimeServicesData as it maps to BIOS_MAP_RES,
+                * while EfiLoaderData becomes BIOS_MAP_FREE.
+                */
+               status = BS->AllocatePool(EfiRuntimeServicesData,
+                   esrt_size, &esrt_copy);
+               if (status == EFI_SUCCESS) {
+                       memcpy(esrt_copy, esrt, esrt_size);
+                       ei->config_esrt = (uintptr_t)esrt_copy;
+                       ei->flags |= BEI_ESRT;
+               }
        }
 
        /*
index f45f2dd..40a2ab0 100644 (file)
@@ -871,6 +871,10 @@ typedef struct {
   { 0x49152e77, 0x1ada, 0x4764,        \
     { 0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b } }
 
+#define EFI_SYSTEM_RESOURCE_TABLE_GUID \
+  { 0xb122a263, 0x3661, 0x4f68,        \
+    { 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80 } }
+
 typedef struct _EFI_CONFIGURATION_TABLE {
   EFI_GUID                VendorGuid;
   VOID                    *VendorTable;
@@ -912,4 +916,27 @@ typedef struct _EFI_SYSTEM_TABLE {
 
 } EFI_SYSTEM_TABLE;
 
+//
+// EFI System Resource Table
+//
+
+typedef struct _EFI_SYSTEM_RESOURCE_TABLE {
+  UINT32       FwResourceCount;
+  UINT32       FwResourceCountMax;
+  UINT64       FwResourceVersion;
+  //EFI_SYSTEM_RESOURCE_ENTRY Entries[];
+} EFI_SYSTEM_RESOURCE_TABLE;
+
+#define EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION 1
+
+typedef struct _EFI_SYSTEM_RESOURCE_ENTRY {
+  EFI_GUID      FwClass;
+  UINT32        FwType;
+  UINT32        FwVersion;
+  UINT32        LowestSupportedFwVersion;
+  UINT32        CapsuleFlags;
+  UINT32        LastAttemptVersion;
+  UINT32        LastAttemptStatus;
+} EFI_SYSTEM_RESOURCE_ENTRY;
+
 #endif