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:
committed by
Ronald G. Minnich
parent
305b19dd7a
commit
48214899c3
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user