From 00bebe0e391889f56d2891b310d7a7250680c021 Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Mon, 24 Jun 2024 16:23:32 +0300 Subject: [PATCH] drivers/efi: add optional ESRT-friently coreboot table tag 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 woudn't be sufficient because there is no universal way of conversion to 32-bit unsigned integers and there are no GUIDs or lowest supported versions. Change-Id: Ic1b768d7bed43edf7ca8e41552087734054de033 Signed-off-by: Sergii Dmytruk --- .../include/commonlib/coreboot_tables.h | 19 +++++++++++ src/drivers/efi/Kconfig | 32 +++++++++++++++++++ src/drivers/efi/Makefile.mk | 2 ++ src/drivers/efi/info.c | 27 ++++++++++++++++ src/include/boot/coreboot_tables.h | 3 ++ src/lib/coreboot_table.c | 4 +++ 6 files changed, 87 insertions(+) create mode 100644 src/drivers/efi/info.c diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h index e3f08331879..d51012ba1e2 100644 --- a/src/commonlib/include/commonlib/coreboot_tables.h +++ b/src/commonlib/include/commonlib/coreboot_tables.h @@ -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 = 0x0046, LB_TAG_LOGO = 0x00a0, /* The following options are CMOS-related */ LB_TAG_CMOS_OPTION_TABLE = 0x00c8, @@ -587,4 +588,22 @@ struct bootlogo_header { uint64_t size; } __packed; +/* + * 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 version fields correspond to more recent versions. + */ +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 */ +} __packed; + #endif diff --git a/src/drivers/efi/Kconfig b/src/drivers/efi/Kconfig index ad27d68b39b..ac031a816c5 100644 --- a/src/drivers/efi/Kconfig +++ b/src/drivers/efi/Kconfig @@ -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_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_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_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. diff --git a/src/drivers/efi/Makefile.mk b/src/drivers/efi/Makefile.mk index 2597c09bff4..47f0e829908 100644 --- a/src/drivers/efi/Makefile.mk +++ b/src/drivers/efi/Makefile.mk @@ -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 diff --git a/src/drivers/efi/info.c b/src/drivers/efi/info.c new file mode 100644 index 00000000000..28154cc542b --- /dev/null +++ b/src/drivers/efi/info.c @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +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_FW_GUID)) { + printk(BIOS_ERR, "%s(): failed to parse firmware's GUID: '%s'\n", __func__, + CONFIG_DRIVERS_EFI_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_FW_VERSION; + fw_info->lowest_supported_version = CONFIG_DRIVERS_EFI_FW_LSV; +} diff --git a/src/include/boot/coreboot_tables.h b/src/include/boot/coreboot_tables.h index e209e4b2de4..112402a7c30 100644 --- a/src/include/boot/coreboot_tables.h +++ b/src/include/boot/coreboot_tables.h @@ -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 (or entries). */ +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); diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c index 8aa48a2d7b2..658cbce6056 100644 --- a/src/lib/coreboot_table.c +++ b/src/lib/coreboot_table.c @@ -572,6 +572,10 @@ static uintptr_t write_coreboot_table(uintptr_t rom_table_end) /* Add board-specific table entries, if any. */ lb_board(head); + /* Add information about firmware in form suitable for EFI updates. */ + if (CONFIG(DRIVERS_EFI_FW_INFO)) + lb_efi_fw_info(head); + if (CONFIG(CHROMEOS_RAMOOPS)) lb_ramoops(head);