Dinesh Gehlot has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/75689?usp=email )
Change subject: soc/intel/cmd/blk: Implement an API to get CSE version ......................................................................
soc/intel/cmd/blk: Implement an API to get CSE version
This patch stores the ISH version in CMOS memory. During a cold reboot, it updates the CBMEM stored ISH version using the CMOS stored ISH version.
Previously, the ISH version was updated using CSE during a cold reboot, which was time-consuming. This change will improve the performance of cold reboots by approximately ~200ms. Additionally it removes unused variables for the CBMEM firmware version data structure.
BUG=b:280722061
Signed-off-by: Dinesh Gehlot digehlot@google.com Change-Id: I2ea03298ae239c4597de9fd23a88c23f21e2f224 --- M src/drivers/intel/ish/ish.c M src/soc/intel/common/block/cse/Kconfig M src/soc/intel/common/block/cse/cse.c M src/soc/intel/common/block/cse/cse_cmos.c M src/soc/intel/common/block/cse/cse_lite.c M src/soc/intel/common/block/include/intelblocks/cse.h M src/soc/intel/common/block/include/intelblocks/cse_cmos.h 7 files changed, 93 insertions(+), 76 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/89/75689/1
diff --git a/src/drivers/intel/ish/ish.c b/src/drivers/intel/ish/ish.c index 0415af0..3608b20 100644 --- a/src/drivers/intel/ish/ish.c +++ b/src/drivers/intel/ish/ish.c @@ -55,10 +55,10 @@ return;
printk(BIOS_DEBUG, "ISH version: %d.%d.%d.%d\n", - version->ish_partition_info.cur_ish_fw_version.major, - version->ish_partition_info.cur_ish_fw_version.minor, - version->ish_partition_info.cur_ish_fw_version.hotfix, - version->ish_partition_info.cur_ish_fw_version.build); + version->ish_version.major, + version->ish_version.minor, + version->ish_version.hotfix, + version->ish_version.build); }
static void intel_ish_final(struct device *dev) diff --git a/src/soc/intel/common/block/cse/Kconfig b/src/soc/intel/common/block/cse/Kconfig index 4426d5a..ea3d8ca 100644 --- a/src/soc/intel/common/block/cse/Kconfig +++ b/src/soc/intel/common/block/cse/Kconfig @@ -54,10 +54,17 @@ CMOS memory. The offset should be byte aligned and must leave enough memory to store required firmware partition versions.
+config SOC_INTEL_STORE_ISH_VERSION + bool + default y + depends on DRIVERS_INTEL_ISH && SOC_INTEL_STORE_CSE_FPT_PARTITION_VERSION + help + This configuration option stores ISH version in CMOS and CBMEM memory. This information + can be used to identify the currently running ISH firmware partition version. + config SOC_INTEL_STORE_CSE_FPT_PARTITION_VERSION bool - default n - depends on DRIVERS_INTEL_ISH + default y help This configuration option stores CSE FPT partitions' version in CMOS and CBMEM memory. This information can be used to identify the currently running firmware partition diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c index 40489c7..18a36f9 100644 --- a/src/soc/intel/common/block/cse/cse.c +++ b/src/soc/intel/common/block/cse/cse.c @@ -1222,10 +1222,10 @@ return;
printk(BIOS_DEBUG, "CSE version: %d.%d.%d.%d\n", - version->cur_cse_fw_version.major, - version->cur_cse_fw_version.minor, - version->cur_cse_fw_version.hotfix, - version->cur_cse_fw_version.build); + version->cse_version.major, + version->cse_version.minor, + version->cse_version.hotfix, + version->cse_version.build); }
#if ENV_RAMSTAGE diff --git a/src/soc/intel/common/block/cse/cse_cmos.c b/src/soc/intel/common/block/cse/cse_cmos.c index 0f8c96a..151ab69 100644 --- a/src/soc/intel/common/block/cse/cse_cmos.c +++ b/src/soc/intel/common/block/cse/cse_cmos.c @@ -40,7 +40,7 @@
struct cse_fw_table { uint32_t signature; - struct fw_version cse_version; + struct cse_fw_partition_info partition_info; uint16_t checksum; } __packed;
@@ -87,7 +87,10 @@ { u8 i, *p, offset = PARTITION_FW_CMOS_OFFSET; version->signature = PARTITION_FW_SIGNATURE; - memset(&version->cse_version, 0, sizeof(struct fw_version)); + memset(&version->partition_info.cse_version, 0, sizeof(struct fw_version)); +#if CONFIG_SOC_INTEL_STORE_ISH_VERSION + memset(&version->partition_info.ish_version, 0, sizeof(struct fw_version)); +#endif version->checksum = compute_ip_checksum(version, offsetof(struct cse_fw_table, checksum));
for (p = (u8 *)version, i = 0; i < sizeof(*version); i++, p++) @@ -105,7 +108,7 @@ */ init_cmos_partition_version(&version); } - memcpy(cse_version, &version.cse_version, sizeof(struct fw_version)); + memcpy(cse_version, &version.partition_info.cse_version, sizeof(struct fw_version)); }
/* API that allows users to update CSE version stored in CMOS memory. */ @@ -119,6 +122,35 @@ */ init_cmos_partition_version(&version); } - memcpy(&version.cse_version, cse_version, sizeof(struct fw_version)); + memcpy(&version.partition_info.cse_version, cse_version, sizeof(struct fw_version)); write_cmos_partition_version(&version); } + +#if CONFIG_SOC_INTEL_STORE_ISH_VERSION + +/* API that allows users to read ISH version stored in CMOS memory. */ +void get_cmos_ish_version(struct fw_version *ish_version) +{ + struct cse_fw_table version; + if (read_cmos_partition_version(&version)) { + /* CMOS failed to read the ISH version. Possibly CMOS area has corrupted. */ + printk(BIOS_WARNING, "CMOS fw version corrupted, initiating memory re-init\n"); + init_cmos_partition_version(&version); + } + memcpy(ish_version, &version.partition_info.ish_version, sizeof(struct fw_version)); +} + +/* API that allows users to update ISH version stored in CMOS memory. */ +void set_cmos_ish_version(const struct fw_version *ish_version) +{ + struct cse_fw_table version; + if (read_cmos_partition_version(&version)) { + /* CMOS failed to read the ISH version. Possibly CMOS area has corrupted. */ + printk(BIOS_WARNING, "CMOS fw version corrupted, initiating memory re-init\n"); + init_cmos_partition_version(&version); + } + memcpy(&version.partition_info.ish_version, ish_version, sizeof(struct fw_version)); + write_cmos_partition_version(&version); +} + +#endif /* SOC_INTEL_STORE_ISH_VERSION */ diff --git a/src/soc/intel/common/block/cse/cse_lite.c b/src/soc/intel/common/block/cse/cse_lite.c index cf1df2b..a8d3f66 100644 --- a/src/soc/intel/common/block/cse/cse_lite.c +++ b/src/soc/intel/common/block/cse/cse_lite.c @@ -1172,6 +1172,7 @@ timestamp_add_now(TS_CSE_FW_SYNC_END); }
+#if CONFIG_SOC_INTEL_STORE_ISH_VERSION static enum cb_err send_get_fpt_partition_info_cmd(enum fpt_partition_id id, struct fw_version_resp *resp) { @@ -1229,52 +1230,7 @@
return send_get_fpt_partition_info_cmd(id, resp); } - -/* - * Helper function to read ISH version from CSE FPT using HECI command. - * - * The HECI command only be executed after memory has been initialized. - * This is because the command relies on resources that are not available - * until DRAM initialization command has been sent. - */ -static void store_ish_version(void) -{ - if (!ENV_RAMSTAGE) - return; - - if (vboot_recovery_mode_enabled()) - return; - - struct cse_fw_partition_info *version; - size_t size = sizeof(struct fw_version); - version = cbmem_find(CBMEM_ID_CSE_PARTITION_VERSION); - if (version == NULL) - return; - - /* - * Compare if stored cse version (from the previous boot) is same as current - * running cse version. - */ - if (memcmp(&version->ish_partition_info.prev_cse_fw_version, - &version->cur_cse_fw_version, sizeof(struct fw_version))) { - /* - * Current running CSE version is different than previous stored CSE version - * which could be due to CSE update or rollback, hence, need to send ISHC - * partition info cmd to know the currently running ISH version. - */ - - struct fw_version_resp resp; - if (cse_get_fpt_partition_info(FPT_PARTITION_NAME_ISHC, &resp) == CB_SUCCESS) { - /* Update stored cse version with current version */ - memcpy(&(version->ish_partition_info.prev_cse_fw_version), - &(version->cur_cse_fw_version), size); - - /* Since cse version has been updated, ish version needs to be updated. */ - memcpy(&(version->ish_partition_info.cur_ish_fw_version), - &(resp.manifest_data.version), size); - } - } -} +#endif
/* * Helper function that stores current CSE firmware version and ISH version to @@ -1319,16 +1275,39 @@ set_cmos_cse_version(&(cse_bp->fw_ver));
/* write cse rw fw version to CBMEM */ - memcpy(&(cbmem_fw->cur_cse_fw_version), &(cse_bp->fw_ver), sizeof(struct fw_version)); + memcpy(&(cbmem_fw->cse_version), &(cse_bp->fw_ver), sizeof(struct fw_version)); +#if CONFIG_SOC_INTEL_STORE_ISH_VERSION + /* Get current ISH firmware version from CSE */ + struct fw_version_resp resp; + if (cse_get_fpt_partition_info(FPT_PARTITION_NAME_ISHC, &resp) == CB_SUCCESS) { + /* + * Since cse version has been updated, ish version needs to be updated in + * both CMOS and CBMEM memory. + */ + set_cmos_ish_version(&(resp.manifest_data.version)); + memcpy(&(cbmem_fw->ish_version), + &(resp.manifest_data.version), vers_size); + } +#endif } else { /* Current running CSE version is same as previous stored CSE version */
- if (memcmp(&(cbmem_fw->cur_cse_fw_version), &(cse_bp->fw_ver), vers_size)) { + if (memcmp(&(cbmem_fw->cse_version), &(cse_bp->fw_ver), vers_size)) { /* * The CBMEM memory was reset during cold reboot, so the CSE version in * CBMEM needs to be updated to the version stored in CMOS. */ - memcpy(&(cbmem_fw->cur_cse_fw_version), &(cse_bp->fw_ver), sizeof(struct fw_version)); + memcpy(&(cbmem_fw->cse_version), &(cse_bp->fw_ver), sizeof(struct fw_version)); +#if CONFIG_SOC_INTEL_STORE_ISH_VERSION + struct fw_version cmos_ish_version; + get_cmos_ish_version(&cmos_ish_version); + /* + * The CBMEM memory was reset during cold reboot, so the ISH version in + * CBMEM needs to be updated to the version stored in CMOS. + */ + memcpy(&(cbmem_fw->ish_version), + &cmos_ish_version, vers_size); +#endif } } } @@ -1348,7 +1327,6 @@ if (CONFIG(SOC_INTEL_STORE_CSE_FPT_PARTITION_VERSION) && soc_is_ish_partition_enabled()) { store_cse_fw_partition_version_info(); - store_ish_version(); } }
diff --git a/src/soc/intel/common/block/include/intelblocks/cse.h b/src/soc/intel/common/block/include/intelblocks/cse.h index e23796a..568cb10 100644 --- a/src/soc/intel/common/block/include/intelblocks/cse.h +++ b/src/soc/intel/common/block/include/intelblocks/cse.h @@ -148,16 +148,12 @@ struct flash_partition_data manifest_data; };
-/* ISHC version */ -struct cse_fw_ish_version_info { - struct fw_version prev_cse_fw_version; - struct fw_version cur_ish_fw_version; -}; - /* CSE and ISHC version */ struct cse_fw_partition_info { - struct fw_version cur_cse_fw_version; - struct cse_fw_ish_version_info ish_partition_info; + struct fw_version cse_version; +#if CONFIG_SOC_INTEL_STORE_ISH_VERSION + struct fw_version ish_version; +#endif };
/* CSE RX and TX error status */ diff --git a/src/soc/intel/common/block/include/intelblocks/cse_cmos.h b/src/soc/intel/common/block/include/intelblocks/cse_cmos.h index 8026a19..1bc2b51 100644 --- a/src/soc/intel/common/block/include/intelblocks/cse_cmos.h +++ b/src/soc/intel/common/block/include/intelblocks/cse_cmos.h @@ -1,14 +1,18 @@ -/* SPDX-License-Identifier: GPL-2.0-only */
+/* SPDX-License-Identifier: GPL-2.0-only */ #ifndef SOC_INTEL_COMMON_BLOCK_CSE_CMOS_H #define SOC_INTEL_COMMON_BLOCK_CSE_CMOS_H - #include <intelblocks/cse.h> - /* Function to get the cse version stored in CMOS memory */ void get_cmos_cse_version(struct fw_version *cse_version); - /* Function to update the cse version stored in CMOS memory */ void set_cmos_cse_version(const struct fw_version *cse_version);
+#if CONFIG_SOC_INTEL_STORE_ISH_VERSION +/* Function to get the ish version stored in CMOS memory */ +void get_cmos_ish_version(struct fw_version *ish_version); +/* Function to update the ish version stored in CMOS memory */ +void set_cmos_ish_version(const struct fw_version *ish_version); +#endif /* SOC_INTEL_STORE_ISH_VERSION */ + #endif /* SOC_INTEL_COMMON_BLOCK_CSE_CMOS_H */