From 673ce1845e7b78fb21bdfbaac73fca306bff3c68 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 11 Jan 2026 09:44:29 +0100 Subject: [PATCH] ec/lenovo/h8: Cache EC version string When APM_CNT_ACPI_DISABLE is issued during LPC init it will enable SMI's when the EC asserts the GPE_EC_SCI GPIO, looking like: [NOTE ] coreboot-25.12 x86_64 smm starting (log level: 6)... [DEBUG] GPI (mask 0002) This happens on all ec_read() calls whenever bits in the status register change, causing lots of unnecessary SMIs at boot. Cache the EC version string when it's first read and use the cached version when writing SMBIOS tables. While on it introduce defines for registers and drop function from global scope. TEST=Seen less SMIs during boot. Version string is still correctly shown in dmidecode. Change-Id: I514c628947c4e14f2379f7e2f265f28a9c7086d6 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/90722 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Paul Menzel --- src/ec/lenovo/h8/h8.c | 56 +++++++++++++++++++++++-------------------- src/ec/lenovo/h8/h8.h | 9 ++++++- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/ec/lenovo/h8/h8.c b/src/ec/lenovo/h8/h8.c index acf5ce5408..564ba85b89 100644 --- a/src/ec/lenovo/h8/h8.c +++ b/src/ec/lenovo/h8/h8.c @@ -81,6 +81,34 @@ static void f1_to_f12_as_primary(int on) ec_clr_bit(0x3b, 3); } +static u8 h8_build_id_and_function_spec_version(char *buf, u8 buf_len) +{ + static char str[16 + 1]; /* 16 ASCII chars + \0 */ + u8 i, c; + + if (!str[0]) { + /* Build ID */ + for (i = 0; i < 8; i++) { + c = ec_read(H8_EC_BUILD_ID + i); + if (c < 0x20 || c > 0x7f) { + i = snprintf(str, sizeof(str), "*INVALID"); + break; + } + str[i] = c; + } + + /* Lenovo EC firmware function specification version */ + i += snprintf(str + i, sizeof(str) - i, "-%u.%u", + ec_read(H8_EC_FUNC_MAJOR_VER), ec_read(H8_EC_FUNC_MINOR_VER)); + } else + i = strlen(str); + + i = MIN(buf_len, i); + memcpy(buf, str, i); + + return i; +} + static void h8_log_ec_version(void) { char ecfw[17]; @@ -90,8 +118,8 @@ static void h8_log_ec_version(void) len = h8_build_id_and_function_spec_version(ecfw, sizeof(ecfw) - 1); ecfw[len] = 0; - fwvh = ec_read(0xe9); - fwvl = ec_read(0xe8); + fwvh = ec_read(H8_EC_FIRMWARE_MAJOR_VER); + fwvl = ec_read(H8_EC_FIRMWARE_MINOR_VER); printk(BIOS_INFO, "H8: EC Firmware ID %s, Version %d.%d%d%c\n", ecfw, fwvh >> 4, fwvh & 0x0f, fwvl >> 4, 0x41 + (fwvl & 0xf)); @@ -162,30 +190,6 @@ int h8_ultrabay_device_present(void) return ec_read(H8_STATUS1) & 0x5 ? 0 : 1; } -u8 h8_build_id_and_function_spec_version(char *buf, u8 buf_len) -{ - u8 i, c; - char str[16 + 1]; /* 16 ASCII chars + \0 */ - - /* Build ID */ - for (i = 0; i < 8; i++) { - c = ec_read(0xf0 + i); - if (c < 0x20 || c > 0x7f) { - i = snprintf(str, sizeof(str), "*INVALID"); - break; - } - str[i] = c; - } - - /* EC firmware function specification version */ - i += snprintf(str + i, sizeof(str) - i, "-%u.%u", ec_read(0xef), ec_read(0xeb)); - - i = MIN(buf_len, i); - memcpy(buf, str, i); - - return i; -} - #if CONFIG(GENERATE_SMBIOS_TABLES) static void h8_smbios_strings(struct device *dev, struct smbios_type11 *t) { diff --git a/src/ec/lenovo/h8/h8.h b/src/ec/lenovo/h8/h8.h index 40816117b1..88d7b07136 100644 --- a/src/ec/lenovo/h8/h8.h +++ b/src/ec/lenovo/h8/h8.h @@ -20,7 +20,6 @@ void h8_usb_power_enable(int on); void h8_enable_event(int event); void h8_disable_event(int event); int h8_ultrabay_device_present(void); -u8 h8_build_id_and_function_spec_version(char *buf, u8 buf_len); void h8_usb_always_on(void); int h8_get_fn_key(void); @@ -141,4 +140,12 @@ void h8_mb_init(void); #define H8_EVENT_FN_F5 0x64 #define H8_EVENT_FN_F6 0x65 +#define H8_EC_FIRMWARE_MINOR_VER 0xe8 +#define H8_EC_FIRMWARE_MAJOR_VER 0xe9 + +#define H8_EC_FUNC_MINOR_VER 0xeb +#define H8_EC_FUNC_MAJOR_VER 0xef + +#define H8_EC_BUILD_ID 0xf0 + #endif /* EC_LENOVO_H8_H */