drivers/efi: add optional ESRT-friendly coreboot table tag

EFI System Resource Table (ESRT) is an informational structure that
reports basic details about current system or device firmware.  This is
chiefly used to perform firmware updates.

New CONFIG_DRIVERS_EFI_FW_INFO is off by default, enabling it adds
DRIVERS_EFI_FW_{GUID,VERSION,LSV} to be used to specify firmware
version/update information.

Existing forms of versions wouldn't be sufficient because there is no
universal way of converting string versions to 32-bit unsigned integers
and there are no GUIDs or lowest supported versions.

Change-Id: Ic1b768d7bed43edf7ca8e41552087734054de033
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/83421
Reviewed-by: Christian Walter <christian.walter@9elements.com>
Reviewed-by: coreboot org <coreboot.org@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Sergii Dmytruk 2024-06-24 16:23:32 +03:00 committed by Felix Held
parent 2355aa7d3b
commit 1a8b9c20f8
6 changed files with 89 additions and 0 deletions

View File

@ -87,6 +87,7 @@ enum {
LB_TAG_TYPE_C_INFO = 0x0042,
LB_TAG_ACPI_RSDP = 0x0043,
LB_TAG_PCIE = 0x0044,
LB_TAG_EFI_FW_INFO = 0x0045,
/* The following options are CMOS-related */
LB_TAG_CMOS_OPTION_TABLE = 0x00c8,
LB_TAG_OPTION = 0x00c9,
@ -578,4 +579,23 @@ struct lb_acpi_rsdp {
lb_uint64_t rsdp_pointer; /* Address of the ACPI RSDP */
};
/*
* Machine-friendly version of a system firmware component. A component is
* identified by a GUID. coreboot is an obvious main component but there could
* be others (like EC) which should get their own instances of the tag.
*
* The main consumer of this information is UEFI firmware but something else
* could reuse it too.
*
* Larger number in a version field corresponds to a more recent version.
*/
struct lb_efi_fw_info {
uint32_t tag;
uint32_t size;
uint8_t guid[16]; /* Called "firmware class" in UEFI */
uint32_t version; /* Current version */
uint32_t lowest_supported_version; /* Lowest allowed version for downgrades */
uint32_t fw_size; /* Size of firmware in bytes */
} __packed;
#endif

View File

@ -6,3 +6,35 @@ config DRIVERS_EFI_VARIABLE_STORE
help
Adds a driver that is able to read and write an EFI formatted
VariableStore as used by tianocore.
config DRIVERS_EFI_FW_INFO
bool "Expose firmware version in a EFI-friendly form"
depends on UDK_BASE
help
Adds firmware version information to coreboot table in a form similar to
EFI System Resource Table (ESRT) that can be used for firmware updates.
config DRIVERS_EFI_MAIN_FW_GUID
string "GUID of the firmware"
default "00112233-4455-6677-8899-aabbccddeeff"
depends on DRIVERS_EFI_FW_INFO
help
GUID used to identify firmware kind for the purposes of updates.
config DRIVERS_EFI_MAIN_FW_VERSION
hex "Version of the firmware"
range 0x00000000 0xFFFFFFFF
default 0x00000000
depends on DRIVERS_EFI_FW_INFO
help
32-bit unsigned integer representing current firmware's version.
config DRIVERS_EFI_MAIN_FW_LSV
hex "Lowest supported firmware version"
range 0x00000000 0xFFFFFFFF
default 0x00000000
depends on DRIVERS_EFI_FW_INFO
help
32-bit unsigned integer representing lowest firmware version number
that is allowed to replace the current one. Can be used to forbid
bugged versions.

View File

@ -5,3 +5,5 @@ smm-$(CONFIG_DRIVERS_EFI_VARIABLE_STORE) += efivars.c
all-$(CONFIG_USE_UEFI_VARIABLE_STORE) += option.c
smm-$(CONFIG_USE_UEFI_VARIABLE_STORE) += option.c
ramstage-$(CONFIG_DRIVERS_EFI_FW_INFO) += info.c

28
src/drivers/efi/info.c Normal file
View File

@ -0,0 +1,28 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <boot/coreboot_tables.h>
#include <console/console.h>
#include <stdint.h>
#include <string.h>
#include <uuid.h>
void lb_efi_fw_info(struct lb_header *header)
{
uint8_t guid[16];
struct lb_efi_fw_info *fw_info;
if (parse_uuid(guid, CONFIG_DRIVERS_EFI_MAIN_FW_GUID)) {
printk(BIOS_ERR, "%s(): failed to parse firmware's GUID: '%s'\n", __func__,
CONFIG_DRIVERS_EFI_MAIN_FW_GUID);
return;
}
fw_info = (struct lb_efi_fw_info *)lb_new_record(header);
fw_info->tag = LB_TAG_EFI_FW_INFO;
fw_info->size = sizeof(*fw_info);
memcpy(fw_info->guid, guid, sizeof(guid));
fw_info->version = CONFIG_DRIVERS_EFI_MAIN_FW_VERSION;
fw_info->lowest_supported_version = CONFIG_DRIVERS_EFI_MAIN_FW_LSV;
fw_info->fw_size = CONFIG_ROM_SIZE;
}

View File

@ -27,6 +27,9 @@ enum cb_err fill_lb_pcie(struct lb_pcie *pcie);
/* Define this in mainboard.c to add board-specific table entries. */
void lb_board(struct lb_header *header);
/* Adds LB_TAG_EFI_FW_INFO table entry. */
void lb_efi_fw_info(struct lb_header *header);
/* Define this function to fill in the frame buffer returning 0 on success and
< 0 on error. */
int fill_lb_framebuffer(struct lb_framebuffer *framebuffer);

View File

@ -536,6 +536,10 @@ static uintptr_t write_coreboot_table(uintptr_t rom_table_end)
if (CONFIG(SMMSTORE_V2))
lb_smmstorev2(head);
/* Add information about firmware in form suitable for EFI updates. */
if (CONFIG(DRIVERS_EFI_FW_INFO))
lb_efi_fw_info(head);
/* Add board-specific table entries, if any. */
lb_board(head);