From patchwork Mon Mar 19 20:27:01 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 147620 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 282C2B6FC9 for ; Tue, 20 Mar 2012 07:28:08 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 0EAD428088; Mon, 19 Mar 2012 21:27:58 +0100 (CET) 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 ubFi-Zpdks7u; Mon, 19 Mar 2012 21:27:57 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 0B8132809A; Mon, 19 Mar 2012 21:27:32 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A54A428089 for ; Mon, 19 Mar 2012 21:27:29 +0100 (CET) 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 9GFSAFmaNTwy for ; Mon, 19 Mar 2012 21:27:29 +0100 (CET) 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 mail-bk0-f74.google.com (mail-bk0-f74.google.com [209.85.214.74]) by theia.denx.de (Postfix) with ESMTPS id 246DD28082 for ; Mon, 19 Mar 2012 21:27:27 +0100 (CET) Received: by bkcjm19 with SMTP id jm19so300595bkc.3 for ; Mon, 19 Mar 2012 13:27:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=9J3dLRYxNaQe+UCRUkV2RnUsmSnUtGPa4psiVw3Nhdg=; b=PfCmdFlNwlV6JCWYXLdoHbuMbpA/fSh94jCxjTm+ECJP33+1pxW/mhxXa7F7fvRHL8 vJSmwaREEMsrlDeAgsW1P1YcBddlxOJnLeoXxVXerNvTd5Ikc00gfKxckN1Q2TZukGBI BIpWoIvgp8Gn2AlAvdDxtwIT4mT0DbzWFk6tlFDdHjp13cCMRzD+Xly9H7bas5zZzLb4 FlR5JPs41nRIrQAxbdUbwqcdngAJC5aqBwUdYelUojkjyS0JBdCfjixXHlUu81tkza10 afXg8lZK3eYYjkk82Cco/eXEYkpLjxTj5Uxp6U123Pk2s6yXcOwWi7pk1Bs/sSWsnsKb R1SA== Received: by 10.14.95.199 with SMTP id p47mr1361759eef.3.1332188845994; Mon, 19 Mar 2012 13:27:25 -0700 (PDT) Received: by 10.14.95.199 with SMTP id p47mr1361735eef.3.1332188845834; Mon, 19 Mar 2012 13:27:25 -0700 (PDT) Received: from hpza10.eem.corp.google.com ([74.125.121.33]) by gmr-mx.google.com with ESMTPS id a14si10858623een.0.2012.03.19.13.27.25 (version=TLSv1/SSLv3 cipher=AES128-SHA); Mon, 19 Mar 2012 13:27:25 -0700 (PDT) Received: from sglass.mtv.corp.google.com (dhcp-172-22-162-38.mtv.corp.google.com [172.22.162.38]) by hpza10.eem.corp.google.com (Postfix) with ESMTP id 6857F20004E; Mon, 19 Mar 2012 13:27:25 -0700 (PDT) Received: by sglass.mtv.corp.google.com (Postfix, from userid 121222) id CA6811409B5; Mon, 19 Mar 2012 13:27:24 -0700 (PDT) From: Simon Glass To: U-Boot Mailing List Date: Mon, 19 Mar 2012 13:27:01 -0700 Message-Id: <1332188824-5447-2-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 1.7.7.3 In-Reply-To: <1332188824-5447-1-git-send-email-sjg@chromium.org> References: <1332188824-5447-1-git-send-email-sjg@chromium.org> X-Gm-Message-State: ALoCoQlj0AVWeIlpo9eA0BCXDthQi01vURDErsibgqpMoyhjCq1MYjH0ZghyZoFqHrgRKDBgEZuTMBlJRRRn+wIT2mucoJ0Bb+QS2D2/qoHLaz2+koBhcvMaqrNxyrpY0zT+WEyNiqGPnw6HTJHvy1ywwltF147tyVcx9aBE23Z7AG8ZvhLGxhg= Cc: Tom Warren Subject: [U-Boot] [PATCH 2/5] Add board_panic_no_console() to deal with early critical errors X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 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 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 --- 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