summaryrefslogtreecommitdiff
path: root/common/console.c
diff options
context:
space:
mode:
authorGraeme Russ <graeme.russ@gmail.com>2011-09-01 00:48:27 +0000
committerWolfgang Denk <wd@denx.de>2011-10-05 22:03:09 +0200
commit9558b48af006a34d3ab7f0bd13a76b97acd45e47 (patch)
treed2fbeae7e5f2ef15cc7194fd21d504229259f2de /common/console.c
parentcc9abfe4ceb360e9adedc4ed44eae0fcc3fd184c (diff)
console: Implement pre-console buffer
Allow redirection of console output prior to console initialisation to a temporary buffer. To enable this functionality, the board (or arch) must define: - CONFIG_PRE_CONSOLE_BUFFER - Enable pre-console buffer - CONFIG_PRE_CON_BUF_ADDR - Base address of pre-console buffer - CONFIG_PRE_CON_BUF_SZ - Size of pre-console buffer (in bytes) The pre-console buffer will buffer the last CONFIG_PRE_CON_BUF_SZ bytes Any earlier characters are silently dropped.
Diffstat (limited to 'common/console.c')
-rw-r--r--common/console.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/common/console.c b/common/console.c
index b23d933d2c3..f17875ead00 100644
--- a/common/console.c
+++ b/common/console.c
@@ -329,6 +329,39 @@ int tstc(void)
return serial_tstc();
}
+#ifdef CONFIG_PRE_CONSOLE_BUFFER
+#define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_PRE_CON_BUF_SZ)
+
+static void pre_console_putc(const char c)
+{
+ char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR;
+
+ buffer[CIRC_BUF_IDX(gd->precon_buf_idx++)] = c;
+}
+
+static void pre_console_puts(const char *s)
+{
+ while (*s)
+ pre_console_putc(*s++);
+}
+
+static void print_pre_console_buffer(void)
+{
+ unsigned long i = 0;
+ char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR;
+
+ if (gd->precon_buf_idx > CONFIG_PRE_CON_BUF_SZ)
+ i = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ;
+
+ while (i < gd->precon_buf_idx)
+ putc(buffer[CIRC_BUF_IDX(i++)]);
+}
+#else
+static inline void pre_console_putc(const char c) {}
+static inline void pre_console_puts(const char *s) {}
+static inline void print_pre_console_buffer(void) {}
+#endif
+
void putc(const char c)
{
#ifdef CONFIG_SILENT_CONSOLE
@@ -342,7 +375,7 @@ void putc(const char c)
#endif
if (!gd->have_console)
- return;
+ return pre_console_putc(c);
if (gd->flags & GD_FLG_DEVINIT) {
/* Send to the standard output */
@@ -366,7 +399,7 @@ void puts(const char *s)
#endif
if (!gd->have_console)
- return;
+ return pre_console_puts(s);
if (gd->flags & GD_FLG_DEVINIT) {
/* Send to the standard output */
@@ -383,8 +416,10 @@ int printf(const char *fmt, ...)
uint i;
char printbuffer[CONFIG_SYS_PBSIZE];
+#ifndef CONFIG_PRE_CONSOLE_BUFFER
if (!gd->have_console)
return 0;
+#endif
va_start(args, fmt);
@@ -404,8 +439,10 @@ int vprintf(const char *fmt, va_list args)
uint i;
char printbuffer[CONFIG_SYS_PBSIZE];
+#ifndef CONFIG_PRE_CONSOLE_BUFFER
if (!gd->have_console)
return 0;
+#endif
/* For this to work, printbuffer must be larger than
* anything we ever want to print.
@@ -547,6 +584,8 @@ int console_init_f(void)
gd->flags |= GD_FLG_SILENT;
#endif
+ print_pre_console_buffer();
+
return 0;
}