soc/intel/cmn/cse: Refactor CSE RW FW Version implementation
This patch introduces a CSE firmware specific data in order to store Intel CSE and associated firmware related information which requires a sync between Pre-RAM and Post-RAM phase. This information will be used further to retrieve currently running CSE RW firmware instead of fetching the version information by sending a HECI cmd (which consumes 7ms-15ms depending upon the CSE operational state). Current implementation attempts to simply the CSE RW FW version store and retrieval operations as below * CSE sync in romstage (aka Pre-RAM) - Relying on .bss segment to store the CSE info data in absence of real physical memory and sync back into the CBMEM once available (after FSP-M exits). * CSE sync in ramstage (aka Post-RAM) - Directly stored the CSE RW version into the CBMEM (as CBMEM is online). BUG=b:285405031 TEST=Able to build and boot google/rex. Verified CSE RW FW version (for LITE SKU) is getting displayed without impacting the boot time. w/o this patch: 10:start of ramstage 722,257 (43) 17:starting LZ4 decompress (ignore for x86) 723,777 (1,520) w/ this patch: 10:start of ramstage 722,257 (43) 17:starting LZ4 decompress (ignore for x86) 723,777 (1,520) Change-Id: Ia873af512851a682cf1fac0e128d842562a316ab Signed-off-by: Subrata Banik <subratabanik@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/77174 Reviewed-by: Julius Werner <jwerner@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Rizwan Qureshi <rizwan.qureshi@intel.com>
This commit is contained in:
parent
5ba16d02b6
commit
65a6d1714d
|
@ -88,6 +88,7 @@
|
|||
#define CBMEM_ID_AMD_STB 0x5f425453
|
||||
#define CBMEM_ID_AMD_MP2 0x5f32504d
|
||||
#define CBMEM_ID_CSE_PARTITION_VERSION 0x43535056
|
||||
#define CBMEM_ID_CSE_INFO 0x4553435F
|
||||
|
||||
#define CBMEM_ID_TO_NAME_TABLE \
|
||||
{ CBMEM_ID_ACPI, "ACPI " }, \
|
||||
|
@ -168,5 +169,6 @@
|
|||
{ CBMEM_ID_MEM_CHIP_INFO, "MEM CHIP INFO"},\
|
||||
{ CBMEM_ID_AMD_STB, "AMD STB"},\
|
||||
{ CBMEM_ID_AMD_MP2, "AMD MP2 BUFFER"},\
|
||||
{ CBMEM_ID_CSE_PARTITION_VERSION, "CSE PARTITION VERSION"}
|
||||
{ CBMEM_ID_CSE_PARTITION_VERSION, "CSE PARTITION VERSION"},\
|
||||
{ CBMEM_ID_CSE_INFO, "CSE SPECIFIC INFORMATION"}
|
||||
#endif /* _CBMEM_ID_H_ */
|
||||
|
|
|
@ -1420,15 +1420,15 @@ void cse_late_finalize(void)
|
|||
|
||||
static void intel_cse_get_rw_version(void)
|
||||
{
|
||||
struct cse_fw_partition_info *version = cbmem_find(CBMEM_ID_CSE_PARTITION_VERSION);
|
||||
if (version == NULL)
|
||||
struct cse_specific_info *info = cbmem_find(CBMEM_ID_CSE_INFO);
|
||||
if (info == NULL)
|
||||
return;
|
||||
|
||||
printk(BIOS_DEBUG, "CSE RW Firmware 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);
|
||||
info->cse_fwp_version.cur_cse_fw_version.major,
|
||||
info->cse_fwp_version.cur_cse_fw_version.minor,
|
||||
info->cse_fwp_version.cur_cse_fw_version.hotfix,
|
||||
info->cse_fwp_version.cur_cse_fw_version.build);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <commonlib/region.h>
|
||||
#include <console/console.h>
|
||||
#include <cpu/cpu.h>
|
||||
#include <crc_byte.h>
|
||||
#include <fmap.h>
|
||||
#include <intelbasecode/debug_feature.h>
|
||||
#include <intelblocks/cse.h>
|
||||
|
@ -134,6 +135,8 @@ struct get_bp_info_rsp {
|
|||
|
||||
static const char * const cse_regions[] = {"RO", "RW"};
|
||||
|
||||
static struct cse_specific_info cse_info;
|
||||
|
||||
void cse_log_ro_write_protection_info(bool mfg_mode)
|
||||
{
|
||||
bool cse_ro_wp_en = is_spi_wp_cse_ro_en();
|
||||
|
@ -198,6 +201,88 @@ static const struct cse_bp_entry *cse_get_bp_entry(enum boot_partition_id bp,
|
|||
return &cse_bp_info->bp_entries[bp];
|
||||
}
|
||||
|
||||
static bool is_cbmem_cse_info_valid(const struct cse_specific_info *info)
|
||||
{
|
||||
uint32_t crc = ~CRC(info, offsetof(struct cse_specific_info, crc), crc32_byte);
|
||||
|
||||
/*
|
||||
* Authenticate the CBMEM persistent data.
|
||||
*
|
||||
* The underlying assumption is that an event (i.e., CSE upgrade/downgrade) which
|
||||
* could change the values stored in this region has to also trigger the global
|
||||
* reset. Hence, CBMEM persistent data won't be available any time after such
|
||||
* event (global reset or cold reset) being initiated.
|
||||
*
|
||||
* During warm boot scenarios CBMEM contents remain persistent hence, we don't
|
||||
* want to override the existing data in CBMEM to avoid any additional boot latency.
|
||||
*/
|
||||
if (info->crc != crc)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void cbmem_store_cse_info_crc(struct cse_specific_info *info)
|
||||
{
|
||||
info->crc = ~CRC(info, offsetof(struct cse_specific_info, crc), crc32_byte);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function that stores current CSE firmware version to CBMEM memory,
|
||||
* except during recovery mode.
|
||||
*/
|
||||
static void cse_store_rw_fw_version(const struct cse_bp_entry *cse_bp)
|
||||
{
|
||||
if (vboot_recovery_mode_enabled())
|
||||
return;
|
||||
|
||||
if (CONFIG(SOC_INTEL_CSE_LITE_SYNC_IN_ROMSTAGE)) {
|
||||
memcpy(&(cse_info.cse_fwp_version.cur_cse_fw_version), &(cse_bp->fw_ver),
|
||||
sizeof(struct fw_version));
|
||||
return;
|
||||
}
|
||||
|
||||
struct cse_specific_info *info = cbmem_add(CBMEM_ID_CSE_INFO, sizeof(*info));
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
/* Avoid CBMEM update if CBMEM already has persistent data */
|
||||
if (is_cbmem_cse_info_valid(info))
|
||||
return;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
memcpy(&(info->cse_fwp_version.cur_cse_fw_version), &(cse_bp->fw_ver),
|
||||
sizeof(struct fw_version));
|
||||
|
||||
/* Update the CRC */
|
||||
cbmem_store_cse_info_crc(info);
|
||||
}
|
||||
|
||||
#if CONFIG(SOC_INTEL_CSE_LITE_SYNC_IN_ROMSTAGE)
|
||||
/* Function to copy PRERAM CSE specific info to pertinent CBMEM. */
|
||||
static void preram_cse_info_sync_to_cbmem(int is_recovery)
|
||||
{
|
||||
if (vboot_recovery_mode_enabled() || !CONFIG(SOC_INTEL_STORE_CSE_FW_VERSION))
|
||||
return;
|
||||
|
||||
struct cse_specific_info *info = cbmem_add(CBMEM_ID_CSE_INFO, sizeof(*info));
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
/* Avoid sync into CBMEM if CBMEM already has persistent data */
|
||||
if (is_cbmem_cse_info_valid(info))
|
||||
return;
|
||||
|
||||
memcpy(info, &cse_info, sizeof(struct cse_specific_info));
|
||||
|
||||
/* Update the CRC */
|
||||
cbmem_store_cse_info_crc(info);
|
||||
}
|
||||
|
||||
CBMEM_CREATION_HOOK(preram_cse_info_sync_to_cbmem);
|
||||
#endif
|
||||
|
||||
static void cse_print_boot_partition_info(const struct cse_bp_info *cse_bp_info)
|
||||
{
|
||||
const struct cse_bp_entry *cse_bp;
|
||||
|
@ -223,6 +308,10 @@ static void cse_print_boot_partition_info(const struct cse_bp_info *cse_bp_info)
|
|||
cse_bp->fw_ver.hotfix, cse_bp->fw_ver.build,
|
||||
cse_bp->status, cse_bp->start_offset,
|
||||
cse_bp->end_offset);
|
||||
|
||||
/* Store the CSE RW Firmware Version into CBMEM */
|
||||
if (CONFIG(SOC_INTEL_STORE_CSE_FW_VERSION))
|
||||
cse_store_rw_fw_version(cse_bp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1171,26 +1260,6 @@ 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 cse_store_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) != CB_SUCCESS) {
|
||||
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)
|
||||
{
|
||||
|
@ -1303,9 +1372,6 @@ static void ramstage_cse_misc_ops(void *unused)
|
|||
if (CONFIG(SOC_INTEL_CSE_LITE_SYNC_IN_RAMSTAGE))
|
||||
cse_fw_sync();
|
||||
|
||||
/* Store the CSE RW Firmware Version into CBMEM */
|
||||
if (CONFIG(SOC_INTEL_STORE_CSE_FW_VERSION))
|
||||
cse_store_rw_fw_version();
|
||||
/*
|
||||
* Store the ISH RW Firmware Version into CBMEM if ISH partition
|
||||
* is available
|
||||
|
|
|
@ -160,6 +160,13 @@ struct cse_fw_partition_info {
|
|||
struct cse_fw_ish_version_info ish_partition_info;
|
||||
};
|
||||
|
||||
/* CSE Specific Information */
|
||||
struct cse_specific_info {
|
||||
struct cse_fw_partition_info cse_fwp_version;
|
||||
bool cse_downgrade_requested;
|
||||
uint32_t crc;
|
||||
};
|
||||
|
||||
/* CSE RX and TX error status */
|
||||
enum cse_tx_rx_status {
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue