
From: Simon Glass <sjg@chromium.org> Send all console output via the pager. If it is disabled, it will do nothing. The pager is only supported if CONSOLE_MUX and SYS_CONSOLE_IS_IN_ENV are enabled. This is the common case for more richly featured boards, i.e. those that can cope with the extra code size of this feature. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <sjg@chromium.org> --- common/Kconfig | 9 ++++++ common/console.c | 52 +++++++++++++++++++++++++------ include/asm-generic/global_data.h | 11 +++++++ 3 files changed, 63 insertions(+), 9 deletions(-) diff --git a/common/Kconfig b/common/Kconfig index 048530adff3..6c54f90109c 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -343,6 +343,15 @@ config CONSOLE_PAGER controlled by the 'pager' environment variable. If the variable is not set or is empty, paging is disabled. +config CONSOLE_PAGER_LINES + int "Number of lines per page" + depends on CONSOLE_PAGER + default 25 + help + Sets the default number of lines that the pager assumes is visible on + the display. This is used as a default if the "pager" environment + variable is unset. + endmenu menu "Logging" diff --git a/common/console.c b/common/console.c index fdccf156b5a..9bc506f0464 100644 --- a/common/console.c +++ b/common/console.c @@ -16,6 +16,7 @@ #include <malloc.h> #include <mapmem.h> #include <os.h> +#include <pager.h> #include <serial.h> #include <stdio_dev.h> #include <exports.h> @@ -377,17 +378,32 @@ int console_printf_select_stderr(bool serial_only, const char *fmt, ...) return ret; } -static void console_puts_pager(int file, const char *s) +static void console_puts(int file, bool use_pager, const char *s) { - int i; - struct stdio_dev *dev; + int key = 0; - for_each_console_dev(i, file, dev) { - if (dev->puts != NULL) - dev->puts(dev, s); + for (s = pager_post(gd_pager(), use_pager, s); s; + s = pager_next(gd_pager(), use_pager, key)) { + struct stdio_dev *dev; + int i; + + key = 0; + if (s == PAGER_WAITING) { + key = getchar(); + } else if (*s) { + for_each_console_dev(i, file, dev) { + if (dev->puts != NULL) + dev->puts(dev, s); + } + } } } +static void console_puts_pager(int file, const char *s) +{ + console_puts(file, true, s); +} + #ifdef CONFIG_CONSOLE_FLUSH_SUPPORT static void console_flush(int file) { @@ -407,7 +423,8 @@ static inline void console_doenv(int file, struct stdio_dev *dev) iomux_doenv(file, dev->name); } #endif -#else + +#else /* !CONSOLE_MUX */ static void console_devices_set(int file, struct stdio_dev *dev) { @@ -780,8 +797,8 @@ void puts(const char *s) return pre_console_puts(s); if (gd->flags & GD_FLG_DEVINIT) { - /* Send to the standard output */ - fputs(stdout, s); + /* Send to the standard output through pager system */ + console_puts_pager(stdout, s); } else { /* Send directly to the handler */ pre_console_puts(s); @@ -1101,6 +1118,21 @@ static void stdio_print_current_devices(void) printf("%s\n", stderrname); } +static void setup_pager(void) +{ + /* Init pager now that console is ready */ + if (IS_ENABLED(CONFIG_CONSOLE_PAGER)) { + int lines = IF_ENABLED_INT(CONFIG_CONSOLE_PAGER, + CONFIG_CONSOLE_PAGER_LINES); + int ret; + + ret = pager_init(gd_pagerp(), env_get_hex("pager", lines), + PAGER_BUF_SIZE); + if (ret) + printf("Failed to init pager\n"); + } +} + #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) /* Called after the relocation - use desired console functions */ int console_init_r(void) @@ -1185,6 +1217,7 @@ done: } gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ + setup_pager(); print_pre_console_buffer(flushpoint); return 0; @@ -1252,6 +1285,7 @@ int console_init_r(void) } gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ + setup_pager(); print_pre_console_buffer(flushpoint); return 0; diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 464b9c3eee1..0157fead337 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -477,6 +477,9 @@ struct global_data { */ struct upl *upl; #endif +#if CONFIG_IS_ENABLED(CONSOLE_PAGER) + struct pager *pager; +#endif }; #ifndef DO_DEPS_ONLY static_assert(sizeof(struct global_data) == GD_SIZE); @@ -618,6 +621,14 @@ static_assert(sizeof(struct global_data) == GD_SIZE); #define gd_passage_dtb() 0 #endif +#if CONFIG_IS_ENABLED(CONSOLE_PAGER) +#define gd_pager() gd->pager +#define gd_pagerp() &gd->pager +#else +#define gd_pager() NULL +#define gd_pagerp() NULL +#endif + /** * enum gd_flags - global data flags * -- 2.43.0