From 48214899c3e74d590ad45f1b8e98f745f2c6b2d0 Mon Sep 17 00:00:00 2001 From: Stefan Reinauer Date: Wed, 6 Jun 2012 13:24:32 -0700 Subject: [PATCH] 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 Reviewed-on: http://review.coreboot.org/1277 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich --- 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 67b3defb75..7dfd10d3ba 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 d774ff0988..00b3bdd362 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; }