aboutsummaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorShelley Chen <shchen@google.com>2020-10-27 15:58:31 -0700
committerShelley Chen <shchen@google.com>2020-11-13 22:57:50 +0000
commit6615c6eaf798556b94ecc44d241222d6b19cd119 (patch)
tree1af1cb5e14a37f1156c4e2cc3dffd3d2a7303802 /src/drivers
parent0c3845d2ee5e582937f65f488e15055fe49464b0 (diff)
mrc_cache: Move code for triggering memory training into mrc_cache
Currently the decision of whether or not to use mrc_cache in recovery mode is made within the individual platforms' drivers (ie: fsp2.0, fsp1.1, etc.). As this is not platform specific, but uses common vboot infrastructure, the code can be unified and moved into mrc_cache. The conditions are as follows: 1. If HAS_RECOVERY_MRC_CACHE, use mrc_cache data (unless retrain switch is true) 2. If !HAS_RECOVERY_MRC_CACHE && VBOOT_STARTS_IN_BOOTBLOCK, this means that memory training will occur after verified boot, meaning that mrc_cache will be filled with data from executing RW code. So in this case, we never want to use the training data in the mrc_cache for recovery mode. 3. If !HAS_RECOVERY_MRC_CACHE && VBOOT_STARTS_IN_ROMSTAGE, this means that memory training happens before verfied boot, meaning that the mrc_cache data is generated by RO code, so it is safe to use for a recovery boot. 4. Any platform that does not use vboot should be unaffected. Additionally, we have removed the MRC_CLEAR_NORMAL_CACHE_ON_RECOVERY_RETRAIN config because the mrc_cache driver takes care of invalidating the mrc_cache data for normal mode. If the platform: 1. !HAS_RECOVERY_MRC_CACHE, always invalidate mrc_cache data 2. HAS_RECOVERY_MRC_CACHE, only invalidate if retrain switch is set BUG=b:150502246 BRANCH=None TEST=1. run dut-control power_state:rec_force_mrc twice on lazor ensure that memory retraining happens both times run dut-control power_state:rec twice on lazor ensure that memory retraining happens only first time 2. remove HAS_RECOVERY_MRC_CACHE from lazor Kconfig boot twice to ensure caching of memory training occurred on each boot. Change-Id: I3875a7b4a4ba3c1aa8a3c1507b3993036a7155fc Signed-off-by: Shelley Chen <shchen@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/46855 Reviewed-by: Furquan Shaikh <furquan@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/intel/fsp1_1/romstage.c48
-rw-r--r--src/drivers/intel/fsp2_0/memory_init.c12
-rw-r--r--src/drivers/mrc_cache/Kconfig5
-rw-r--r--src/drivers/mrc_cache/mrc_cache.c70
4 files changed, 79 insertions, 56 deletions
diff --git a/src/drivers/intel/fsp1_1/romstage.c b/src/drivers/intel/fsp1_1/romstage.c
index 5a59c502a9..5129dc696b 100644
--- a/src/drivers/intel/fsp1_1/romstage.c
+++ b/src/drivers/intel/fsp1_1/romstage.c
@@ -41,35 +41,29 @@ static void raminit_common(struct romstage_params *params)
params->saved_data_size = 0;
params->saved_data = NULL;
if (!params->disable_saved_data) {
- if (vboot_recovery_mode_enabled()) {
- /* Recovery mode does not use MRC cache */
+ /* Assume boot device is memory mapped. */
+ assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));
+
+ params->saved_data = NULL;
+ if (CONFIG(CACHE_MRC_SETTINGS))
+ params->saved_data =
+ mrc_cache_current_mmap_leak(MRC_TRAINING_DATA,
+ params->fsp_version,
+ &mrc_size);
+ if (params->saved_data) {
+ /* MRC cache found */
+ params->saved_data_size = mrc_size;
+
+ } else if (s3wake) {
+ /* Waking from S3 and no cache. */
printk(BIOS_DEBUG,
- "Recovery mode: not using MRC cache.\n");
+ "No MRC cache "
+ "found in S3 resume path.\n");
+ post_code(POST_RESUME_FAILURE);
+ /* FIXME: A "system" reset is likely enough: */
+ full_reset();
} else {
- /* Assume boot device is memory mapped. */
- assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));
-
- params->saved_data = NULL;
- if (CONFIG(CACHE_MRC_SETTINGS))
- params->saved_data =
- mrc_cache_current_mmap_leak(MRC_TRAINING_DATA,
- params->fsp_version,
- &mrc_size);
- if (params->saved_data) {
- /* MRC cache found */
- params->saved_data_size = mrc_size;
-
- } else if (s3wake) {
- /* Waking from S3 and no cache. */
- printk(BIOS_DEBUG,
- "No MRC cache "
- "found in S3 resume path.\n");
- post_code(POST_RESUME_FAILURE);
- /* FIXME: A "system" reset is likely enough: */
- full_reset();
- } else {
- printk(BIOS_DEBUG, "No MRC cache found.\n");
- }
+ printk(BIOS_DEBUG, "No MRC cache found.\n");
}
}
diff --git a/src/drivers/intel/fsp2_0/memory_init.c b/src/drivers/intel/fsp2_0/memory_init.c
index 68cc1215a5..27e34fef0d 100644
--- a/src/drivers/intel/fsp2_0/memory_init.c
+++ b/src/drivers/intel/fsp2_0/memory_init.c
@@ -92,18 +92,6 @@ static void fsp_fill_mrc_cache(FSPM_ARCH_UPD *arch_upd, uint32_t fsp_version)
if (!CONFIG(CACHE_MRC_SETTINGS))
return;
- /*
- * In recovery mode, force retraining:
- * 1. Recovery cache is not supported, or
- * 2. Memory retrain switch is set.
- */
- if (vboot_recovery_mode_enabled()) {
- if (!CONFIG(HAS_RECOVERY_MRC_CACHE))
- return;
- if (get_recovery_mode_retrain_switch())
- return;
- }
-
/* Assume boot device is memory mapped. */
assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));
diff --git a/src/drivers/mrc_cache/Kconfig b/src/drivers/mrc_cache/Kconfig
index b09c19672e..df6973b0a4 100644
--- a/src/drivers/mrc_cache/Kconfig
+++ b/src/drivers/mrc_cache/Kconfig
@@ -17,11 +17,6 @@ config HAS_RECOVERY_MRC_CACHE
bool
default n
-config MRC_CLEAR_NORMAL_CACHE_ON_RECOVERY_RETRAIN
- bool
- depends on VBOOT_STARTS_IN_BOOTBLOCK
- default n
-
config MRC_SETTINGS_VARIABLE_DATA
bool
default n
diff --git a/src/drivers/mrc_cache/mrc_cache.c b/src/drivers/mrc_cache/mrc_cache.c
index eb43123c67..8b26ea5905 100644
--- a/src/drivers/mrc_cache/mrc_cache.c
+++ b/src/drivers/mrc_cache/mrc_cache.c
@@ -69,7 +69,20 @@ static const struct cache_region normal_training = {
.type = MRC_TRAINING_DATA,
.elog_slot = ELOG_MEM_CACHE_UPDATE_SLOT_NORMAL,
.tpm_hash_index = MRC_RW_HASH_NV_INDEX,
+#if CONFIG(VBOOT_STARTS_IN_ROMSTAGE)
+ /*
+ * If VBOOT_STARTS_IN_ROMSTAGE is selected, this means that
+ * memory training happens before vboot (in RO) and the
+ * mrc_cache data is always safe to use.
+ */
.flags = NORMAL_FLAG | RECOVERY_FLAG,
+#else
+ /*
+ * If !VBOOT_STARTS_IN_ROMSTAGE, this means that memory training happens after
+ * vboot (in RW code) and is never safe to use in recovery.
+ */
+ .flags = NORMAL_FLAG,
+#endif
};
static const struct cache_region variable_data = {
@@ -78,7 +91,20 @@ static const struct cache_region variable_data = {
.type = MRC_VARIABLE_DATA,
.elog_slot = ELOG_MEM_CACHE_UPDATE_SLOT_VARIABLE,
.tpm_hash_index = 0,
+#if CONFIG(VBOOT_STARTS_IN_ROMSTAGE)
+ /*
+ * If VBOOT_STARTS_IN_ROMSTAGE is selected, this means that
+ * memory training happens before vboot (in RO) and the
+ * mrc_cache data is always safe to use.
+ */
.flags = NORMAL_FLAG | RECOVERY_FLAG,
+#else
+ /*
+ * If !VBOOT_STARTS_IN_ROMSTAGE, this means that memory training happens after
+ * vboot (in RW code) and is never safe to use in recovery.
+ */
+ .flags = NORMAL_FLAG,
+#endif
};
/* Order matters here for priority in matching. */
@@ -255,6 +281,13 @@ static int mrc_cache_find_current(int type, uint32_t version,
const size_t md_size = sizeof(*md);
const bool fail_bad_data = true;
+ /*
+ * In recovery mode, force retraining if the memory retrain
+ * switch is set.
+ */
+ if (vboot_recovery_mode_enabled() && get_recovery_mode_retrain_switch())
+ return -1;
+
cr = lookup_region(&region, type);
if (cr == NULL)
@@ -566,10 +599,24 @@ static void invalidate_normal_cache(void)
const char *name = DEFAULT_MRC_CACHE;
const uint32_t invalid = ~MRC_DATA_SIGNATURE;
- /* Invalidate only on recovery mode with retraining enabled. */
+ /*
+ * If !HAS_RECOVERY_MRC_CACHE and VBOOT_STARTS_IN_ROMSTAGE is
+ * selected, this means that memory training occurs before
+ * verified boot (in RO), so normal mode cache does not need
+ * to be invalidated.
+ */
+ if (!CONFIG(HAS_RECOVERY_MRC_CACHE) && CONFIG(VBOOT_STARTS_IN_ROMSTAGE))
+ return;
+
+ /* We only invalidate the normal cache in recovery mode. */
if (!vboot_recovery_mode_enabled())
return;
- if (!get_recovery_mode_retrain_switch())
+
+ /*
+ * For platforms with a recovery mrc_cache, no need to
+ * invalidate when retrain switch is not set.
+ */
+ if (CONFIG(HAS_RECOVERY_MRC_CACHE) && !get_recovery_mode_retrain_switch())
return;
if (fmap_locate_area_as_rdev_rw(name, &rdev) < 0) {
@@ -599,7 +646,7 @@ static void update_mrc_cache_from_cbmem(int type)
cr = lookup_region(&region, type);
if (cr == NULL) {
- printk(BIOS_ERR, "MRC: could not find cache_region type %d\n", type);
+ printk(BIOS_INFO, "MRC: could not find cache_region type %d\n", type);
return;
}
@@ -631,8 +678,7 @@ static void finalize_mrc_cache(void *unused)
update_mrc_cache_from_cbmem(MRC_VARIABLE_DATA);
}
- if (CONFIG(MRC_CLEAR_NORMAL_CACHE_ON_RECOVERY_RETRAIN))
- invalidate_normal_cache();
+ invalidate_normal_cache();
protect_mrc_region();
}
@@ -642,13 +688,6 @@ int mrc_cache_stash_data(int type, uint32_t version, const void *data,
{
const struct cache_region *cr;
- cr = lookup_region_type(type);
- if (cr == NULL) {
- printk(BIOS_ERR, "MRC: failed to add to cbmem for type %d.\n",
- type);
- return -1;
- }
-
struct mrc_metadata md = {
.signature = MRC_DATA_SIGNATURE,
.data_size = size,
@@ -664,6 +703,13 @@ int mrc_cache_stash_data(int type, uint32_t version, const void *data,
size_t cbmem_size;
cbmem_size = sizeof(*cbmem_md) + size;
+ cr = lookup_region_type(type);
+ if (cr == NULL) {
+ printk(BIOS_INFO, "MRC: No region type found. Skip adding to cbmem for type %d.\n",
+ type);
+ return 0;
+ }
+
cbmem_md = cbmem_add(cr->cbmem_id, cbmem_size);
if (cbmem_md == NULL) {