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

Reply via email to