[U-Boot] [PATCH V2] console: Implement pre-console buffer
Simon Glass
sjg at chromium.org
Tue Aug 30 21:45:25 CEST 2011
Hi Graeme,
On Tue, Aug 30, 2011 at 5:49 AM, Graeme Russ <graeme.russ at 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.russ at 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 at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
More information about the U-Boot
mailing list