diff options
| author | Tom Rini <[email protected]> | 2022-09-24 13:58:49 -0400 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2022-09-24 13:58:49 -0400 |
| commit | 81da5042e514bfd27516d3530dde4d62a6708ca4 (patch) | |
| tree | 75203cc106a2c1c340024fdb562be7c9b6d0e4e2 /common | |
| parent | 694e9008674c2008b9ccdc25a9bb3ac078e20911 (diff) | |
| parent | efc3f9526f9cfcd8614668c03b9c66b209782c41 (diff) | |
Merge branch '2022-09-24-add-console-flush' into next
To quote the author:
On certain places it is required to flush output print buffers to ensure
that text strings were sent to console or serial devices. For example when
printing message that U-Boot is going to boot kernel or when U-Boot is
going to change baudrate of terminal device.
Some console devices, like UART, have putc/puts functions which just put
characters into HW transmit queue and do not wait until all data are
transmitted. Doing some sensitive operations (like changing baudrate or
starting kernel which resets UART HW) cause that U-Boot messages are lost.
Therefore introduce a new flush() function, implement it for all serial
devices via pending(false) callback and use this new flush() function on
sensitive places after which output device may go into reset state.
This change fixes printing of U-Boot messages:
"## Starting application at ..."
"## Switch baudrate to ..."
In addition, take a patch from Heinrich to rename some EFI test
functions in order to not conflict with this series.
Diffstat (limited to 'common')
| -rw-r--r-- | common/Kconfig | 6 | ||||
| -rw-r--r-- | common/console.c | 64 | ||||
| -rw-r--r-- | common/stdio.c | 8 |
3 files changed, 78 insertions, 0 deletions
diff --git a/common/Kconfig b/common/Kconfig index b776c5ca1ec..6591acd2fd0 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -186,6 +186,12 @@ config PRE_CON_BUF_ADDR We should consider removing this option and allocating the memory in board_init_f_init_reserve() instead. +config CONSOLE_FLUSH_SUPPORT + bool "Enable console flush support" + default y + help + This enables compilation of flush() function for console flush support. + config CONSOLE_MUX bool "Enable console multiplexing" default y if DM_VIDEO || VIDEO || LCD diff --git a/common/console.c b/common/console.c index e5be6ff44b0..0c9bf66c3f6 100644 --- a/common/console.c +++ b/common/console.c @@ -199,6 +199,7 @@ static int console_setfile(int file, struct stdio_dev * dev) case stdout: gd->jt->putc = putc; gd->jt->puts = puts; + STDIO_DEV_ASSIGN_FLUSH(gd->jt, flush); gd->jt->printf = printf; break; } @@ -364,6 +365,19 @@ static void console_puts(int file, const char *s) } } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static void console_flush(int file) +{ + int i; + struct stdio_dev *dev; + + for_each_console_dev(i, file, dev) { + if (dev->flush != NULL) + dev->flush(dev); + } +} +#endif + #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) static inline void console_doenv(int file, struct stdio_dev *dev) { @@ -413,6 +427,14 @@ static inline void console_puts(int file, const char *s) stdio_devices[file]->puts(stdio_devices[file], s); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static inline void console_flush(int file) +{ + if (stdio_devices[file]->flush) + stdio_devices[file]->flush(stdio_devices[file]); +} +#endif + #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) static inline void console_doenv(int file, struct stdio_dev *dev) { @@ -526,6 +548,14 @@ void fputs(int file, const char *s) console_puts(file, s); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void fflush(int file) +{ + if (file < MAX_FILES) + console_flush(file); +} +#endif + int fprintf(int file, const char *fmt, ...) { va_list args; @@ -740,6 +770,40 @@ void puts(const char *s) } } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void flush(void) +{ + if (!gd) + return; + + /* sandbox can send characters to stdout before it has a console */ + if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) { + os_flush(); + return; + } + + if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) + return; + + if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) + return; + + if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE)) + return; + + if (!gd->have_console) + return; + + if (gd->flags & GD_FLG_DEVINIT) { + /* Send to the standard output */ + fflush(stdout); + } else { + /* Send directly to the handler */ + serial_flush(); + } +} +#endif + #ifdef CONFIG_CONSOLE_RECORD int console_record_init(void) { diff --git a/common/stdio.c b/common/stdio.c index 92161a0df87..13083842cbd 100644 --- a/common/stdio.c +++ b/common/stdio.c @@ -87,6 +87,13 @@ static void stdio_serial_puts(struct stdio_dev *dev, const char *s) serial_puts(s); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static void stdio_serial_flush(struct stdio_dev *dev) +{ + serial_flush(); +} +#endif + static int stdio_serial_getc(struct stdio_dev *dev) { return serial_getc(); @@ -112,6 +119,7 @@ static void drv_system_init (void) dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; dev.putc = stdio_serial_putc; dev.puts = stdio_serial_puts; + STDIO_DEV_ASSIGN_FLUSH(&dev, stdio_serial_flush); dev.getc = stdio_serial_getc; dev.tstc = stdio_serial_tstc; stdio_register (&dev); |
