summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSubrata Banik <subratabanik@google.com>2023-04-14 01:31:29 +0530
committerFelix Held <felix-coreboot@felixheld.de>2023-04-21 17:22:00 +0000
commitfc313d655fa1074ad68c48dd4eec3ecb607ea003 (patch)
tree5e023ced968e55c7e875aaf27259e5b03857eb5d
parent4b94f1dc874af4c851db28b70a0e0330748f2f08 (diff)
{commonlib, soc/intel/cmn/cse}: Store CSE firmware version into CBMEM
The patch implements an API that stores the CSE firmware version in the CBMEM table. The API will be called from RAMSTAGE based on boot state machine BS_PRE_DEVICE/BS_ON_EXIT Additionally, renamed ramstage_cse_fw_sync() to ramstage_cse_misc_ops() in order to add more CSE related operations at ramstage. This patch also adds a configuration option, 'SOC_INTEL_STORE_CSE_FPT_PARTITION_VERSION', which enables the storage of firmware version information in CBMEM memory. This information can be used to identify the firmware version that is currently installed on the system. The option depends on the `DRIVERS_INTEL_ISH` config and platform should be flexible enough to opt out from enabling this feature. 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. Finally, ensure this feature is platform specific hence, getting enabled for the platform that would like to store the ISH version into the CBMEM and parse to perform some additional work. BUG=b:273661726 TEST=Able to build and boot google/marasov. Signed-off-by: Dinesh Gehlot <digehlot@google.com> Change-Id: I923049d2f1f589f87e1a29e1ac94af7f5fccc2c8 Reviewed-on: https://review.coreboot.org/c/coreboot/+/74256 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
-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.
*/