diff --git a/src/drivers/efi/Kconfig b/src/drivers/efi/Kconfig index 9f63938a3a..9effc0d778 100644 --- a/src/drivers/efi/Kconfig +++ b/src/drivers/efi/Kconfig @@ -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 "." and encoding it as + (major << 16) | minor. + + Non-digits before and after "." 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 diff --git a/src/drivers/efi/info.c b/src/drivers/efi/info.c index fc1cfea573..ca4dd42a1f 100644 --- a/src/drivers/efi/info.c +++ b/src/drivers/efi/info.c @@ -6,10 +6,42 @@ #include #include +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; }