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>
Reviewed-on: http://review.coreboot.org/1277
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
Stefan Reinauer
2012-06-06 13:24:32 -07:00
committed by Ronald G. Minnich
parent 305b19dd7a
commit 48214899c3
2 changed files with 40 additions and 14 deletions

View File

@ -78,6 +78,24 @@ config CACHE_MRC_SIZE_KB
int int
default 512 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 config DCACHE_RAM_BASE
hex hex
default 0xff7e0000 default 0xff7e0000

View File

@ -118,17 +118,22 @@ struct mrc_data_container *find_current_mrc_cache(void)
* from having no cache area at all * from having no cache area at all
*/ */
return mrc_cache; return mrc_cache;
} else { }
/* Search for the last filled entry in the region */
while (is_mrc_cache(mrc_next)) { /* Search for the last filled entry in the region */
entry_id++; while (is_mrc_cache(mrc_next)) {
mrc_cache = mrc_next; entry_id++;
mrc_next = next_mrc_block(mrc_cache); mrc_cache = mrc_next;
/* Stay in the mrc data region */ mrc_next = next_mrc_block(mrc_cache);
if ((void*)mrc_next >= (void*)(mrc_region + region_size)) /* Stay in the mrc data region */
break; if ((void*)mrc_next >= (void*)(mrc_region + region_size))
} break;
entry_id--; }
entry_id--;
if (entry_id == -1) {
printk(BIOS_ERR, "%s: No valid MRC cache found.\n", __func__);
return NULL;
} }
/* Verify checksum */ /* Verify checksum */
@ -150,6 +155,7 @@ struct mrc_data_container *find_current_mrc_cache(void)
#if !defined(__PRE_RAM__) #if !defined(__PRE_RAM__)
void update_mrc_cache(void) void update_mrc_cache(void)
{ {
printk(BIOS_DEBUG, "Updating MRC cache data.\n");
struct mrc_data_container *current = cbmem_find(CBMEM_ID_MRCDATA); struct mrc_data_container *current = cbmem_find(CBMEM_ID_MRCDATA);
if (!current) { if (!current) {
printk(BIOS_ERR, "No MRC cache in cbmem. Can't update flash.\n"); 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) // 0. compare MRC data to last mrc-cache block (exit if same)
struct mrc_data_container *cache; struct mrc_data_container *cache;
if ((cache = find_current_mrc_cache()) == NULL) { 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; return;
} }
if ((cache->mrc_data_size == current->mrc_data_size) && (memcmp(cache, current, cache->mrc_data_size) == 0)) { if ((cache->mrc_data_size == current->mrc_data_size) &&
printk(BIOS_DEBUG, "MRC data in flash is up to date. No update.\n"); (memcmp(cache, current, cache->mrc_data_size) == 0)) {
printk(BIOS_DEBUG,
"MRC data in flash is up to date. No update.\n");
return; return;
} }