This patch adds support for calling panic() before stdio is initialized. At present this will just hang with little or no indication of what the problem is.
A new board_panic_no_console() function is added to the board API. If provided by the board it will be called in the event of a panic before the console is ready. This function should turn on all UARTS and spray the message out if it possibly can. The feature is controlled by a new CONFIG_PRE_CONSOLE_PANIC option. Signed-off-by: Simon Glass <s...@chromium.org> --- Changes in v2: - Made this feature conditional on CONFIG_PRE_CONSOLE_PANIC README | 11 +++++++++++ include/common.h | 8 ++++++++ lib/vsprintf.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 0 deletions(-) diff --git a/README b/README index eb9ade9..0748a6f 100644 --- a/README +++ b/README @@ -634,6 +634,17 @@ The following options need to be configured: 'Sane' compilers will generate smaller code if CONFIG_PRE_CON_BUF_SZ is a power of 2 +- Pre-console Panic: + Prior to the console being initialised, since console output + is silently discarded, a panic() will cause no output and no + indication of what is wrong. However, if the + CONFIG_PRE_CONSOLE_PANIC option is defined, then U-Boot will + call board_panic_no_console() in this case, passing the panic + message. This function should try to output the message if + possible, perhaps on all available UARTs (it will need to do + this directly, since the console code is not functional yet). + Another option is to flash some LEDs to indicate a panic. + - Boot Delay: CONFIG_BOOTDELAY - in seconds Delay before automatically booting the default image; set to -1 to disable autoboot. diff --git a/include/common.h b/include/common.h index 4c3e3a6..acc4030 100644 --- a/include/common.h +++ b/include/common.h @@ -277,6 +277,14 @@ int last_stage_init(void); extern ulong monitor_flash_len; int mac_read_from_eeprom(void); +/* + * Called during a panic() when no console is available. The board should do + * its best to get a message to the user any way it can. This function should + * return if it can, in which case the system will either hang or reset. + * See panic(). + */ +void board_panic_no_console(const char *str); + /* common/flash.c */ void flash_perror (int); diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 79dead3..56a2aef 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -24,6 +24,8 @@ # define NUM_TYPE long long #define noinline __attribute__((noinline)) +DECLARE_GLOBAL_DATA_PTR; + const char hex_asc[] = "0123456789abcdef"; #define hex_asc_lo(x) hex_asc[((x) & 0x0f)] #define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4] @@ -714,12 +716,39 @@ int sprintf(char * buf, const char *fmt, ...) return i; } +#ifdef CONFIG_PRE_CONSOLE_PANIC +/* Provide a default function for when no console is available */ +static void __board_panic_no_console(const char *msg) +{ + /* Just return since we can't access the console */ +} + +void board_panic_no_console(const char *msg) __attribute__((weak, + alias("__board_panic_no_console"))); +#endif + void panic(const char *fmt, ...) { va_list args; + va_start(args, fmt); +#ifdef CONFIG_PRE_CONSOLE_PANIC + { + char str[CONFIG_SYS_PBSIZE]; + + /* TODO)sjg): Move to vsnprintf() when available */ + vsprintf(str, fmt, args); + if (gd->have_console) { + puts(str); + putc('\n'); + } else { + board_panic_no_console(str); + } + } +#else vprintf(fmt, args); putc('\n'); +#endif va_end(args); #if defined (CONFIG_PANIC_HANG) hang(); -- 1.7.3.1 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot