diff --git a/README b/README index 91b6695cf90c25269a89bb1fefbea7e392ef0683..dfc7ada61e1e9cc418f3fd8f8648b0382ac000fa 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 circular 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 4fc51fdc75f2ccaa09a138ae6af7984d18275c85..b85b7fe808f53a0590fb8160e61ff0a91386c6b9 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 4ef8fc570f34524691e59a6f03da60e2dac1fe92..5c654bd5e0325ec845cf7e882422e4dc67a8a765 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 eba5e93e212c0199be859697d3dcc5057cf9b752..f7aa71113de0b2765660a766ab33599d33d4649f 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 fc486fda58ddf52f00f857380f4f8f498b7574b8..0ba2b43305d0a940538387e9c8208f2b1f61ab79 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 557ad27e9d4aec121ea646f8e9baf3875752e102..6e8537c8ed13b1ead5a58ba0c2dd37c9be68fb04 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 271a290a51c392926bd41f198997c77c999578d0..b193517889e001fbb91e467ce6aa44b0bdda42dc 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 2c4a719409d41f99206c31aae815239499708503..d9f06645a3ae2aa70d59cda9d894d3319badf0ad 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 a33ca2f7b74eac9eb9c38bfba6f1b92aacf91b84..7fcaf384ed766668fe20152a2256b2c25108d36b 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 0c09ba9bad7db563d684d4fda45495eb297f49f4..1b782fc77181cd3780f41955440b1ff39a7745a7 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 9b146748d96aaee8e871fc3d10320a254bbaf963..a1e4b44aac8973d94e256f1b9aea1c01cc231b8d 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 f8a16d646fd41db195838a0c667d3de0c0679a96..f177a4fa3b6859ee44c1871c3dae2feb3ca67c55 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 b23d933d2c35742521c34aad25852b2f553ac4c6..f17875ead007703a76aec99a09c0f3705e759773 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; }