Stefan Reinauer (stefan.reinauer@coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1277
-gerrit
commit 07e941bfd3b775f6f3f03768d886a6b735d73d2d Author: Stefan Reinauer reinauer@chromium.org Date: Wed Jun 6 13:24:32 2012 -0700
Fix MRC cache update delays
When no valid MRC cache area is found, the mrc_cache data structure was used without prior initialization. This sometimes caused a long delay when booting because compute_ip_checksum would checksum up to 4GB of memory.
Change-Id: I6a0ca1aa618838bbc3d042be425700fc34b427f2 Signed-off-by: Stefan Reinauer reinauer@google.com --- src/northbridge/intel/sandybridge/Kconfig | 18 +++++++++++++ src/northbridge/intel/sandybridge/mrccache.c | 36 ++++++++++++++++---------- 2 files changed, 40 insertions(+), 14 deletions(-)
diff --git a/src/northbridge/intel/sandybridge/Kconfig b/src/northbridge/intel/sandybridge/Kconfig index 67b3def..7dfd10d 100644 --- a/src/northbridge/intel/sandybridge/Kconfig +++ b/src/northbridge/intel/sandybridge/Kconfig @@ -78,6 +78,24 @@ config CACHE_MRC_SIZE_KB int default 512
+# FIXME: build from rom size +config MRC_CACHE_BASE + hex + default 0xff800000 + +config MRC_CACHE_LOCATION + hex + default 0x370000 + +config MRC_CACHE_SIZE + hex + default 0x10000 + +config MRC_CACHE_ALIGNMENT + hex + default 0x1000 + + config DCACHE_RAM_BASE hex default 0xff7e0000 diff --git a/src/northbridge/intel/sandybridge/mrccache.c b/src/northbridge/intel/sandybridge/mrccache.c index d774ff0..00b3bdd 100644 --- a/src/northbridge/intel/sandybridge/mrccache.c +++ b/src/northbridge/intel/sandybridge/mrccache.c @@ -118,17 +118,22 @@ struct mrc_data_container *find_current_mrc_cache(void) * from having no cache area at all */ return mrc_cache; - } else { - /* Search for the last filled entry in the region */ - while (is_mrc_cache(mrc_next)) { - entry_id++; - mrc_cache = mrc_next; - mrc_next = next_mrc_block(mrc_cache); - /* Stay in the mrc data region */ - if ((void*)mrc_next >= (void*)(mrc_region + region_size)) - break; - } - entry_id--; + } + + /* Search for the last filled entry in the region */ + while (is_mrc_cache(mrc_next)) { + entry_id++; + mrc_cache = mrc_next; + mrc_next = next_mrc_block(mrc_cache); + /* Stay in the mrc data region */ + if ((void*)mrc_next >= (void*)(mrc_region + region_size)) + break; + } + entry_id--; + + if (entry_id == -1) { + printk(BIOS_ERR, "%s: No valid MRC cache found.\n", __func__); + return NULL; }
/* Verify checksum */ @@ -150,6 +155,7 @@ struct mrc_data_container *find_current_mrc_cache(void) #if !defined(__PRE_RAM__) void update_mrc_cache(void) { + printk(BIOS_DEBUG, "Updating MRC cache data.\n"); struct mrc_data_container *current = cbmem_find(CBMEM_ID_MRCDATA); if (!current) { printk(BIOS_ERR, "No MRC cache in cbmem. Can't update flash.\n"); @@ -166,12 +172,14 @@ void update_mrc_cache(void) // 0. compare MRC data to last mrc-cache block (exit if same) struct mrc_data_container *cache; if ((cache = find_current_mrc_cache()) == NULL) { - printk(BIOS_DEBUG, "Failure looking for current last block\n"); + printk(BIOS_DEBUG, "Failure looking for current last block.\n"); return; }
- if ((cache->mrc_data_size == current->mrc_data_size) && (memcmp(cache, current, cache->mrc_data_size) == 0)) { - printk(BIOS_DEBUG, "MRC data in flash is up to date. No update.\n"); + if ((cache->mrc_data_size == current->mrc_data_size) && + (memcmp(cache, current, cache->mrc_data_size) == 0)) { + printk(BIOS_DEBUG, + "MRC data in flash is up to date. No update.\n"); return; }