diff --git a/common/Kconfig b/common/Kconfig index 620d41f..ccf5475 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -679,3 +679,31 @@ config CMD_TPM_TEST endmenu endmenu + +config CONSOLE_RECORD + bool "Console recording" + help + This provides a way to record console output (and provide console + input) through cirular buffers. This is mostly useful for testing. + Console output is recorded even when the console is silent. + To enable console recording, call console_record_reset_enable() + from your code. + +config CONSOLE_RECORD_OUT_SIZE + hex "Output buffer size" + depends on CONSOLE_RECORD + default 0x400 if CONSOLE_RECORD + help + Set the size of the console output buffer. When this fills up, no + more data will be recorded until some is removed. The buffer is + allocated immediately after the malloc() region is ready. + +config CONSOLE_RECORD_IN_SIZE + hex "Input buffer size" + depends on CONSOLE_RECORD + default 0x100 if CONSOLE_RECORD + help + Set the size of the console input buffer. When this contains data, + tstc() and getc() will use this in preference to real device input. + The buffer is allocated immediately after the malloc() region is + ready. diff --git a/common/board_f.c b/common/board_f.c index 09baa5c..b035c90 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -737,6 +737,15 @@ static int mark_bootstage(void) return 0; } +static int initf_console_record(void) +{ +#if defined(CONFIG_CONSOLE_RECORD) && defined(CONFIG_SYS_MALLOC_F_LEN) + return console_record_init(); +#else + return 0; +#endif +} + static int initf_dm(void) { #if defined(CONFIG_DM) && defined(CONFIG_SYS_MALLOC_F_LEN) @@ -773,6 +782,7 @@ static init_fnc_t init_sequence_f[] = { trace_early_init, #endif initf_malloc, + initf_console_record, #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) /* TODO: can this go into arch_cpu_init()? */ probecpu, diff --git a/common/board_r.c b/common/board_r.c index 85aef95..f7118e8 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -280,6 +280,15 @@ static int initr_malloc(void) return 0; } +static int initr_console_record(void) +{ +#if defined(CONFIG_CONSOLE_RECORD) + return console_record_init(); +#else + return 0; +#endif +} + #ifdef CONFIG_SYS_NONCACHED_MEMORY static int initr_noncached(void) { @@ -731,6 +740,7 @@ init_fnc_t init_sequence_r[] = { #endif initr_barrier, initr_malloc, + initr_console_record, #ifdef CONFIG_SYS_NONCACHED_MEMORY initr_noncached, #endif diff --git a/common/console.c b/common/console.c index 10972b0..b3f126c 100644 --- a/common/console.c +++ b/common/console.c @@ -378,6 +378,15 @@ int getc(void) if (!gd->have_console) return 0; +#ifdef CONFIG_CONSOLE_RECORD + if (gd->console_in.start) { + int ch; + + ch = membuff_getbyte(&gd->console_in); + if (ch != -1) + return 1; + } +#endif if (gd->flags & GD_FLG_DEVINIT) { /* Get from the standard input */ return fgetc(stdin); @@ -396,7 +405,12 @@ int tstc(void) if (!gd->have_console) return 0; - +#ifdef CONFIG_CONSOLE_RECORD + if (gd->console_in.start) { + if (membuff_peekbyte(&gd->console_in) != -1) + return 1; + } +#endif if (gd->flags & GD_FLG_DEVINIT) { /* Test the standard input */ return ftstc(stdin); @@ -470,6 +484,10 @@ void putc(const char c) return; } #endif +#ifdef CONFIG_CONSOLE_RECORD + if (gd && (gd->flags & GD_FLG_RECORD) && gd->console_out.start) + membuff_putbyte(&gd->console_out, c); +#endif #ifdef CONFIG_SILENT_CONSOLE if (gd->flags & GD_FLG_SILENT) return; @@ -513,6 +531,10 @@ void puts(const char *s) return; } #endif +#ifdef CONFIG_CONSOLE_RECORD + if (gd && (gd->flags & GD_FLG_RECORD) && gd->console_out.start) + membuff_put(&gd->console_out, s, strlen(s)); +#endif #ifdef CONFIG_SILENT_CONSOLE if (gd->flags & GD_FLG_SILENT) return; @@ -575,6 +597,32 @@ int vprintf(const char *fmt, va_list args) return i; } +#ifdef CONFIG_CONSOLE_RECORD +int console_record_init(void) +{ + int ret; + + ret = membuff_new(&gd->console_out, CONFIG_CONSOLE_RECORD_OUT_SIZE); + if (ret) + return ret; + ret = membuff_new(&gd->console_in, CONFIG_CONSOLE_RECORD_IN_SIZE); + + return ret; +} + +void console_record_reset(void) +{ + membuff_purge(&gd->console_out); + membuff_purge(&gd->console_in); +} + +void console_record_reset_enable(void) +{ + console_record_reset(); + gd->flags |= GD_FLG_RECORD; +} +#endif + /* test if ctrl-c was pressed */ static int ctrlc_disabled = 0; /* see disable_ctrl() */ static int ctrlc_was_pressed = 0; diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index d0383f3..1abdcaa 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -21,6 +21,7 @@ */ #ifndef __ASSEMBLY__ +#include #include typedef struct global_data { @@ -103,6 +104,10 @@ typedef struct global_data { #endif struct udevice *cur_serial_dev; /* current serial device */ struct arch_global_data arch; /* architecture-specific data */ +#ifdef CONFIG_CONSOLE_RECORD + struct membuff console_out; /* console output */ + struct membuff console_in; /* console input */ +#endif } gd_t; #endif @@ -121,5 +126,6 @@ typedef struct global_data { #define GD_FLG_FULL_MALLOC_INIT 0x00200 /* Full malloc() is ready */ #define GD_FLG_SPL_INIT 0x00400 /* spl_init() has been called */ #define GD_FLG_SKIP_RELOC 0x00800 /* Don't relocate */ +#define GD_FLG_RECORD 0x01000 /* Record console */ #endif /* __ASM_GENERIC_GBL_DATA_H */ diff --git a/include/console.h b/include/console.h index 097518d..3d37f6a 100644 --- a/include/console.h +++ b/include/console.h @@ -20,6 +20,28 @@ void clear_ctrlc(void); /* clear the Control-C condition */ int disable_ctrlc(int); /* 1 to disable, 0 to enable Control-C detect */ int confirm_yesno(void); /* 1 if input is "y", "Y", "yes" or "YES" */ +/** + * console_record_init() - set up the console recording buffers + * + * This should be called as soon as malloc() is available so that the maximum + * amount of console output can be recorded. + */ +int console_record_init(void); + +/** + * console_record_reset() - reset the console recording buffers + * + * Removes any data in the buffers + */ +void console_record_reset(void); + +/** + * console_record_reset_enable() - reset and enable the console buffers + * + * This should be called to enable the console buffer. + */ +void console_record_reset_enable(void); + /* * CONSOLE multiplexing. */