<p>Philipp Deppenwiese <strong>merged</strong> this change.</p><p><a href="https://review.coreboot.org/18902">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  build bot (Jenkins): Verified
  Philipp Deppenwiese: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">util/intelvbttool: Rewrite tool<br><br>* Add Makefile dependency to source file<br>* Add argument support<br>* Add help support<br>* Print usage on wrong arguments<br>* Add support for parsing VBT binary file<br>* Add support for parsing PCI Option ROM<br>* Add support for writing VBT binary file<br>* Add support for patching PCI Option ROM<br>* Keep support for accessing legacy VGA area Option ROM<br>* Keep support for dumping VBT contents to stdout<br><br>Allows to extract VBT, analyse VBT and patch PCI Option ROMs as needed.<br><br>The required arguments have been changed:<br><br>./intelvbttool --<SOURCECMD> [filename] --<DESTCMD> [filename]<br><br>SOURCECMD set the VBT source. Supported:<br> inlegacy  : Legacy BIOS area at phys. memory 0xc0000<br> invbt     : Read raw Intel VBT file<br> inoprom   : Read VBT from Intel Option ROM file<br><br>DESTCMD set the VBT destination. Supported:<br> outdump   : Print VBT in human readable form<br> outvbt    : Write raw Intel VBT file<br> patchoprom: Patch existing Intel Option ROM<br><br>Any combination of SOURCECMD and DESTCMD is possible.<br><br>Change-Id: I8cbde042c7f5632f36648419becd23e248ba6f76<br>Signed-off-by: Patrick Rudolph <siro@das-labor.org><br>Reviewed-on: https://review.coreboot.org/18902<br>Tested-by: build bot (Jenkins) <no-reply@coreboot.org><br>Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com><br>---<br>M util/intelvbttool/Makefile<br>M util/intelvbttool/intelvbttool.c<br>2 files changed, 807 insertions(+), 113 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/util/intelvbttool/Makefile b/util/intelvbttool/Makefile</span><br><span>index 7d50d30..fb9aade 100644</span><br><span>--- a/util/intelvbttool/Makefile</span><br><span>+++ b/util/intelvbttool/Makefile</span><br><span>@@ -15,12 +15,13 @@</span><br><span> </span><br><span> PROGRAM = intelvbttool</span><br><span> CC ?= gcc</span><br><span style="color: hsl(0, 100%, 40%);">-CFLAGS ?= -O2</span><br><span style="color: hsl(120, 100%, 40%);">+CFLAGS ?= -O2 -g</span><br><span> CFLAGS += -Wall -Werror</span><br><span style="color: hsl(120, 100%, 40%);">+CFLAGS += -I../../src/commonlib/include</span><br><span> </span><br><span> all: $(PROGRAM)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-$(PROGRAM):</span><br><span style="color: hsl(120, 100%, 40%);">+$(PROGRAM): $(PROGRAM).c</span><br><span>     $(CC) $(CFLAGS) $(CPPFLAGS) $(PROGRAM).c -o $(PROGRAM)</span><br><span> </span><br><span> clean:</span><br><span>diff --git a/util/intelvbttool/intelvbttool.c b/util/intelvbttool/intelvbttool.c</span><br><span>index f0216dd..c8b973e 100644</span><br><span>--- a/util/intelvbttool/intelvbttool.c</span><br><span>+++ b/util/intelvbttool/intelvbttool.c</span><br><span>@@ -20,7 +20,10 @@</span><br><span> #include <sys/types.h></span><br><span> #include <sys/stat.h></span><br><span> #include <fcntl.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <getopt.h></span><br><span> #include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdarg.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <commonlib/helpers.h></span><br><span> </span><br><span> typedef uint8_t u8;</span><br><span> typedef uint16_t u16;</span><br><span>@@ -30,11 +33,28 @@</span><br><span> typedef struct {</span><br><span>      u16 signature;</span><br><span>       u8 size;</span><br><span style="color: hsl(0, 100%, 40%);">-        u8 reserved[21];</span><br><span style="color: hsl(120, 100%, 40%);">+      u8 entrypoint[4];</span><br><span style="color: hsl(120, 100%, 40%);">+     u8 checksum;</span><br><span style="color: hsl(120, 100%, 40%);">+  u8 reserved[16];</span><br><span>     u16 pcir_offset;</span><br><span>     u16 vbt_offset;</span><br><span> } __attribute__ ((packed)) optionrom_header_t;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+typedef struct {</span><br><span style="color: hsl(120, 100%, 40%);">+       u32 signature;</span><br><span style="color: hsl(120, 100%, 40%);">+        u16 vendor;</span><br><span style="color: hsl(120, 100%, 40%);">+   u16 device;</span><br><span style="color: hsl(120, 100%, 40%);">+   u16 reserved1;</span><br><span style="color: hsl(120, 100%, 40%);">+        u16 length;</span><br><span style="color: hsl(120, 100%, 40%);">+   u8  revision;</span><br><span style="color: hsl(120, 100%, 40%);">+ u8  classcode[3];</span><br><span style="color: hsl(120, 100%, 40%);">+     u16 imagelength;</span><br><span style="color: hsl(120, 100%, 40%);">+      u16 coderevision;</span><br><span style="color: hsl(120, 100%, 40%);">+     u8  codetype;</span><br><span style="color: hsl(120, 100%, 40%);">+ u8  indicator;</span><br><span style="color: hsl(120, 100%, 40%);">+        u16 reserved2;</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__((packed)) optionrom_pcir_t;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct vbt_header {</span><br><span>         u8 signature[20];</span><br><span>    u16 version;</span><br><span>@@ -221,6 +241,8 @@</span><br><span> } __attribute__ ((packed));</span><br><span> </span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static const size_t ignore_checksum = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #define BDB_GENERAL_FEATURES     1</span><br><span> #define BDB_GENERAL_DEFINITIONS    2</span><br><span> </span><br><span>@@ -233,143 +255,370 @@</span><br><span> </span><br><span> #define BDB_SKIP               254</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void parse_vbt(const void *vbt)</span><br><span style="color: hsl(120, 100%, 40%);">+/* print helpers */</span><br><span style="color: hsl(120, 100%, 40%);">+static void print(const char *format, ...)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     const struct vbt_header *head = vbt;</span><br><span style="color: hsl(120, 100%, 40%);">+  va_list args;</span><br><span style="color: hsl(120, 100%, 40%);">+ fprintf(stdout, "VBTTOOL: ");</span><br><span style="color: hsl(120, 100%, 40%);">+       va_start(args, format);</span><br><span style="color: hsl(120, 100%, 40%);">+       vfprintf(stdout, format, args);</span><br><span style="color: hsl(120, 100%, 40%);">+       va_end(args);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void printt(const char *format, ...)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    va_list args;</span><br><span style="color: hsl(120, 100%, 40%);">+ fprintf(stdout, "\t");</span><br><span style="color: hsl(120, 100%, 40%);">+      va_start(args, format);</span><br><span style="color: hsl(120, 100%, 40%);">+       vfprintf(stdout, format, args);</span><br><span style="color: hsl(120, 100%, 40%);">+       va_end(args);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void printwarn(const char *format, ...)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ va_list args;</span><br><span style="color: hsl(120, 100%, 40%);">+ fprintf(stderr, "VBTTOOL: WARN: ");</span><br><span style="color: hsl(120, 100%, 40%);">+ va_start(args, format);</span><br><span style="color: hsl(120, 100%, 40%);">+       vfprintf(stderr, format, args);</span><br><span style="color: hsl(120, 100%, 40%);">+       va_end(args);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void printerr(const char *format, ...)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  va_list args;</span><br><span style="color: hsl(120, 100%, 40%);">+ fprintf(stderr, "VBTTOOL: ERR: ");</span><br><span style="color: hsl(120, 100%, 40%);">+  va_start(args, format);</span><br><span style="color: hsl(120, 100%, 40%);">+       vfprintf(stderr, format, args);</span><br><span style="color: hsl(120, 100%, 40%);">+       va_end(args);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct fileobject {</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned char *data;</span><br><span style="color: hsl(120, 100%, 40%);">+  size_t size;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* file object helpers */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Alloc a file object of given size.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns NULL on error.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct fileobject *malloc_fo(const size_t size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct fileobject *fo;</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!size)</span><br><span style="color: hsl(120, 100%, 40%);">+            return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        fo = malloc(sizeof(*fo));</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!fo)</span><br><span style="color: hsl(120, 100%, 40%);">+              return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  fo->data = malloc(size);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!fo->data) {</span><br><span style="color: hsl(120, 100%, 40%);">+           free(fo);</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     fo->size = size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return fo;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Free a fileobject structure */</span><br><span style="color: hsl(120, 100%, 40%);">+static void free_fo(struct fileobject *fo)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     if (fo) {</span><br><span style="color: hsl(120, 100%, 40%);">+             free(fo->data);</span><br><span style="color: hsl(120, 100%, 40%);">+            free(fo);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Resize file object and keep memory content */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct fileobject *remalloc_fo(struct fileobject *old,</span><br><span style="color: hsl(120, 100%, 40%);">+                                     const size_t size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct fileobject *fo = old;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!old || !size)</span><br><span style="color: hsl(120, 100%, 40%);">+            return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        fo->data = realloc(fo->data, size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!fo->data)</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        fo->size = size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return fo;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Creates a new subregion copy of fileobject.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns NULL if offset is greater than fileobject size.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns NULL on error.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct fileobject *malloc_fo_sub(const struct fileobject *old,</span><br><span style="color: hsl(120, 100%, 40%);">+                                        const size_t off)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct fileobject *fo;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!old || off > old->size)</span><br><span style="color: hsl(120, 100%, 40%);">+            return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        fo = malloc_fo(old->size - off);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!fo)</span><br><span style="color: hsl(120, 100%, 40%);">+              return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        memcpy(fo->data, old->data + off, fo->size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return fo;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* file helpers */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Create fileobject from file */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct fileobject *read_file(const char *filename)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        FILE *fd = fopen(filename, "rb");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!fd) {</span><br><span style="color: hsl(120, 100%, 40%);">+            printerr("%s open failed: %s\n", filename, strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (fseek(fd, 0, SEEK_END)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         printerr("%s seek failed: %s\n", filename, strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                fclose(fd);</span><br><span style="color: hsl(120, 100%, 40%);">+           return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   const off_t size = ftell(fd);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (size < 0 || size > SIZE_MAX) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printerr("%s tell failed: %s\n", filename, strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                fclose(fd);</span><br><span style="color: hsl(120, 100%, 40%);">+           return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (fseek(fd, 0, SEEK_SET)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         printerr("%s seek failed: %s\n", filename, strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                fclose(fd);</span><br><span style="color: hsl(120, 100%, 40%);">+           return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   struct fileobject *fo = malloc_fo(size);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!fo) {</span><br><span style="color: hsl(120, 100%, 40%);">+            printerr("malloc failed\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                fclose(fd);</span><br><span style="color: hsl(120, 100%, 40%);">+           return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (fread(fo->data, 1, size, fd) != size) {</span><br><span style="color: hsl(120, 100%, 40%);">+                fclose(fd);</span><br><span style="color: hsl(120, 100%, 40%);">+           free_fo(fo);</span><br><span style="color: hsl(120, 100%, 40%);">+          return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (fclose(fd)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             printerr("%s close failed: %s\n", filename, strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+               free_fo(fo);</span><br><span style="color: hsl(120, 100%, 40%);">+          return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   fo->size = size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return fo;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Create fileobject from physical memory at given address of size 64 KiB */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct fileobject *read_physmem(size_t addr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const int fd = open("/dev/mem", O_RDONLY);</span><br><span style="color: hsl(120, 100%, 40%);">+  const size_t size = 64 * 2 * KiB;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (fd < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printerr("/dev/mem open failed: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+            return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   const void *data = mmap(0, size, PROT_READ, MAP_SHARED, fd, addr);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (data == MAP_FAILED) {</span><br><span style="color: hsl(120, 100%, 40%);">+             close(fd);</span><br><span style="color: hsl(120, 100%, 40%);">+            printerr("mmap failed: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   struct fileobject *fo = malloc_fo(size);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!fo) {</span><br><span style="color: hsl(120, 100%, 40%);">+            printerr("malloc failed\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                munmap((void *)data, size);</span><br><span style="color: hsl(120, 100%, 40%);">+           close(fd);</span><br><span style="color: hsl(120, 100%, 40%);">+            return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   memcpy(fo->data, data, size);</span><br><span style="color: hsl(120, 100%, 40%);">+      munmap((void *)data, size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (close(fd)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printerr("/dev/mem close failed: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+           free_fo(fo);</span><br><span style="color: hsl(120, 100%, 40%);">+          return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return fo;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Write fileobject contents to file */</span><br><span style="color: hsl(120, 100%, 40%);">+static int write_file(const char *filename, const struct fileobject *fo)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ FILE *fd_out = fopen(filename, "wb");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!fd_out) {</span><br><span style="color: hsl(120, 100%, 40%);">+                printerr("%s open failed: %s\n", filename, strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (fwrite(fo->data, 1, fo->size, fd_out) != fo->size) {</span><br><span style="color: hsl(120, 100%, 40%);">+             fclose(fd_out);</span><br><span style="color: hsl(120, 100%, 40%);">+               return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     return fclose(fd_out);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* dump VBT contents in human readable form */</span><br><span style="color: hsl(120, 100%, 40%);">+static void dump_vbt(const struct fileobject *fo)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     if (fo->size < sizeof(struct vbt_header))</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     const struct vbt_header *head = (const struct vbt_header *)fo->data;</span><br><span>      const struct bdb_header *bdb;</span><br><span style="color: hsl(0, 100%, 40%);">-   int i;</span><br><span>       const u8 *ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+        int i;</span><br><span>       int is_first_skip = 1;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      if (memcmp(head->signature, "$VBT", 4) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-             fprintf(stderr, "invalid VBT signature\n");</span><br><span style="color: hsl(0, 100%, 40%);">-           exit(1);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-       printf("signature: <%20.20s>\n", head->signature);</span><br><span style="color: hsl(0, 100%, 40%);">-   printf("version: %d.%02d\n", head->version / 100,</span><br><span style="color: hsl(120, 100%, 40%);">+        printt("signature: <%20.20s>\n", head->signature);</span><br><span style="color: hsl(120, 100%, 40%);">+ printt("version: %d.%02d\n", head->version / 100,</span><br><span>              head->version % 100);</span><br><span>      if (head->header_size != sizeof(struct vbt_header))</span><br><span style="color: hsl(0, 100%, 40%);">-          printf("header size: 0x%x\n", head->header_size);</span><br><span style="color: hsl(0, 100%, 40%);">-  printf("VBT size: 0x%x\n", head->vbt_size);</span><br><span style="color: hsl(0, 100%, 40%);">-        printf("VBT checksum: 0x%x\n", head->vbt_checksum);</span><br><span style="color: hsl(120, 100%, 40%);">+              printt("header size: 0x%x\n", head->header_size);</span><br><span style="color: hsl(120, 100%, 40%);">+        printt("VBT size: 0x%x\n", head->vbt_size);</span><br><span style="color: hsl(120, 100%, 40%);">+      printt("VBT checksum: 0x%x\n", head->vbt_checksum);</span><br><span>     if (head->reserved0)</span><br><span style="color: hsl(0, 100%, 40%);">-         printf("header reserved0: 0x%x\n", head->reserved0);</span><br><span style="color: hsl(120, 100%, 40%);">+             printt("header reserved0: 0x%x\n", head->reserved0);</span><br><span>    if (head->bdb_offset != sizeof(struct vbt_header))</span><br><span style="color: hsl(0, 100%, 40%);">-           printf("BDB offset: 0x%x\n", head->bdb_offset);</span><br><span style="color: hsl(120, 100%, 40%);">+          printt("BDB offset: 0x%x\n", head->bdb_offset);</span><br><span> </span><br><span>     for (i = 0; i < 4; i++)</span><br><span>           if (head->aim_offset[i])</span><br><span style="color: hsl(0, 100%, 40%);">-                     printf("AIM[%d] offset: 0x%x\n", i,</span><br><span style="color: hsl(120, 100%, 40%);">+                 printt("AIM[%d] offset: 0x%x\n", i,</span><br><span>                               head->aim_offset[i]);</span><br><span style="color: hsl(0, 100%, 40%);">- bdb = (const void *) ((const char *) vbt + head->bdb_offset);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (head->bdb_offset + sizeof(*bdb) > fo->size)</span><br><span style="color: hsl(120, 100%, 40%);">+              return;</span><br><span style="color: hsl(120, 100%, 40%);">+       bdb = (const void *) (fo->data + head->bdb_offset);</span><br><span> </span><br><span>        if (memcmp("BIOS_DATA_BLOCK ", bdb->signature, 16) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-         fprintf(stderr, "invalid BDB signature:%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+               printerr("invalid BDB signature:%s\n",</span><br><span>                     bdb->signature);</span><br><span>          exit(1);</span><br><span>     }</span><br><span style="color: hsl(0, 100%, 40%);">-       printf("BDB version: %d.%02d\n", bdb->version / 100,</span><br><span style="color: hsl(120, 100%, 40%);">+     printt("BDB version: %d.%02d\n", bdb->version / 100,</span><br><span>           bdb->version % 100);</span><br><span>       if (bdb->header_size != sizeof(struct bdb_header))</span><br><span style="color: hsl(0, 100%, 40%);">-           printf("BDB header size: 0x%x\n", bdb->header_size);</span><br><span style="color: hsl(120, 100%, 40%);">+             printt("BDB header size: 0x%x\n", bdb->header_size);</span><br><span>    if (bdb->bdb_size != head->vbt_size - head->bdb_offset)</span><br><span style="color: hsl(0, 100%, 40%);">-                printf("BDB size: 0x%x\n", bdb->bdb_size);</span><br><span style="color: hsl(120, 100%, 40%);">+               printt("BDB size: 0x%x\n", bdb->bdb_size);</span><br><span>      for (ptr = (const u8 *) bdb + bdb->header_size;</span><br><span>        ptr < (const u8 *) bdb + bdb->bdb_size;) {</span><br><span>                u16 secsz = (ptr[1] | (ptr[2] << 8));</span><br><span>          u8 sectype = ptr[0];</span><br><span>                 const u8 *section = ptr + 3;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                printf("section type %d, size 0x%x\n", sectype, secsz);</span><br><span style="color: hsl(120, 100%, 40%);">+             printt("section type %d, size 0x%x\n", sectype, secsz);</span><br><span>            ptr += secsz + 3;</span><br><span>            switch (sectype) {</span><br><span>           case BDB_GENERAL_FEATURES:{</span><br><span>                          const struct bdb_general_features *sec =</span><br><span>                                 (const void *) section;</span><br><span style="color: hsl(0, 100%, 40%);">-                             printf("General features:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                              printt("General features:\n");</span><br><span> </span><br><span>                                 if (sec->panel_fitting)</span><br><span style="color: hsl(0, 100%, 40%);">-                                      printf("\tpanel_fitting = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                  printt("\tpanel_fitting = 0x%x\n",</span><br><span>                                                sec->panel_fitting);</span><br><span>                               if (sec->flexaim)</span><br><span style="color: hsl(0, 100%, 40%);">-                                    printf("\tflexaim = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                        printt("\tflexaim = 0x%x\n",</span><br><span>                                              sec->flexaim);</span><br><span>                             if (sec->msg_enable)</span><br><span style="color: hsl(0, 100%, 40%);">-                                 printf("\tmsg_enable = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                     printt("\tmsg_enable = 0x%x\n",</span><br><span>                                           sec->msg_enable);</span><br><span>                          if (sec->clear_screen)</span><br><span style="color: hsl(0, 100%, 40%);">-                                       printf("\tclear_screen = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                   printt("\tclear_screen = 0x%x\n",</span><br><span>                                         sec->clear_screen);</span><br><span>                                if (sec->color_flip)</span><br><span style="color: hsl(0, 100%, 40%);">-                                 printf("\tcolor_flip = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                     printt("\tcolor_flip = 0x%x\n",</span><br><span>                                           sec->color_flip);</span><br><span>                          if (sec->download_ext_vbt)</span><br><span style="color: hsl(0, 100%, 40%);">-                                   printf</span><br><span style="color: hsl(120, 100%, 40%);">+                                        printt</span><br><span>                                           ("\tdownload_ext_vbt = 0x%x\n",</span><br><span>                                             sec->download_ext_vbt);</span><br><span style="color: hsl(0, 100%, 40%);">-                         printf("\t*enable_ssc = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                            printt("\t*enable_ssc = 0x%x\n",</span><br><span>                                  sec->enable_ssc);</span><br><span style="color: hsl(0, 100%, 40%);">-                             printf("\t*ssc_freq = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                              printt("\t*ssc_freq = 0x%x\n",</span><br><span>                                    sec->ssc_freq);</span><br><span>                            if (sec->enable_lfp_on_override)</span><br><span style="color: hsl(0, 100%, 40%);">-                                     printf</span><br><span style="color: hsl(120, 100%, 40%);">+                                        printt</span><br><span>                                           ("\tenable_lfp_on_override = 0x%x\n",</span><br><span>                                       sec->enable_lfp_on_override);</span><br><span>                                if (sec->disable_ssc_ddt)</span><br><span style="color: hsl(0, 100%, 40%);">-                                    printf</span><br><span style="color: hsl(120, 100%, 40%);">+                                        printt</span><br><span>                                           ("\tdisable_ssc_ddt = 0x%x\n",</span><br><span>                                              sec->disable_ssc_ddt);</span><br><span>                               if (sec->rsvd7)</span><br><span style="color: hsl(0, 100%, 40%);">-                                      printf("\trsvd7 = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                  printt("\trsvd7 = 0x%x\n",</span><br><span>                                                sec->rsvd7);</span><br><span style="color: hsl(0, 100%, 40%);">-                          printf("\t*display_clock_mode = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                            printt("\t*display_clock_mode = 0x%x\n",</span><br><span>                                  sec->display_clock_mode);</span><br><span>                          if (sec->rsvd8)</span><br><span style="color: hsl(0, 100%, 40%);">-                                      printf("\trsvd8 = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                  printt("\trsvd8 = 0x%x\n",</span><br><span>                                                sec->rsvd8);</span><br><span style="color: hsl(0, 100%, 40%);">-                          printf("\tdisable_smooth_vision = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                          printt("\tdisable_smooth_vision = 0x%x\n",</span><br><span>                                        sec->disable_smooth_vision);</span><br><span>                               if (sec->single_dvi)</span><br><span style="color: hsl(0, 100%, 40%);">-                                 printf("\tsingle_dvi = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                     printt("\tsingle_dvi = 0x%x\n",</span><br><span>                                           sec->single_dvi);</span><br><span>                          if (sec->rsvd9)</span><br><span style="color: hsl(0, 100%, 40%);">-                                      printf("\trsvd9 = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                  printt("\trsvd9 = 0x%x\n",</span><br><span>                                                sec->rsvd9);</span><br><span style="color: hsl(0, 100%, 40%);">-                          printf</span><br><span style="color: hsl(120, 100%, 40%);">+                                printt</span><br><span>                                   ("\t*fdi_rx_polarity_inverted = 0x%x\n",</span><br><span>                                    sec->fdi_rx_polarity_inverted);</span><br><span>                              if (sec->rsvd10)</span><br><span style="color: hsl(0, 100%, 40%);">-                                     printf("\trsvd10 = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                 printt("\trsvd10 = 0x%x\n",</span><br><span>                                               sec->rsvd10);</span><br><span>                              if (sec->legacy_monitor_detect)</span><br><span style="color: hsl(0, 100%, 40%);">-                                      printf</span><br><span style="color: hsl(120, 100%, 40%);">+                                        printt</span><br><span>                                           ("\tlegacy_monitor_detect = 0x%x\n",</span><br><span>                                        sec->legacy_monitor_detect);</span><br><span style="color: hsl(0, 100%, 40%);">-                            printf("\t*int_crt_support = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                               printt("\t*int_crt_support = 0x%x\n",</span><br><span>                                     sec->int_crt_support);</span><br><span style="color: hsl(0, 100%, 40%);">-                                printf("\t*int_tv_support = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                printt("\t*int_tv_support = 0x%x\n",</span><br><span>                                      sec->int_tv_support);</span><br><span>                              if (sec->int_efp_support)</span><br><span style="color: hsl(0, 100%, 40%);">-                                    printf</span><br><span style="color: hsl(120, 100%, 40%);">+                                        printt</span><br><span>                                           ("\tint_efp_support = 0x%x\n",</span><br><span>                                              sec->int_efp_support);</span><br><span>                               if (sec->dp_ssc_enb)</span><br><span style="color: hsl(0, 100%, 40%);">-                                 printf("\tdp_ssc_enb = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                     printt("\tdp_ssc_enb = 0x%x\n",</span><br><span>                                           sec->dp_ssc_enb);</span><br><span>                          if (sec->dp_ssc_freq)</span><br><span style="color: hsl(0, 100%, 40%);">-                                        printf("\tdp_ssc_freq = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                    printt("\tdp_ssc_freq = 0x%x\n",</span><br><span>                                          sec->dp_ssc_freq);</span><br><span>                                 if (sec->rsvd11)</span><br><span style="color: hsl(0, 100%, 40%);">-                                     printf("\trsvd11 = 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                 printt("\trsvd11 = 0x%x\n",</span><br><span>                                               sec->rsvd11);</span><br><span>                              break;</span><br><span>                       }</span><br><span>            case BDB_DRIVER_FEATURES:{</span><br><span>                           const struct bdb_driver_features *sec =</span><br><span>                                  (const void *) section;</span><br><span style="color: hsl(0, 100%, 40%);">-                             printf("\t*LVDS config: %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                              printt("\t*LVDS config: %d\n",</span><br><span>                                    sec->lvds_config);</span><br><span style="color: hsl(0, 100%, 40%);">-                            printf("\t*Dual frequency: %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                           printt("\t*Dual frequency: %d\n",</span><br><span>                                 sec->dual_frequency);</span><br><span> </span><br><span>                          break;</span><br><span>@@ -377,7 +626,7 @@</span><br><span>                 case BDB_SDVO_LVDS_OPTIONS:{</span><br><span>                                 const struct bdb_sdvo_lvds_options *sec =</span><br><span>                                (const void *) section;</span><br><span style="color: hsl(0, 100%, 40%);">-                             printf("\t*Panel type: %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                               printt("\t*Panel type: %d\n",</span><br><span>                                     sec->panel_type);</span><br><span> </span><br><span>                              break;</span><br><span>@@ -386,29 +635,29 @@</span><br><span>                               const struct bdb_general_definitions *sec =</span><br><span>                              (const void *) section;</span><br><span>                          int ndev;</span><br><span style="color: hsl(0, 100%, 40%);">-                               printf("\t*CRT DDC GMBUS pin: %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                printt("\t*CRT DDC GMBUS pin: %d\n",</span><br><span>                                      sec->crt_ddc_gmbus_pin);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                          printf("\tDPMS ACPI: %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                         printt("\tDPMS ACPI: %d\n",</span><br><span>                                       sec->dpms_acpi);</span><br><span style="color: hsl(0, 100%, 40%);">-                              printf("\tSkip boot CRT detect: %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                              printt("\tSkip boot CRT detect: %d\n",</span><br><span>                                    sec->skip_boot_crt_detect);</span><br><span style="color: hsl(0, 100%, 40%);">-                           printf("\tDPMS aim: %d\n", sec->dpms_aim);</span><br><span style="color: hsl(120, 100%, 40%);">+                               printt("\tDPMS aim: %d\n", sec->dpms_aim);</span><br><span>                              if (sec->rsvd1)</span><br><span style="color: hsl(0, 100%, 40%);">-                                      printf("\trsvd1: 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                   printt("\trsvd1: 0x%x\n",</span><br><span>                                         sec->rsvd1);</span><br><span style="color: hsl(0, 100%, 40%);">-                          printf("\tboot_display: { %x, %x }\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                              printt("\tboot_display: { %x, %x }\n",</span><br><span>                                    sec->boot_display[0],</span><br><span>                                     sec->boot_display[1]);</span><br><span>                             if (sec->child_dev_size !=</span><br><span>                                    sizeof(struct common_child_dev_config))</span><br><span style="color: hsl(0, 100%, 40%);">-                                     printf("\tchild_dev_size: %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                    printt("\tchild_dev_size: %d\n",</span><br><span>                                          sec->child_dev_size);</span><br><span>                              ndev = (secsz - sizeof(*sec)) /</span><br><span>                                      sizeof(struct common_child_dev_config);</span><br><span style="color: hsl(0, 100%, 40%);">-                         printf("\t%d devices\n", ndev);</span><br><span style="color: hsl(120, 100%, 40%);">+                             printt("\t%d devices\n", ndev);</span><br><span>                            for (i = 0; i < ndev; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                 printf("\t*device type: %x ",</span><br><span style="color: hsl(120, 100%, 40%);">+                                       printt("\t*device type: %x ",</span><br><span>                                             sec->devices[i].</span><br><span>                                          device_type);</span><br><span> #define  DEVICE_TYPE_INT_LFP    0x1022</span><br><span>@@ -416,35 +665,35 @@</span><br><span> #define DEVICE_TYPE_EFP_DVI_HOTPLUG_PWR       0x6052</span><br><span>                                       switch (sec->devices[i].device_type) {</span><br><span>                                    case DEVICE_TYPE_INT_LFP:</span><br><span style="color: hsl(0, 100%, 40%);">-                                               printf("(flat panel)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                                           printt("(flat panel)\n");</span><br><span>                                          break;</span><br><span>                                       case DEVICE_TYPE_INT_TV:</span><br><span style="color: hsl(0, 100%, 40%);">-                                                printf("(TV)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                                           printt("(TV)\n");</span><br><span>                                          break;</span><br><span>                                       case DEVICE_TYPE_EFP_DVI_HOTPLUG_PWR:</span><br><span style="color: hsl(0, 100%, 40%);">-                                           printf</span><br><span style="color: hsl(120, 100%, 40%);">+                                                printt</span><br><span>                                                   ("(DVI)\n");</span><br><span>                                           break;</span><br><span>                                       case 0:</span><br><span style="color: hsl(0, 100%, 40%);">-                                         printf("(Empty)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                                                printt("(Empty)\n");</span><br><span>                                               break;</span><br><span>                                       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                                                printf("(Unknown)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                                              printt("(Unknown)\n");</span><br><span>                                             break;</span><br><span>                                       }</span><br><span>                                    if (!sec->devices[i].device_type)</span><br><span>                                                 continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                                       printf("\t *dvo_port: %x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                        printt("\t *dvo_port: %x\n",</span><br><span>                                              sec->devices[i].dvo_port);</span><br><span style="color: hsl(0, 100%, 40%);">-                                    printf("\t *i2c_pin: %x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                 printt("\t *i2c_pin: %x\n",</span><br><span>                                               sec->devices[i].i2c_pin);</span><br><span style="color: hsl(0, 100%, 40%);">-                                     printf("\t *slave_addr: %x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                      printt("\t *slave_addr: %x\n",</span><br><span>                                            sec->devices[i].slave_addr);</span><br><span style="color: hsl(0, 100%, 40%);">-                                  printf("\t *ddc_pin: %x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                 printt("\t *ddc_pin: %x\n",</span><br><span>                                               sec->devices[i].ddc_pin);</span><br><span style="color: hsl(0, 100%, 40%);">-                                     printf("\t *dvo_wiring: %x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                      printt("\t *dvo_wiring: %x\n",</span><br><span>                                            sec->devices[i].dvo_wiring);</span><br><span style="color: hsl(0, 100%, 40%);">-                                  printf("\t edid_ptr: %x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                 printt("\t edid_ptr: %x\n",</span><br><span>                                               sec->devices[i].edid_ptr);</span><br><span>                                 }</span><br><span> </span><br><span>@@ -456,84 +705,528 @@</span><br><span>                               if (!is_first_skip)</span><br><span>                                  break;</span><br><span>                               is_first_skip = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                              printf("\ttype: %x\n", sec->type);</span><br><span style="color: hsl(0, 100%, 40%);">-                         printf("\trelstage: %x\n", sec->relstage);</span><br><span style="color: hsl(0, 100%, 40%);">-                         printf("\tchipset: %x\n", sec->chipset);</span><br><span style="color: hsl(0, 100%, 40%);">-                           printf(sec->lvds_present ? "\tLVDS\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                            printt("\ttype: %x\n", sec->type);</span><br><span style="color: hsl(120, 100%, 40%);">+                               printt("\trelstage: %x\n", sec->relstage);</span><br><span style="color: hsl(120, 100%, 40%);">+                               printt("\tchipset: %x\n", sec->chipset);</span><br><span style="color: hsl(120, 100%, 40%);">+                         printt(sec->lvds_present ? "\tLVDS\n"</span><br><span>                                  : "\tNo LVDS\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                              printf(sec->tv_present ? "\tTV\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                                printt(sec->tv_present ? "\tTV\n"</span><br><span>                                      : "\tNo TV\n");</span><br><span>                             if (sec->rsvd2)</span><br><span style="color: hsl(0, 100%, 40%);">-                                      printf("\trsvd2: 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                   printt("\trsvd2: 0x%x\n",</span><br><span>                                         sec->rsvd2);</span><br><span>                               for (i = 0; i < 4; i++)</span><br><span>                                   if (sec->rsvd3[i])</span><br><span style="color: hsl(0, 100%, 40%);">-                                           printf</span><br><span style="color: hsl(120, 100%, 40%);">+                                                printt</span><br><span>                                                   ("\trsvd3[%d]: 0x%x\n",</span><br><span>                                                     i, sec->rsvd3[i]);</span><br><span style="color: hsl(0, 100%, 40%);">-                              printf("\tSignon: %.155s\n", sec->signon);</span><br><span style="color: hsl(0, 100%, 40%);">-                         printf("\tCopyright: %.155s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                             printt("\tSignon: %.155s\n", sec->signon);</span><br><span style="color: hsl(120, 100%, 40%);">+                               printt("\tCopyright: %.155s\n",</span><br><span>                                   sec->copyright);</span><br><span style="color: hsl(0, 100%, 40%);">-                              printf("\tCode segment: %x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                              printt("\tCode segment: %x\n",</span><br><span>                                    sec->code_segment);</span><br><span style="color: hsl(0, 100%, 40%);">-                           printf("\tDOS Boot mode: %x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                             printt("\tDOS Boot mode: %x\n",</span><br><span>                                   sec->dos_boot_mode);</span><br><span style="color: hsl(0, 100%, 40%);">-                          printf("\tBandwidth percent: %x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                         printt("\tBandwidth percent: %x\n",</span><br><span>                                       sec->bandwidth_percent);</span><br><span>                           if (sec->rsvd4)</span><br><span style="color: hsl(0, 100%, 40%);">-                                      printf("\trsvd4: 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                   printt("\trsvd4: 0x%x\n",</span><br><span>                                         sec->rsvd4);</span><br><span style="color: hsl(0, 100%, 40%);">-                          printf("\tBandwidth percent: %x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                         printt("\tBandwidth percent: %x\n",</span><br><span>                                       sec->resize_pci_bios);</span><br><span>                             if (sec->rsvd5)</span><br><span style="color: hsl(0, 100%, 40%);">-                                      printf("\trsvd5: 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                   printt("\trsvd5: 0x%x\n",</span><br><span>                                         sec->rsvd5);</span><br><span>                               break;</span><br><span>                       }</span><br><span>            }</span><br><span>    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void parse_vbios(const void *ptr)</span><br><span style="color: hsl(120, 100%, 40%);">+/* Returns a new fileobject containing a valid VBT */</span><br><span style="color: hsl(120, 100%, 40%);">+static void parse_vbt(const struct fileobject *fo,</span><br><span style="color: hsl(120, 100%, 40%);">+               struct fileobject **vbt)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     const optionrom_header_t *oh;</span><br><span style="color: hsl(0, 100%, 40%);">-   oh = ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+     *vbt = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (fo->size < sizeof(struct vbt_header)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             printerr("image is to small\n");</span><br><span style="color: hsl(120, 100%, 40%);">+            return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   const struct vbt_header *head =</span><br><span style="color: hsl(120, 100%, 40%);">+           (const struct vbt_header *)fo->data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (memcmp(head->signature, "$VBT", 4) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printerr("invalid VBT signature\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!head->vbt_size || head->vbt_size > fo->size) {</span><br><span style="color: hsl(120, 100%, 40%);">+               printerr("invalid VBT size\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!head->bdb_offset ||</span><br><span style="color: hsl(120, 100%, 40%);">+       head->bdb_offset > fo->size - sizeof(struct bdb_header)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               printerr("invalid BDB offset\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!head->header_size || head->header_size > fo->size) {</span><br><span style="color: hsl(120, 100%, 40%);">+         printerr("invalid header size\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   const struct bdb_header *const bdb_head =</span><br><span style="color: hsl(120, 100%, 40%);">+         (const struct bdb_header *)((const u8 *)head + head->bdb_offset);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (memcmp(bdb_head->signature, "BIOS_DATA_BLOCK ", 16) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+          printerr("invalid BDB signature\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!bdb_head->header_size || bdb_head->header_size > fo->size) {</span><br><span style="color: hsl(120, 100%, 40%);">+         printerr("invalid BDB header size\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Duplicate fo as caller is owner and remalloc frees the object */</span><br><span style="color: hsl(120, 100%, 40%);">+   *vbt = remalloc_fo(malloc_fo_sub(fo, 0), head->vbt_size);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Option ROM checksum */</span><br><span style="color: hsl(120, 100%, 40%);">+static u8 checksum_vbios(const optionrom_header_t *oh)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       const u8 *ptr = (const u8 *)oh;</span><br><span style="color: hsl(120, 100%, 40%);">+       size_t i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   u8 cksum = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < ((MIN(oh->size, 128)) * 512); i++)</span><br><span style="color: hsl(120, 100%, 40%);">+              cksum += ptr[i];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return cksum;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Verify Option ROM contents */</span><br><span style="color: hsl(120, 100%, 40%);">+static int is_valid_vbios(const struct fileobject *fo)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       if (fo->size > 64 * 2 * KiB) {</span><br><span style="color: hsl(120, 100%, 40%);">+          printerr("VBIOS is to big\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (fo->size < sizeof(optionrom_header_t)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            printerr("VBIOS is to small\n");</span><br><span style="color: hsl(120, 100%, 40%);">+            return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   const optionrom_header_t *oh = (const optionrom_header_t *)fo->data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    if (oh->signature != 0xaa55) {</span><br><span style="color: hsl(0, 100%, 40%);">-               fprintf(stderr, "bad oprom signature: %x\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                  oh->signature);</span><br><span style="color: hsl(0, 100%, 40%);">-              return;</span><br><span style="color: hsl(120, 100%, 40%);">+               printerr("bad oprom signature: 0x%x\n", oh->signature);</span><br><span style="color: hsl(120, 100%, 40%);">+          return 0;</span><br><span>    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (oh->size == 0 || oh->size > 0x80 || oh->size * 512 > fo->size) {</span><br><span style="color: hsl(120, 100%, 40%);">+                printerr("bad oprom size: 0x%x\n", oh->size);</span><br><span style="color: hsl(120, 100%, 40%);">+            return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   const u8 cksum = checksum_vbios(oh);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (cksum) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (!ignore_checksum) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       printerr("bad oprom checksum: 0x%x\n", cksum);</span><br><span style="color: hsl(120, 100%, 40%);">+                      return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             printwarn("bad oprom checksum: 0x%x\n", cksum);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (oh->pcir_offset + sizeof(optionrom_pcir_t) > fo->size) {</span><br><span style="color: hsl(120, 100%, 40%);">+         printerr("bad pcir offset: 0x%x\n", oh->pcir_offset);</span><br><span style="color: hsl(120, 100%, 40%);">+            return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (oh->pcir_offset) {</span><br><span style="color: hsl(120, 100%, 40%);">+             const optionrom_pcir_t *pcir;</span><br><span style="color: hsl(120, 100%, 40%);">+         pcir = (const optionrom_pcir_t *)</span><br><span style="color: hsl(120, 100%, 40%);">+                 ((const u8 *)oh + oh->pcir_offset);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          if (pcir->signature != 0x52494350) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       printerr("Invalid PCIR signature\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                       return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (pcir->vendor != 0x8086) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      printerr("Not an Intel VBIOS\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (pcir->classcode[0] != 0 || pcir->classcode[1] != 0 ||</span><br><span style="color: hsl(120, 100%, 40%);">+                   pcir->classcode[2] != 3) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     printerr("Not a VGA Option Rom\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              printwarn("no PCIR header found\n");</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Parse Option ROM and return a valid VBT fileobject.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Caller has to make sure that it is a valid VBIOS.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Return a NULL fileobject on error.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void parse_vbios(const struct fileobject *fo,</span><br><span style="color: hsl(120, 100%, 40%);">+                    struct fileobject **vbt)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   const optionrom_header_t *oh = (const optionrom_header_t *)fo->data;</span><br><span style="color: hsl(120, 100%, 40%);">+       const struct vbt_header *head;</span><br><span style="color: hsl(120, 100%, 40%);">+        size_t i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   *vbt = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       if (!oh->vbt_offset) {</span><br><span style="color: hsl(0, 100%, 40%);">-               fprintf(stderr, "no VBT found\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          printerr("no VBT found\n");</span><br><span>                return;</span><br><span>      }</span><br><span style="color: hsl(0, 100%, 40%);">-       parse_vbt((const char *) ptr + oh->vbt_offset);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (oh->vbt_offset > (fo->size - sizeof(struct vbt_header))) {</span><br><span style="color: hsl(120, 100%, 40%);">+               printerr("invalid VBT offset\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   head = (const struct vbt_header *)fo->data;</span><br><span style="color: hsl(120, 100%, 40%);">+        if (memcmp(head->signature, "$VBT", 4) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           parse_vbt(fo, vbt);</span><br><span style="color: hsl(120, 100%, 40%);">+           if (*vbt)</span><br><span style="color: hsl(120, 100%, 40%);">+                     return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   printwarn("VBT wasn't found at specified offset\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  for (i = sizeof(optionrom_header_t);</span><br><span style="color: hsl(120, 100%, 40%);">+       i <= fo->size - sizeof(struct vbt_header); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          struct fileobject *fo_vbt = malloc_fo_sub(fo, i);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (!fo_vbt)</span><br><span style="color: hsl(120, 100%, 40%);">+                  continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           head = (const struct vbt_header *)fo_vbt->data;</span><br><span style="color: hsl(120, 100%, 40%);">+            if (memcmp(head->signature, "$VBT", 4) == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                     parse_vbt(fo_vbt, vbt);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             free_fo(fo_vbt);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            if (*vbt)</span><br><span style="color: hsl(120, 100%, 40%);">+                     return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Short VBT summary in human readable form */</span><br><span style="color: hsl(120, 100%, 40%);">+static void print_vbt(const struct fileobject *fo)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct bdb_header *bdb;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (fo->size < sizeof(struct vbt_header))</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     const struct vbt_header *head = (const struct vbt_header *)fo->data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     print("Found VBT:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+      printt("signature: <%20.20s>\n", head->signature);</span><br><span style="color: hsl(120, 100%, 40%);">+ printt("version: %d.%02d\n", head->version / 100, head->version % 100);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (head->header_size != sizeof(struct vbt_header))</span><br><span style="color: hsl(120, 100%, 40%);">+                printt("header size: 0x%x\n", head->header_size);</span><br><span style="color: hsl(120, 100%, 40%);">+        printt("VBT size: 0x%x\n", head->vbt_size);</span><br><span style="color: hsl(120, 100%, 40%);">+      printt("VBT checksum: 0x%x\n", head->vbt_checksum);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (head->bdb_offset > (fo->size - sizeof(struct bdb_header))) {</span><br><span style="color: hsl(120, 100%, 40%);">+             printerr("invalid BDB offset\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     bdb = (const struct bdb_header *)</span><br><span style="color: hsl(120, 100%, 40%);">+         ((const char *)head + head->bdb_offset);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (memcmp("BIOS_DATA_BLOCK ", bdb->signature, 16) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               printerr("invalid BDB signature:%s\n", bdb->signature);</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     printt("BDB version: %u.%02u\n", bdb->version / 100,</span><br><span style="color: hsl(120, 100%, 40%);">+            bdb->version % 100);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void print_usage(const char *argv0, struct option *long_options)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       size_t i = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("\nUsage:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("%s --<SOURCECMD> [filename] --<DESTCMD> [filename]\n\n", argv0);</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("SOURCECMD set the VBT source. Supported:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       printf(" %-10s: Legacy BIOS area at phys. memory 0xc0000\n",</span><br><span style="color: hsl(120, 100%, 40%);">+               "inlegacy");</span><br><span style="color: hsl(120, 100%, 40%);">+ printf(" %-10s: Read raw Intel VBT file\n", "invbt");</span><br><span style="color: hsl(120, 100%, 40%);">+     printf(" %-10s: Read VBT from Intel Option ROM file\n\n", "inoprom");</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("DESTCMD set the VBT destination. Supported:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+    printf(" %-10s: Print VBT in human readable form\n", "outdump");</span><br><span style="color: hsl(120, 100%, 40%);">+  printf(" %-10s: Write raw Intel VBT file\n", "outvbt");</span><br><span style="color: hsl(120, 100%, 40%);">+   printf(" %-10s: Patch existing Intel Option ROM\n\n", "patchoprom");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    printf("Supported arguments:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+   while (long_options[i].name) {</span><br><span style="color: hsl(120, 100%, 40%);">+                printf("\t-%c --%s %s\n", long_options[i].val,</span><br><span style="color: hsl(120, 100%, 40%);">+                     long_options[i].name, long_options[i].has_arg ?</span><br><span style="color: hsl(120, 100%, 40%);">+                       "<path>"  : "");</span><br><span style="color: hsl(120, 100%, 40%);">+             i++;</span><br><span style="color: hsl(120, 100%, 40%);">+  };</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Open a VBIOS file, calculate the checksum and fix it */</span><br><span style="color: hsl(120, 100%, 40%);">+static int fix_vbios_checksum(const char *filename)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct fileobject *fo = read_file(filename);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!fo) {</span><br><span style="color: hsl(120, 100%, 40%);">+            printerr("%s open failed\n", filename);</span><br><span style="color: hsl(120, 100%, 40%);">+             return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (fo->size < sizeof(optionrom_header_t))</span><br><span style="color: hsl(120, 100%, 40%);">+              return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   optionrom_header_t *oh = (optionrom_header_t *)fo->data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (oh->size * 512 > fo->size)</span><br><span style="color: hsl(120, 100%, 40%);">+               return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* fix checksum */</span><br><span style="color: hsl(120, 100%, 40%);">+    oh->checksum = -(checksum_vbios(oh) - oh->checksum);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (write_file(filename, fo)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               printerr("%s write failed\n", filename);</span><br><span style="color: hsl(120, 100%, 40%);">+            free_fo(fo);</span><br><span style="color: hsl(120, 100%, 40%);">+          return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     free_fo(fo);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Return the VBT structure size in bytes */</span><br><span style="color: hsl(120, 100%, 40%);">+static size_t vbt_size(const struct fileobject *fo)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!fo || fo->size < sizeof(struct vbt_header))</span><br><span style="color: hsl(120, 100%, 40%);">+                return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     const struct vbt_header *head = (const struct vbt_header *)fo->data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return head->vbt_size;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Patch an Intel Option ROM with new VBT.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Caller has to make sure that VBIOS and VBT are valid.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Return 1 on error.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static int patch_vbios(struct fileobject *fo,</span><br><span style="color: hsl(120, 100%, 40%);">+                  const struct fileobject *fo_vbt)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    optionrom_header_t *oh = (optionrom_header_t *)fo->data;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct vbt_header *head;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    struct fileobject *old_vbt = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+    parse_vbios(fo, &old_vbt);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (old_vbt) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (oh->vbt_offset + vbt_size(old_vbt) == fo->size) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   /* Located at the end of file - reduce file size */</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (fo->size < vbt_size(old_vbt))</span><br><span style="color: hsl(120, 100%, 40%);">+                               return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                     fo = remalloc_fo(fo, fo->size - vbt_size(old_vbt));</span><br><span style="color: hsl(120, 100%, 40%);">+                        if (!fo) {</span><br><span style="color: hsl(120, 100%, 40%);">+                            printerr("Failed to allocate memory\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                            return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+                     oh->vbt_offset = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                } else if (vbt_size(old_vbt) < vbt_size(fo_vbt)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 /* In the middle of the file - Remove old VBT */</span><br><span style="color: hsl(120, 100%, 40%);">+                      memset(fo->data + oh->vbt_offset, 0xff,</span><br><span style="color: hsl(120, 100%, 40%);">+                        vbt_size(old_vbt));</span><br><span style="color: hsl(120, 100%, 40%);">+                    oh->vbt_offset = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* New VBT overwrites existing one - Clear memory */</span><br><span style="color: hsl(120, 100%, 40%);">+                  memset(fo->data + oh->vbt_offset, 0xff,</span><br><span style="color: hsl(120, 100%, 40%);">+                        vbt_size(old_vbt));</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           free_fo(old_vbt);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!oh->vbt_offset) {</span><br><span style="color: hsl(120, 100%, 40%);">+             print("increasing VBIOS to append VBT\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          if ((fo->size + vbt_size(fo_vbt)) >= 64 * KiB) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        printerr("VBT won't fit\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                    return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           oh->vbt_offset = fo->size;</span><br><span style="color: hsl(120, 100%, 40%);">+              fo = remalloc_fo(fo, fo->size + vbt_size(fo_vbt));</span><br><span style="color: hsl(120, 100%, 40%);">+         if (!fo) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    printerr("Failed to allocate memory\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                    return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             oh->size = (fo->size + 512 - 1) / 512;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   head = (struct vbt_header *)((u8 *)oh + oh->vbt_offset);</span><br><span style="color: hsl(120, 100%, 40%);">+   memcpy(head, fo_vbt->data, vbt_size(fo_vbt));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return 0;</span><br><span> }</span><br><span> </span><br><span> int main(int argc, char **argv)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      const void *ptr;</span><br><span style="color: hsl(0, 100%, 40%);">-        int fd;</span><br><span style="color: hsl(0, 100%, 40%);">- off_t offset;</span><br><span style="color: hsl(0, 100%, 40%);">-   if (argc == 2) {</span><br><span style="color: hsl(0, 100%, 40%);">-                fd = open(argv[1], O_RDONLY);</span><br><span style="color: hsl(0, 100%, 40%);">-           offset = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-     } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                fd = open("/dev/mem", O_RDONLY);</span><br><span style="color: hsl(0, 100%, 40%);">-              offset = 0xc0000;</span><br><span style="color: hsl(120, 100%, 40%);">+     int opt, option_index = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  size_t has_input = 0, has_output = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t dump = 0, in_legacy = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       char *in_vbt = NULL, *in_oprom = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+        char *out_vbt = NULL, *patch_oprom = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+    static struct option long_options[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+               {"help", 0, 0, 'h'},</span><br><span style="color: hsl(120, 100%, 40%);">+                {"outdump", 0, 0, 'd'},</span><br><span style="color: hsl(120, 100%, 40%);">+             {"inlegacy", 0, 0, 'l'},</span><br><span style="color: hsl(120, 100%, 40%);">+            {"invbt", required_argument, 0, 'f'},</span><br><span style="color: hsl(120, 100%, 40%);">+               {"inoprom", required_argument, 0, 'o'},</span><br><span style="color: hsl(120, 100%, 40%);">+             {"outvbt", required_argument, 0, 'v'},</span><br><span style="color: hsl(120, 100%, 40%);">+              {"patchoprom", required_argument, 0, 'p'},</span><br><span style="color: hsl(120, 100%, 40%);">+          {0, 0, 0, 0}</span><br><span style="color: hsl(120, 100%, 40%);">+  };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  while ((opt = getopt_long(argc, argv, "hdlf:o:v:p:i",</span><br><span style="color: hsl(120, 100%, 40%);">+                  long_options, &option_index)) != EOF) {</span><br><span style="color: hsl(120, 100%, 40%);">+                switch (opt) {</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'd':</span><br><span style="color: hsl(120, 100%, 40%);">+                     dump = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                     has_output = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                       break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'l':</span><br><span style="color: hsl(120, 100%, 40%);">+                     in_legacy = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                        has_input = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                        break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'f':</span><br><span style="color: hsl(120, 100%, 40%);">+                     in_vbt = strdup(optarg);</span><br><span style="color: hsl(120, 100%, 40%);">+                      has_input = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                        break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'o':</span><br><span style="color: hsl(120, 100%, 40%);">+                     in_oprom = strdup(optarg);</span><br><span style="color: hsl(120, 100%, 40%);">+                    has_input = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                        break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'v':</span><br><span style="color: hsl(120, 100%, 40%);">+                     out_vbt = strdup(optarg);</span><br><span style="color: hsl(120, 100%, 40%);">+                     has_output = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                       break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'p':</span><br><span style="color: hsl(120, 100%, 40%);">+                     patch_oprom = strdup(optarg);</span><br><span style="color: hsl(120, 100%, 40%);">+                 has_output = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                       break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case '?':</span><br><span style="color: hsl(120, 100%, 40%);">+             case 'h':</span><br><span style="color: hsl(120, 100%, 40%);">+                     print_usage(argv[0], long_options);</span><br><span style="color: hsl(120, 100%, 40%);">+                   exit(0);</span><br><span style="color: hsl(120, 100%, 40%);">+                      break;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span>    }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (fd < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                fprintf(stderr, "open failed: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!has_input)</span><br><span style="color: hsl(120, 100%, 40%);">+               printerr("No input specified !\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!has_output)</span><br><span style="color: hsl(120, 100%, 40%);">+              printerr("No output specified !\n");</span><br><span style="color: hsl(120, 100%, 40%);">+        if (argc < 2 || argc > 6 || !has_input || !has_output) {</span><br><span style="color: hsl(120, 100%, 40%);">+                print_usage(argv[0], long_options);</span><br><span>          return 1;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ptr = mmap(0, 65536, PROT_READ, MAP_SHARED, fd, offset);</span><br><span style="color: hsl(0, 100%, 40%);">-        if (ptr == MAP_FAILED) {</span><br><span style="color: hsl(0, 100%, 40%);">-                fprintf(stderr, "mmap failed: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+      struct fileobject *fo;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (in_legacy)</span><br><span style="color: hsl(120, 100%, 40%);">+                fo = read_physmem(0xc0000);</span><br><span style="color: hsl(120, 100%, 40%);">+   else if (in_vbt)</span><br><span style="color: hsl(120, 100%, 40%);">+              fo = read_file(in_vbt);</span><br><span style="color: hsl(120, 100%, 40%);">+       else</span><br><span style="color: hsl(120, 100%, 40%);">+          fo = read_file(in_oprom);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!fo) {</span><br><span style="color: hsl(120, 100%, 40%);">+            printerr("Failed to read input file\n");</span><br><span>           return 1;</span><br><span>    }</span><br><span style="color: hsl(0, 100%, 40%);">-       parse_vbios(ptr);</span><br><span style="color: hsl(0, 100%, 40%);">-       close(fd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  struct fileobject *vbt = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+        if (in_legacy || in_oprom) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (!is_valid_vbios(fo)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    printerr("Invalid input file\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                 free_fo(fo);</span><br><span style="color: hsl(120, 100%, 40%);">+                  return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             parse_vbios(fo, &vbt);</span><br><span style="color: hsl(120, 100%, 40%);">+    } else</span><br><span style="color: hsl(120, 100%, 40%);">+                parse_vbt(fo, &vbt);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    free_fo(fo);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!vbt) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printerr("Failed to find VBT.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!dump)</span><br><span style="color: hsl(120, 100%, 40%);">+            print_vbt(vbt);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (dump) {</span><br><span style="color: hsl(120, 100%, 40%);">+           dump_vbt(vbt);</span><br><span style="color: hsl(120, 100%, 40%);">+        } else if (out_vbt) {</span><br><span style="color: hsl(120, 100%, 40%);">+         if (write_file(out_vbt, vbt))</span><br><span style="color: hsl(120, 100%, 40%);">+                 printerr("Failed to write VBT\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          else</span><br><span style="color: hsl(120, 100%, 40%);">+                  print("VBT written to %s\n", out_vbt);</span><br><span style="color: hsl(120, 100%, 40%);">+      } else if (patch_oprom) {</span><br><span style="color: hsl(120, 100%, 40%);">+             fo = read_file(patch_oprom);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (!fo) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    printerr("Failed to read input file\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                    return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (!is_valid_vbios(fo)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    printerr("Invalid input file\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                   free_fo(fo);</span><br><span style="color: hsl(120, 100%, 40%);">+                  return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (patch_vbios(fo, vbt)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   printerr("Failed to patch VBIOS\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                        free_fo(fo);</span><br><span style="color: hsl(120, 100%, 40%);">+                  return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (write_file(patch_oprom, fo)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    printerr("Failed to write VBIOS\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                        free_fo(fo);</span><br><span style="color: hsl(120, 100%, 40%);">+                  return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             free_fo(fo);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (fix_vbios_checksum(patch_oprom)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        printerr("Failed to fix checksum\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                       return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             print("VBIOS %s successfully patched\n", patch_oprom);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* cleanup */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (patch_oprom)</span><br><span style="color: hsl(120, 100%, 40%);">+              free(patch_oprom);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (out_vbt)</span><br><span style="color: hsl(120, 100%, 40%);">+          free(out_vbt);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (in_vbt)</span><br><span style="color: hsl(120, 100%, 40%);">+           free(in_vbt);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (in_oprom)</span><br><span style="color: hsl(120, 100%, 40%);">+         free(in_oprom);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     free_fo(vbt);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      return 0;</span><br><span> }</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/18902">change 18902</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/18902"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I8cbde042c7f5632f36648419becd23e248ba6f76 </div>
<div style="display:none"> Gerrit-Change-Number: 18902 </div>
<div style="display:none"> Gerrit-PatchSet: 17 </div>
<div style="display:none"> Gerrit-Owner: Patrick Rudolph <siro@das-labor.org> </div>
<div style="display:none"> Gerrit-Reviewer: Martin Roth <martinroth@google.com> </div>
<div style="display:none"> Gerrit-Reviewer: Nico Huber <nico.h@gmx.de> </div>
<div style="display:none"> Gerrit-Reviewer: Patrick Rudolph <patrick.rudolph@9elements.com> </div>
<div style="display:none"> Gerrit-Reviewer: Patrick Rudolph <siro@das-labor.org> </div>
<div style="display:none"> Gerrit-Reviewer: Paul Menzel <paulepanter@users.sourceforge.net> </div>
<div style="display:none"> Gerrit-Reviewer: Philipp Deppenwiese <zaolin.daisuki@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Samuel Holland <samuel@sholland.org> </div>
<div style="display:none"> Gerrit-Reviewer: Stefan Reinauer <stefan.reinauer@coreboot.org> </div>
<div style="display:none"> Gerrit-Reviewer: Vladimir Serbinenko <phcoder@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: build bot (Jenkins) <no-reply@coreboot.org> </div>