summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/commonlib/include/commonlib/coreboot_tables.h20
-rw-r--r--src/drivers/efi/Kconfig32
-rw-r--r--src/drivers/efi/Makefile.mk2
-rw-r--r--src/drivers/efi/info.c28
-rw-r--r--src/include/boot/coreboot_tables.h3
-rw-r--r--src/lib/coreboot_table.c4
6 files changed, 89 insertions, 0 deletions
diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h
index 94985b1567..a9e14c7bff 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 = 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
diff --git a/src/drivers/efi/Kconfig b/src/drivers/efi/Kconfig
index ad27d68b39..399443bdaa 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_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.
diff --git a/src/drivers/efi/Makefile.mk b/src/drivers/efi/Makefile.mk
index 2597c09bff..47f0e82990 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 0000000000..fc1cfea573
--- /dev/null
+++ b/src/drivers/efi/info.c
@@ -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;
+}
diff --git a/src/include/boot/coreboot_tables.h b/src/include/boot/coreboot_tables.h
index e209e4b2de..a87933dcf7 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. */
+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 d7b6126385..913588feb6 100644
--- a/src/lib/coreboot_table.c
+++ b/src/lib/coreboot_table.c
@@ -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);