[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, &region)) {
+	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(&region, 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(&region, &current_saved,
+	if (!__mrc_cache_get_current(region, &current_saved,
 					current_boot->version)) {
 		if (current_saved->size == current_boot->size &&
 		    !memcmp(&current_saved->data[0], &current_boot->data[0],
@@ -383,18 +397,49 @@ static void update_mrc_region(void)
 		}
 	}
 
-	next_slot = mrc_cache_next_slot(&region, 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(&region, 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