[U-Boot] [PATCH v2 2/5] Add board_panic_no_console() to deal with early critical errors
Simon Glass
sjg at chromium.org
Tue Mar 20 05:59:15 CET 2012
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 <sjg at 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
More information about the U-Boot
mailing list