This patch adds support for console output in the event of a panic() before the console is inited. The main purpose of this is to deal with a very early panic() which would otherwise cause a silent hang.
A new board_pre_console_panic() 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 available UARTs and output the string (plus a newline) if it possibly can. Signed-off-by: Simon Glass <s...@chromium.org> --- README | 34 ++++++++++++++++++++++++++++++++++ include/common.h | 8 ++++++++ lib/vsprintf.c | 25 +++++++++++++++++++++++-- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/README b/README index 84757a5..38ce52a 100644 --- a/README +++ b/README @@ -638,6 +638,40 @@ 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, console output is + normally silently discarded. This can be annoying if a + panic() happens in this time. One reason for this might be + that you have CONFIG_OF_CONTROL defined but have not + provided a valid device tree for U-Boot. In general U-Boot's + console code cannot resolve this problem, since the console + has not been set up, and it may not be known which UART is + the console anyway (for example if this information is in + the device tree). + + The solution is to define a function called + board_pre_console_panic() for your board, which alerts the + user however it can. Hopefuly this will involve displaying + a message on available UARTs, or perhaps at least flashing + an LED. The function should be very careful to only output + to UARTs that are known to be unused for peripheral + interfaces, and change GPIOs that will have no ill effect + on the board. That said, it is fine to do something + destructive that will prevent the board from continuing to + boot, since it isn't going to... + + The function will need to output serial data directly, + since the console code is not functional yet. Note that if + the panic happens early enough, then it is possible that + board_init_f() (or even arch_cpu_init() on ARM) has not + been called yet. You should init all clocks, GPIOs, etc. + that are needed to get the string out. Baud rates will need + to default to something sensible. + + If your function returns, then the normal panic processing + will occur (it will either hang or reset depending on + CONFIG_PANIC_HANG). + - Safe printf() functions Define CONFIG_SYS_VSNPRINTF to compile in safe versions of the printf() functions. These are defined in diff --git a/include/common.h b/include/common.h index b588410..9db3a6a 100644 --- a/include/common.h +++ b/include/common.h @@ -285,6 +285,14 @@ extern ulong monitor_flash_len; int mac_read_from_eeprom(void); extern u8 _binary_dt_dtb_start[]; /* embedded device tree blob */ +/* + * 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_pre_console_panic(const char *str); + /* common/flash.c */ void flash_perror (int); diff --git a/lib/vsprintf.c b/lib/vsprintf.c index e38a4b7..a478ff5ab 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -33,6 +33,9 @@ const char hex_asc[] = "0123456789abcdef"; #define hex_asc_lo(x) hex_asc[((x) & 0x0f)] #define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4] +DECLARE_GLOBAL_DATA_PTR; + + static inline char *pack_hex_byte(char *buf, u8 byte) { *buf++ = hex_asc_hi(byte); @@ -777,13 +780,31 @@ int sprintf(char * buf, const char *fmt, ...) return i; } +/* Provide a default function for when no console is available */ +static void __board_pre_console_panic(const char *msg) +{ + /* Just return since we can't access the console */ +} + +void board_pre_console_panic(const char *msg) __attribute__((weak, + alias("__board_pre_console_panic"))); + void panic(const char *fmt, ...) { + char str[CONFIG_SYS_PBSIZE]; va_list args; + va_start(args, fmt); - vprintf(fmt, args); - putc('\n'); + vsnprintf(str, sizeof(str), fmt, args); va_end(args); + + if (gd->have_console) { + puts(str); + putc('\n'); + } else { + board_pre_console_panic(str); + } + #if defined (CONFIG_PANIC_HANG) hang(); #else -- 1.7.7.3 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot