From ca0f827dc78aa23d3b898856cbe2727bdec108e2 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 22 Sep 2022 15:26:43 +0200 Subject: [PATCH 1/7] efi_selftest: prefix test functions with efi_st_ An upcoming patch set creates a global function flush(). To make debugging easier we should not use the same name for a static function. Rename static functions in the LoadImage() unit test adding an efi_st_ prefix. Signed-off-by: Heinrich Schuchardt Reviewed-by: Ilias Apalodimas --- lib/efi_selftest/efi_selftest_loadimage.c | 87 ++++++++++++----------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/lib/efi_selftest/efi_selftest_loadimage.c b/lib/efi_selftest/efi_selftest_loadimage.c index d4c76f557c..24548f1ae6 100644 --- a/lib/efi_selftest/efi_selftest_loadimage.c +++ b/lib/efi_selftest/efi_selftest_loadimage.c @@ -142,38 +142,39 @@ static struct efi_file_system_info *file_system_info = &priv_file_system_info.info; /* Forward definitions of file and file system functions */ -static efi_status_t EFIAPI open_volume +static efi_status_t EFIAPI efi_st_open_volume (struct efi_simple_file_system_protocol *this, struct efi_file_handle **root); -static efi_status_t EFIAPI open +static efi_status_t EFIAPI efi_st_open (struct efi_file_handle *this, struct efi_file_handle **new_handle, u16 *file_name, u64 open_mode, u64 attributes); -static efi_status_t EFIAPI close(struct efi_file_handle *this); +static efi_status_t EFIAPI efi_st_close(struct efi_file_handle *this); -static efi_status_t EFIAPI delete(struct efi_file_handle *this); +static efi_status_t EFIAPI efi_st_delete(struct efi_file_handle *this); -static efi_status_t EFIAPI read +static efi_status_t EFIAPI efi_st_read (struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer); -static efi_status_t EFIAPI write +static efi_status_t EFIAPI efi_st_write (struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer); -static efi_status_t EFIAPI getpos(struct efi_file_handle *this, u64 *pos); +static efi_status_t EFIAPI efi_st_getpos(struct efi_file_handle *this, + u64 *pos); -static efi_status_t EFIAPI setpos(struct efi_file_handle *this, u64 pos); +static efi_status_t EFIAPI efi_st_setpos(struct efi_file_handle *this, u64 pos); -static efi_status_t EFIAPI getinfo +static efi_status_t EFIAPI efi_st_getinfo (struct efi_file_handle *this, const efi_guid_t *info_type, efi_uintn_t *buffer_size, void *buffer); -static efi_status_t EFIAPI setinfo +static efi_status_t EFIAPI efi_st_setinfo (struct efi_file_handle *this, const efi_guid_t *info_type, efi_uintn_t buffer_size, void *buffer); -static efi_status_t EFIAPI flush(struct efi_file_handle *this); +static efi_status_t EFIAPI efi_st_flush(struct efi_file_handle *this); /* Internal information about status of file system */ static struct { @@ -190,40 +191,40 @@ static struct { /* EFI_FILE_PROTOCOL for file */ static struct efi_file_handle file = { .rev = 0x00010000, - .open = open, - .close = close, - .delete = delete, - .read = read, - .write = write, - .getpos = getpos, - .setpos = setpos, - .getinfo = getinfo, - .setinfo = setinfo, - .flush = flush, + .open = efi_st_open, + .close = efi_st_close, + .delete = efi_st_delete, + .read = efi_st_read, + .write = efi_st_write, + .getpos = efi_st_getpos, + .setpos = efi_st_setpos, + .getinfo = efi_st_getinfo, + .setinfo = efi_st_setinfo, + .flush = efi_st_flush, }; /* EFI_FILE_PROTOCOL for root directory */ static struct efi_file_handle volume = { .rev = 0x00010000, - .open = open, - .close = close, - .delete = delete, - .read = read, - .write = write, - .getpos = getpos, - .setpos = setpos, - .getinfo = getinfo, - .setinfo = setinfo, - .flush = flush, + .open = efi_st_open, + .close = efi_st_close, + .delete = efi_st_delete, + .read = efi_st_read, + .write = efi_st_write, + .getpos = efi_st_getpos, + .setpos = efi_st_setpos, + .getinfo = efi_st_getinfo, + .setinfo = efi_st_setinfo, + .flush = efi_st_flush, }; /* EFI_SIMPLE_FILE_SYSTEM_PROTOCOL of the block device */ struct efi_simple_file_system_protocol file_system = { .rev = 0x00010000, - .open_volume = open_volume, + .open_volume = efi_st_open_volume, }; -static efi_status_t EFIAPI open_volume +static efi_status_t EFIAPI efi_st_open_volume (struct efi_simple_file_system_protocol *this, struct efi_file_handle **root) { @@ -236,7 +237,7 @@ static efi_status_t EFIAPI open_volume return EFI_SUCCESS; } -static efi_status_t EFIAPI open +static efi_status_t EFIAPI efi_st_open (struct efi_file_handle *this, struct efi_file_handle **new_handle, u16 *file_name, u64 open_mode, u64 attributes) @@ -251,7 +252,7 @@ static efi_status_t EFIAPI open return EFI_SUCCESS; } -static efi_status_t EFIAPI close(struct efi_file_handle *this) +static efi_status_t EFIAPI efi_st_close(struct efi_file_handle *this) { if (this == &file) priv.file_open_count--; @@ -263,7 +264,7 @@ static efi_status_t EFIAPI close(struct efi_file_handle *this) return EFI_SUCCESS; } -static efi_status_t EFIAPI delete(struct efi_file_handle *this) +static efi_status_t EFIAPI efi_st_delete(struct efi_file_handle *this) { if (this != &file) return EFI_INVALID_PARAMETER; @@ -271,7 +272,7 @@ static efi_status_t EFIAPI delete(struct efi_file_handle *this) return EFI_UNSUPPORTED; } -static efi_status_t EFIAPI read +static efi_status_t EFIAPI efi_st_read (struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer) { if (this != &file) @@ -288,7 +289,7 @@ static efi_status_t EFIAPI read return EFI_SUCCESS; } -static efi_status_t EFIAPI write +static efi_status_t EFIAPI efi_st_write (struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer) { if (this != &file) @@ -297,7 +298,7 @@ static efi_status_t EFIAPI write return EFI_UNSUPPORTED; } -static efi_status_t EFIAPI getpos(struct efi_file_handle *this, u64 *pos) +static efi_status_t EFIAPI efi_st_getpos(struct efi_file_handle *this, u64 *pos) { if (this != &file) return EFI_INVALID_PARAMETER; @@ -307,7 +308,7 @@ static efi_status_t EFIAPI getpos(struct efi_file_handle *this, u64 *pos) return EFI_SUCCESS; } -static efi_status_t EFIAPI setpos(struct efi_file_handle *this, u64 pos) +static efi_status_t EFIAPI efi_st_setpos(struct efi_file_handle *this, u64 pos) { if (this != &file) return EFI_INVALID_PARAMETER; @@ -317,7 +318,7 @@ static efi_status_t EFIAPI setpos(struct efi_file_handle *this, u64 pos) return EFI_SUCCESS; } -static efi_status_t EFIAPI getinfo +static efi_status_t EFIAPI efi_st_getinfo (struct efi_file_handle *this, const efi_guid_t *info_type, efi_uintn_t *buffer_size, void *buffer) { @@ -348,7 +349,7 @@ static efi_status_t EFIAPI getinfo return EFI_SUCCESS; } -static efi_status_t EFIAPI setinfo +static efi_status_t EFIAPI efi_st_setinfo (struct efi_file_handle *this, const efi_guid_t *info_type, efi_uintn_t buffer_size, void *buffer) { @@ -358,7 +359,7 @@ static efi_status_t EFIAPI setinfo return EFI_UNSUPPORTED; } -static efi_status_t EFIAPI flush(struct efi_file_handle *this) +static efi_status_t EFIAPI efi_st_flush(struct efi_file_handle *this) { if (this != &file) return EFI_INVALID_PARAMETER; From 7df5b353347621cca0eef7420ba045bf852e778a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 5 Sep 2022 11:31:16 +0200 Subject: [PATCH 2/7] sandbox: Add function os_flush() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It flushes stdout. Signed-off-by: Pali Rohár Reviewed-by: Simon Glass --- arch/sandbox/cpu/os.c | 5 +++++ include/os.h | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index f937991139..01845e388d 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -669,6 +669,11 @@ void os_puts(const char *str) os_putc(*str++); } +void os_flush(void) +{ + fflush(stdout); +} + int os_write_ram_buf(const char *fname) { struct sandbox_state *state = state_get_current(); diff --git a/include/os.h b/include/os.h index 148178787b..5b353ae9d9 100644 --- a/include/os.h +++ b/include/os.h @@ -295,6 +295,14 @@ void os_putc(int ch); */ void os_puts(const char *str); +/** + * os_flush() - flush controlling OS terminal + * + * This bypasses the U-Boot console support and flushes directly the OS + * stdout file descriptor. + */ +void os_flush(void); + /** * os_write_ram_buf() - write the sandbox RAM buffer to a existing file * From 974f48366f5b151f13b91961ec7721e74fb54fa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 5 Sep 2022 11:31:17 +0200 Subject: [PATCH 3/7] console: Implement flush() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. Therefore introduce a new flush() and fflush() functions into console code. These functions will call .flush callback of associated stdio_dev device. As this function may increase U-Boot side, allow to compile U-Boot without this function. For this purpose there is a new config CONSOLE_FLUSH_SUPPORT which is enabled by default and can be disabled. It is a good idea to have this option enabled for all boards which have enough space for it. When option is disabled when U-Boot defines just empty static inline function fflush() to avoid ifdefs in other code. Signed-off-by: Pali Rohár Reviewed-by: Simon Glass --- common/Kconfig | 6 +++++ common/console.c | 61 +++++++++++++++++++++++++++++++++++++++++++++ include/_exports.h | 3 +++ include/stdio.h | 15 +++++++++++ include/stdio_dev.h | 7 ++++++ 5 files changed, 92 insertions(+) diff --git a/common/Kconfig b/common/Kconfig index b776c5ca1e..6591acd2fd 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 e5be6ff44b..ce0c9b69f5 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,37 @@ 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); + } +} +#endif + #ifdef CONFIG_CONSOLE_RECORD int console_record_init(void) { diff --git a/include/_exports.h b/include/_exports.h index f6df8b6107..1af946fac3 100644 --- a/include/_exports.h +++ b/include/_exports.h @@ -12,6 +12,9 @@ EXPORT_FUNC(tstc, int, tstc, void) EXPORT_FUNC(putc, void, putc, const char) EXPORT_FUNC(puts, void, puts, const char *) +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT + EXPORT_FUNC(flush, void, flush, void) +#endif EXPORT_FUNC(printf, int, printf, const char*, ...) #if (defined(CONFIG_X86) && !defined(CONFIG_X86_64)) || defined(CONFIG_PPC) EXPORT_FUNC(irq_install_handler, void, install_hdlr, diff --git a/include/stdio.h b/include/stdio.h index 1939a48f0f..3241e2d493 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -15,6 +15,11 @@ int tstc(void); defined(CONFIG_SPL_SERIAL)) void putc(const char c); void puts(const char *s); +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void flush(void); +#else +static inline void flush(void) {} +#endif int __printf(1, 2) printf(const char *fmt, ...); int vprintf(const char *fmt, va_list args); #else @@ -26,6 +31,10 @@ static inline void puts(const char *s) { } +static inline void flush(void) +{ +} + static inline int __printf(1, 2) printf(const char *fmt, ...) { return 0; @@ -48,11 +57,17 @@ static inline int vprintf(const char *fmt, va_list args) /* stderr */ #define eputc(c) fputc(stderr, c) #define eputs(s) fputs(stderr, s) +#define eflush() fflush(stderr) #define eprintf(fmt, args...) fprintf(stderr, fmt, ##args) int __printf(2, 3) fprintf(int file, const char *fmt, ...); void fputs(int file, const char *s); void fputc(int file, const char c); +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void fflush(int file); +#else +static inline void fflush(int file) {} +#endif int ftstc(int file); int fgetc(int file); diff --git a/include/stdio_dev.h b/include/stdio_dev.h index 270fa2729f..3105928970 100644 --- a/include/stdio_dev.h +++ b/include/stdio_dev.h @@ -37,6 +37,13 @@ struct stdio_dev { void (*putc)(struct stdio_dev *dev, const char c); /* To put a string (accelerator) */ void (*puts)(struct stdio_dev *dev, const char *s); +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT + /* To flush output queue */ + void (*flush)(struct stdio_dev *dev); +#define STDIO_DEV_ASSIGN_FLUSH(dev, flush_func) ((dev)->flush = (flush_func)) +#else +#define STDIO_DEV_ASSIGN_FLUSH(dev, flush_func) +#endif /* INPUT functions */ From 016e2be96d4247ceacca05932f2e94d31607cc57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 5 Sep 2022 11:31:18 +0200 Subject: [PATCH 4/7] serial: Implement flush callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UART drivers have putc/puts functions which just put characters into HW transmit queue and do not wait until all data are transmitted. Implement flush callback via serial driver's pending(false) callback which waits until HW transmit all characters from the queue. Signed-off-by: Pali Rohár Reviewed-by: Simon Glass --- drivers/serial/serial-uclass.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 0d43e9b625..1234fe0e84 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -238,6 +238,18 @@ static void _serial_puts(struct udevice *dev, const char *str) } while (*str); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static void _serial_flush(struct udevice *dev) +{ + struct dm_serial_ops *ops = serial_get_ops(dev); + + if (!ops->pending) + return; + while (ops->pending(dev, false) > 0) + ; +} +#endif + static int __serial_getc(struct udevice *dev) { struct dm_serial_ops *ops = serial_get_ops(dev); @@ -398,6 +410,13 @@ static void serial_stub_puts(struct stdio_dev *sdev, const char *str) _serial_puts(sdev->priv, str); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static void serial_stub_flush(struct stdio_dev *sdev) +{ + _serial_flush(sdev->priv); +} +#endif + static int serial_stub_getc(struct stdio_dev *sdev) { return _serial_getc(sdev->priv); @@ -520,6 +539,7 @@ static int serial_post_probe(struct udevice *dev) sdev.priv = dev; sdev.putc = serial_stub_putc; sdev.puts = serial_stub_puts; + STDIO_DEV_ASSIGN_FLUSH(&sdev, serial_stub_flush); sdev.getc = serial_stub_getc; sdev.tstc = serial_stub_tstc; From 78b5243182be8fa222f6d496e7d49675fde4d09e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 5 Sep 2022 11:31:19 +0200 Subject: [PATCH 5/7] serial: Implement serial_flush() function for console flush() fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Like in all other console functions, implement also serial_flush() function as a fallback int console flush() function. Flush support is available only when config option CONSOLE_FLUSH_SUPPORT is enabled. So when it is disabled then provides just empty static inline function serial_flush(). Signed-off-by: Pali Rohár Reviewed-by: Simon Glass --- common/console.c | 3 +++ common/stdio.c | 8 ++++++++ drivers/serial/serial-uclass.c | 10 ++++++++++ include/serial.h | 5 +++++ 4 files changed, 26 insertions(+) diff --git a/common/console.c b/common/console.c index ce0c9b69f5..0c9bf66c3f 100644 --- a/common/console.c +++ b/common/console.c @@ -797,6 +797,9 @@ void flush(void) if (gd->flags & GD_FLG_DEVINIT) { /* Send to the standard output */ fflush(stdout); + } else { + /* Send directly to the handler */ + serial_flush(); } } #endif diff --git a/common/stdio.c b/common/stdio.c index 92161a0df8..13083842cb 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); diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 1234fe0e84..53df10ee85 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -327,6 +327,16 @@ void serial_puts(const char *str) _serial_puts(gd->cur_serial_dev, str); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void serial_flush(void) +{ + if (!gd->cur_serial_dev) + return; + + _serial_flush(gd->cur_serial_dev); +} +#endif + int serial_getc(void) { if (!gd->cur_serial_dev) diff --git a/include/serial.h b/include/serial.h index 8c2e7adbc3..fe01bcfadb 100644 --- a/include/serial.h +++ b/include/serial.h @@ -362,6 +362,11 @@ void serial_setbrg(void); void serial_putc(const char ch); void serial_putc_raw(const char ch); void serial_puts(const char *str); +#if defined(CONFIG_CONSOLE_FLUSH_SUPPORT) && CONFIG_IS_ENABLED(DM_SERIAL) +void serial_flush(void); +#else +static inline void serial_flush(void) {} +#endif int serial_getc(void); int serial_tstc(void); From 989cc40f806b68678e10203ec3b63d38d0fdd6eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 5 Sep 2022 11:31:20 +0200 Subject: [PATCH 6/7] serial: Call flush() before changing baudrate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changing baudrate is a sensitive operation. To ensure that U-Boot messages printed before changing baudrate are not lost, call new U-Boot console flush() function. Signed-off-by: Pali Rohár Reviewed-by: Simon Glass --- cmd/load.c | 5 +++++ drivers/serial/serial-uclass.c | 1 + 2 files changed, 6 insertions(+) diff --git a/cmd/load.c b/cmd/load.c index e44ae0d56b..5c4f34781d 100644 --- a/cmd/load.c +++ b/cmd/load.c @@ -83,6 +83,7 @@ static int do_load_serial(struct cmd_tbl *cmdtp, int flag, int argc, printf("## Switch baudrate to %d bps and press ENTER ...\n", load_baudrate); udelay(50000); + flush(); gd->baudrate = load_baudrate; serial_setbrg(); udelay(50000); @@ -126,6 +127,7 @@ static int do_load_serial(struct cmd_tbl *cmdtp, int flag, int argc, printf("## Switch baudrate to %d bps and press ESC ...\n", current_baudrate); udelay(50000); + flush(); gd->baudrate = current_baudrate; serial_setbrg(); udelay(50000); @@ -317,6 +319,7 @@ int do_save_serial(struct cmd_tbl *cmdtp, int flag, int argc, printf("## Switch baudrate to %d bps and press ESC ...\n", (int)current_baudrate); udelay(50000); + flush(); gd->baudrate = current_baudrate; serial_setbrg(); udelay(50000); @@ -471,6 +474,7 @@ static int do_load_serial_bin(struct cmd_tbl *cmdtp, int flag, int argc, printf("## Switch baudrate to %d bps and press ENTER ...\n", load_baudrate); udelay(50000); + flush(); gd->baudrate = load_baudrate; serial_setbrg(); udelay(50000); @@ -533,6 +537,7 @@ static int do_load_serial_bin(struct cmd_tbl *cmdtp, int flag, int argc, printf("## Switch baudrate to %d bps and press ESC ...\n", current_baudrate); udelay(50000); + flush(); gd->baudrate = current_baudrate; serial_setbrg(); udelay(50000); diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 53df10ee85..da3e1eb3ab 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -476,6 +476,7 @@ static int on_baudrate(const char *name, const char *value, enum env_op op, printf("## Switch baudrate to %d bps and press ENTER ...\n", baudrate); udelay(50000); + flush(); } gd->baudrate = baudrate; From efc3f9526f9cfcd8614668c03b9c66b209782c41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 5 Sep 2022 11:31:21 +0200 Subject: [PATCH 7/7] boot: Call flush() before booting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In a lot of cases kernel resets UART HW. To ensure that U-Boot messages printed before booting the kernel are not lost, call new U-Boot console flush() function. Signed-off-by: Pali Rohár Reviewed-by: Simon Glass --- boot/bootm_os.c | 1 + cmd/boot.c | 1 + cmd/elf.c | 2 ++ 3 files changed, 4 insertions(+) diff --git a/boot/bootm_os.c b/boot/bootm_os.c index f31820cd07..079224ce58 100644 --- a/boot/bootm_os.c +++ b/boot/bootm_os.c @@ -303,6 +303,7 @@ static void do_bootvx_fdt(bootm_headers_t *images) #else printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep); #endif + flush(); boot_jump_vxworks(images); diff --git a/cmd/boot.c b/cmd/boot.c index be67a5980d..14839c1ced 100644 --- a/cmd/boot.c +++ b/cmd/boot.c @@ -32,6 +32,7 @@ static int do_go(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) addr = hextoul(argv[1], NULL); printf ("## Starting application at 0x%08lX ...\n", addr); + flush(); /* * pass address parameter as argv[0] (aka command name), diff --git a/cmd/elf.c b/cmd/elf.c index ce40d3f72a..b7b9f506a5 100644 --- a/cmd/elf.c +++ b/cmd/elf.c @@ -72,6 +72,7 @@ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) return rcode; printf("## Starting application at 0x%08lx ...\n", addr); + flush(); /* * pass address parameter as argv[0] (aka command name), @@ -274,6 +275,7 @@ int do_bootvx(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) puts("## Not an ELF image, assuming binary\n"); printf("## Starting vxWorks at 0x%08lx ...\n", addr); + flush(); dcache_disable(); #if defined(CONFIG_ARM64) && defined(CONFIG_ARMV8_PSCI)