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:
		| @@ -24,10 +24,6 @@ config ARM_BOOTBLOCK_CUSTOM | ||||
| 	bool | ||||
| 	default n | ||||
|  | ||||
| config CBMEM_CONSOLE_PRERAM_BASE | ||||
| 	hex | ||||
| 	depends on CONSOLE_CBMEM | ||||
|  | ||||
| config CPU_HAS_BOOTBLOCK_INIT | ||||
| 	bool | ||||
| 	default n | ||||
|   | ||||
| @@ -49,8 +49,8 @@ SECTIONS | ||||
| 		*(.sbss.*); | ||||
| 	} : to_load = 0xff | ||||
|  | ||||
| 	preram_cbmem_console = CONFIG_CBMEM_CONSOLE_PRERAM_BASE; | ||||
| 	verstage_preram_cbmem_console = CONFIG_CBMEM_CONSOLE_PRERAM_BASE; | ||||
| 	preram_cbmem_console = CONFIG_CONSOLE_PRERAM_BUFFER_BASE; | ||||
| 	verstage_preram_cbmem_console = CONFIG_CONSOLE_PRERAM_BUFFER_BASE; | ||||
|  | ||||
| 	/DISCARD/ : { | ||||
| 		*(.comment) | ||||
|   | ||||
| @@ -69,7 +69,7 @@ SECTIONS | ||||
|  | ||||
| 	_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/ : { | ||||
|   | ||||
| @@ -49,6 +49,8 @@ SECTIONS | ||||
| 		*(.sbss.*); | ||||
| 	} : to_load = 0xff | ||||
|  | ||||
| 	preram_cbmem_console = CONFIG_CONSOLE_PRERAM_BUFFER_BASE; | ||||
|  | ||||
| 	/DISCARD/ : { | ||||
| 		*(.comment) | ||||
| 		*(.note) | ||||
|   | ||||
| @@ -76,7 +76,7 @@ SECTIONS | ||||
|  | ||||
| 	_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/ : { | ||||
|   | ||||
| @@ -76,7 +76,7 @@ SECTIONS | ||||
|  | ||||
| 	_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/ : { | ||||
|   | ||||
| @@ -175,8 +175,9 @@ config CONSOLE_CBMEM | ||||
| 	  Enable this to save the console output in a CBMEM buffer. This would | ||||
| 	  allow to see coreboot console output from Linux space. | ||||
|  | ||||
| if CONSOLE_CBMEM | ||||
|  | ||||
| config CONSOLE_CBMEM_BUFFER_SIZE | ||||
| 	depends on CONSOLE_CBMEM | ||||
| 	hex "Room allocated for console output in CBMEM" | ||||
| 	default 0x20000 | ||||
| 	help | ||||
| @@ -184,9 +185,14 @@ config CONSOLE_CBMEM_BUFFER_SIZE | ||||
| 	  value (128K or 0x20000 bytes) is large enough to accommodate | ||||
| 	  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 | ||||
| 	depends on CONSOLE_CBMEM | ||||
| 	hex "Room allocated for console output before RAM is initialized" | ||||
| 	hex | ||||
| 	default 0x0 if CONSOLE_PRERAM_BUFFER_BASE = 0xabadbeef | ||||
| 	default 0xc00 | ||||
| 	help | ||||
| 	  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 | ||||
| 	  the BIOS_SPEW level. | ||||
|  | ||||
| endif | ||||
|  | ||||
| config CONSOLE_QEMU_DEBUGCON | ||||
| 	bool "QEMU debug console output" | ||||
| 	depends on BOARD_EMULATION_QEMU_X86 | ||||
|   | ||||
| @@ -32,7 +32,8 @@ static inline void cbmemc_reinit(void) {} | ||||
| #endif | ||||
|  | ||||
| #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__ | ||||
| static inline void __cbmemc_init(void)	{ cbmemc_init(); } | ||||
|   | ||||
| @@ -21,6 +21,7 @@ subdirs-y += loaders | ||||
| bootblock-y += cbfs.c cbfs_core.c | ||||
| bootblock-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c | ||||
|  | ||||
| bootblock-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c | ||||
| bootblock-y += memchr.c | ||||
| bootblock-y += memcmp.c | ||||
|  | ||||
|   | ||||
| @@ -37,6 +37,9 @@ struct cbmem_console { | ||||
|  | ||||
| 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__ | ||||
| /* | ||||
|  * 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]; | ||||
| #endif | ||||
|  | ||||
| /* flags for init */ | ||||
| #define CBMEMC_RESET	(1<<0) | ||||
| #define CBMEMC_APPEND	(1<<1) | ||||
|  | ||||
| static inline struct cbmem_console *current_console(void) | ||||
| { | ||||
| 	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); | ||||
| } | ||||
|  | ||||
| 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; | ||||
|  | ||||
| 	/* Initialize the cache-as-ram pointer and underlying structure. */ | ||||
| 	car_set_var(cbmem_console_p, cbm_cons_p); | ||||
| 	if (!cbm_cons_p) { | ||||
| 		current_console_set(NULL); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	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) | ||||
| { | ||||
| #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, | ||||
| 			 CONFIG_CONSOLE_PRERAM_BUFFER_SIZE); | ||||
| 			 CONFIG_CONSOLE_PRERAM_BUFFER_SIZE, flags); | ||||
| #else | ||||
| 	/* | ||||
| 	 * Initializing before CBMEM is available, use static buffer to store | ||||
| 	 * the log. | ||||
| 	 */ | ||||
| 	init_console_ptr(static_console, sizeof(static_console)); | ||||
| 	init_console_ptr(static_console, sizeof(static_console), CBMEMC_RESET); | ||||
| #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 | ||||
|  * 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 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) | ||||
| 		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) | ||||
| { | ||||
| 	struct cbmem_console *cbm_cons_p = NULL; | ||||
| 	int flags = CBMEMC_APPEND; | ||||
|  | ||||
| #ifdef __PRE_RAM__ | ||||
| 	if (IS_ENABLED(CONFIG_BROKEN_CAR_MIGRATE)) | ||||
| 	if (ENV_ROMSTAGE && (CONFIG_CONSOLE_PRERAM_BUFFER_SIZE == 0)) | ||||
| 		return; | ||||
| #endif | ||||
|  | ||||
| #ifndef __PRE_RAM__ | ||||
| 	cbm_cons_p = cbmem_find(CBMEM_ID_CONSOLE); | ||||
| #endif | ||||
|  | ||||
| 	if (!cbm_cons_p) { | ||||
| 	/* If CBMEM entry already existed, old contents is not altered. */ | ||||
| 	cbm_cons_p = cbmem_add(CBMEM_ID_CONSOLE, | ||||
| 		CONFIG_CONSOLE_CBMEM_BUFFER_SIZE); | ||||
|  | ||||
| 		if (!cbm_cons_p) { | ||||
| 			current_console_set(NULL); | ||||
| 			return; | ||||
| 		} | ||||
| 	/* Clear old contents of CBMEM buffer. */ | ||||
| 	if (ENV_ROMSTAGE || (CONFIG_CONSOLE_PRERAM_BUFFER_SIZE == 0)) | ||||
| 		flags |= CBMEMC_RESET; | ||||
|  | ||||
| 		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); | ||||
| 	init_console_ptr(cbm_cons_p, | ||||
| 		CONFIG_CONSOLE_CBMEM_BUFFER_SIZE, flags); | ||||
| } | ||||
|  | ||||
| /* Call cbmemc_reinit() at CAR migration time. */ | ||||
| CAR_MIGRATE(cbmemc_reinit) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user