ec/google/chromeec: Add EC_GOOGLE_CHROMEEC_FW_CONFIG_FROM_UFSC

Introduce a Kconfig option EC_GOOGLE_CHROMEEC_FW_CONFIG_FROM_UFSC for
reading firmware configuration from Unified Firmware and Second-source
Config (UFSC) [1] from EC CBI. As the UFSC already includes both the
32-bit FW_CONFIG and 32-bit SSFC, this option is incompatible with
EC_GOOGLE_CHROMEEC_INCLUDE_SSFC_IN_FW_CONFIG.

Also check the size of the data read from CBI.

[1] https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/6974727

BUG=b:448300592
TEST=emerge=skywalker coreboot
BRANCH=none

Change-Id: I2f686838d2f7a6f3eec3bd5224f89389340f7471
Signed-off-by: Yu-Ping Wu <yupingso@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/89404
Reviewed-by: Paul Menzel <paulepanter@mailbox.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
Yu-Ping Wu 2025-10-03 09:04:30 +08:00 committed by Matt DeVillier
commit e59c5abd13
2 changed files with 44 additions and 24 deletions

View file

@ -185,8 +185,16 @@ config EC_GOOGLE_CHROMEEC_SWITCHES
Enable support for ChromeOS mode switches provided by the ChromeOS
EC.
config EC_GOOGLE_CHROMEEC_FW_CONFIG_FROM_UFSC
depends on FW_CONFIG_SOURCE_CHROMEEC_CBI
bool
help
Get firmware configuration from Unified Firmware and Second-source
Config (UFSC) in CBI.
config EC_GOOGLE_CHROMEEC_INCLUDE_SSFC_IN_FW_CONFIG
depends on FW_CONFIG_SOURCE_CHROMEEC_CBI
depends on !EC_GOOGLE_CHROMEEC_FW_CONFIG_FROM_UFSC
bool
help
Fetch Second Source Factory Cache from CBI EEPROM and add it in the most significant

View file

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
@ -666,31 +667,38 @@ void google_chromeec_ap_poweroff(void)
halt();
}
static int cbi_get_uint32(uint32_t *id, uint32_t tag)
static int cbi_read(void *buf, size_t bufsize, uint32_t tag, bool check_size)
{
struct ec_params_get_cbi params = {
.tag = tag,
};
uint32_t r = 0;
struct chromeec_command cmd = {
.cmd_code = EC_CMD_GET_CROS_BOARD_INFO,
.cmd_version = 0,
.cmd_data_in = &params,
.cmd_data_out = &r,
.cmd_data_out = buf,
.cmd_size_in = sizeof(params),
.cmd_size_out = sizeof(r),
.cmd_dev_index = 0,
.cmd_size_out = bufsize,
};
int rv;
rv = google_chromeec_command(&cmd);
if (rv != 0)
int rv = google_chromeec_command(&cmd);
if (rv)
return rv;
*id = r;
if (check_size && cmd.cmd_size_out != bufsize) {
printk(BIOS_ERR, "Wrong out size for CBI tag %d: expected %zu, got %u\n",
tag, bufsize, cmd.cmd_size_out);
return -1;
}
return 0;
}
static int cbi_get_uint32(uint32_t *id, uint32_t tag)
{
return cbi_read(id, sizeof(*id), tag, true);
}
int google_chromeec_cbi_get_sku_id(uint32_t *id)
{
return cbi_get_uint32(id, CBI_TAG_SKU_ID);
@ -711,8 +719,25 @@ uint32_t google_chromeec_get_board_sku(void)
int google_chromeec_cbi_get_fw_config(uint64_t *fw_config)
{
int rv;
uint32_t config;
_Static_assert(!CONFIG(EC_GOOGLE_CHROMEEC_FW_CONFIG_FROM_UFSC) ||
!CONFIG(EC_GOOGLE_CHROMEEC_INCLUDE_SSFC_IN_FW_CONFIG),
"EC_GOOGLE_CHROMEEC_FW_CONFIG_FROM_UFSC and "
"EC_GOOGLE_CHROMEEC_INCLUDE_SSFC_IN_FW_CONFIG are conflicting");
if (CONFIG(EC_GOOGLE_CHROMEEC_FW_CONFIG_FROM_UFSC)) {
struct cbi_ufsc ufsc;
rv = cbi_read(&ufsc, sizeof(ufsc), CBI_TAG_UFSC, true);
if (rv)
return rv;
_Static_assert(sizeof(*fw_config) == sizeof(ufsc.data[0]) * 2,
"Wrong UFSC size");
*fw_config = ufsc.data[0] | ((uint64_t)ufsc.data[1] << 32);
return 0;
}
if (cbi_get_uint32(&config, CBI_TAG_FW_CONFIG))
return -1;
@ -760,27 +785,14 @@ bool google_chromeec_get_ucsi_enabled(void)
static int cbi_get_string(char *buf, size_t bufsize, uint32_t tag)
{
struct ec_params_get_cbi params = {
.tag = tag,
};
struct chromeec_command cmd = {
.cmd_code = EC_CMD_GET_CROS_BOARD_INFO,
.cmd_version = 0,
.cmd_data_in = &params,
.cmd_data_out = buf,
.cmd_size_in = sizeof(params),
.cmd_size_out = bufsize,
};
int rv;
rv = google_chromeec_command(&cmd);
if (rv != 0)
return rv;
rv = cbi_read(buf, bufsize, tag, false);
/* Ensure NUL termination. */
buf[bufsize - 1] = '\0';
return 0;
return rv;
}
int google_chromeec_cbi_get_dram_part_num(char *buf, size_t bufsize)