Add support for storing POST codes in CMOS

This will use 3 bytes of CMOS to keep track of the POST
code for the current boot while also leaving a record of
the previous boot.

The active bank is switched early in the bootblock.

Test:
1) clear cmos
2) reboot
3) use "mosys nvram dump" to verify that the first byte
contains 0x80 and the second byte contains 0xF8
4) powerd_suspend and then resume
5) use "mosys nvram dump" to verify that the first byte
contains 0x81 and the second byte contains 0xFD

Change-Id: I1ee6bb2dac053018f3042ab5a0b26c435dbfd151
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: http://review.coreboot.org/1743
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
Duncan Laurie 2012-09-09 19:09:56 -07:00 committed by Stefan Reinauer
parent 31409617a4
commit b6e97b19ae
5 changed files with 82 additions and 0 deletions

View File

@ -34,3 +34,27 @@ static void sanitize_cmos(void)
} }
} }
#endif #endif
#if CONFIG_CMOS_POST
#include <pc80/mc146818rtc.h>
static void cmos_post_init(void)
{
u8 magic = CMOS_POST_BANK_0_MAGIC;
/* Switch to the other bank */
switch (cmos_read(CMOS_POST_BANK_OFFSET)) {
case CMOS_POST_BANK_1_MAGIC:
break;
case CMOS_POST_BANK_0_MAGIC:
magic = CMOS_POST_BANK_1_MAGIC;
break;
default:
/* Initialize to zero */
cmos_write(0, CMOS_POST_BANK_0_OFFSET);
cmos_write(0, CMOS_POST_BANK_1_OFFSET);
}
cmos_write(magic, CMOS_POST_BANK_OFFSET);
}
#endif

View File

@ -9,6 +9,9 @@ static void main(unsigned long bist)
#if CONFIG_USE_OPTION_TABLE #if CONFIG_USE_OPTION_TABLE
sanitize_cmos(); sanitize_cmos();
#endif
#if CONFIG_CMOS_POST
cmos_post_init();
#endif #endif
} }

View File

@ -373,5 +373,23 @@ config CONSOLE_POST
usually displayed using a so-called "POST card" ISA/PCI/PCI-E usually displayed using a so-called "POST card" ISA/PCI/PCI-E
device) on the debug console. device) on the debug console.
config CMOS_POST
bool "Store post codes in CMOS for debugging"
depends on !NO_POST
default n
help
If enabled, coreboot will store post codes in CMOS and switch between
two offsets on each boot so the last post code in the previous boot
can be retrieved. This uses 3 bytes of CMOS.
config CMOS_POST_OFFSET
hex "Offset into CMOS to store POST codes"
depends on CMOS_POST
default 0
help
If CMOS_POST is enabled then an offset into CMOS must be provided.
If CONFIG_HAVE_OPTION_TABLE is enabled then it will use the value
defined in the mainboard option table.
endmenu endmenu

View File

@ -21,6 +21,7 @@
#include <arch/io.h> #include <arch/io.h>
#include <console/console.h> #include <console/console.h>
#include <pc80/mc146818rtc.h>
/* Write POST information */ /* Write POST information */
@ -38,6 +39,20 @@ void __attribute__((weak)) mainboard_post(uint8_t value)
#define mainboard_post(x) #define mainboard_post(x)
#endif #endif
#if CONFIG_CMOS_POST
static void cmos_post_code(u8 value)
{
switch (cmos_read(CMOS_POST_BANK_OFFSET)) {
case CMOS_POST_BANK_0_MAGIC:
cmos_write(value, CMOS_POST_BANK_0_OFFSET);
break;
case CMOS_POST_BANK_1_MAGIC:
cmos_write(value, CMOS_POST_BANK_1_OFFSET);
break;
}
}
#endif /* CONFIG_CMOS_POST */
void post_code(uint8_t value) void post_code(uint8_t value)
{ {
#if !CONFIG_NO_POST #if !CONFIG_NO_POST
@ -45,6 +60,9 @@ void post_code(uint8_t value)
print_emerg("POST: 0x"); print_emerg("POST: 0x");
print_emerg_hex8(value); print_emerg_hex8(value);
print_emerg("\n"); print_emerg("\n");
#endif
#if CONFIG_CMOS_POST
cmos_post_code(value);
#endif #endif
outb(value, CONFIG_POST_PORT); outb(value, CONFIG_POST_PORT);
#endif #endif

View File

@ -158,4 +158,23 @@ static inline int get_option(void *dest __attribute__((unused)),
#endif #endif
#define read_option(name, default) read_option_lowlevel(CMOS_VSTART_ ##name, CMOS_VLEN_ ##name, (default)) #define read_option(name, default) read_option_lowlevel(CMOS_VSTART_ ##name, CMOS_VLEN_ ##name, (default))
#if CONFIG_CMOS_POST
#if CONFIG_USE_OPTION_TABLE
# include "option_table.h"
# define CMOS_POST_OFFSET (CMOS_VSTART_cmos_post_offset >> 3)
#else
# if defined(CONFIG_CMOS_POST_OFFSET)
# define CMOS_POST_OFFSET CONFIG_CMOS_POST_OFFSET
# else
# error "Must define CONFIG_CMOS_POST_OFFSET"
# endif
#endif
#define CMOS_POST_BANK_OFFSET (CMOS_POST_OFFSET)
#define CMOS_POST_BANK_0_MAGIC 0x80
#define CMOS_POST_BANK_0_OFFSET (CMOS_POST_OFFSET + 1)
#define CMOS_POST_BANK_1_MAGIC 0x81
#define CMOS_POST_BANK_1_OFFSET (CMOS_POST_OFFSET + 2)
#endif /* CONFIG_CMOS_POST */
#endif /* PC80_MC146818RTC_H */ #endif /* PC80_MC146818RTC_H */