summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/Kconfig28
-rw-r--r--common/board_f.c10
-rw-r--r--common/board_r.c10
-rw-r--r--common/console.c50
-rw-r--r--include/asm-generic/global_data.h6
-rw-r--r--include/console.h22
6 files changed, 125 insertions, 1 deletions
diff --git a/common/Kconfig b/common/Kconfig
index 620d41f9ea..ccf5475bac 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 09baa5c550..b035c90ff3 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 85aef95a89..f7118e8fc4 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 10972b04a6..b3f126cceb 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 d0383f3d76..1abdcaa6b7 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -21,6 +21,7 @@
*/
#ifndef __ASSEMBLY__
+#include <membuff.h>
#include <linux/list.h>
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 097518d150..3d37f6a53b 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.
*/
OpenPOWER on IntegriCloud