diff --git a/src/soc/intel/common/block/cse/cse_lite.c b/src/soc/intel/common/block/cse/cse_lite.c index f7ebed07e5..4cc4f51d86 100644 --- a/src/soc/intel/common/block/cse/cse_lite.c +++ b/src/soc/intel/common/block/cse/cse_lite.c @@ -1236,6 +1236,52 @@ 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); } +/* + * 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); + } + } +} + static void ramstage_cse_misc_ops(void *unused) { if (acpi_get_sleep_type() == ACPI_S3) @@ -1245,12 +1291,14 @@ static void ramstage_cse_misc_ops(void *unused) cse_fw_sync(); /* - * Store the CSE RW Firmware Version into CBMEM if ISH partition + * Store the CSE/ISH RW Firmware Version into CBMEM if ISH partition * is available */ if (CONFIG(SOC_INTEL_STORE_CSE_FPT_PARTITION_VERSION) && - soc_is_ish_partition_enabled()) + soc_is_ish_partition_enabled()) { store_cse_rw_fw_version(); + store_ish_version(); + } } BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_EXIT, ramstage_cse_misc_ops, NULL);