drivers/efi: Derive ESRT version from LOCALVERSION

fwupd shows the ESRT (UEFI System Resource Table) version as 0 when
DRIVERS_EFI_MAIN_FW_VERSION is left at the default. That makes it easy
to ship firmware with no meaningful ESRT version and forces maintainers
to duplicate versioning in multiple places.

If DRIVERS_EFI_MAIN_FW_VERSION is 0, parse a leading "<major>.<minor>"
from LOCALVERSION (ignoring non-digits before/after) and encode it as
(major << 16) | minor (e.g. "v26.01-rc1" -> 0x001A0001).

If DRIVERS_EFI_MAIN_FW_LSV is 0, default it to the effective firmware
version. This provides a sane, more secure default (prevents accidental
rollback to older versions) while still allowing platforms to override
LSV explicitly when rollback is desired.

Test=boot adl/horizon and check `fwupdmgr get-devices` shows a
version:
    ├─System Firmware:
    │     Device ID:          f48f261c7fc0724729b817bfd4e8340e3195a6bc
    │     Current version:    26.3


Change-Id: I3f47ee7a38e79312532f4ed5d4516c57911f727e
Signed-off-by: Sean Rhodes <sean@starlabs.systems>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/90861
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Reviewed-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
Reviewed-by: Paul Menzel <paulepanter@mailbox.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Sean Rhodes 2026-01-21 22:08:37 +00:00 committed by Matt DeVillier
commit fc312590d1
2 changed files with 59 additions and 2 deletions

View file

@ -29,6 +29,15 @@ config DRIVERS_EFI_MAIN_FW_VERSION
help
32-bit unsigned integer representing current firmware's version.
If set to 0, coreboot will try to derive a version from LOCALVERSION by
parsing a leading "<major>.<minor>" and encoding it as
(major << 16) | minor.
Non-digits before and after "<major>.<minor>" are ignored.
Examples:
- "26.01" -> 0x001A0001
- "v26.01-rc1" -> 0x001A0001
config DRIVERS_EFI_MAIN_FW_LSV
hex "Lowest supported firmware version"
range 0x00000000 0xFFFFFFFF
@ -39,6 +48,8 @@ config DRIVERS_EFI_MAIN_FW_LSV
that is allowed to replace the current one. Can be used to forbid
bugged versions.
If set to 0, coreboot uses DRIVERS_EFI_MAIN_FW_VERSION.
config DRIVERS_EFI_UPDATE_CAPSULES
bool "Include EFI update capsules driver"
depends on DRIVERS_EFI_VARIABLE_STORE && SMMSTORE_V2 && DRIVERS_EFI_FW_INFO

View file

@ -6,10 +6,42 @@
#include <string.h>
#include <uuid.h>
static uint32_t efi_fw_version_from_localversion(void)
{
const char *localversion = CONFIG_LOCALVERSION;
uint32_t major = 0;
uint32_t minor = 0;
const char *p = localversion;
while (*p != '\0' && (*p < '0' || *p > '9'))
p++;
while (*p >= '0' && *p <= '9') {
major = major * 10 + (*p - '0');
p++;
}
if (*p != '.')
return 0;
p++;
while (*p >= '0' && *p <= '9') {
minor = minor * 10 + (*p - '0');
p++;
}
if (major > 0xffff || minor > 0xffff)
return 0;
return (major << 16) | minor;
}
void lb_efi_fw_info(struct lb_header *header)
{
uint8_t guid[16];
struct lb_efi_fw_info *fw_info;
uint32_t fw_version;
uint32_t lsv;
if (parse_uuid(guid, CONFIG_DRIVERS_EFI_MAIN_FW_GUID)) {
printk(BIOS_ERR, "%s(): failed to parse firmware's GUID: '%s'\n", __func__,
@ -22,7 +54,21 @@ void lb_efi_fw_info(struct lb_header *header)
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_version = CONFIG_DRIVERS_EFI_MAIN_FW_VERSION;
if (fw_version == 0) {
fw_version = efi_fw_version_from_localversion();
if (fw_version != 0)
printk(BIOS_DEBUG,
"EFI FW version derived from CONFIG_LOCALVERSION '%s': 0x%08x\n",
CONFIG_LOCALVERSION, fw_version);
}
lsv = CONFIG_DRIVERS_EFI_MAIN_FW_LSV;
if (lsv == 0)
lsv = fw_version;
fw_info->version = fw_version;
fw_info->lowest_supported_version = lsv;
fw_info->fw_size = CONFIG_ROM_SIZE;
}