Dear Sergii,

Sorry for the delay, but I have finally found the time to work on the
EFI variable and ESRT support for OpenBSD.  As a first step, here is a
diff that adds support for copying the ESRT in the bootloader and
passing it on to the kernel.

I adjusted your diff a bit.  It now adds the new config_esrt member at
the end of the bios_efiinfo struct and sets a flag to indicate that
extra bit of information is present.  That makes it possible to load
new kernels with the old bootloader and vice versa.

patrick@, mlarkin@, yasuoka@ and other devs: ok?


Index: arch/amd64/include/biosvar.h
===================================================================
RCS file: /cvs/src/sys/arch/amd64/include/biosvar.h,v
retrieving revision 1.29
diff -u -p -r1.29 biosvar.h
--- arch/amd64/include/biosvar.h        29 Nov 2022 21:41:39 -0000      1.29
+++ arch/amd64/include/biosvar.h        28 Dec 2022 20:03:32 -0000
@@ -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: arch/amd64/stand/efiboot/conf.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/conf.c,v
retrieving revision 1.39
diff -u -p -r1.39 conf.c
--- arch/amd64/stand/efiboot/conf.c     12 Aug 2022 20:18:58 -0000      1.39
+++ arch/amd64/stand/efiboot/conf.c     28 Dec 2022 20:03:32 -0000
@@ -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: arch/amd64/stand/efiboot/efiboot.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/efiboot.c,v
retrieving revision 1.40
diff -u -p -r1.40 efiboot.c
--- arch/amd64/stand/efiboot/efiboot.c  11 Jul 2022 19:45:02 -0000      1.40
+++ arch/amd64/stand/efiboot/efiboot.c  28 Dec 2022 20:03:32 -0000
@@ -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: stand/efi/include/efiapi.h
===================================================================
RCS file: /cvs/src/sys/stand/efi/include/efiapi.h,v
retrieving revision 1.3
diff -u -p -r1.3 efiapi.h
--- stand/efi/include/efiapi.h  7 Dec 2022 23:04:26 -0000       1.3
+++ stand/efi/include/efiapi.h  28 Dec 2022 20:03:32 -0000
@@ -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;
@@ -911,5 +915,28 @@ typedef struct _EFI_SYSTEM_TABLE {
   EFI_CONFIGURATION_TABLE         *ConfigurationTable;
 
 } 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

Reply via email to