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