summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/sandbox/cpu/os.c5
-rw-r--r--boot/bootm_os.c1
-rw-r--r--cmd/boot.c1
-rw-r--r--cmd/elf.c2
-rw-r--r--cmd/load.c5
-rw-r--r--common/Kconfig6
-rw-r--r--common/console.c64
-rw-r--r--common/stdio.c8
-rw-r--r--drivers/serial/serial-uclass.c31
-rw-r--r--include/_exports.h3
-rw-r--r--include/os.h8
-rw-r--r--include/serial.h5
-rw-r--r--include/stdio.h15
-rw-r--r--include/stdio_dev.h7
-rw-r--r--lib/efi_selftest/efi_selftest_loadimage.c87
15 files changed, 205 insertions, 43 deletions
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index f937991139c..01845e388d3 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/boot/bootm_os.c b/boot/bootm_os.c
index f31820cd07e..079224ce585 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 be67a5980de..14839c1cedc 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 ce40d3f72a7..b7b9f506a52 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)
diff --git a/cmd/load.c b/cmd/load.c
index e44ae0d56b7..5c4f34781d4 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/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);
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 0d43e9b6258..da3e1eb3ab1 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);
@@ -315,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)
@@ -398,6 +420,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);
@@ -447,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;
@@ -520,6 +550,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;
diff --git a/include/_exports.h b/include/_exports.h
index f6df8b61073..1af946fac32 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/os.h b/include/os.h
index 148178787bc..5b353ae9d94 100644
--- a/include/os.h
+++ b/include/os.h
@@ -296,6 +296,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
*
* @fname: filename to write memory to (simple binary format)
diff --git a/include/serial.h b/include/serial.h
index 8c2e7adbc32..fe01bcfadb9 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);
diff --git a/include/stdio.h b/include/stdio.h
index 1939a48f0fb..3241e2d493f 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 270fa2729fb..3105928970d 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 */
diff --git a/lib/efi_selftest/efi_selftest_loadimage.c b/lib/efi_selftest/efi_selftest_loadimage.c
index d4c76f557c7..24548f1ae63 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;