[coreboot-gerrit] New patch to review for coreboot: mrc cache: split finding vs writing.
Aaron Durbin (adurbin@chromium.org)
gerrit at coreboot.org
Thu Nov 10 19:59:09 CET 2016
Aaron Durbin (adurbin at chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17368
-gerrit
commit b43dccaca3a335c55e3d65dd7f94386cbac9cf5d
Author: Aaron Durbin <adurbin at chromium.org>
Date: Thu Nov 10 12:56:38 2016 -0600
mrc cache: split finding vs writing.
NOT TESTED. NEEDS CLEANING
Change-Id: I0e95187509f8e6dca347cff491f606f4d3ccfd72
Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
src/soc/intel/common/mrc_cache.c | 77 +++++++++++++++++++++++++++++++---------
1 file changed, 61 insertions(+), 16 deletions(-)
diff --git a/src/soc/intel/common/mrc_cache.c b/src/soc/intel/common/mrc_cache.c
index 7b66043..0ce5f2a 100644
--- a/src/soc/intel/common/mrc_cache.c
+++ b/src/soc/intel/common/mrc_cache.c
@@ -336,26 +336,40 @@ static void log_event_cache_update(uint8_t slot, uint8_t status)
printk(BIOS_ERR, "Failed to log mem cache update event.\n");
}
-static void update_mrc_region(void)
+
+struct mrc_write_info {
+ const void *write_slot;
+ int slot_type;
+ struct mrc_data_region region;
+ const char *region_name;
+};
+
+static struct mrc_write_info mrc_write_info;
+
+static void find_mrc_write_slot(void *unused)
{
const struct mrc_saved_data *current_boot;
const struct mrc_saved_data *current_saved;
- const struct mrc_saved_data *next_slot;
- struct mrc_data_region region;
- const char *region_name = DEFAULT_MRC_CACHE;
- uint8_t slot = ELOG_MEM_CACHE_UPDATE_SLOT_NORMAL;
+ struct mrc_data_region *region;
+ const char *region_name;
- printk(BIOS_DEBUG, "MRC: Updating cache data.\n");
+ printk(BIOS_DEBUG, "MRC: Determining where to update cache data.\n");
+
+ mrc_write_info.region_name = DEFAULT_MRC_CACHE;
+ mrc_write_info.slot_type = ELOG_MEM_CACHE_UPDATE_SLOT_NORMAL;
if (vboot_recovery_mode_enabled() &&
IS_ENABLED(CONFIG_HAS_RECOVERY_MRC_CACHE)) {
- region_name = RECOVERY_MRC_CACHE;
- slot = ELOG_MEM_CACHE_UPDATE_SLOT_RECOVERY;
+ mrc_write_info.region_name = RECOVERY_MRC_CACHE;
+ mrc_write_info.slot_type = ELOG_MEM_CACHE_UPDATE_SLOT_RECOVERY;
}
+ region = &mrc_write_info.region;
+ region_name = mrc_write_info.region_name;
+
printk(BIOS_ERR, "MRC: Cache region selected - %s\n", region_name);
- if (mrc_cache_get_region(region_name, ®ion)) {
+ if (mrc_cache_get_region(region_name, region)) {
printk(BIOS_ERR, "MRC: Could not obtain cache region.\n");
return;
}
@@ -366,14 +380,14 @@ static void update_mrc_region(void)
return;
}
- if (!mrc_cache_valid(®ion, current_boot)) {
+ if (!mrc_cache_valid(region, current_boot)) {
printk(BIOS_ERR, "MRC: Cache data in cbmem invalid.\n");
return;
}
current_saved = NULL;
- if (!__mrc_cache_get_current(®ion, ¤t_saved,
+ if (!__mrc_cache_get_current(region, ¤t_saved,
current_boot->version)) {
if (current_saved->size == current_boot->size &&
!memcmp(¤t_saved->data[0], ¤t_boot->data[0],
@@ -383,18 +397,49 @@ static void update_mrc_region(void)
}
}
- next_slot = mrc_cache_next_slot(®ion, current_saved);
+ mrc_write_info.write_slot = mrc_cache_next_slot(region, current_saved);
+}
+
+/* Do this before MTRR initialization to take advantage of chipsets that
+ * have the MMIO BIOS region cached. */
+BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, find_mrc_write_slot, NULL);
+
+static void update_mrc_region(void)
+{
+ const struct mrc_saved_data *current_boot;
+ const void *next_slot = mrc_write_info.write_slot;
+ struct mrc_data_region *region = &mrc_write_info.region;
+ const char *region_name = mrc_write_info.region_name;
+ int slot = mrc_write_info.slot_type;
+
+ /* No need to perform any writes. */
+ if (next_slot == NULL)
+ return;
+
+ current_boot = cbmem_find(CBMEM_ID_MRCDATA);
+ if (!current_boot) {
+ printk(BIOS_ERR, "MRC: No cache in cbmem.\n");
+ return;
+ }
+
+ printk(BIOS_DEBUG, "MRC: Updating cache data.\n");
+
+ /* Check again that it's valid. */
+ if (!mrc_cache_valid(region, current_boot)) {
+ printk(BIOS_ERR, "MRC: Cache data in cbmem invalid.\n");
+ return;
+ }
- if (!mrc_slot_valid(®ion, next_slot, current_boot)) {
+ if (!mrc_slot_valid(region, next_slot, current_boot)) {
printk(BIOS_DEBUG, "MRC: Slot @ %p is invalid.\n", next_slot);
- if (!nvm_is_erased(region.base, region.size)) {
- if (nvm_erase(region.base, region.size) < 0) {
+ if (!nvm_is_erased(region->base, region->size)) {
+ if (nvm_erase(region->base, region->size) < 0) {
printk(BIOS_DEBUG, "MRC: Failure erasing "
"region %s.\n", region_name);
return;
}
}
- next_slot = region.base;
+ next_slot = region->base;
}
if (nvm_write((void *)next_slot, current_boot,
More information about the coreboot-gerrit
mailing list