elog: Correct behavior when FMAP section doesn't exist on ChromeOS
The elog driver has a really stupid bug that checks a result which is stored in an unsigned variable for < 0. Surprisingly GCC does not catch this nonsense right now, and I spent an hour trying out different warning options without finding one that doesn't also bring a load of stupid and unavoidable false positives (the biggest offender being -Wtype-limits, which does exactly what we'd want except for flagging things like if ((u8)var >= CONFIG_VAR_MIN) where the VAR_MIN Kconfig may or may not be 0). So, the only thing we can do is fix this one and wait for the next time something like that blows up. -.- Also change some more code to make the behavior more explicit (the old code already intended to work this way since flash_base is statically initialized to 0, never assigned in the error path and checked later in elog_init()... but there was an error message that incorrectly claimed a different fallback behavior, and explicitly assigning the values makes this easier to see). Finally, add another state to the elog_initialized variable to avoid trying to reinitialize a broken eventlog on every event (if it doesn't work the first time, chances are that it won't work later on during the same boot either). BRANCH=None BUG=chrome-os-partner:35940 TEST=Flashed Jerry with RO 6588.4 and RW 6588.23, observed how it now cleanly enters recovery mode without blowing its bootblock away with stray eventlog entries. Change-Id: I0e5348ba961ce4835c30f7108a2453522095f2ee Signed-off-by: Stefan Reinauer <reinauer@chromium.org> Original-Commit-Id: f9798dbf0c2b2e337062ecd84d0f45434343c0d9 Original-Change-Id: I4d93f48d2d01d75a04550d419e023aa42ca95a7a Original-Signed-off-by: Julius Werner <jwerner@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/243671 Original-Reviewed-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: http://review.coreboot.org/9557 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
parent
b9d961550c
commit
5d686229e8
|
@ -75,9 +75,13 @@ static elog_event_buffer_state event_buffer_state;
|
||||||
static u16 next_event_offset;
|
static u16 next_event_offset;
|
||||||
static u16 event_count;
|
static u16 event_count;
|
||||||
|
|
||||||
static int elog_initialized;
|
|
||||||
static struct spi_flash *elog_spi;
|
static struct spi_flash *elog_spi;
|
||||||
|
|
||||||
|
static enum {
|
||||||
|
ELOG_UNINITIALIZED = 0,
|
||||||
|
ELOG_INITIALIZED,
|
||||||
|
ELOG_BROKEN,
|
||||||
|
} elog_initialized = ELOG_UNINITIALIZED;
|
||||||
|
|
||||||
static inline u32 get_rom_size(void)
|
static inline u32 get_rom_size(void)
|
||||||
{
|
{
|
||||||
|
@ -522,25 +526,18 @@ int elog_clear(void)
|
||||||
|
|
||||||
static void elog_find_flash(void)
|
static void elog_find_flash(void)
|
||||||
{
|
{
|
||||||
#if CONFIG_CHROMEOS
|
|
||||||
u8 *flash_base_ptr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
elog_debug("elog_find_flash()\n");
|
elog_debug("elog_find_flash()\n");
|
||||||
|
|
||||||
#if CONFIG_CHROMEOS
|
#if CONFIG_CHROMEOS
|
||||||
/* Find the ELOG base and size in FMAP */
|
/* Find the ELOG base and size in FMAP */
|
||||||
total_size = find_fmap_entry("RW_ELOG", (void **)&flash_base_ptr);
|
u8 *flash_base_ptr;
|
||||||
if (total_size < 0) {
|
int fmap_size = find_fmap_entry("RW_ELOG", (void **)&flash_base_ptr);
|
||||||
printk(BIOS_WARNING, "ELOG: Unable to find RW_ELOG in FMAP, "
|
if (fmap_size < 0) {
|
||||||
"using CONFIG_ELOG_FLASH_BASE instead\n");
|
printk(BIOS_WARNING, "ELOG: Unable to find RW_ELOG in FMAP\n");
|
||||||
total_size = CONFIG_ELOG_AREA_SIZE;
|
flash_base = total_size = 0;
|
||||||
} else {
|
} else {
|
||||||
flash_base = elog_flash_address_to_offset(flash_base_ptr);
|
flash_base = elog_flash_address_to_offset(flash_base_ptr);
|
||||||
|
total_size = MIN(fmap_size, CONFIG_ELOG_AREA_SIZE);
|
||||||
/* Use configured size if smaller than FMAP size */
|
|
||||||
if (total_size > CONFIG_ELOG_AREA_SIZE)
|
|
||||||
total_size = CONFIG_ELOG_AREA_SIZE;
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
flash_base = CONFIG_ELOG_FLASH_BASE;
|
flash_base = CONFIG_ELOG_FLASH_BASE;
|
||||||
|
@ -554,8 +551,15 @@ static void elog_find_flash(void)
|
||||||
*/
|
*/
|
||||||
int elog_init(void)
|
int elog_init(void)
|
||||||
{
|
{
|
||||||
if (elog_initialized)
|
switch (elog_initialized) {
|
||||||
|
case ELOG_UNINITIALIZED:
|
||||||
|
break;
|
||||||
|
case ELOG_INITIALIZED:
|
||||||
return 0;
|
return 0;
|
||||||
|
case ELOG_BROKEN:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
elog_initialized = ELOG_BROKEN;
|
||||||
|
|
||||||
elog_debug("elog_init()\n");
|
elog_debug("elog_init()\n");
|
||||||
|
|
||||||
|
@ -600,8 +604,6 @@ int elog_init(void)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
elog_initialized = 1;
|
|
||||||
|
|
||||||
printk(BIOS_INFO, "ELOG: FLASH @0x%p [SPI 0x%08x]\n",
|
printk(BIOS_INFO, "ELOG: FLASH @0x%p [SPI 0x%08x]\n",
|
||||||
elog_area, flash_base);
|
elog_area, flash_base);
|
||||||
|
|
||||||
|
@ -637,6 +639,8 @@ int elog_init(void)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
elog_initialized = ELOG_INITIALIZED;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue