Extend CMOS POST code logging to store extra data

This can be used to indicate sub-state within a POST
code range which can assist in debugging BIOS hangs.

For example this can be used to indicate which device
is about to be initialized so if the system hangs
while talking to that device it can be identified.

Change-Id: I2f8155155f09fe9e242ebb7204f0b5cba3a1fa1e
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/58104
Reviewed-on: http://review.coreboot.org/4229
Tested-by: build bot (Jenkins)
Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
This commit is contained in:
Duncan Laurie 2013-06-10 10:21:41 -07:00 committed by Stefan Reinauer
parent e807c34a5e
commit d5686fe23b
6 changed files with 61 additions and 0 deletions

View File

@ -65,6 +65,10 @@ static void cmos_post_init(void)
/* Initialize to zero */ /* Initialize to zero */
cmos_write(0, CMOS_POST_BANK_0_OFFSET); cmos_write(0, CMOS_POST_BANK_0_OFFSET);
cmos_write(0, CMOS_POST_BANK_1_OFFSET); cmos_write(0, CMOS_POST_BANK_1_OFFSET);
#if CONFIG_CMOS_POST_EXTRA
cmos_write32(CMOS_POST_BANK_0_EXTRA, 0);
cmos_write32(CMOS_POST_BANK_1_EXTRA, 0);
#endif
} }
cmos_write(magic, CMOS_POST_BANK_OFFSET); cmos_write(magic, CMOS_POST_BANK_OFFSET);

View File

@ -413,6 +413,14 @@ config CMOS_POST_OFFSET
If CONFIG_HAVE_OPTION_TABLE is enabled then it will use the value If CONFIG_HAVE_OPTION_TABLE is enabled then it will use the value
defined in the mainboard option table. defined in the mainboard option table.
config CMOS_POST_EXTRA
bool "Store extra logging info into CMOS"
depends on CMOS_POST
default n
help
This will enable extra logging of work that happens between post
codes into CMOS for debug. This uses an additional 8 bytes of CMOS.
config IO_POST config IO_POST
bool "Send POST codes to an IO port" bool "Send POST codes to an IO port"
depends on PC80_SYSTEM depends on PC80_SYSTEM

View File

@ -25,6 +25,9 @@
#include <pc80/mc146818rtc.h> #include <pc80/mc146818rtc.h>
#include <smp/spinlock.h> #include <smp/spinlock.h>
#endif #endif
#if CONFIG_CMOS_POST_EXTRA
#include <device/device.h>
#endif
#include <elog.h> #include <elog.h>
/* Write POST information */ /* Write POST information */
@ -51,6 +54,9 @@ DECLARE_SPIN_LOCK(cmos_post_lock)
void cmos_post_log(void) void cmos_post_log(void)
{ {
u8 code = 0; u8 code = 0;
#if CONFIG_CMOS_POST_EXTRA
u32 extra = 0;
#endif
spin_lock(&cmos_post_lock); spin_lock(&cmos_post_lock);
@ -58,9 +64,15 @@ void cmos_post_log(void)
switch (cmos_read(CMOS_POST_BANK_OFFSET)) { switch (cmos_read(CMOS_POST_BANK_OFFSET)) {
case CMOS_POST_BANK_0_MAGIC: case CMOS_POST_BANK_0_MAGIC:
code = cmos_read(CMOS_POST_BANK_1_OFFSET); code = cmos_read(CMOS_POST_BANK_1_OFFSET);
#if CONFIG_CMOS_POST_EXTRA
extra = cmos_read32(CMOS_POST_BANK_1_EXTRA);
#endif
break; break;
case CMOS_POST_BANK_1_MAGIC: case CMOS_POST_BANK_1_MAGIC:
code = cmos_read(CMOS_POST_BANK_0_OFFSET); code = cmos_read(CMOS_POST_BANK_0_OFFSET);
#if CONFIG_CMOS_POST_EXTRA
extra = cmos_read32(CMOS_POST_BANK_0_EXTRA);
#endif
break; break;
} }
@ -78,9 +90,31 @@ void cmos_post_log(void)
"in previous boot: 0x%02x\n", code); "in previous boot: 0x%02x\n", code);
#if CONFIG_ELOG #if CONFIG_ELOG
elog_add_event_word(ELOG_TYPE_LAST_POST_CODE, code); elog_add_event_word(ELOG_TYPE_LAST_POST_CODE, code);
#if CONFIG_CMOS_POST_EXTRA
if (extra)
elog_add_event_dword(ELOG_TYPE_POST_EXTRA, extra);
#endif
#endif #endif
} }
} }
#if CONFIG_CMOS_POST_EXTRA
void post_log_extra(u32 value)
{
spin_lock(&cmos_post_lock);
switch (cmos_read(CMOS_POST_BANK_OFFSET)) {
case CMOS_POST_BANK_0_MAGIC:
cmos_write32(CMOS_POST_BANK_0_EXTRA, value);
break;
case CMOS_POST_BANK_1_MAGIC:
cmos_write32(CMOS_POST_BANK_1_EXTRA, value);
break;
}
spin_unlock(&cmos_post_lock);
}
#endif /* CONFIG_CMOS_POST_EXTRA */
#endif /* !__PRE_RAM__ */ #endif /* !__PRE_RAM__ */
static void cmos_post_code(u8 value) static void cmos_post_code(u8 value)

View File

@ -72,6 +72,11 @@ void console_init(void);
void console_tx_byte(unsigned char byte); void console_tx_byte(unsigned char byte);
void console_tx_flush(void); void console_tx_flush(void);
void post_code(u8 value); void post_code(u8 value);
#if CONFIG_CMOS_POST_EXTRA
void post_log_extra(u32 value);
#else
#define post_log_extra(x) do {} while (0)
#endif
/* this function is weak and can be overridden by a mainboard function. */ /* this function is weak and can be overridden by a mainboard function. */
void mainboard_post(u8 value); void mainboard_post(u8 value);
void __attribute__ ((noreturn)) die(const char *msg); void __attribute__ ((noreturn)) die(const char *msg);

View File

@ -140,6 +140,7 @@ struct elog_event_data_me_extended {
/* Last post code from previous boot */ /* Last post code from previous boot */
#define ELOG_TYPE_LAST_POST_CODE 0xa3 #define ELOG_TYPE_LAST_POST_CODE 0xa3
#define ELOG_TYPE_POST_EXTRA 0xa6
/* EC Shutdown Reason */ /* EC Shutdown Reason */
#define ELOG_TYPE_EC_SHUTDOWN 0xa5 #define ELOG_TYPE_EC_SHUTDOWN 0xa5

View File

@ -202,11 +202,20 @@ static inline enum cb_err get_option(void *dest __attribute__((unused)),
# endif # endif
#endif #endif
/*
* 0 = Bank Select Magic
* 1 = Bank 0 POST
* 2 = Bank 1 POST
* 3-6 = BANK 0 Extra log
* 7-10 = BANK 1 Extra log
*/
#define CMOS_POST_BANK_OFFSET (CMOS_POST_OFFSET) #define CMOS_POST_BANK_OFFSET (CMOS_POST_OFFSET)
#define CMOS_POST_BANK_0_MAGIC 0x80 #define CMOS_POST_BANK_0_MAGIC 0x80
#define CMOS_POST_BANK_0_OFFSET (CMOS_POST_OFFSET + 1) #define CMOS_POST_BANK_0_OFFSET (CMOS_POST_OFFSET + 1)
#define CMOS_POST_BANK_0_EXTRA (CMOS_POST_OFFSET + 3)
#define CMOS_POST_BANK_1_MAGIC 0x81 #define CMOS_POST_BANK_1_MAGIC 0x81
#define CMOS_POST_BANK_1_OFFSET (CMOS_POST_OFFSET + 2) #define CMOS_POST_BANK_1_OFFSET (CMOS_POST_OFFSET + 2)
#define CMOS_POST_BANK_1_EXTRA (CMOS_POST_OFFSET + 7)
void cmos_post_log(void); void cmos_post_log(void);
#endif /* CONFIG_CMOS_POST */ #endif /* CONFIG_CMOS_POST */