diff options
-rw-r--r-- | src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h | 4 | ||||
-rw-r--r-- | src/soc/intel/common/block/cse/Kconfig | 21 | ||||
-rw-r--r-- | src/soc/intel/common/block/cse/cse_lite.c | 32 | ||||
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/cse.h | 33 |
4 files changed, 87 insertions, 3 deletions
diff --git a/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h b/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h index fa5c8d9e94..4162d84c73 100644 --- a/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h +++ b/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h @@ -85,6 +85,7 @@ #define CBMEM_ID_MEM_CHIP_INFO 0x5048434D #define CBMEM_ID_AMD_STB 0x5f425453 #define CBMEM_ID_AMD_MP2 0x5f32504d +#define CBMEM_ID_CSE_PARTITION_VERSION 0x43535056 #define CBMEM_ID_TO_NAME_TABLE \ { CBMEM_ID_ACPI, "ACPI " }, \ @@ -163,5 +164,6 @@ { CBMEM_ID_TYPE_C_INFO, "TYPE_C INFO"},\ { CBMEM_ID_MEM_CHIP_INFO, "MEM CHIP INFO"},\ { CBMEM_ID_AMD_STB, "AMD STB"},\ - { CBMEM_ID_AMD_MP2, "AMD MP2 BUFFER"} + { CBMEM_ID_AMD_MP2, "AMD MP2 BUFFER"},\ + { CBMEM_ID_CSE_PARTITION_VERSION, "CSE PARTITION VERSION"} #endif /* _CBMEM_ID_H_ */ diff --git a/src/soc/intel/common/block/cse/Kconfig b/src/soc/intel/common/block/cse/Kconfig index 33d703fb50..73cb51bc7f 100644 --- a/src/soc/intel/common/block/cse/Kconfig +++ b/src/soc/intel/common/block/cse/Kconfig @@ -45,6 +45,27 @@ config SOC_INTEL_COMMON_BLOCK_HECI1_DISABLE_USING_PCR Use this config for SoC platform prior to CNL PCH (with postboot_sai implemented) to make `HECI1` device disable using private configuration register (PCR) write. +config SOC_INTEL_STORE_CSE_FPT_PARTITION_VERSION + bool + default n + depends on DRIVERS_INTEL_ISH + help + This configuration option stores CSE FPT partitions' version in CBMEM memory. + This information can be used to identify the currently running firmware partition + version. + + The cost of sending HECI command to read the CSE FPT is significant (~200ms) + hence, the idea is to read the CSE RW version on every cold reset (to cover + the CSE update scenarios) and store into CBMEM to avoid the cost of resending + the HECI command in all consecutive warm boots. + + Later boot stages can just read the CBMEM ID to retrieve the ISH version if + required. + + Additionally, ensure this feature is platform specific hence, only enabled + for the platform that would like to store the ISH version into the CBMEM and + parse to perform some additional work. + config SOC_INTEL_CSE_SEND_EOP_EARLY bool "CSE send EOP early" depends on SOC_INTEL_COMMON_BLOCK_CSE diff --git a/src/soc/intel/common/block/cse/cse_lite.c b/src/soc/intel/common/block/cse/cse_lite.c index 14a73814bf..f7ebed07e5 100644 --- a/src/soc/intel/common/block/cse/cse_lite.c +++ b/src/soc/intel/common/block/cse/cse_lite.c @@ -1159,6 +1159,26 @@ void cse_fw_sync(void) timestamp_add_now(TS_CSE_FW_SYNC_END); } +/* + * Helper function that stores current CSE firmware version to CBMEM memory, + * except during recovery mode. + */ +static void store_cse_rw_fw_version(void) +{ + if (vboot_recovery_mode_enabled()) + return; + + struct get_bp_info_rsp cse_bp_info; + if (!cse_get_bp_info(&cse_bp_info)) { + printk(BIOS_ERR, "cse_lite: Failed to get CSE boot partition info\n"); + return; + } + const struct cse_bp_entry *cse_bp = cse_get_bp_entry(RW, &cse_bp_info.bp_info); + struct cse_fw_partition_info *version; + version = cbmem_add(CBMEM_ID_CSE_PARTITION_VERSION, sizeof(*version)); + memcpy(&(version->cur_cse_fw_version), &(cse_bp->fw_ver), sizeof(struct fw_version)); +} + static enum cb_err send_get_fpt_partition_info_cmd(enum fpt_partition_id id, struct fw_version_resp *resp) { @@ -1216,13 +1236,21 @@ enum cb_err cse_get_fpt_partition_info(enum fpt_partition_id id, struct fw_versi return send_get_fpt_partition_info_cmd(id, resp); } -static void ramstage_cse_fw_sync(void *unused) +static void ramstage_cse_misc_ops(void *unused) { if (acpi_get_sleep_type() == ACPI_S3) return; if (CONFIG(SOC_INTEL_CSE_LITE_SYNC_IN_RAMSTAGE)) cse_fw_sync(); + + /* + * Store the CSE RW Firmware Version into CBMEM if ISH partition + * is available + */ + if (CONFIG(SOC_INTEL_STORE_CSE_FPT_PARTITION_VERSION) && + soc_is_ish_partition_enabled()) + store_cse_rw_fw_version(); } -BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_EXIT, ramstage_cse_fw_sync, NULL); +BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_EXIT, ramstage_cse_misc_ops, NULL); diff --git a/src/soc/intel/common/block/include/intelblocks/cse.h b/src/soc/intel/common/block/include/intelblocks/cse.h index 6b708cab1e..f3a7f83666 100644 --- a/src/soc/intel/common/block/include/intelblocks/cse.h +++ b/src/soc/intel/common/block/include/intelblocks/cse.h @@ -144,6 +144,18 @@ struct fw_version_resp { 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; +}; + /* CSE RX and TX error status */ enum cse_tx_rx_status { /* @@ -502,6 +514,27 @@ void cse_late_finalize(void); void soc_disable_heci1_using_pcr(void); /* + * SoC override API to identify if ISH Firmware existed inside CSE FPT. + * + * This override is required to avoid making default call into non-ISH + * supported SKU to attempt to retrieve ISH version which would results into + * increased boot time by 100ms+. + * + * Ideally SoC with UFS enabled would like to keep ISH enabled as well, hence + * identifying the UFS enabled device is enough to conclude if ISH partition is + * available. + */ +#if CONFIG(SOC_INTEL_STORE_CSE_FPT_PARTITION_VERSION) +bool soc_is_ish_partition_enabled(void); +#else +static inline bool soc_is_ish_partition_enabled(void) +{ + /* Default implementation, ISH not enabled. */ + return false; +} +#endif + +/* * Injects CSE timestamps into cbmem timestamp table. SoC code needs to * implement it since timestamp definitions differ from SoC to SoC. */ |