summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h4
-rw-r--r--src/soc/intel/common/block/cse/Kconfig21
-rw-r--r--src/soc/intel/common/block/cse/cse_lite.c32
-rw-r--r--src/soc/intel/common/block/include/intelblocks/cse.h33
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.
*/