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 <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/90722
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Reviewed-by: Paul Menzel <paulepanter@mailbox.org>
This commit is contained in:
Patrick Rudolph 2026-01-11 09:44:29 +01:00 committed by Matt DeVillier
commit 673ce1845e
2 changed files with 38 additions and 27 deletions

View file

@ -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)
{

View file

@ -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 */