[coreboot-gerrit] Change in coreboot[master]: drivers/elog: Group event log state information

Karthik Ramasubramanian (Code Review) gerrit at coreboot.org
Thu Nov 8 01:12:18 CET 2018


Karthik Ramasubramanian has uploaded this change for review. ( https://review.coreboot.org/29541


Change subject: drivers/elog: Group event log state information
......................................................................

drivers/elog: Group event log state information

Group event log state information together to manage them better during
different stages of coreboot.

BUG=b:117884485
BRANCH=None
TEST=Add an event log from romstage, boot to ChromeOS

Change-Id: I62792c0f5063c89ad11b512f1777c7ab8a2c13e5
Signed-off-by: Karthikeyan Ramasubramanian <kramasub at google.com>
---
M src/drivers/elog/elog.c
1 file changed, 102 insertions(+), 58 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/41/29541/1

diff --git a/src/drivers/elog/elog.c b/src/drivers/elog/elog.c
index d3c01c2..d1a9f4f 100644
--- a/src/drivers/elog/elog.c
+++ b/src/drivers/elog/elog.c
@@ -16,6 +16,7 @@
 #if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)
 #include <arch/acpi.h>
 #endif
+#include <arch/early_variables.h>
 #include <bootstate.h>
 #include <cbmem.h>
 #include <console/console.h>
@@ -42,33 +43,38 @@
 #endif
 
 #define NV_NEEDS_ERASE (~(size_t)0)
-/*
- * Static variables for ELOG state
- */
-static u16 full_threshold;
-static u16 shrink_size;
-
-/*
- * The non-volatile storage chases the mirrored copy. When nv_last_write
- * is less than the mirrored last write the non-volatile storage needs
- * to be updated.
- */
-static size_t mirror_last_write;
-static size_t nv_last_write;
-
-static struct region_device nv_dev;
-/* Device that mirrors the eventlog in memory. */
-static struct mem_region_device mirror_dev;
-
-static enum {
+enum elog_init_state {
 	ELOG_UNINITIALIZED = 0,
 	ELOG_INITIALIZED,
 	ELOG_BROKEN,
-} elog_initialized = ELOG_UNINITIALIZED;
+};
+
+struct elog_state {
+	u16 full_threshold;
+	u16 shrink_size;
+
+	/*
+	 * The non-volatile storage chases the mirrored copy. When nv_last_write
+	 * is less than the mirrored last write the non-volatile storage needs
+	 * to be updated.
+	 */
+	size_t mirror_last_write;
+	size_t nv_last_write;
+
+	struct region_device nv_dev;
+	/* Device that mirrors the eventlog in memory. */
+	struct mem_region_device mirror_dev;
+
+	enum elog_init_state elog_initialized;
+};
+
+static struct elog_state g_elog_state CAR_GLOBAL;
 
 static inline struct region_device *mirror_dev_get(void)
 {
-	return &mirror_dev.rdev;
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+
+	return &g_elog_statep->mirror_dev.rdev;
 }
 
 static size_t elog_events_start(void)
@@ -79,7 +85,9 @@
 
 static size_t elog_events_total_space(void)
 {
-	return region_device_sz(&nv_dev) - elog_events_start();
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+
+	return region_device_sz(&g_elog_statep->nv_dev) - elog_events_start();
 }
 
 static struct event_header *elog_get_event_buffer(size_t offset, size_t size)
@@ -89,8 +97,11 @@
 
 static struct event_header *elog_get_next_event_buffer(size_t size)
 {
-	elog_debug("ELOG: new event at offset 0x%zx\n", mirror_last_write);
-	return elog_get_event_buffer(mirror_last_write, size);
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+
+	elog_debug("ELOG: new event at offset 0x%zx\n",
+				g_elog_statep->mirror_last_write);
+	return elog_get_event_buffer(g_elog_statep->mirror_last_write, size);
 }
 
 static void elog_put_event_buffer(struct event_header *event)
@@ -100,53 +111,72 @@
 
 static size_t elog_mirror_reset_last_write(void)
 {
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
 	/* Return previous write value. */
-	size_t prev = mirror_last_write;
-	mirror_last_write = 0;
+	size_t prev = g_elog_statep->mirror_last_write;
+
+	g_elog_statep->mirror_last_write = 0;
 	return prev;
 }
 
 static void elog_mirror_increment_last_write(size_t size)
 {
-	mirror_last_write += size;
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+
+	g_elog_statep->mirror_last_write += size;
 }
 
 static void elog_nv_reset_last_write(void)
 {
-	nv_last_write = 0;
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+
+	g_elog_statep->nv_last_write = 0;
 }
 
 static void elog_nv_increment_last_write(size_t size)
 {
-	nv_last_write += size;
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+
+	g_elog_statep->nv_last_write += size;
 }
 
 static void elog_nv_needs_possible_erase(void)
 {
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+
 	/* If last write is 0 it means it is already erased. */
-	if (nv_last_write != 0)
-		nv_last_write = NV_NEEDS_ERASE;
+	if (g_elog_statep->nv_last_write != 0)
+		g_elog_statep->nv_last_write = NV_NEEDS_ERASE;
 }
 
 static bool elog_should_shrink(void)
 {
-	return mirror_last_write >= full_threshold;
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+
+	return g_elog_statep->mirror_last_write >=
+				g_elog_statep->full_threshold;
 }
 
 static bool elog_nv_needs_erase(void)
 {
-	return nv_last_write == NV_NEEDS_ERASE;
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+
+	return g_elog_statep->nv_last_write == NV_NEEDS_ERASE;
 }
 
 static bool elog_nv_needs_update(void)
 {
-	return nv_last_write != mirror_last_write;
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+
+	return g_elog_statep->nv_last_write != g_elog_statep->mirror_last_write;
 }
 
 static size_t elog_nv_region_to_update(size_t *offset)
 {
-	*offset = nv_last_write;
-	return mirror_last_write - nv_last_write;
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+
+	*offset = g_elog_statep->nv_last_write;
+	return g_elog_statep->mirror_last_write - g_elog_statep->nv_last_write;
 }
 
 /*
@@ -318,6 +348,7 @@
 {
 	void *address;
 	const struct region_device *rdev = mirror_dev_get();
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
 
 	if (!size)
 		return;
@@ -331,7 +362,7 @@
 		return;
 
 	/* Write the data to flash */
-	if (rdev_writeat(&nv_dev, address, offset, size) != size)
+	if (rdev_writeat(&g_elog_statep->nv_dev, address, offset, size) != size)
 		printk(BIOS_ERR, "ELOG: NV Write failed at 0x%zx, size 0x%zx\n",
 			offset, size);
 
@@ -344,11 +375,12 @@
  */
 static void elog_nv_erase(void)
 {
-	size_t size = region_device_sz(&nv_dev);
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+	size_t size = region_device_sz(&g_elog_statep->nv_dev);
 	elog_debug("%s()\n", __func__);
 
 	/* Erase the sectors in this region */
-	if (rdev_eraseat(&nv_dev, 0, size) != size)
+	if (rdev_eraseat(&g_elog_statep->nv_dev, 0, size) != size)
 		printk(BIOS_ERR, "ELOG: erase failure.\n");
 }
 
@@ -406,11 +438,13 @@
 	elog_debug("elog_scan_flash()\n");
 	void *mirror_buffer;
 	const struct region_device *rdev = mirror_dev_get();
-	size_t size = region_device_sz(&nv_dev);
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+	size_t size = region_device_sz(&g_elog_statep->nv_dev);
 
 	/* Fill memory buffer by reading from SPI */
 	mirror_buffer = rdev_mmap_full(rdev);
-	if (rdev_readat(&nv_dev, mirror_buffer, 0, size) != size) {
+	if (rdev_readat(&g_elog_statep->nv_dev, mirror_buffer, 0, size) !=
+									size) {
 		rdev_munmap(rdev, mirror_buffer);
 		printk(BIOS_ERR, "ELOG: NV read failure.\n");
 		return -1;
@@ -574,8 +608,10 @@
 
 static int elog_shrink(void)
 {
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+
 	if (elog_should_shrink())
-		return elog_shrink_by_size(shrink_size);
+		return elog_shrink_by_size(g_elog_statep->shrink_size);
 	return 0;
 }
 
@@ -584,16 +620,19 @@
  */
 static inline u8 *elog_flash_offset_to_address(void)
 {
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+
 	/* Only support memory-mapped devices. */
 	if (!IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED))
 		return NULL;
 
-	if (!region_device_sz(&nv_dev))
+	if (!region_device_sz(&g_elog_statep->nv_dev))
 		return NULL;
 
 	/* Get a view into the read-only boot device. */
-	return rdev_mmap(boot_device_ro(), region_device_offset(&nv_dev),
-			region_device_sz(&nv_dev));
+	return rdev_mmap(boot_device_ro(),
+			region_device_offset(&g_elog_statep->nv_dev),
+			region_device_sz(&g_elog_statep->nv_dev));
 }
 
 /*
@@ -605,7 +644,8 @@
 	struct smbios_type15 *t = (struct smbios_type15 *)*current;
 	int len = sizeof(struct smbios_type15);
 	uintptr_t log_address;
-	size_t elog_size = region_device_sz(&nv_dev);
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+	size_t elog_size = region_device_sz(&g_elog_statep->nv_dev);
 
 	if (IS_ENABLED(CONFIG_ELOG_CBMEM)) {
 		/* Save event log buffer into CBMEM for the OS to read */
@@ -659,7 +699,8 @@
 {
 	size_t total_size;
 	size_t reserved_space = ELOG_MIN_AVAILABLE_ENTRIES * MAX_EVENT_SIZE;
-	struct region_device *rdev = &nv_dev;
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
+	struct region_device *rdev = &g_elog_statep->nv_dev;
 
 	elog_debug("%s()\n", __func__);
 
@@ -682,10 +723,10 @@
 	total_size = MIN(4*KiB, region_device_sz(rdev));
 	rdev_chain(rdev, rdev, 0, total_size);
 
-	full_threshold = total_size - reserved_space;
-	shrink_size = total_size * ELOG_SHRINK_PERCENTAGE / 100;
+	g_elog_statep->full_threshold = total_size - reserved_space;
+	g_elog_statep->shrink_size = total_size * ELOG_SHRINK_PERCENTAGE / 100;
 
-	if (reserved_space > shrink_size) {
+	if (reserved_space > g_elog_statep->shrink_size) {
 		printk(BIOS_ERR, "ELOG: SHRINK_PERCENTAGE too small\n");
 		return -1;
 	}
@@ -698,6 +739,7 @@
 	size_t offset;
 	size_t size;
 	bool erase_needed;
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
 
 	/* Determine if any updates are required. */
 	if (!elog_nv_needs_update())
@@ -729,7 +771,7 @@
 	if (elog_scan_flash() < 0) {
 		printk(BIOS_ERR, "ELOG: Sync back from NV storage failed.\n");
 		elog_debug_dump_buffer("ELOG: Buffer from NV:\n");
-		elog_initialized = ELOG_BROKEN;
+		g_elog_statep->elog_initialized = ELOG_BROKEN;
 		return -1;
 	}
 
@@ -758,8 +800,9 @@
 {
 	void *mirror_buffer;
 	size_t elog_size;
+	struct elog_state *g_elog_statep = car_get_var_ptr(&g_elog_state);
 
-	switch (elog_initialized) {
+	switch (g_elog_statep->elog_initialized) {
 	case ELOG_UNINITIALIZED:
 		break;
 	case ELOG_INITIALIZED:
@@ -767,7 +810,7 @@
 	case ELOG_BROKEN:
 		return -1;
 	}
-	elog_initialized = ELOG_BROKEN;
+	g_elog_statep->elog_initialized = ELOG_BROKEN;
 
 	elog_debug("elog_init()\n");
 
@@ -775,19 +818,20 @@
 	if (elog_find_flash() < 0)
 		return -1;
 
-	elog_size = region_device_sz(&nv_dev);
+	elog_size = region_device_sz(&g_elog_statep->nv_dev);
 	mirror_buffer = malloc(elog_size);
 	if (!mirror_buffer) {
 		printk(BIOS_ERR, "ELOG: Unable to allocate backing store\n");
 		return -1;
 	}
-	mem_region_device_rw_init(&mirror_dev, mirror_buffer, elog_size);
+	mem_region_device_rw_init(&g_elog_statep->mirror_dev, mirror_buffer,
+								elog_size);
 
 	/*
 	 * Mark as initialized to allow elog_init() to be called and deemed
 	 * successful in the prepare/shrink path which adds events.
 	 */
-	elog_initialized = ELOG_INITIALIZED;
+	g_elog_statep->elog_initialized = ELOG_INITIALIZED;
 
 	/* Load the log from flash and prepare the flash if necessary. */
 	if (elog_scan_flash() < 0 && elog_prepare_empty() < 0) {
@@ -796,8 +840,8 @@
 	}
 
 	printk(BIOS_INFO, "ELOG: area is %zu bytes, full threshold %d,"
-	       " shrink size %d\n", region_device_sz(&nv_dev),
-		full_threshold, shrink_size);
+	       " shrink size %d\n", region_device_sz(&g_elog_statep->nv_dev),
+		g_elog_statep->full_threshold, g_elog_statep->shrink_size);
 
 	if (elog_do_add_boot_count()) {
 		elog_add_event_dword(ELOG_TYPE_BOOT, boot_count_read());

-- 
To view, visit https://review.coreboot.org/29541
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I62792c0f5063c89ad11b512f1777c7ab8a2c13e5
Gerrit-Change-Number: 29541
Gerrit-PatchSet: 1
Gerrit-Owner: Karthik Ramasubramanian <kramasub at google.com>
Gerrit-Reviewer: Karthikeyan Ramasubramanian <kramasub at chromium.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20181108/c7f759eb/attachment-0001.html>


More information about the coreboot-gerrit mailing list