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 Enable support for ChromeOS mode switches provided by the ChromeOS
EC. 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 config EC_GOOGLE_CHROMEEC_INCLUDE_SSFC_IN_FW_CONFIG
depends on FW_CONFIG_SOURCE_CHROMEEC_CBI depends on FW_CONFIG_SOURCE_CHROMEEC_CBI
depends on !EC_GOOGLE_CHROMEEC_FW_CONFIG_FROM_UFSC
bool bool
help help
Fetch Second Source Factory Cache from CBI EEPROM and add it in the most significant 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 */ /* SPDX-License-Identifier: GPL-2.0-only */
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
@ -666,31 +667,38 @@ void google_chromeec_ap_poweroff(void)
halt(); 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 = { struct ec_params_get_cbi params = {
.tag = tag, .tag = tag,
}; };
uint32_t r = 0;
struct chromeec_command cmd = { struct chromeec_command cmd = {
.cmd_code = EC_CMD_GET_CROS_BOARD_INFO, .cmd_code = EC_CMD_GET_CROS_BOARD_INFO,
.cmd_version = 0, .cmd_version = 0,
.cmd_data_in = &params, .cmd_data_in = &params,
.cmd_data_out = &r, .cmd_data_out = buf,
.cmd_size_in = sizeof(params), .cmd_size_in = sizeof(params),
.cmd_size_out = sizeof(r), .cmd_size_out = bufsize,
.cmd_dev_index = 0,
}; };
int rv;
rv = google_chromeec_command(&cmd); int rv = google_chromeec_command(&cmd);
if (rv != 0) if (rv)
return 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; 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) int google_chromeec_cbi_get_sku_id(uint32_t *id)
{ {
return cbi_get_uint32(id, CBI_TAG_SKU_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 google_chromeec_cbi_get_fw_config(uint64_t *fw_config)
{ {
int rv;
uint32_t config; 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)) if (cbi_get_uint32(&config, CBI_TAG_FW_CONFIG))
return -1; 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) 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; int rv;
rv = google_chromeec_command(&cmd); rv = cbi_read(buf, bufsize, tag, false);
if (rv != 0)
return rv;
/* Ensure NUL termination. */ /* Ensure NUL termination. */
buf[bufsize - 1] = '\0'; buf[bufsize - 1] = '\0';
return 0; return rv;
} }
int google_chromeec_cbi_get_dram_part_num(char *buf, size_t bufsize) int google_chromeec_cbi_get_dram_part_num(char *buf, size_t bufsize)