On Wed, Dec 28, 2022 at 09:13:16PM +0100, Mark Kettenis wrote:
> 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?
>
I am ok with this if not committed already. Thanks!
-ml
>
> 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