Subrata Banik has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/75899?usp=email )
Change subject: Use MRC version for storing MRC cache instead FSP version ......................................................................
Use MRC version for storing MRC cache instead FSP version
So far FSP version is getting used to store the MRC cache hence, MRC cache is getting erase and retrain the memory with every FSP uprev (irrespective of whether MRC is being uprev'ed or not)
TEST=Try below scenarios on google/rex
FSP version: 0D.00.7B.41 MRC version: 07.18.01
update the FSP version alone (w/o changing the MRC version)
uprev FSP version: 0D.00.7B.42 MRC version: 07.18.01
w/o this patch:
Result: Retrain the complete memory as coreboot erased the mrc cache due to FSP version mismatch.
w/ this patch:
Result: Utilize the existing MRC cache and skip memory retraining. Improve the user experience during in-field FW update where save boot time by not doing memory training as MRC is not being updated although FSP is getting uprev'ed.
Change-Id: I82faac3fe600d2b37103e25357f6cf3c2310875c Signed-off-by: Subrata Banik subratabanik@google.com --- M src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h M src/drivers/intel/fsp2_0/Kconfig M src/drivers/intel/fsp2_0/include/fsp/soc_binding.h M src/drivers/intel/fsp2_0/memory_init.c M src/drivers/intel/fsp2_0/save_mrc_data.c M src/soc/intel/meteorlake/Kconfig 6 files changed, 82 insertions(+), 21 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/99/75899/1
diff --git a/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h b/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h index 5080812..fd752b0 100644 --- a/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h +++ b/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h @@ -27,6 +27,7 @@ #define CBMEM_ID_FSP_RESERVED_MEMORY 0x46535052 #define CBMEM_ID_FSP_RUNTIME 0x52505346 #define CBMEM_ID_FSPM_VERSION 0x56505346 +#define CBMEM_ID_MRC_VERSION 0x5f43524d #define CBMEM_ID_GDT 0x4c474454 #define CBMEM_ID_HOB_POINTER 0x484f4221 #define CBMEM_ID_IGD_OPREGION 0x4f444749 @@ -112,6 +113,7 @@ { CBMEM_ID_FSP_RESERVED_MEMORY, "FSP MEMORY " }, \ { CBMEM_ID_FSP_RUNTIME, "FSP RUNTIME" }, \ { CBMEM_ID_FSPM_VERSION, "FSPM VERSION" }, \ + { CBMEM_ID_MRC_VERSION, "MRC VERSION" }, \ { CBMEM_ID_GDT, "GDT " }, \ { CBMEM_ID_HOB_POINTER, "HOB " }, \ { CBMEM_ID_IGD_OPREGION, "IGD OPREGION" }, \ diff --git a/src/drivers/intel/fsp2_0/Kconfig b/src/drivers/intel/fsp2_0/Kconfig index 378f4fb..310bac7 100644 --- a/src/drivers/intel/fsp2_0/Kconfig +++ b/src/drivers/intel/fsp2_0/Kconfig @@ -402,4 +402,12 @@ reported with Alder Lake and Raptor Lake FSP where MultiPhaseSiInit API is unable to return any ERROR status.
+config FSP_HEADER_HAS_MRC_VERSION_INFO + bool + default n + help + Select this Kconfig if FSP binary for platforms that have MRC version part of + FSP_PRODUCER_DATA_TABLES. FSP_PRODUCER_DATA_TABLES defined in `FspProducerDataHeader.h` + file. + endif diff --git a/src/drivers/intel/fsp2_0/include/fsp/soc_binding.h b/src/drivers/intel/fsp2_0/include/fsp/soc_binding.h index 02cd4e0..40110a6 100644 --- a/src/drivers/intel/fsp2_0/include/fsp/soc_binding.h +++ b/src/drivers/intel/fsp2_0/include/fsp/soc_binding.h @@ -27,6 +27,10 @@ #include <Base.h> #include <FspmUpd.h> #include <FspsUpd.h> +#if CONFIG(FSP_HEADER_HAS_MRC_VERSION_INFO) +#define BUILD_TIME_STAMP_SIZE 12 +#include <FspProducerDataHeader.h> +#endif #if CONFIG(DISPLAY_FSP_VERSION_INFO) #include <FirmwareVersionInfoHob.h> #elif CONFIG(DISPLAY_FSP_VERSION_INFO_2) diff --git a/src/drivers/intel/fsp2_0/memory_init.c b/src/drivers/intel/fsp2_0/memory_init.c index 6d25844..39fa963 100644 --- a/src/drivers/intel/fsp2_0/memory_init.c +++ b/src/drivers/intel/fsp2_0/memory_init.c @@ -30,10 +30,11 @@
static uint8_t temp_ram[CONFIG_FSP_TEMP_RAM_SIZE] __aligned(sizeof(uint64_t));
-static void do_fsp_post_memory_init(bool s3wake, uint32_t fsp_version) +static void do_fsp_post_memory_init(bool s3wake, uint32_t version) { struct range_entry fsp_mem; uint32_t *fsp_version_cbmem; + uint32_t *mrc_version_cbmem;
fsp_find_reserved_memory(&fsp_mem);
@@ -56,20 +57,29 @@ (uintptr_t)cbmem_find(CBMEM_ID_FSP_RESERVED_MEMORY)) die("Failed to accommodate FSP reserved memory request!\n");
- /* ramstage uses the FSP-M version when updating the MRC cache */ if (CONFIG(CACHE_MRC_SETTINGS) && !s3wake) { - fsp_version_cbmem = cbmem_add(CBMEM_ID_FSPM_VERSION, - sizeof(fsp_version)); - if (!fsp_version_cbmem) - printk(BIOS_ERR, "Failed to add FSP-M version to cbmem.\n"); - *fsp_version_cbmem = fsp_version; + if (CONFIG(FSP_HEADER_HAS_MRC_VERSION_INFO)) { + /* ramstage uses the MRC version when updating the MRC cache */ + mrc_version_cbmem = cbmem_add(CBMEM_ID_MRC_VERSION, + sizeof(version)); + if (!mrc_version_cbmem) + printk(BIOS_ERR, "Failed to add MRC version to cbmem.\n"); + *mrc_version_cbmem = version; + } else { + /* ramstage uses the FSP-M version when updating the MRC cache */ + fsp_version_cbmem = cbmem_add(CBMEM_ID_FSPM_VERSION, + sizeof(version)); + if (!fsp_version_cbmem) + printk(BIOS_ERR, "Failed to add FSP-M version to cbmem.\n"); + *fsp_version_cbmem = version; + } }
/* Create romstage handof information */ romstage_handoff_init(s3wake); }
-static void fsp_fill_mrc_cache(FSPM_ARCH_UPD *arch_upd, uint32_t fsp_version) +static void fsp_fill_mrc_cache(FSPM_ARCH_UPD *arch_upd, uint32_t version) { void *data; size_t mrc_size; @@ -82,7 +92,7 @@ /* Assume boot device is memory mapped. */ assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));
- data = mrc_cache_current_mmap_leak(MRC_TRAINING_DATA, fsp_version, + data = mrc_cache_current_mmap_leak(MRC_TRAINING_DATA, version, &mrc_size); if (data == NULL) return; @@ -134,7 +144,7 @@ }
static enum cb_err fsp_fill_common_arch_params(FSPM_ARCH_UPD *arch_upd, - bool s3wake, uint32_t fsp_version, + bool s3wake, uint32_t version, const struct memranges *memmap) { /* @@ -152,7 +162,7 @@ return CB_ERR; }
- fsp_fill_mrc_cache(arch_upd, fsp_version); + fsp_fill_mrc_cache(arch_upd, version);
/* Configure bootmode */ if (s3wake) { @@ -210,19 +220,51 @@ struct memranges memmap; };
+#if CONFIG(FSP_HEADER_HAS_MRC_VERSION_INFO) +/* + * Helper function to read MRC version + * + * There are multiple ways to read the MRC version using + * Intel FSP. Currently the only supported method to read + * MRC by reading the FSP_PRODUCER_DATA_TABLES (part of the + * FSP binary). + */ +static uint32_t fsp_mrc_version(void) +{ + uint32_t ver = 0; + size_t fspm_blob_size; + void *fspm_blob_file = cbfs_map(CONFIG_FSP_M_CBFS, &fspm_blob_size); + if (!fspm_blob_file) + return 0; + + FSP_PRODUCER_DATA_TABLES *ft = fspm_blob_file + FSP_HDR_OFFSET; + FSP_PRODUCER_DATA_TYPE2 *table2 = &ft->FspProduceDataType2; + size_t mrc_version_size = sizeof(table2->MrcVersion); + for (size_t i = 0; i < mrc_version_size; i++) { + ver |= (table2->MrcVersion[i] << ((mrc_version_size - 1) - i) * 8); + } + cbfs_unmap(fspm_blob_file); + return ver; +} +#endif + static void do_fsp_memory_init(const struct fspm_context *context, bool s3wake) { uint32_t status; fsp_memory_init_fn fsp_raminit; FSPM_UPD fspm_upd, *upd; FSPM_ARCH_UPD *arch_upd; - uint32_t fsp_version; + uint32_t version; const struct fsp_header *hdr = &context->header; const struct memranges *memmap = &context->memmap;
post_code(POST_MEM_PREINIT_PREP_START);
- fsp_version = fsp_memory_settings_version(hdr); + version = fsp_memory_settings_version(hdr); +#if CONFIG(FSP_HEADER_HAS_MRC_VERSION_INFO) + version = fsp_mrc_version(); + printk(BIOS_ERR, "Subrata MRC version = %x\n", version); +#endif
upd = (FSPM_UPD *)(uintptr_t)(hdr->cfg_region_offset + hdr->image_base);
@@ -254,7 +296,7 @@ arch_upd->BootLoaderTolumSize = cbmem_overhead_size();
/* Fill common settings on behalf of chipset. */ - if (fsp_fill_common_arch_params(arch_upd, s3wake, fsp_version, + if (fsp_fill_common_arch_params(arch_upd, s3wake, version, memmap) != CB_SUCCESS) die_with_post_code(POST_INVALID_VENDOR_BINARY, "FSPM_ARCH_UPD not found!\n"); @@ -266,7 +308,7 @@ #endif
/* Give SoC and mainboard a chance to update the UPD */ - platform_fsp_memory_init_params_cb(&fspm_upd, fsp_version); + platform_fsp_memory_init_params_cb(&fspm_upd, version);
/* * For S3 resume case, if valid mrc cache data is not found or @@ -309,7 +351,7 @@ "FspMemoryInit returned with error 0x%08x!\n", status); }
- do_fsp_post_memory_init(s3wake, fsp_version); + do_fsp_post_memory_init(s3wake, version);
/* * fsp_debug_after_memory_init() checks whether the end of the tolum diff --git a/src/drivers/intel/fsp2_0/save_mrc_data.c b/src/drivers/intel/fsp2_0/save_mrc_data.c index 8550b68..830f10a8 100644 --- a/src/drivers/intel/fsp2_0/save_mrc_data.c +++ b/src/drivers/intel/fsp2_0/save_mrc_data.c @@ -11,14 +11,18 @@ { size_t mrc_data_size; const void *mrc_data; - uint32_t *fspm_version; + uint32_t *version;
if (acpi_is_wakeup_s3()) return;
- fspm_version = cbmem_find(CBMEM_ID_FSPM_VERSION); - if (!fspm_version) { - printk(BIOS_ERR, "Failed to read FSP-M version from cbmem.\n"); + if (CONFIG(FSP_HEADER_HAS_MRC_VERSION_INFO)) + version = cbmem_find(CBMEM_ID_MRC_VERSION); + else + version = cbmem_find(CBMEM_ID_FSPM_VERSION); + + if (!version) { + printk(BIOS_ERR, "Failed to read FSP-M/MRC version from cbmem.\n"); return; }
@@ -34,7 +38,7 @@ * code which saves the data to flash doesn't write if the latest * training data matches this one. */ - if (mrc_cache_stash_data(MRC_TRAINING_DATA, *fspm_version, mrc_data, + if (mrc_cache_stash_data(MRC_TRAINING_DATA, *version, mrc_data, mrc_data_size) < 0) printk(BIOS_ERR, "Failed to stash MRC data\n"); } diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index 0bcbcf2..80915a9 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -117,6 +117,7 @@ select X86_CLFLUSH_CAR select X86_INIT_NEED_1_SIPI select INTEL_KEYLOCKER + select FSP_HEADER_HAS_MRC_VERSION_INFO
config SOC_INTEL_METEORLAKE_TCSS_USB4_SUPPORT bool