[coreboot-gerrit] New patch to review for coreboot: drivers/elog: treat offsets relateive to start of mirror

Aaron Durbin (adurbin@chromium.org) gerrit at coreboot.org
Sat Aug 6 08:32:50 CEST 2016


Aaron Durbin (adurbin at chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16098

-gerrit

commit 38db33f60b79d2450da2c03233c0dca83be97824
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Thu Aug 4 15:59:35 2016 -0500

    drivers/elog: treat offsets relateive to start of mirror
    
    Instead of treating offsets relative to after the header make
    the offsets relative to the in-memory mirror buffer. This
    simplifies the logic in that all offsets are treated the same.
    It also allows one to remove a global variable.
    
    BUG=chrome-os-partner:55932
    
    Change-Id: I42491e05755d414562b02b6f9ae47f5c357d2f8a
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 src/drivers/elog/elog.c | 85 ++++++++++++++++++-------------------------------
 1 file changed, 31 insertions(+), 54 deletions(-)

diff --git a/src/drivers/elog/elog.c b/src/drivers/elog/elog.c
index a981e50..d1579d2 100644
--- a/src/drivers/elog/elog.c
+++ b/src/drivers/elog/elog.c
@@ -45,16 +45,15 @@
  * Static variables for ELOG state
  */
 static u16 total_size;
-static u16 log_size; /* excluding header */
 static u32 flash_base;
-static u16 full_threshold; /* from end of header */
-static u16 shrink_size; /* from end of header */
+static u16 full_threshold;
+static u16 shrink_size;
 
 static elog_area_state area_state;
 static elog_header_state header_state;
 static elog_event_buffer_state event_buffer_state;
 
-static u16 next_event_offset; /* from end of header */
+static u16 next_event_offset;
 static u16 event_count;
 
 static struct spi_flash *elog_spi;
@@ -72,16 +71,22 @@ static inline struct region_device *mirror_dev_get(void)
 	return &mirror_dev.rdev;
 }
 
+static size_t elog_events_start(void)
+{
+	/* Events are added directly after the header. */
+	return sizeof(struct elog_header);
+}
+
+static size_t elog_events_total_space(void)
+{
+	return total_size - elog_events_start();
+}
+
 /*
  * Pointer to an event log header in the event data area
  */
 static struct event_header *elog_get_event_buffer(size_t offset, size_t size)
 {
-	/*
-	 * Events are appended relative to the end of the header. Update
-	 * offset to include the header size.
-	 */
-	offset += sizeof(struct elog_header);
 	return rdev_mmap(mirror_dev_get(), offset, size);
 }
 
@@ -139,17 +144,6 @@ static int elog_is_buffer_clear(size_t offset)
 	return ret;
 }
 
-static int elog_event_buffer_is_clear(size_t offset)
-{
-	/*
-	 * Events are appended relative to the end of the header. Update
-	 * offset to include the header size.
-	 */
-	offset += sizeof(struct elog_header);
-
-	return elog_is_buffer_clear(offset);
-}
-
 /*
  * Check that the ELOG area has been initialized and is valid.
  */
@@ -266,16 +260,6 @@ static void elog_flash_write(size_t offset, size_t size)
 	rdev_munmap(rdev, address);
 }
 
-static void elog_append_event(size_t offset, size_t event_size)
-{
-	/*
-	 * Events are appended relative to the end of the header. Update
-	 * offset to include the header size.
-	 */
-	offset += sizeof(struct elog_header);
-	elog_flash_write(offset, event_size);
-}
-
 /*
  * Erase the first block specified in the address.
  * Only handles flash area within a single flash block.
@@ -298,7 +282,7 @@ static void elog_flash_erase(void)
 static void elog_update_event_buffer_state(void)
 {
 	u32 count = 0;
-	u32 offset = 0;
+	size_t offset = elog_events_start();
 
 	elog_debug("elog_update_event_buffer_state()\n");
 
@@ -308,10 +292,9 @@ static void elog_update_event_buffer_state(void)
 		const size_t type_offset = offsetof(struct event_header, type);
 		size_t len;
 		const size_t size = sizeof(type);
-		size_t abs_offset = offset + sizeof(struct elog_header);
 
 		if (rdev_readat(mirror_dev_get(), &type,
-				abs_offset + type_offset, size) < 0) {
+				offset + type_offset, size) < 0) {
 			event_buffer_state = ELOG_EVENT_BUFFER_CORRUPTED;
 			break;
 		}
@@ -321,7 +304,7 @@ static void elog_update_event_buffer_state(void)
 			break;
 
 		/* Validate the event */
-		len = elog_is_event_valid(abs_offset);
+		len = elog_is_event_valid(offset);
 
 		if (!len) {
 			event_buffer_state = ELOG_EVENT_BUFFER_CORRUPTED;
@@ -334,7 +317,7 @@ static void elog_update_event_buffer_state(void)
 	}
 
 	/* Ensure the remaining buffer is empty */
-	if (!elog_event_buffer_is_clear(offset))
+	if (!elog_is_buffer_clear(offset))
 		event_buffer_state = ELOG_EVENT_BUFFER_CORRUPTED;
 
 	/* Update ELOG state */
@@ -357,7 +340,7 @@ static void elog_scan_flash(void)
 	elog_spi->read(elog_spi, flash_base, total_size, mirror_buffer);
 	rdev_munmap(rdev, mirror_buffer);
 
-	next_event_offset = 0;
+	next_event_offset = elog_events_start();
 	event_count = 0;
 
 	/* Check if the area is empty or not */
@@ -410,14 +393,9 @@ static void elog_move_events_to_front(size_t offset, size_t size)
 {
 	void *src;
 	void *dest;
-	size_t start_offset = sizeof(struct elog_header);
+	size_t start_offset = elog_events_start();
 	const struct region_device *rdev = mirror_dev_get();
 
-	/*
-	 * Events are appended relative to the end of the header. Update
-	 * offset to include the header size.
-	 */
-	offset += start_offset;
 	src = rdev_mmap(rdev, offset, size);
 	dest = rdev_mmap(rdev, start_offset, size);
 
@@ -452,7 +430,7 @@ static void elog_move_events_to_front(size_t offset, size_t size)
 static int elog_shrink(void)
 {
 	const struct region_device *rdev = mirror_dev_get();
-	u16 offset = 0;
+	size_t offset = elog_events_start();
 
 	elog_debug("elog_shrink()\n");
 
@@ -462,21 +440,19 @@ static int elog_shrink(void)
 		const size_t size = sizeof(uint8_t);
 		uint8_t type;
 		uint8_t len;
-		size_t abs_offset = offset + sizeof(struct elog_header);
 
 		/* Next event has exceeded constraints */
 		if (offset > shrink_size)
 			break;
 
-		if (rdev_readat(rdev, &type, abs_offset + type_offset,
-				size) < 0)
+		if (rdev_readat(rdev, &type, offset + type_offset, size) < 0)
 			break;
 
 		/* Reached the end of the area */
 		if (type == ELOG_TYPE_EOL)
 			break;
 
-		if (rdev_readat(rdev, &len, abs_offset + len_offset, size) < 0)
+		if (rdev_readat(rdev, &len, offset + len_offset, size) < 0)
 			break;
 
 		offset += len;
@@ -495,7 +471,7 @@ static int elog_shrink(void)
 	}
 
 	/* Add clear event */
-	elog_add_event_word(ELOG_TYPE_LOG_CLEAR, offset);
+	elog_add_event_word(ELOG_TYPE_LOG_CLEAR, offset - elog_events_start());
 
 	return 0;
 }
@@ -579,7 +555,7 @@ int elog_clear(void)
 		return -1;
 
 	/* Log the clear event */
-	elog_add_event_word(ELOG_TYPE_LOG_CLEAR, log_size);
+	elog_add_event_word(ELOG_TYPE_LOG_CLEAR, elog_events_total_space());
 
 	return 0;
 }
@@ -587,6 +563,7 @@ int elog_clear(void)
 static void elog_find_flash(void)
 {
 	struct region r;
+	size_t reserved_space = ELOG_MIN_AVAILABLE_ENTRIES * MAX_EVENT_SIZE;
 
 	elog_debug("elog_find_flash()\n");
 
@@ -600,8 +577,7 @@ static void elog_find_flash(void)
 		total_size = MIN(4*KiB, region_sz(&r));
 	}
 
-	log_size = total_size - sizeof(struct elog_header);
-	full_threshold = log_size - ELOG_MIN_AVAILABLE_ENTRIES * MAX_EVENT_SIZE;
+	full_threshold = total_size - reserved_space;
 	shrink_size = MIN(total_size * ELOG_SHRINK_PERCENTAGE / 100,
 								full_threshold);
 }
@@ -640,7 +616,7 @@ int elog_init(void)
 	} else if (total_size < sizeof(struct elog_header) + MAX_EVENT_SIZE) {
 		printk(BIOS_ERR, "ELOG: Region too small to hold any events\n");
 		return -1;
-	} else if (log_size - shrink_size >= full_threshold) {
+	} else if (total_size - shrink_size >= full_threshold) {
 		printk(BIOS_ERR,
 			"ELOG: SHRINK_PERCENTAGE set too small for MIN_AVAILABLE_ENTRIES\n");
 		return -1;
@@ -689,7 +665,8 @@ int elog_init(void)
 
 	/* Log a clear event if necessary */
 	if (event_count == 0)
-		elog_add_event_word(ELOG_TYPE_LOG_CLEAR, log_size);
+		elog_add_event_word(ELOG_TYPE_LOG_CLEAR,
+					elog_events_total_space());
 
 #if !defined(__SMM__)
 	/* Log boot count event except in S3 resume */
@@ -791,7 +768,7 @@ void elog_add_event_raw(u8 event_type, void *data, u8 data_size)
 	/* Update the ELOG state */
 	event_count++;
 
-	elog_append_event(next_event_offset, event_size);
+	elog_flash_write(next_event_offset, event_size);
 
 	next_event_offset += event_size;
 



More information about the coreboot-gerrit mailing list