[coreboot-gerrit] Patch set updated for coreboot: 190f8d1 elog: Stream line the elog driver.

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Tue Nov 26 20:26:24 CET 2013


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4244

-gerrit

commit 190f8d18aecad9e51e68b1fa2dbbeb3b20f417e6
Author: Gabe Black <gabeblack at google.com>
Date:   Wed Apr 24 23:31:41 2013 -0700

    elog: Stream line the elog driver.
    
    The elog driver's design was a bit more elaborate than it really needed to be
    since it no longer had to keep track of multiple copies of the log in flash
    and also in memory. This change streamlines it by removing unnecessary
    compartmentalization of some bits of code, and some variables which tracked
    the last entry added which were never used.
    
    Built and booted on Link. Ran mosys eventlog list. Added 2000 events to
    the event log and ran mosys eventlog list again. Cleared the log by echoing 1
    into /sys/firmware/gsmi/clear_eventlog and ran mosys eventlog list.
    
    Change-Id: I7d4cdebf2f5b1f6bb1fc70e65eca18f71b124b18
    Signed-off-by: Gabe Black <gabeblack at google.com>
    Reviewed-on: https://gerrit.chromium.org/gerrit/49309
    Reviewed-by: Duncan Laurie <dlaurie at chromium.org>
    Commit-Queue: Gabe Black <gabeblack at chromium.org>
    Tested-by: Gabe Black <gabeblack at chromium.org>
---
 src/drivers/elog/elog.c          | 270 ++++++++++++---------------------------
 src/drivers/elog/elog_internal.h |   2 -
 2 files changed, 79 insertions(+), 193 deletions(-)

diff --git a/src/drivers/elog/elog.c b/src/drivers/elog/elog.c
index ca5b3fb..7786d3b 100644
--- a/src/drivers/elog/elog.c
+++ b/src/drivers/elog/elog.c
@@ -114,15 +114,6 @@ elog_get_next_event_base(struct elog_descriptor *elog)
 }
 
 /*
- * Pointer to the last logged event
- */
-static inline struct event_header*
-elog_get_last_event_base(struct elog_descriptor *elog)
-{
-	return elog_get_event_base(elog, elog->last_event_offset);
-}
-
-/*
  * Update the checksum at the last byte
  */
 static void elog_update_checksum(struct event_header *event, u8 checksum)
@@ -308,8 +299,6 @@ static void elog_update_event_buffer_state(struct elog_descriptor *elog)
 {
 	u32 count = 0;
 	u32 offset = 0;
-	u32 last_offset = 0;
-	u32 last_event_size = 0;
 	struct event_header *event;
 
 	elog_debug("elog_update_event_buffer_state()\n");
@@ -337,8 +326,6 @@ static void elog_update_event_buffer_state(struct elog_descriptor *elog)
 
 		/* Move to the next event */
 		count++;
-		last_offset = offset;
-		last_event_size = event->length;
 		offset += event->length;
 	}
 
@@ -350,16 +337,14 @@ static void elog_update_event_buffer_state(struct elog_descriptor *elog)
 	/* Update data into elog descriptor */
 	elog->event_count = count;
 	elog->next_event_offset = offset;
-	elog->last_event_offset = last_offset;
-	elog->last_event_size = last_event_size;
 }
 
 /*
  * (Re)initialize a new ELOG descriptor
  */
-static void elog_init_descriptor(struct elog_descriptor *elog)
+static void elog_scan_flash(struct elog_descriptor *elog)
 {
-	elog_debug("elog_init_descriptor()\n");
+	elog_debug("elog_scan_flash()\n");
 
 	elog->area_state = ELOG_AREA_UNDEFINED;
 	elog->header_state = ELOG_HEADER_INVALID;
@@ -370,8 +355,6 @@ static void elog_init_descriptor(struct elog_descriptor *elog)
 		       elog->backing_store);
 
 	elog->next_event_offset = 0;
-	elog->last_event_offset = 0;
-	elog->last_event_size = 0;
 	elog->event_count = 0;
 
 	/* Check if the area is empty or not */
@@ -392,61 +375,12 @@ static void elog_init_descriptor(struct elog_descriptor *elog)
 	elog_update_event_buffer_state(elog);
 }
 
-/*
- * Create ELOG descriptor data structures for all ELOG areas.
- */
-static int elog_setup_descriptors(u32 flash_base, u32 area_size)
-{
-	u8 *area;
-	struct elog_descriptor *flash = elog_get_flash();
-
-	elog_debug("elog_setup_descriptors(base=0x%08x size=%u)\n",
-		   flash_base, area_size);
-
-	/* Prepare flash descriptors */
-	if (flash_base == 0) {
-		printk(BIOS_ERR, "ELOG: Invalid flash base\n");
-		return -1;
-	}
-
-	area = malloc(area_size);
-	if (!area) {
-		printk(BIOS_ERR, "ELOG: Unable to allocate backing store\n");
-		return -1;
-	}
-	flash->flash_base = flash_base;
-	flash->backing_store = area;
-	flash->total_size = area_size;
-
-	/* Data starts immediately after header */
-	flash->data = area + sizeof(struct elog_header);
-	flash->data_size = area_size - sizeof(struct elog_header);
-
-	elog_init_descriptor(flash);
-
-	return 0;
-}
-
-static void elog_flash_erase_area(void)
-{
-	struct elog_descriptor *elog = elog_get_flash();
-
-	elog_debug("elog_flash_erase_area()\n");
-
-	elog_flash_erase(elog->backing_store, elog->total_size);
-	memset(elog->backing_store, ELOG_TYPE_EOL, elog->total_size);
-	elog_init_descriptor(elog);
-}
-
 static void elog_prepare_empty(struct elog_descriptor *elog)
 {
 	struct elog_header *header;
 
 	elog_debug("elog_prepare_empty(%u bytes)\n", data_size);
 
-	if (!elog_is_area_clear(elog))
-		return;
-
 	/* Write out the header */
 	header = elog_get_header(elog);
 	header->magic = ELOG_SIGNATURE;
@@ -456,64 +390,7 @@ static void elog_prepare_empty(struct elog_descriptor *elog)
 	header->reserved[1] = ELOG_TYPE_EOL;
 	elog_flash_write(elog->backing_store, header->header_size);
 
-	elog_init_descriptor(elog);
-}
-
-static int elog_sync_flash_to_mem(void)
-{
-	struct elog_descriptor *flash = elog_get_flash();
-
-	elog_debug("elog_sync_flash_to_mem()\n");
-
-	/* Fill with empty pattern first */
-	memset(flash->backing_store, ELOG_TYPE_EOL, flash->total_size);
-
-	/* Read the header from SPI to memory */
-	elog_spi->read(elog_spi, flash->flash_base,
-		       sizeof(struct elog_header), flash->backing_store);
-
-	/* Read the valid flash contents from SPI to memory */
-	elog_spi->read(elog_spi, flash->flash_base + sizeof(struct elog_header),
-		       flash->next_event_offset, flash->data);
-
-	elog_init_descriptor(flash);
-
-	return elog_is_area_valid(flash) ? 0 : -1;
-}
-
-/*
- * Called during ELOG entry handler to prepare state for flash.
- */
-static int elog_flash_area_bootstrap(void)
-{
-	struct elog_descriptor *elog = elog_get_flash();
-
-	elog_debug("elog_flash_area_bootstrap()\n");
-
-	switch (elog->area_state) {
-	case ELOG_AREA_UNDEFINED:
-		printk(BIOS_ERR, "ELOG: flash area undefined\n");
-		return -1;
-
-	case ELOG_AREA_EMPTY:
-		/* Write a new header with no data */
-		elog_prepare_empty(elog);
-		break;
-
-	case ELOG_AREA_HAS_CONTENT:
-		break;
-	}
-
-	if (elog->header_state == ELOG_HEADER_INVALID ||
-		elog->event_buffer_state == ELOG_EVENT_BUFFER_CORRUPTED) {
-		/* If the header is invalid or the events are corrupted,
-		 * no events can be salvaged so erase the entire area. */
-		printk(BIOS_ERR, "ELOG: flash area invalid\n");
-		elog_flash_erase_area();
-		elog_prepare_empty(elog);
-	}
-
-	return 0;
+	elog_scan_flash(elog);
 }
 
 /*
@@ -555,7 +432,7 @@ static int elog_shrink(void)
 
 	elog_flash_erase(flash->backing_store, flash->total_size);
 	elog_flash_write(flash->backing_store, flash->total_size);
-	elog_init_descriptor(flash);
+	elog_scan_flash(flash);
 
 	/* Ensure the area was successfully erased */
 	if (flash->next_event_offset >= CONFIG_ELOG_FULL_THRESHOLD) {
@@ -569,22 +446,6 @@ static int elog_shrink(void)
 	return 0;
 }
 
-/*
- * Initialize the SPI bus and probe for a flash chip
- */
-static int elog_spi_init(void)
-{
-	elog_debug("elog_spi_init()\n");
-
-	/* Prepare SPI subsystem */
-	spi_init();
-
-	/* Look for flash chip */
-	elog_spi = spi_flash_probe(0, 0, 0, 0);
-
-	return elog_spi ? 0 : -1;
-}
-
 #ifndef __SMM__
 /*
  * Fill out SMBIOS Type 15 table entry so the
@@ -642,13 +503,10 @@ int elog_clear(void)
 		return -1;
 
 	/* Erase flash area */
-	elog_flash_erase_area();
-
-	/* Prepare new empty area */
+	elog_flash_erase(flash->backing_store, flash->total_size);
 	elog_prepare_empty(flash);
 
-	/* Update memory area from flash */
-	if (elog_sync_flash_to_mem() < 0)
+	if (!elog_is_area_valid(flash))
 		return -1;
 
 	/* Log the clear event */
@@ -657,90 +515,122 @@ int elog_clear(void)
 	return 0;
 }
 
+static void elog_find_flash(u32 *base, int *size)
+{
+#if CONFIG_CHROMEOS
+	u8 *flash_base_ptr;
+#endif
+
+	elog_debug("elog_find_flash(base = %p, size = %p)\n", base, size);
+
+#if CONFIG_CHROMEOS
+	/* Find the ELOG base and size in FMAP */
+	*size = find_fmap_entry("RW_ELOG", (void **)&flash_base_ptr);
+	if (*size < 0) {
+		printk(BIOS_WARNING, "ELOG: Unable to find RW_ELOG in FMAP, "
+		       "using CONFIG_ELOG_FLASH_BASE instead\n");
+		*size = CONFIG_ELOG_AREA_SIZE;
+	} else {
+		*base = elog_flash_address_to_offset(flash_base_ptr);
+
+		/* Use configured size if smaller than FMAP size */
+		if (*size > CONFIG_ELOG_AREA_SIZE)
+			*size = CONFIG_ELOG_AREA_SIZE;
+	}
+#else
+	*base = CONFIG_ELOG_FLASH_BASE;
+	*size = CONFIG_ELOG_AREA_SIZE;
+#endif
+}
+
 /*
  * Event log main entry point
  */
 int elog_init(void)
 {
+	struct elog_descriptor *flash = elog_get_flash();
 	u32 flash_base = CONFIG_ELOG_FLASH_BASE;
 	int flash_size = CONFIG_ELOG_AREA_SIZE;
-#if CONFIG_CHROMEOS
-	u8 *flash_base_ptr;
-#endif
 
 	if (elog_initialized)
 		return 0;
 
 	elog_debug("elog_init()\n");
 
-	/* Find SPI flash chip for backing store */
-	if (elog_spi_init() < 0) {
+	/* Prepare SPI */
+	spi_init();
+	elog_spi = spi_flash_probe(0, 0, 0, 0);
+	if (!elog_spi) {
 		printk(BIOS_ERR, "ELOG: Unable to find SPI flash\n");
 		return -1;
 	}
 
-#if CONFIG_CHROMEOS
-	/* Find the ELOG base and size in FMAP */
-	flash_size = find_fmap_entry("RW_ELOG", (void **)&flash_base_ptr);
-	if (flash_size < 0) {
-		printk(BIOS_WARNING, "ELOG: Unable to find RW_ELOG in FMAP, "
-		       "using CONFIG_ELOG_FLASH_BASE instead\n");
-		flash_size = CONFIG_ELOG_AREA_SIZE;
-	} else {
-		flash_base = elog_flash_address_to_offset(flash_base_ptr);
-
-		/* Use configured size if smaller than FMAP size */
-		if (flash_size > CONFIG_ELOG_AREA_SIZE)
-			flash_size = CONFIG_ELOG_AREA_SIZE;
+	/* Set up the backing store */
+	elog_find_flash(&flash_base, &flash_size);
+	if (flash_base == 0) {
+		printk(BIOS_ERR, "ELOG: Invalid flash base\n");
+		return -1;
 	}
-#endif
 
-	/* Setup descriptors for flash and memory areas */
-	if (elog_setup_descriptors(flash_base, flash_size) < 0) {
-		printk(BIOS_ERR, "ELOG: Unable to initialize descriptors\n");
+	flash->backing_store = malloc(flash_size);
+	if (!flash->backing_store) {
+		printk(BIOS_ERR, "ELOG: Unable to allocate backing store\n");
 		return -1;
 	}
+	flash->flash_base = flash_base;
+	flash->total_size = flash_size;
 
-	/* Bootstrap the flash area */
-	if (elog_flash_area_bootstrap() < 0) {
-		printk(BIOS_ERR, "ELOG: Unable to bootstrap flash area\n");
-		return -1;
+	/* Data starts immediately after header */
+	flash->data = flash->backing_store + sizeof(struct elog_header);
+	flash->data_size = flash_size - sizeof(struct elog_header);
+
+	/* Load the log from flash */
+	elog_scan_flash(flash);
+
+	/* Prepare the flash if necessary */
+	if (flash->header_state == ELOG_HEADER_INVALID ||
+		flash->event_buffer_state == ELOG_EVENT_BUFFER_CORRUPTED) {
+		/* If the header is invalid or the events are corrupted,
+		 * no events can be salvaged so erase the entire area. */
+		printk(BIOS_ERR, "ELOG: flash area invalid\n");
+		elog_flash_erase(flash->backing_store, flash->total_size);
+		elog_prepare_empty(flash);
 	}
 
-	/* Initialize the memory area */
-	if (elog_sync_flash_to_mem() < 0) {
-		printk(BIOS_ERR, "ELOG: Unable to initialize memory area\n");
+	if (flash->area_state == ELOG_AREA_EMPTY)
+		elog_prepare_empty(flash);
+
+	if (!elog_is_area_valid(flash)) {
+		printk(BIOS_ERR, "ELOG: Unable to prepare flash\n");
 		return -1;
 	}
 
 	elog_initialized = 1;
 
 	printk(BIOS_INFO, "ELOG: FLASH @0x%p [SPI 0x%08x]\n",
-	       elog_get_flash()->backing_store, elog_get_flash()->flash_base);
+	       flash->backing_store, flash->flash_base);
 
-	printk(BIOS_INFO, "ELOG: areas are %d bytes, full threshold %d,"
-	       " shrink size %d\n", CONFIG_ELOG_AREA_SIZE,
+	printk(BIOS_INFO, "ELOG: area is %d bytes, full threshold %d,"
+	       " shrink size %d\n", flash_size,
 	       CONFIG_ELOG_FULL_THRESHOLD, CONFIG_ELOG_SHRINK_SIZE);
 
 	/* Log a clear event if necessary */
-	if (elog_get_flash()->event_count == 0)
-		elog_add_event_word(ELOG_TYPE_LOG_CLEAR,
-				    elog_get_flash()->total_size);
+	if (flash->event_count == 0)
+		elog_add_event_word(ELOG_TYPE_LOG_CLEAR, flash->total_size);
 
 	/* Shrink the log if we are getting too full */
-	if (elog_get_flash()->next_event_offset >= CONFIG_ELOG_FULL_THRESHOLD)
+	if (flash->next_event_offset >= CONFIG_ELOG_FULL_THRESHOLD)
 		if (elog_shrink() < 0)
 			return -1;
 
-#if CONFIG_ELOG_BOOT_COUNT && !defined(__SMM__)
+#if !defined(__SMM__)
 	/* Log boot count event except in S3 resume */
-	if (acpi_slp_type != 3)
+	if (CONFIG_ELOG_BOOT_COUNT && acpi_slp_type != 3)
 		elog_add_event_dword(ELOG_TYPE_BOOT, boot_count_read());
-#endif
 
-#if CONFIG_CMOS_POST && !defined(__SMM__)
 	/* Check and log POST codes from previous boot */
-	cmos_post_log();
+	if (CONFIG_CMOS_POST)
+		cmos_post_log();
 #endif
 
 	return 0;
@@ -818,8 +708,6 @@ void elog_add_event_raw(u8 event_type, void *data, u8 data_size)
 
 	elog_flash_write((void *)event, event_size);
 
-	flash->last_event_offset = flash->next_event_offset;
-	flash->last_event_size = event_size;
 	flash->next_event_offset += event_size;
 
 	printk(BIOS_INFO, "ELOG: Event(%X) added with size %d\n",
diff --git a/src/drivers/elog/elog_internal.h b/src/drivers/elog/elog_internal.h
index 799e7e2..e83df5f 100644
--- a/src/drivers/elog/elog_internal.h
+++ b/src/drivers/elog/elog_internal.h
@@ -76,8 +76,6 @@ struct elog_descriptor {
 	u16                     total_size;
 	u16			data_size;
 	u16			next_event_offset;
-	u16			last_event_offset;
-	u16			last_event_size;
 	u16			event_count;
 };
 



More information about the coreboot-gerrit mailing list