Youness Alaoui has uploaded a new change for review. ( https://review.coreboot.org/19866 )
Change subject: console/flashconsole: Add support for FMAP based flash console ......................................................................
console/flashconsole: Add support for FMAP based flash console
Add support for writing the console log to the FMAP 'CONSOLE' area and keep the CBFS support as an alternative.
Also remove the need for the offset variable and instead use a region_device subregion directly.
Change-Id: I7905480feebd906dd100228ca22c7f506d5a43b8 Signed-off-by: Youness Alaoui youness.alaoui@puri.sm --- M src/drivers/spi/flashconsole.c 1 file changed, 45 insertions(+), 40 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/66/19866/1
diff --git a/src/drivers/spi/flashconsole.c b/src/drivers/spi/flashconsole.c index b9b8877..a9d7fc3 100644 --- a/src/drivers/spi/flashconsole.c +++ b/src/drivers/spi/flashconsole.c @@ -17,6 +17,7 @@ #include <region.h> #include <boot_device.h> #include <cbfs.h> +#include <fmap.h> #include <console/flash.h> #include <string.h> #include <assert.h> @@ -24,40 +25,49 @@
#define LINE_BUFFER_SIZE 0x1000
-static const struct region_device *g_rdev CAR_GLOBAL; +static const struct region_device *g_rdev_ptr CAR_GLOBAL; +static struct region_device g_rdev CAR_GLOBAL; static uint8_t g_line_buffer[LINE_BUFFER_SIZE] CAR_GLOBAL; -static size_t g_region_offset CAR_GLOBAL; -static size_t g_region_size CAR_GLOBAL; static uint32_t g_offset CAR_GLOBAL; static uint32_t g_line_offset CAR_GLOBAL;
void flashconsole_init(void) { - struct cbfsf file; - struct region_device cbfs_region; - const struct region_device *rdev; + struct region_device *rdev = car_get_var_ptr(&g_rdev); uint8_t *line_buffer = car_get_var_ptr(g_line_buffer); - uint32_t cbfs_offset; - uint32_t cbfs_size; + uint32_t size; uint32_t offset = 0; int i; int len = LINE_BUFFER_SIZE;
- car_set_var(g_rdev, NULL); + car_set_var(g_rdev_ptr, NULL); car_set_var(g_offset, 0); car_set_var(g_line_offset, 0);
- cbfs_prepare_program_locate(); - if (cbfs_boot_locate(&file, "console", NULL) == 0) { - printk(BIOS_INFO, "Can't find 'console' region in CBFS."); - return; - } - cbfs_file_data(&cbfs_region, &file); - cbfs_offset = region_device_offset(&cbfs_region); - cbfs_size = region_device_sz(&cbfs_region); + if (fmap_locate_area_as_rdev_rw("CONSOLE", rdev) == 0) { + size = region_device_sz(rdev); + } else { + struct cbfsf file; + struct region_device cbfs_region; + const struct region_device *rdev_rw; + size_t cbfs_offset;
- boot_device_init(); - rdev = boot_device_rw(); + printk(BIOS_INFO, "Can't find 'CONSOLE' area in FMAP, trying CBFS\n"); + + cbfs_prepare_program_locate(); + if (cbfs_boot_locate(&file, "console", NULL)) { + printk(BIOS_INFO, "Can't find 'console' file in CBFS.\n"); + return; + } + cbfs_file_data(&cbfs_region, &file); + cbfs_offset = region_device_offset(&cbfs_region); + size = region_device_sz(&cbfs_region); + + boot_device_init(); + rdev_rw = boot_device_rw(); + if (rdev_chain(rdev, rdev_rw, cbfs_offset, size)) + return; + }
/* * We need to check the region until we find a 0xff indicating @@ -69,12 +79,11 @@ * the sector is already erased, so we would need to read * anyways to check if it's all 0xff). */ - for (i = 0; i < len && offset < cbfs_size; ) { + for (i = 0; i < len && offset < size; ) { // Fill the buffer on first iteration if (i == 0) { - len = min(LINE_BUFFER_SIZE, cbfs_size - offset); - rdev_readat(rdev, line_buffer, cbfs_offset + offset, - len); + len = min(LINE_BUFFER_SIZE, size - offset); + rdev_readat(rdev, line_buffer, offset, len); } if (line_buffer[i] == 0xff) { offset += i; @@ -87,32 +96,28 @@ } } // Make sure there is still space left on the console - if (offset >= cbfs_size) { - printk(BIOS_INFO, "No space left on 'console' region in CBFS."); + if (offset >= size) { + printk(BIOS_INFO, "No space left on 'console' region in SPI flash."); return; } // Now we can enable tx_byte - car_set_var(g_region_offset, cbfs_offset); - car_set_var(g_region_size, cbfs_size); car_set_var(g_offset, offset); - memset(line_buffer, 0, LINE_BUFFER_SIZE); - // Set g_rdev last so tx_byte doesn't get executed early - car_set_var(g_rdev, rdev); + // Set g_rdev_ptr last so tx_byte doesn't get executed early + car_set_var(g_rdev_ptr, rdev); }
static const struct region_device *_tx_flush(const struct region_device *rdev) { uint8_t *line_buffer = car_get_var_ptr(g_line_buffer); uint32_t offset = car_get_var(g_offset); - uint32_t region_offset = car_get_var(g_region_offset); - uint32_t region_size = car_get_var(g_region_size); + uint32_t region_size = region_device_sz(rdev); uint32_t len = car_get_var(g_line_offset);
// We crop the rest of the line if the region is full if (offset + len >= region_size) len = region_size - offset;
- rdev_writeat(rdev, line_buffer, region_offset + offset, len); + rdev_writeat(rdev, line_buffer, offset, len);
// If the region is full, stop future write attempts if (offset + len >= region_size) @@ -126,18 +131,18 @@
void flashconsole_tx_byte(unsigned char c) { - const struct region_device *rdev = car_get_var(g_rdev); + const struct region_device *rdev = car_get_var(g_rdev_ptr);
if (rdev) { uint8_t *line_buffer = car_get_var_ptr(g_line_buffer); uint32_t offset = car_get_var(g_offset); - uint32_t region_size = car_get_var(g_region_size); uint32_t len = car_get_var(g_line_offset); + uint32_t region_size = region_device_sz(rdev);
/* Prevent any recursive loops in case the spi flash driver * calls printk (in case of transaction timeout or * any other error while writing) */ - car_set_var(g_rdev, NULL); + car_set_var(g_rdev_ptr, NULL);
/* Do line-buffering on the writes to avoid doing an SPI write * on every byte */ @@ -148,21 +153,21 @@ offset + len >= region_size || c == '\n') { rdev = _tx_flush(rdev); } - car_set_var(g_rdev, rdev); + car_set_var(g_rdev_ptr, rdev); }
}
void flashconsole_tx_flush(void) { - const struct region_device *rdev = car_get_var(g_rdev); + const struct region_device *rdev = car_get_var(g_rdev_ptr);
if (rdev) { /* Prevent any recursive loops in case the spi flash driver * calls printk (in case of transaction timeout or * any other error while writing) */ - car_set_var(g_rdev, NULL); + car_set_var(g_rdev_ptr, NULL); rdev = _tx_flush(rdev); - car_set_var(g_rdev, rdev); + car_set_var(g_rdev_ptr, rdev); } }