From patchwork Tue Oct 18 02:16:26 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 120358 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 8CF40B6F84 for ; Tue, 18 Oct 2011 13:16:47 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 6BF0A290D8; Tue, 18 Oct 2011 04:16:44 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id PoZOJfU+PtPY; Tue, 18 Oct 2011 04:16:43 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 6A5C228FEF; Tue, 18 Oct 2011 04:16:42 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 18A6728FEF for ; Tue, 18 Oct 2011 04:16:39 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8I-W4WCHxhrz for ; Tue, 18 Oct 2011 04:16:38 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from smtp-out.google.com (smtp-out.google.com [74.125.121.67]) by theia.denx.de (Postfix) with ESMTPS id 22E6E28FAA for ; Tue, 18 Oct 2011 04:16:36 +0200 (CEST) Received: from wpaz37.hot.corp.google.com (wpaz37.hot.corp.google.com [172.24.198.101]) by smtp-out.google.com with ESMTP id p9I2GUfu020918; Mon, 17 Oct 2011 19:16:31 -0700 Received: from sglass.mtv.corp.google.com (sglass.mtv.corp.google.com [172.22.72.144]) by wpaz37.hot.corp.google.com with ESMTP id p9I2GTfs016396; Mon, 17 Oct 2011 19:16:29 -0700 Received: by sglass.mtv.corp.google.com (Postfix, from userid 121222) id D2E72140B9B; Mon, 17 Oct 2011 19:16:28 -0700 (PDT) From: Simon Glass To: U-Boot Mailing List Date: Mon, 17 Oct 2011 19:16:26 -0700 Message-Id: <1318904186-12271-1-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 1.7.3.1 X-System-Of-Record: true Subject: [U-Boot] [PATCH v2] Add board_panic_no_console to deal with early critical errors X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de 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 --- 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();