Hi Graeme, On Tue, Aug 30, 2011 at 5:49 AM, Graeme Russ <graeme.r...@gmail.com> wrote: > Allow redirection of console output prior to console initialisation to a > temporary buffer. > > To enable this functionality, the board configuration file 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)
Please can you add these to the README? Also I wonder if it is safe to have boards setting the buffer address. Should not arch/xxx/lib/board.c work this out based on CONFIG_SYS_INIT_SP_ADDR as it does all the other memory areas? > > The pre-console buffer will buffer the last CONFIG_PRE_CON_BUF_SZ bytes > Any earlier characters are silently dropped. > > Signed-off-by: Graeme Russ <graeme.r...@gmail.com> > --- > Changes Since V1 > - Implemented circular buffer > - Trivial code style corrections > > arch/arm/include/asm/global_data.h | 3 ++ > arch/avr32/include/asm/global_data.h | 3 ++ > arch/blackfin/include/asm/global_data.h | 3 ++ > arch/m68k/include/asm/global_data.h | 3 ++ > arch/microblaze/include/asm/global_data.h | 3 ++ > arch/mips/include/asm/global_data.h | 3 ++ > arch/nios2/include/asm/global_data.h | 3 ++ > arch/powerpc/include/asm/global_data.h | 3 ++ > arch/sh/include/asm/global_data.h | 3 ++ > arch/sparc/include/asm/global_data.h | 3 ++ > arch/x86/include/asm/global_data.h | 3 ++ > common/console.c | 49 +++++++++++++++++++++++++++- > 12 files changed, 80 insertions(+), 2 deletions(-) > > diff --git a/arch/arm/include/asm/global_data.h > b/arch/arm/include/asm/global_data.h > index 4fc51fd..b85b7fe 100644 > --- a/arch/arm/include/asm/global_data.h > +++ b/arch/arm/include/asm/global_data.h > @@ -38,6 +38,9 @@ typedef struct global_data { > unsigned long flags; > unsigned long baudrate; > unsigned long have_console; /* serial_init() was called */ > +#ifdef CONFIG_PRE_CONSOLE_BUFFER > + unsigned long precon_buf_idx; /* Pre-Console buffer index */ > +#endif > unsigned long env_addr; /* Address of Environment struct */ > unsigned long env_valid; /* Checksum of Environment valid? */ > unsigned long fb_base; /* base address of frame buffer */ > diff --git a/arch/avr32/include/asm/global_data.h > b/arch/avr32/include/asm/global_data.h > index 4ef8fc5..5c654bd 100644 > --- a/arch/avr32/include/asm/global_data.h > +++ b/arch/avr32/include/asm/global_data.h > @@ -38,6 +38,9 @@ typedef struct global_data { > unsigned long baudrate; > unsigned long stack_end; /* highest stack address */ > unsigned long have_console; /* serial_init() was called */ > +#ifdef CONFIG_PRE_CONSOLE_BUFFER > + unsigned long precon_buf_idx; /* Pre-Console buffer index */ > +#endif > unsigned long reloc_off; /* Relocation Offset */ > unsigned long env_addr; /* Address of env struct */ > unsigned long env_valid; /* Checksum of env valid? */ > diff --git a/arch/blackfin/include/asm/global_data.h > b/arch/blackfin/include/asm/global_data.h > index eba5e93..f7aa711 100644 > --- a/arch/blackfin/include/asm/global_data.h > +++ b/arch/blackfin/include/asm/global_data.h > @@ -45,6 +45,9 @@ typedef struct global_data { > unsigned long board_type; > unsigned long baudrate; > unsigned long have_console; /* serial_init() was called */ > +#ifdef CONFIG_PRE_CONSOLE_BUFFER > + unsigned long precon_buf_idx; /* Pre-Console buffer index */ > +#endif > phys_size_t ram_size; /* RAM size */ > unsigned long env_addr; /* Address of Environment struct */ > unsigned long env_valid; /* Checksum of Environment valid? */ > diff --git a/arch/m68k/include/asm/global_data.h > b/arch/m68k/include/asm/global_data.h > index fc486fd..0ba2b43 100644 > --- a/arch/m68k/include/asm/global_data.h > +++ b/arch/m68k/include/asm/global_data.h > @@ -57,6 +57,9 @@ typedef struct global_data { > unsigned long env_addr; /* Address of Environment struct > */ > unsigned long env_valid; /* Checksum of Environment valid? > */ > unsigned long have_console; /* serial_init() was called > */ > +#ifdef CONFIG_PRE_CONSOLE_BUFFER > + unsigned long precon_buf_idx; /* Pre-Console buffer index */ > +#endif > #if defined(CONFIG_LCD) || defined(CONFIG_VIDEO) > unsigned long fb_base; /* Base addr of framebuffer memory */ > #endif > diff --git a/arch/microblaze/include/asm/global_data.h > b/arch/microblaze/include/asm/global_data.h > index 557ad27..6e8537c 100644 > --- a/arch/microblaze/include/asm/global_data.h > +++ b/arch/microblaze/include/asm/global_data.h > @@ -39,6 +39,9 @@ typedef struct global_data { > unsigned long flags; > unsigned long baudrate; > unsigned long have_console; /* serial_init() was called */ > +#ifdef CONFIG_PRE_CONSOLE_BUFFER > + unsigned long precon_buf_idx; /* Pre-Console buffer index */ > +#endif > unsigned long env_addr; /* Address of Environment struct */ > unsigned long env_valid; /* Checksum of Environment valid? */ > unsigned long fb_base; /* base address of frame buffer */ > diff --git a/arch/mips/include/asm/global_data.h > b/arch/mips/include/asm/global_data.h > index 271a290..b193517 100644 > --- a/arch/mips/include/asm/global_data.h > +++ b/arch/mips/include/asm/global_data.h > @@ -41,6 +41,9 @@ typedef struct global_data { > unsigned long flags; > unsigned long baudrate; > unsigned long have_console; /* serial_init() was called */ > +#ifdef CONFIG_PRE_CONSOLE_BUFFER > + unsigned long precon_buf_idx; /* Pre-Console buffer index */ > +#endif > phys_size_t ram_size; /* RAM size */ > unsigned long reloc_off; /* Relocation Offset */ > unsigned long env_addr; /* Address of Environment struct */ > diff --git a/arch/nios2/include/asm/global_data.h > b/arch/nios2/include/asm/global_data.h > index 2c4a719..d9f0664 100644 > --- a/arch/nios2/include/asm/global_data.h > +++ b/arch/nios2/include/asm/global_data.h > @@ -29,6 +29,9 @@ typedef struct global_data { > unsigned long baudrate; > unsigned long cpu_clk; /* CPU clock in Hz! */ > unsigned long have_console; /* serial_init() was called */ > +#ifdef CONFIG_PRE_CONSOLE_BUFFER > + unsigned long precon_buf_idx; /* Pre-Console buffer index */ > +#endif > phys_size_t ram_size; /* RAM size */ > unsigned long env_addr; /* Address of Environment struct */ > unsigned long env_valid; /* Checksum of Environment valid */ > diff --git a/arch/powerpc/include/asm/global_data.h > b/arch/powerpc/include/asm/global_data.h > index a33ca2f..7fcaf38 100644 > --- a/arch/powerpc/include/asm/global_data.h > +++ b/arch/powerpc/include/asm/global_data.h > @@ -138,6 +138,9 @@ typedef struct global_data { > unsigned long env_addr; /* Address of Environment struct > */ > unsigned long env_valid; /* Checksum of Environment valid? > */ > unsigned long have_console; /* serial_init() was called > */ > +#ifdef CONFIG_PRE_CONSOLE_BUFFER > + unsigned long precon_buf_idx; /* Pre-Console buffer index */ > +#endif > #if defined(CONFIG_SYS_ALLOC_DPRAM) || defined(CONFIG_CPM2) > unsigned int dp_alloc_base; > unsigned int dp_alloc_top; > diff --git a/arch/sh/include/asm/global_data.h > b/arch/sh/include/asm/global_data.h > index 0c09ba9..1b782fc 100644 > --- a/arch/sh/include/asm/global_data.h > +++ b/arch/sh/include/asm/global_data.h > @@ -34,6 +34,9 @@ typedef struct global_data > unsigned long baudrate; > unsigned long cpu_clk; /* CPU clock in Hz! */ > unsigned long have_console; /* serial_init() was called */ > +#ifdef CONFIG_PRE_CONSOLE_BUFFER > + unsigned long precon_buf_idx; /* Pre-Console buffer index */ > +#endif > phys_size_t ram_size; /* RAM size */ > unsigned long env_addr; /* Address of Environment struct */ > unsigned long env_valid; /* Checksum of Environment valid */ > diff --git a/arch/sparc/include/asm/global_data.h > b/arch/sparc/include/asm/global_data.h > index 9b14674..a1e4b44 100644 > --- a/arch/sparc/include/asm/global_data.h > +++ b/arch/sparc/include/asm/global_data.h > @@ -53,6 +53,9 @@ typedef struct global_data { > unsigned long env_valid; /* Checksum of Environment valid? > */ > unsigned long have_console; /* serial_init() was called */ > > +#ifdef CONFIG_PRE_CONSOLE_BUFFER > + unsigned long precon_buf_idx; /* Pre-Console buffer index */ > +#endif > #if defined(CONFIG_LCD) || defined(CONFIG_VIDEO) > unsigned long fb_base; /* Base address of framebuffer memory */ > #endif > diff --git a/arch/x86/include/asm/global_data.h > b/arch/x86/include/asm/global_data.h > index f977dbe..6cf7955 100644 > --- a/arch/x86/include/asm/global_data.h > +++ b/arch/x86/include/asm/global_data.h > @@ -40,6 +40,9 @@ typedef struct global_data { > unsigned long flags; > unsigned long baudrate; > unsigned long have_console; /* serial_init() was called */ > +#ifdef CONFIG_PRE_CONSOLE_BUFFER > + unsigned long precon_buf_idx; /* Pre-Console buffer index */ > +#endif > unsigned long reloc_off; /* Relocation Offset */ > unsigned long load_off; /* Load Offset */ > unsigned long env_addr; /* Address of Environment struct */ > diff --git a/common/console.c b/common/console.c > index b23d933..ae87148 100644 > --- a/common/console.c > +++ b/common/console.c > @@ -329,6 +329,35 @@ int tstc(void) > return serial_tstc(); > } > > +#ifdef CONFIG_PRE_CONSOLE_BUFFER > +#define CIRC_BUF_IDX(idx) ((idx) % CONFIG_PRE_CON_BUF_SZ) The division here sticks in the craw, but unless we go with CONFIG_PRE_CON_BUF_SZ_LOG2 then I don't see an easy way around it, and since this is serial output we can't honestly claim to worry much about performance. > + > +void pre_console_putc(const char c) > +{ > + char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR; > + > + buffer[CIRC_BUF_IDX(gd->precon_buf_idx++)] = c; > +} > + > +void pre_console_puts(const char *s) > +{ > + while (*s) > + pre_console_putc(*s++); > +} > + > +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; Gosh this is clever - perhaps a little comment? > + > + while (i < gd->precon_buf_idx) > + putc(buffer[CIRC_BUF_IDX(i++)]); > +} > +#endif > + > void putc(const char c) > { > #ifdef CONFIG_SILENT_CONSOLE > @@ -341,8 +370,12 @@ void putc(const char c) > return; > #endif > > - if (!gd->have_console) > + if (!gd->have_console) { > +#ifdef CONFIG_PRE_CONSOLE_BUFFER > + pre_console_putc(c); > +#endif > return; > + } > > if (gd->flags & GD_FLG_DEVINIT) { > /* Send to the standard output */ > @@ -365,8 +398,12 @@ void puts(const char *s) > return; > #endif > > - if (!gd->have_console) > + if (!gd->have_console) { > +#ifdef CONFIG_PRE_CONSOLE_BUFFER > + pre_console_puts(s); > +#endif > return; > + } > > if (gd->flags & GD_FLG_DEVINIT) { > /* Send to the standard output */ > @@ -383,8 +420,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 +443,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 +588,10 @@ int console_init_f(void) > gd->flags |= GD_FLG_SILENT; > #endif > > +#ifdef CONFIG_PRE_CONSOLE_BUFFER > + print_pre_console_buffer(); > +#endif > + > return 0; > } > > -- > 1.7.5.2.317.g391b14 > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot