CBMEM console: Fix and enhance pre-RAM support

Use the value of CONSOLE_PRERAM_BUFFER_SIZE to determine if we can
do CBMEM console in bootblock and romstage. Kconfig forces it to zero
if _BASE is unset or we cannot do CAR migration on x86.

Add CBMEM console to bootblock, except for x86. Only one of bootblock
and romstage clears the pre-RAM buffer.

To start with empty console log on S3 wakeup, ramstage now clears
previous contents of CBMEM buffer if there was no pre-RAM buffer.

Unify Kconfig variable naming.

TODO: ARM configurations do not define PRERAM_BUFFER_BASE values.

Change-Id: I70d82da629529dbfd7bc9491223abd703cbc0115
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: http://review.coreboot.org/7862
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@google.com>
This commit is contained in:
Kyösti Mälkki
2014-12-21 08:55:47 +02:00
parent 4d10750d13
commit 8659e4072e
10 changed files with 66 additions and 48 deletions

View File

@@ -24,10 +24,6 @@ config ARM_BOOTBLOCK_CUSTOM
bool bool
default n default n
config CBMEM_CONSOLE_PRERAM_BASE
hex
depends on CONSOLE_CBMEM
config CPU_HAS_BOOTBLOCK_INIT config CPU_HAS_BOOTBLOCK_INIT
bool bool
default n default n

View File

@@ -49,8 +49,8 @@ SECTIONS
*(.sbss.*); *(.sbss.*);
} : to_load = 0xff } : to_load = 0xff
preram_cbmem_console = CONFIG_CBMEM_CONSOLE_PRERAM_BASE; preram_cbmem_console = CONFIG_CONSOLE_PRERAM_BUFFER_BASE;
verstage_preram_cbmem_console = CONFIG_CBMEM_CONSOLE_PRERAM_BASE; verstage_preram_cbmem_console = CONFIG_CONSOLE_PRERAM_BUFFER_BASE;
/DISCARD/ : { /DISCARD/ : {
*(.comment) *(.comment)

View File

@@ -69,7 +69,7 @@ SECTIONS
_end = .; _end = .;
preram_cbmem_console = CONFIG_CBMEM_CONSOLE_PRERAM_BASE; preram_cbmem_console = CONFIG_CONSOLE_PRERAM_BUFFER_BASE;
/* Discard the sections we don't need/want */ /* Discard the sections we don't need/want */
/DISCARD/ : { /DISCARD/ : {

View File

@@ -49,6 +49,8 @@ SECTIONS
*(.sbss.*); *(.sbss.*);
} : to_load = 0xff } : to_load = 0xff
preram_cbmem_console = CONFIG_CONSOLE_PRERAM_BUFFER_BASE;
/DISCARD/ : { /DISCARD/ : {
*(.comment) *(.comment)
*(.note) *(.note)

View File

@@ -76,7 +76,7 @@ SECTIONS
_end = .; _end = .;
preram_cbmem_console = CONFIG_CBMEM_CONSOLE_PRERAM_BASE; preram_cbmem_console = CONFIG_CONSOLE_PRERAM_BUFFER_BASE;
/* Discard the sections we don't need/want */ /* Discard the sections we don't need/want */
/DISCARD/ : { /DISCARD/ : {

View File

@@ -76,7 +76,7 @@ SECTIONS
_end = .; _end = .;
/*preram_cbmem_console = CONFIG_CBMEM_CONSOLE_PRERAM_BASE;*/ /*preram_cbmem_console = CONFIG_CONSOLE_PRERAM_BUFFER_BASE;*/
/* Discard the sections we don't need/want */ /* Discard the sections we don't need/want */
/DISCARD/ : { /DISCARD/ : {

View File

@@ -175,8 +175,9 @@ config CONSOLE_CBMEM
Enable this to save the console output in a CBMEM buffer. This would Enable this to save the console output in a CBMEM buffer. This would
allow to see coreboot console output from Linux space. allow to see coreboot console output from Linux space.
if CONSOLE_CBMEM
config CONSOLE_CBMEM_BUFFER_SIZE config CONSOLE_CBMEM_BUFFER_SIZE
depends on CONSOLE_CBMEM
hex "Room allocated for console output in CBMEM" hex "Room allocated for console output in CBMEM"
default 0x20000 default 0x20000
help help
@@ -184,9 +185,14 @@ config CONSOLE_CBMEM_BUFFER_SIZE
value (128K or 0x20000 bytes) is large enough to accommodate value (128K or 0x20000 bytes) is large enough to accommodate
even the BIOS_SPEW level. even the BIOS_SPEW level.
config CONSOLE_PRERAM_BUFFER_BASE
hex
default 0xabadbeef if !CACHE_AS_RAM || BROKEN_CAR_MIGRATE
default 0x0
config CONSOLE_PRERAM_BUFFER_SIZE config CONSOLE_PRERAM_BUFFER_SIZE
depends on CONSOLE_CBMEM hex
hex "Room allocated for console output before RAM is initialized" default 0x0 if CONSOLE_PRERAM_BUFFER_BASE = 0xabadbeef
default 0xc00 default 0xc00
help help
Console is used before RAM is initialized. This is the room reserved Console is used before RAM is initialized. This is the room reserved
@@ -194,6 +200,8 @@ config CONSOLE_PRERAM_BUFFER_SIZE
can be saved in a CBMEM buffer. 3K bytes should be enough even for can be saved in a CBMEM buffer. 3K bytes should be enough even for
the BIOS_SPEW level. the BIOS_SPEW level.
endif
config CONSOLE_QEMU_DEBUGCON config CONSOLE_QEMU_DEBUGCON
bool "QEMU debug console output" bool "QEMU debug console output"
depends on BOARD_EMULATION_QEMU_X86 depends on BOARD_EMULATION_QEMU_X86

View File

@@ -32,7 +32,8 @@ static inline void cbmemc_reinit(void) {}
#endif #endif
#define __CBMEM_CONSOLE_ENABLE__ CONFIG_CONSOLE_CBMEM && \ #define __CBMEM_CONSOLE_ENABLE__ CONFIG_CONSOLE_CBMEM && \
((ENV_ROMSTAGE && !CONFIG_BROKEN_CAR_MIGRATE) || ENV_RAMSTAGE) (ENV_RAMSTAGE || (CONFIG_CONSOLE_PRERAM_BUFFER_SIZE && \
((ENV_BOOTBLOCK && CONFIG_BOOTBLOCK_CONSOLE) || ENV_ROMSTAGE)))
#if __CBMEM_CONSOLE_ENABLE__ #if __CBMEM_CONSOLE_ENABLE__
static inline void __cbmemc_init(void) { cbmemc_init(); } static inline void __cbmemc_init(void) { cbmemc_init(); }

View File

@@ -21,6 +21,7 @@ subdirs-y += loaders
bootblock-y += cbfs.c cbfs_core.c bootblock-y += cbfs.c cbfs_core.c
bootblock-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c bootblock-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
bootblock-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
bootblock-y += memchr.c bootblock-y += memchr.c
bootblock-y += memcmp.c bootblock-y += memcmp.c

View File

@@ -37,6 +37,9 @@ struct cbmem_console {
static struct cbmem_console *cbmem_console_p CAR_GLOBAL; static struct cbmem_console *cbmem_console_p CAR_GLOBAL;
static void copy_console_buffer(struct cbmem_console *old_cons_p,
struct cbmem_console *new_cons_p);
#ifdef __PRE_RAM__ #ifdef __PRE_RAM__
/* /*
* While running from ROM, before DRAM is initialized, some area in cache as * While running from ROM, before DRAM is initialized, some area in cache as
@@ -63,6 +66,10 @@ extern struct cbmem_console preram_cbmem_console;
static u8 static_console[STATIC_CONSOLE_SIZE]; static u8 static_console[STATIC_CONSOLE_SIZE];
#endif #endif
/* flags for init */
#define CBMEMC_RESET (1<<0)
#define CBMEMC_APPEND (1<<1)
static inline struct cbmem_console *current_console(void) static inline struct cbmem_console *current_console(void)
{ {
return car_sync_var(cbmem_console_p); return car_sync_var(cbmem_console_p);
@@ -73,27 +80,46 @@ static inline void current_console_set(struct cbmem_console *new_console_p)
car_set_var(cbmem_console_p, new_console_p); car_set_var(cbmem_console_p, new_console_p);
} }
static inline void init_console_ptr(void *storage, u32 total_space) static inline void init_console_ptr(void *storage, u32 total_space, int flags)
{ {
struct cbmem_console *cbm_cons_p = storage; struct cbmem_console *cbm_cons_p = storage;
/* Initialize the cache-as-ram pointer and underlying structure. */ if (!cbm_cons_p) {
car_set_var(cbmem_console_p, cbm_cons_p); current_console_set(NULL);
cbm_cons_p->buffer_size = total_space - sizeof(struct cbmem_console); return;
cbm_cons_p->buffer_cursor = 0; }
if (flags & CBMEMC_RESET) {
cbm_cons_p->buffer_size = total_space - sizeof(struct cbmem_console);
cbm_cons_p->buffer_cursor = 0;
}
if (flags & CBMEMC_APPEND) {
struct cbmem_console *tmp_cons_p = current_console();
if (tmp_cons_p)
copy_console_buffer(tmp_cons_p, cbm_cons_p);
}
current_console_set(cbm_cons_p);
} }
void cbmemc_init(void) void cbmemc_init(void)
{ {
#ifdef __PRE_RAM__ #ifdef __PRE_RAM__
int flags = CBMEMC_RESET;
/* Do not clear output from bootblock. */
if (ENV_ROMSTAGE && !IS_ENABLED(CONFIG_CACHE_AS_RAM))
if (IS_ENABLED(CONFIG_BOOTBLOCK_CONSOLE))
flags = 0;
init_console_ptr(&preram_cbmem_console, init_console_ptr(&preram_cbmem_console,
CONFIG_CONSOLE_PRERAM_BUFFER_SIZE); CONFIG_CONSOLE_PRERAM_BUFFER_SIZE, flags);
#else #else
/* /*
* Initializing before CBMEM is available, use static buffer to store * Initializing before CBMEM is available, use static buffer to store
* the log. * the log.
*/ */
init_console_ptr(static_console, sizeof(static_console)); init_console_ptr(static_console, sizeof(static_console), CBMEMC_RESET);
#endif #endif
} }
@@ -119,13 +145,11 @@ void cbmemc_tx_byte(unsigned char data)
* If there is overflow - add to the destination area a string, reporting the * If there is overflow - add to the destination area a string, reporting the
* overflow and the number of dropped characters. * overflow and the number of dropped characters.
*/ */
static void copy_console_buffer(struct cbmem_console *new_cons_p) static void copy_console_buffer(struct cbmem_console *old_cons_p,
struct cbmem_console *new_cons_p)
{ {
u32 copy_size, dropped_chars; u32 copy_size, dropped_chars;
u32 cursor = new_cons_p->buffer_cursor; u32 cursor = new_cons_p->buffer_cursor;
struct cbmem_console *old_cons_p;
old_cons_p = current_console();
if (old_cons_p->buffer_cursor < old_cons_p->buffer_size) if (old_cons_p->buffer_cursor < old_cons_p->buffer_size)
copy_size = old_cons_p->buffer_cursor; copy_size = old_cons_p->buffer_cursor;
@@ -187,35 +211,21 @@ static void copy_console_buffer(struct cbmem_console *new_cons_p)
void cbmemc_reinit(void) void cbmemc_reinit(void)
{ {
struct cbmem_console *cbm_cons_p = NULL; struct cbmem_console *cbm_cons_p = NULL;
int flags = CBMEMC_APPEND;
#ifdef __PRE_RAM__ if (ENV_ROMSTAGE && (CONFIG_CONSOLE_PRERAM_BUFFER_SIZE == 0))
if (IS_ENABLED(CONFIG_BROKEN_CAR_MIGRATE))
return; return;
#endif
#ifndef __PRE_RAM__ /* If CBMEM entry already existed, old contents is not altered. */
cbm_cons_p = cbmem_find(CBMEM_ID_CONSOLE); cbm_cons_p = cbmem_add(CBMEM_ID_CONSOLE,
#endif CONFIG_CONSOLE_CBMEM_BUFFER_SIZE);
if (!cbm_cons_p) { /* Clear old contents of CBMEM buffer. */
cbm_cons_p = cbmem_add(CBMEM_ID_CONSOLE, if (ENV_ROMSTAGE || (CONFIG_CONSOLE_PRERAM_BUFFER_SIZE == 0))
CONFIG_CONSOLE_CBMEM_BUFFER_SIZE); flags |= CBMEMC_RESET;
if (!cbm_cons_p) { init_console_ptr(cbm_cons_p,
current_console_set(NULL); CONFIG_CONSOLE_CBMEM_BUFFER_SIZE, flags);
return;
}
cbm_cons_p->buffer_size = CONFIG_CONSOLE_CBMEM_BUFFER_SIZE -
sizeof(struct cbmem_console);
cbm_cons_p->buffer_cursor = 0;
}
copy_console_buffer(cbm_cons_p);
current_console_set(cbm_cons_p);
} }
/* Call cbmemc_reinit() at CAR migration time. */ /* Call cbmemc_reinit() at CAR migration time. */
CAR_MIGRATE(cbmemc_reinit) CAR_MIGRATE(cbmemc_reinit)