[U-Boot] [PATCH 1/2] console: Support board-specific early console

From: Thierry Reding treding@nvidia.com
This is mostly useful for debugging the early boot process. Often boards can provide some low-level code that outputs a character on some debug port prior to passing the early setup code. Allow boards to implement an early_putc() function that will be used to redirect printf() and friends to this debug port until the proper console becomes ready.
Cc: Simon Glass sjg@chromium.org Cc: Tom Rini trini@konsulko.com Signed-off-by: Thierry Reding treding@nvidia.com --- README | 17 +++++++++++++++++ common/console.c | 21 +++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/README b/README index b0124d6022e1..a7cb3d86d2d2 100644 --- a/README +++ b/README @@ -5014,6 +5014,23 @@ Low Level (hardware related) configuration options: driver that uses this: drivers/mtd/nand/davinci_nand.c
+- CONFIG_EARLY_CONSOLE + Enables support for an early console. Output from puts() and + printf() will be redirected to this early console. A primary + use-case for this is early board bring up, where U-Boot does + not boot to the proper console yet, but it can also be quite + handy to help debug U-Boot's early boot phases. + + Boards that specify this option in their configuration must + provide an implementation of the early_putc() function: + + void early_putc(char ch); + + This function should output a single character on a device + that is available during early boot. Often this will be a + debug UART that has been preconfigured by a bootloader or + ROM before executing U-Boot. + Freescale QE/FMAN Firmware Support: -----------------------------------
diff --git a/common/console.c b/common/console.c index 3f25e76fe79e..d552dff4ee0f 100644 --- a/common/console.c +++ b/common/console.c @@ -479,6 +479,16 @@ void putc(const char c) } }
+#ifdef CONFIG_EARLY_CONSOLE +extern void early_putc(char ch); + +static void early_puts(const char *s) +{ + while (*s) + early_putc(*s++); +} +#endif + void puts(const char *s) { #ifdef CONFIG_SANDBOX @@ -498,6 +508,11 @@ void puts(const char *s) return; #endif
+#ifdef CONFIG_EARLY_CONSOLE + if (!gd->have_console) + early_puts(s); +#endif + if (!gd->have_console) return pre_console_puts(s);
@@ -517,7 +532,8 @@ int printf(const char *fmt, ...) uint i; char printbuffer[CONFIG_SYS_PBSIZE];
-#if !defined(CONFIG_SANDBOX) && !defined(CONFIG_PRE_CONSOLE_BUFFER) +#if !defined(CONFIG_SANDBOX) && !defined(CONFIG_PRE_CONSOLE_BUFFER) && \ + !defined(CONFIG_EARLY_CONSOLE) if (!gd->have_console) return 0; #endif @@ -540,7 +556,8 @@ int vprintf(const char *fmt, va_list args) uint i; char printbuffer[CONFIG_SYS_PBSIZE];
-#if defined(CONFIG_PRE_CONSOLE_BUFFER) && !defined(CONFIG_SANDBOX) +#if !defined(CONFIG_SANDBOX) && !defined(CONFIG_PRE_CONSOLE_BUFFER) && \ + !defined(CONFIG_EARLY_CONSOLE) if (!gd->have_console) return 0; #endif

From: Thierry Reding treding@nvidia.com
Use the physical address of the debug serial port from the configuration to provide an early_putc() implementation that can be used with the new early console support.
Cc: Tom Warren twarren@nvidia.com Signed-off-by: Thierry Reding treding@nvidia.com --- board/nvidia/common/board.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c index c3d77893ded3..d945de456ea2 100644 --- a/board/nvidia/common/board.c +++ b/board/nvidia/common/board.c @@ -155,6 +155,28 @@ int board_init(void) return 0; }
+#ifdef CONFIG_EARLY_CONSOLE +#define UART_THR 0x00 +#define UART_LSR 0x14 + +void early_putc(char ch) +{ + uint32_t mask = UART_LSR_TEMT | UART_LSR_THRE, value; + unsigned long base = CONFIG_SYS_NS16550_COM1; + + if (ch == '\n') + early_putc('\r'); + + writel(ch, base + UART_THR); + + while (true) { + value = readl(base + UART_LSR); + if ((value & mask) == mask) + break; + } +} +#endif + #ifdef CONFIG_BOARD_EARLY_INIT_F static void __gpio_early_init(void) {

On Fri, Mar 20, 2015 at 12:30:33PM +0100, Thierry Reding wrote:
From: Thierry Reding treding@nvidia.com
This is mostly useful for debugging the early boot process. Often boards can provide some low-level code that outputs a character on some debug port prior to passing the early setup code. Allow boards to implement an early_putc() function that will be used to redirect printf() and friends to this debug port until the proper console becomes ready.
Cc: Simon Glass sjg@chromium.org Cc: Tom Rini trini@konsulko.com Signed-off-by: Thierry Reding treding@nvidia.com
Dumb question, shouldn't this plug into the DEBUG_UART stuff Simon did that's already merged?

Dear Thierry,
In message 1426851034-29393-1-git-send-email-thierry.reding@gmail.com you wrote:
This is mostly useful for debugging the early boot process. Often boards can provide some low-level code that outputs a character on some debug port prior to passing the early setup code. Allow boards to implement an early_putc() function that will be used to redirect printf() and friends to this debug port until the proper console becomes ready.
Hm... it is one of the basic design principles of U-Boot to provide debug output on the console as soon as possible. It should be the primary purpose of low level initialization to enable console output, before anything else.
Now you say, you have output even before that - this aears to be a contradiction to me. If you can output characters, then use this as your console. I feel we should not need any special configuration options to do what we should do anyway.
Or am I missing somthing?
Best regards,
Wolfgang Denk

Hi,
On 20 March 2015 at 10:55, Wolfgang Denk wd@denx.de wrote:
Dear Thierry,
In message 1426851034-29393-1-git-send-email-thierry.reding@gmail.com you wrote:
This is mostly useful for debugging the early boot process. Often boards can provide some low-level code that outputs a character on some debug port prior to passing the early setup code. Allow boards to implement an early_putc() function that will be used to redirect printf() and friends to this debug port until the proper console becomes ready.
Hm... it is one of the basic design principles of U-Boot to provide debug output on the console as soon as possible. It should be the primary purpose of low level initialization to enable console output, before anything else.
Now you say, you have output even before that - this aears to be a contradiction to me. If you can output characters, then use this as your console. I feel we should not need any special configuration options to do what we should do anyway.
Or am I missing somthing?
I agree we need to set things up so that the console can work as early as possible. With boards that support driver model, until that is running we have no serial, so I think we are talking about the time between entering U-Boot and console_init_f(). This has always been a bit of an issue.
I wonder if we can use the debug UART stuff (as Tom mentioned) but enhance it to support printf()? We could plumb the console into that perhaps? This is a little like CONFIG_PRE_CONSOLE_BUFFER.
It would be nice if it were seamless.
Regards, Simon
participants (4)
-
Simon Glass
-
Thierry Reding
-
Tom Rini
-
Wolfgang Denk