summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h2
-rw-r--r--src/drivers/intel/fsp2_0/Makefile.inc1
-rw-r--r--src/drivers/intel/fsp2_0/memory_init.c33
-rw-r--r--src/drivers/intel/fsp2_0/save_mrc_data.c46
4 files changed, 58 insertions, 24 deletions
diff --git a/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h b/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h
index 1e63c6622c..d0feb39af9 100644
--- a/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h
+++ b/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h
@@ -26,6 +26,7 @@
#define CBMEM_ID_FREESPACE 0x46524545
#define CBMEM_ID_FSP_RESERVED_MEMORY 0x46535052
#define CBMEM_ID_FSP_RUNTIME 0x52505346
+#define CBMEM_ID_FSPM_VERSION 0x56505346
#define CBMEM_ID_GDT 0x4c474454
#define CBMEM_ID_HOB_POINTER 0x484f4221
#define CBMEM_ID_IGD_OPREGION 0x4f444749
@@ -108,6 +109,7 @@
{ CBMEM_ID_FREESPACE, "FREE SPACE " }, \
{ CBMEM_ID_FSP_RESERVED_MEMORY, "FSP MEMORY " }, \
{ CBMEM_ID_FSP_RUNTIME, "FSP RUNTIME" }, \
+ { CBMEM_ID_FSPM_VERSION, "FSPM VERSION" }, \
{ CBMEM_ID_GDT, "GDT " }, \
{ CBMEM_ID_HOB_POINTER, "HOB " }, \
{ CBMEM_ID_IGD_OPREGION, "IGD OPREGION" }, \
diff --git a/src/drivers/intel/fsp2_0/Makefile.inc b/src/drivers/intel/fsp2_0/Makefile.inc
index f5641ac182..f11ebee102 100644
--- a/src/drivers/intel/fsp2_0/Makefile.inc
+++ b/src/drivers/intel/fsp2_0/Makefile.inc
@@ -29,6 +29,7 @@ ramstage-y += notify.c
ramstage-y += silicon_init.c
ramstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c
ramstage-y += util.c
+ramstage-$(CONFIG_CACHE_MRC_SETTINGS) += save_mrc_data.c
ramstage-$(CONFIG_MMA) += mma_core.c
ifneq ($(CONFIG_NO_FSP_TEMP_RAM_EXIT),y)
diff --git a/src/drivers/intel/fsp2_0/memory_init.c b/src/drivers/intel/fsp2_0/memory_init.c
index 99b0feae49..740b9c63f8 100644
--- a/src/drivers/intel/fsp2_0/memory_init.c
+++ b/src/drivers/intel/fsp2_0/memory_init.c
@@ -26,31 +26,10 @@
static uint8_t temp_ram[CONFIG_FSP_TEMP_RAM_SIZE] __aligned(sizeof(uint64_t));
-static void save_memory_training_data(uint32_t fsp_version)
-{
- size_t mrc_data_size;
- const void *mrc_data;
-
- mrc_data = fsp_find_nv_storage_data(&mrc_data_size);
- if (!mrc_data) {
- printk(BIOS_ERR, "FSP_NON_VOLATILE_STORAGE_HOB missing!\n");
- return;
- }
-
- /*
- * Save MRC Data to CBMEM. By always saving the data this forces
- * a retrain after a trip through ChromeOS recovery path. The
- * 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, fsp_version, mrc_data,
- mrc_data_size) < 0)
- printk(BIOS_ERR, "Failed to stash MRC data\n");
-}
-
static void do_fsp_post_memory_init(bool s3wake, uint32_t fsp_version)
{
struct range_entry fsp_mem;
+ uint32_t *fsp_version_cbmem;
fsp_find_reserved_memory(&fsp_mem);
@@ -73,8 +52,14 @@ static void do_fsp_post_memory_init(bool s3wake, uint32_t fsp_version)
(uintptr_t)cbmem_find(CBMEM_ID_FSP_RESERVED_MEMORY))
die("Failed to accommodate FSP reserved memory request!\n");
- if (CONFIG(CACHE_MRC_SETTINGS) && !s3wake)
- save_memory_training_data(fsp_version);
+ /* 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;
+ }
/* Create romstage handof information */
romstage_handoff_init(s3wake);
diff --git a/src/drivers/intel/fsp2_0/save_mrc_data.c b/src/drivers/intel/fsp2_0/save_mrc_data.c
new file mode 100644
index 0000000000..7313967da3
--- /dev/null
+++ b/src/drivers/intel/fsp2_0/save_mrc_data.c
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <acpi/acpi.h>
+#include <bootstate.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <fsp/util.h>
+#include <mrc_cache.h>
+
+static void save_mrc_data(void *unused)
+{
+ size_t mrc_data_size;
+ const void *mrc_data;
+ uint32_t *fspm_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");
+ return;
+ }
+
+ mrc_data = fsp_find_nv_storage_data(&mrc_data_size);
+ if (!mrc_data) {
+ printk(BIOS_ERR, "FSP_NON_VOLATILE_STORAGE_HOB missing!\n");
+ return;
+ }
+
+ /*
+ * Save MRC data to SPI flash. By always saving the data this forces
+ * a retrain after a trip through ChromeOS recovery path. The
+ * 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,
+ mrc_data_size) < 0)
+ printk(BIOS_ERR, "Failed to stash MRC data\n");
+}
+
+/*
+ * Should be done before ramstage_cse_fw_sync() to avoid traning memory twice on
+ * a cold boot after a full firmware update.
+ */
+BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, save_mrc_data, NULL);