From mboxrd@z Thu Jan 1 00:00:00 1970 From: Vadim Bendebury Date: Mon, 26 Sep 2011 15:50:52 -0700 Subject: [U-Boot] [PATCH V4] console: Implement pre-console buffer In-Reply-To: <1314795505-14321-1-git-send-email-graeme.russ@gmail.com> References: <1314794155-14186-1-git-send-email-graeme.russ@gmail.com> <1314795505-14321-1-git-send-email-graeme.russ@gmail.com> Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On Wed, Aug 31, 2011 at 5:58 AM, Graeme Russ 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) > > 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 > --- > Changes since V3 > ?- Fixed ?blank subject caused by gap between the Cc: list and Date: > > Changes since V2 > ?- Cast buffer size to unsigned long to help compilers produce tighter > ? code > ?- Use inline stub functions to reduce #ifdef clutter > ?- Add documentation to README > > Changes Since V1 > ?- Implemented circular buffer > ?- Trivial code styl corrections > > ?README ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? 14 +++++++++ > ?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 ++ I know I am late to the party here, but all of a sudden I need to implement something similar, albeit slightly different: - the memory could be allocated by the "cold bootprom" which starts u-boot; - all console output needs to be saved, not just until the moment when the console hardware is initialized. I could work on top of this patch and send another one once this one has been accepted. May I suggest an improvement though: is it really necessary to store the index in the global data structure. This requires editing all these .h files adding another unsighty conditionally compiled field. Why not to store the index as the first word in the buffer allocated for this temp storage? cheers, /vb > ?common/console.c ? ? ? ? ? ? ? ? ? ? ? ? ?| ? 43 +++++++++++++++++++++++++++- > ?13 files changed, 88 insertions(+), 2 deletions(-) > > diff --git a/README b/README > index 0886987..170e67b 100644 > --- a/README > +++ b/README > @@ -619,6 +619,20 @@ The following options need to be configured: > ? ? ? ? ? ? ? ?must be defined, to setup the maximum idle timeout for > ? ? ? ? ? ? ? ?the SMC. > > +- Pre-Console Buffer: > + ? ? ? ? ? ? ? ?Prior to the console being initialised (i.e. serial UART > + ? ? ? ? ? ? ? ?initialised etc) all console output is silently discarded. > + ? ? ? ? ? ? ? ?Defining CONFIG_PRE_CONSOLE_BUFFER will cause U-Boot to > + ? ? ? ? ? ? ? ?buffer any console messages prior to the console being > + ? ? ? ? ? ? ? ?initialised to a buffer of size CONFIG_PRE_CON_BUF_SZ > + ? ? ? ? ? ? ? ?bytes located at CONFIG_PRE_CON_BUF_ADDR. The buffer is > + ? ? ? ? ? ? ? ?a cicular buffer, so if more than CONFIG_PRE_CON_BUF_SZ > + ? ? ? ? ? ? ? ?bytes are output before the console is ?initialised, the > + ? ? ? ? ? ? ? ?earlier bytes are discarded. > + > + ? ? ? ? ? ? ? ?'Sane' compilers will generate smaller code if > + ? ? ? ? ? ? ? ?CONFIG_PRE_CON_BUF_SZ is a power of 2 > + > ?- Boot Delay: ?CONFIG_BOOTDELAY - in seconds > ? ? ? ? ? ? ? ?Delay before automatically booting the default image; > ? ? ? ? ? ? ? ?set to -1 to disable autoboot. > 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..570196e 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) > + > +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; > + > + ? ? ? 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; > ?} > > -- > 1.7.5.2.317.g391b14 > > _______________________________________________ > U-Boot mailing list > U-Boot at lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot >