[coreboot-gerrit] New patch to review for coreboot: 249dda0 cbmem utility: compatibility with older coreboot versions

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Fri Apr 19 23:49:07 CEST 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/3117


commit 249dda0e71c19b25487451a1bfba0af4a85163ae
Author: Stefan Reinauer <reinauer at chromium.org>
Date:   Fri Apr 19 14:22:29 2013 -0700

    cbmem utility: compatibility with older coreboot versions
    Commit b8ad224 changed the memory address in lb_cbmem_ref coreboot
    table entries from a pointer to a uint64_t. This change was introduced
    to make the cbmem utility work on both 32bit and 64bit userland.
    Unfortunately, this broke the cbmem utility running on older versions
    of coreboot because they were still providing a 32bit only field for
    the address while the cbmem utility would now take the following 4
    bytes as upper 32bits of a pointer that can obviously not be
    mmapped. This change checks if the size of the lb_cbmem_ref structure
    provided by coreboot is smaller than expected, and if so, ignore the
    upper 32bit of the address read. Also make the memory mapping more
    robust by using O_SYNC and O_DIRECT when opening /dev/mem and fix a
    potential type conflict in a debug message.
    Change-Id: I9dff766a89663322b1854b425ca5fd32e9e502d7
 util/cbmem/cbmem.c | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/util/cbmem/cbmem.c b/util/cbmem/cbmem.c
index 1ff9a08..7e22b18 100644
--- a/util/cbmem/cbmem.c
+++ b/util/cbmem/cbmem.c
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <inttypes.h>
 #include <getopt.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -127,12 +128,31 @@ static struct lb_cbmem_ref timestamps;
 static struct lb_cbmem_ref console;
 static struct lb_memory_range cbmem;
+/* This is a work-around for a nasty problem introduced by initially having
+ * pointer sized entries in the lb_cbmem_ref structures. This caused problems
+ * on 64bit x86 systems because coreboot is 32bit on those systems.
+ * When the problem was found, it was corrected, but there are a lot of systems
+ * out there with a firmware that does not produce the right lb_cbmem_ref structure.
+ * Hence we try to autocorrect this issue here.
+ */
+static struct lb_cbmem_ref parse_cbmem_ref(struct lb_cbmem_ref *cbmem_ref)
+	struct lb_cbmem_ref ret;
+	ret = *cbmem_ref;
+	if (cbmem_ref->size < sizeof(*cbmem_ref))
+		ret.cbmem_addr = (uint32_t)ret.cbmem_addr;
+	return ret;
 static int parse_cbtable(u64 address)
 	int i, found = 0;
 	void *buf;
-	debug("Looking for coreboot table at %llx\n", address);
+	debug("Looking for coreboot table at %" PRIx64 "\n", address);
 	buf = map_memory(address);
 	/* look at every 16 bytes within 4K of the base */
@@ -183,12 +203,12 @@ static int parse_cbtable(u64 address)
 				debug("    Found timestamp table.\n");
-				timestamps = *(struct lb_cbmem_ref *) lbr_p;
+				timestamps = parse_cbmem_ref((struct lb_cbmem_ref *) lbr_p);
 				debug("    Found cbmem console.\n");
-				console = *(struct lb_cbmem_ref *) lbr_p;
+				console = parse_cbmem_ref((struct lb_cbmem_ref *) lbr_p);
 			case LB_TAG_FORWARD: {
@@ -603,7 +623,7 @@ int main(int argc, char** argv)
-	fd = open("/dev/mem", O_RDONLY, 0);
+	fd = open("/dev/mem", O_RDONLY | O_SYNC | O_DIRECT, 0);
 	if (fd < 0) {
 		fprintf(stderr, "Failed to gain memory access: %s\n",

More information about the coreboot-gerrit mailing list