[SeaBIOS] [PATCH] Cache romfile entries.

Kevin O'Connor kevin at koconnor.net
Thu May 31 06:32:46 CEST 2012


Create a 'struct romfile_s' and populate a list of all romfiles at
start of init.  Caching the romfiles both simplifies the code and
makes it more efficient.

Also, convert the ramdisk code to use romfile helpers instead of
directly accessing cbfs.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 Makefile         |    2 +-
 src/boot.c       |    4 +-
 src/bootsplash.c |    1 -
 src/coreboot.c   |  208 +++++++++++++++++-------------------------------------
 src/optionroms.c |   16 ++--
 src/paravirt.c   |  138 +++++++----------------------------
 src/paravirt.h   |   45 +------------
 src/pci.c        |    2 +-
 src/post.c       |    4 +
 src/ps2port.c    |    1 -
 src/ramdisk.c    |   12 ++--
 src/romfile.c    |   96 +++++++++++++++++++++++++
 src/util.h       |   24 +++++--
 13 files changed, 232 insertions(+), 321 deletions(-)
 create mode 100644 src/romfile.c

diff --git a/Makefile b/Makefile
index 5f3740d..fe974f7 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ SRC16=$(SRCBOTH) system.c disk.c font.c
 SRC32FLAT=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \
     acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c \
     lzmadecode.c bootsplash.c jpeg.c usb-hub.c paravirt.c \
-    biostables.c xen.c bmp.c
+    biostables.c xen.c bmp.c romfile.c
 SRC32SEG=util.c output.c pci.c pcibios.c apm.c stacks.c
 
 # Default compiler flags
diff --git a/src/boot.c b/src/boot.c
index 3f6375b..6949490 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -11,8 +11,8 @@
 #include "bregs.h" // struct bregs
 #include "boot.h" // func defs
 #include "cmos.h" // inb_cmos
-#include "paravirt.h" // romfile_loadfile
-#include "pci.h" //pci_bdf_to_*
+#include "paravirt.h" // qemu_cfg_show_boot_menu
+#include "pci.h" // pci_bdf_to_*
 #include "usb.h" // struct usbdevice_s
 
 
diff --git a/src/bootsplash.c b/src/bootsplash.c
index f85f734..a85e2b2 100644
--- a/src/bootsplash.c
+++ b/src/bootsplash.c
@@ -10,7 +10,6 @@
 #include "config.h" // CONFIG_*
 #include "util.h" // dprintf
 #include "jpeg.h" // splash
-#include "paravirt.h" // romfile_find
 #include "vbe.h" // struct vbe_info
 #include "bmp.h"
 
diff --git a/src/coreboot.c b/src/coreboot.c
index e116a14..d93196f 100644
--- a/src/coreboot.c
+++ b/src/coreboot.c
@@ -121,8 +121,8 @@ static struct cb_memory *CBMemTable;
 const char *CBvendor = "", *CBpart = "";
 
 // Populate max ram and e820 map info by scanning for a coreboot table.
-static void
-coreboot_fill_map(void)
+void
+coreboot_setup(void)
 {
     dprintf(3, "Attempting to find coreboot table\n");
 
@@ -286,25 +286,6 @@ struct cbfs_header {
     u32 pad[2];
 } PACKED;
 
-static struct cbfs_header *CBHDR;
-
-static void
-cbfs_setup(void)
-{
-    if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH)
-        return;
-
-    CBHDR = *(void **)CBFS_HEADPTR_ADDR;
-    if (CBHDR->magic != htonl(CBFS_HEADER_MAGIC)) {
-        dprintf(1, "Unable to find CBFS (ptr=%p; got %x not %x)\n"
-                , CBHDR, CBHDR->magic, htonl(CBFS_HEADER_MAGIC));
-        CBHDR = NULL;
-        return;
-    }
-
-    dprintf(1, "Found CBFS header at %p\n", CBHDR);
-}
-
 #define CBFS_FILE_MAGIC 0x455649484352414cLL // LARCHIVE
 
 struct cbfs_file {
@@ -316,124 +297,22 @@ struct cbfs_file {
     char filename[0];
 } PACKED;
 
-// Verify a cbfs entry looks valid.
-static struct cbfs_file *
-cbfs_verify(struct cbfs_file *file)
-{
-    if (file < (struct cbfs_file *)(0xFFFFFFFF - ntohl(CBHDR->romsize)))
-        return NULL;
-    u64 magic = file->magic;
-    if (magic == CBFS_FILE_MAGIC) {
-        dprintf(8, "Found CBFS file %s\n", file->filename);
-        return file;
-    }
-    return NULL;
-}
-
-// Return the first file in the CBFS archive
-static struct cbfs_file *
-cbfs_getfirst(void)
-{
-    if (! CBHDR)
-        return NULL;
-    return cbfs_verify((void *)(0 - ntohl(CBHDR->romsize) + ntohl(CBHDR->offset)));
-}
-
-// Return the file after the given file.
-static struct cbfs_file *
-cbfs_getnext(struct cbfs_file *file)
-{
-    file = (void*)file + ALIGN(ntohl(file->len) + ntohl(file->offset), ntohl(CBHDR->align));
-    return cbfs_verify(file);
-}
-
-// Find the file with the given filename.
-struct cbfs_file *
-cbfs_findfile(const char *fname)
-{
-    dprintf(7, "Searching CBFS for %s\n", fname);
-    struct cbfs_file *file;
-    for (file = cbfs_getfirst(); file; file = cbfs_getnext(file))
-        if (strcmp(fname, file->filename) == 0)
-            return file;
-    return NULL;
-}
-
-// Find next file with the given filename prefix.
-struct cbfs_file *
-cbfs_findprefix(const char *prefix, struct cbfs_file *last)
-{
-    if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH)
-        return NULL;
-
-    dprintf(7, "Searching CBFS for prefix %s\n", prefix);
-    int len = strlen(prefix);
-    struct cbfs_file *file;
-    if (! last)
-        file = cbfs_getfirst();
-    else
-        file = cbfs_getnext(last);
-    for (; file; file = cbfs_getnext(file))
-        if (memcmp(prefix, file->filename, len) == 0)
-            return file;
-    return NULL;
-}
-
-// Find a file with the given filename (possibly with ".lzma" extension).
-struct cbfs_file *
-cbfs_finddatafile(const char *fname)
-{
-    int fnlen = strlen(fname);
-    struct cbfs_file *file = NULL;
-    for (;;) {
-        file = cbfs_findprefix(fname, file);
-        if (!file)
-            return NULL;
-        if (file->filename[fnlen] == '\0'
-            || strcmp(&file->filename[fnlen], ".lzma") == 0)
-            return file;
-    }
-}
-
-// Determine whether the file has a ".lzma" extension.
-static int
-cbfs_iscomp(struct cbfs_file *file)
-{
-    int fnamelen = strlen(file->filename);
-    return fnamelen > 5 && strcmp(&file->filename[fnamelen-5], ".lzma") == 0;
-}
-
-// Return the filename of a given file.
-const char *
-cbfs_filename(struct cbfs_file *file)
-{
-    return file->filename;
-}
-
-// Determine the uncompressed size of a datafile.
-u32
-cbfs_datasize(struct cbfs_file *file)
-{
-    void *src = (void*)file + ntohl(file->offset);
-    if (cbfs_iscomp(file))
-        return *(u32*)(src + LZMA_PROPERTIES_SIZE);
-    return ntohl(file->len);
-}
-
 // Copy a file to memory (uncompressing if necessary)
-int
-cbfs_copyfile(struct cbfs_file *file, void *dst, u32 maxlen)
+static int
+cbfs_copyfile(struct romfile_s *file, void *dst, u32 maxlen)
 {
-    if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH || !file)
+    if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH)
         return -1;
 
-    u32 size = ntohl(file->len);
-    void *src = (void*)file + ntohl(file->offset);
-    if (cbfs_iscomp(file)) {
+    u32 size = file->rawsize;
+    void *src = file->data;
+    if (file->flags) {
         // Compressed - copy to temp ram and uncompress it.
         void *temp = malloc_tmphigh(size);
-        if (!temp)
+        if (!temp) {
+            warn_noalloc();
             return -1;
+        }
         iomemcpy(temp, src, size);
         int ret = ulzma(dst, maxlen, temp, size);
         yield();
@@ -451,6 +330,53 @@ cbfs_copyfile(struct cbfs_file *file, void *dst, u32 maxlen)
     return size;
 }
 
+void
+coreboot_cbfs_setup(void)
+{
+    if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH)
+        return;
+
+    struct cbfs_header *hdr = *(void **)CBFS_HEADPTR_ADDR;
+    if (hdr->magic != htonl(CBFS_HEADER_MAGIC)) {
+        dprintf(1, "Unable to find CBFS (ptr=%p; got %x not %x)\n"
+                , hdr, hdr->magic, htonl(CBFS_HEADER_MAGIC));
+        return;
+    }
+    dprintf(1, "Found CBFS header at %p\n", hdr);
+
+    struct cbfs_file *cfile = (void *)(0 - ntohl(hdr->romsize)
+                                       + ntohl(hdr->offset));
+    for (;;) {
+        if (cfile < (struct cbfs_file *)(0xFFFFFFFF - ntohl(hdr->romsize)))
+            break;
+        u64 magic = cfile->magic;
+        if (magic != CBFS_FILE_MAGIC)
+            break;
+        struct romfile_s *file = malloc_tmp(sizeof(*file));
+        if (!file) {
+            warn_noalloc();
+            break;
+        }
+        memset(file, 0, sizeof(*file));
+        strtcpy(file->name, cfile->filename, sizeof(file->name));
+        dprintf(3, "Found CBFS file: %s\n", file->name);
+        file->size = file->rawsize = ntohl(cfile->len);
+        file->id = (u32)cfile;
+        file->copy = cbfs_copyfile;
+        file->data = (void*)cfile + ntohl(cfile->offset);
+        int len = strlen(file->name);
+        if (len > 5 && strcmp(&file->name[len-5], ".lzma") == 0) {
+            // Using compression.
+            file->flags = 1;
+            file->name[len-5] = '\0';
+            file->size = *(u32*)(file->data + LZMA_PROPERTIES_SIZE);
+        }
+        romfile_add(file);
+
+        cfile = (void*)ALIGN((u32)file->data + file->size, ntohl(hdr->align));
+    }
+}
+
 struct cbfs_payload_segment {
     u32 type;
     u32 compression;
@@ -524,20 +450,16 @@ cbfs_run_payload(struct cbfs_file *file)
 void
 cbfs_payload_setup(void)
 {
-    struct cbfs_file *file = NULL;
+    if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH)
+        return;
+    struct romfile_s *file = NULL;
     for (;;) {
-        file = cbfs_findprefix("img/", file);
+        file = romfile_findprefix("img/", file);
         if (!file)
             break;
-        const char *filename = cbfs_filename(file);
+        const char *filename = file->name;
         char *desc = znprintf(MAXDESCSIZE, "Payload [%s]", &filename[4]);
-        boot_add_cbfs(file, desc, bootprio_find_named_rom(filename, 0));
+        boot_add_cbfs((void*)file->id, desc
+                      , bootprio_find_named_rom(filename, 0));
     }
 }
-
-void
-coreboot_setup(void)
-{
-    coreboot_fill_map();
-    cbfs_setup();
-}
diff --git a/src/optionroms.c b/src/optionroms.c
index bd2f977..00697b2 100644
--- a/src/optionroms.c
+++ b/src/optionroms.c
@@ -13,7 +13,6 @@
 #include "pci_regs.h" // PCI_ROM_ADDRESS
 #include "pci_ids.h" // PCI_CLASS_DISPLAY_VGA
 #include "boot.h" // IPL
-#include "paravirt.h" // qemu_cfg_*
 #include "optionroms.h" // struct rom_header
 
 
@@ -151,7 +150,8 @@ getRomPriority(u64 *sources, struct rom_header *rom, int instance)
         return -1;
     if (source & RS_PCIROM)
         return bootprio_find_pci_rom((void*)(u32)source, instance);
-    return bootprio_find_named_rom(romfile_name(source), instance);
+    struct romfile_s *file = (void*)(u32)source;
+    return bootprio_find_named_rom(file->name, instance);
 }
 
 
@@ -160,15 +160,15 @@ getRomPriority(u64 *sources, struct rom_header *rom, int instance)
  ****************************************************************/
 
 static struct rom_header *
-deploy_romfile(u32 file)
+deploy_romfile(struct romfile_s *file)
 {
-    u32 size = romfile_size(file);
+    u32 size = file->size;
     struct rom_header *rom = rom_reserve(size);
     if (!rom) {
         warn_noalloc();
         return NULL;
     }
-    int ret = romfile_copy(file, rom, size);
+    int ret = file->copy(file, rom, size);
     if (ret <= 0)
         return NULL;
     return rom;
@@ -181,7 +181,7 @@ lookup_hardcode(struct pci_device *pci)
     char fname[17];
     snprintf(fname, sizeof(fname), "pci%04x,%04x.rom"
              , pci->vendor, pci->device);
-    u32 file = romfile_find(fname);
+    struct romfile_s *file = romfile_find(fname);
     if (file)
         return deploy_romfile(file);
     return NULL;
@@ -191,14 +191,14 @@ lookup_hardcode(struct pci_device *pci)
 static void
 run_file_roms(const char *prefix, int isvga, u64 *sources)
 {
-    u32 file = 0;
+    struct romfile_s *file = NULL;
     for (;;) {
         file = romfile_findprefix(prefix, file);
         if (!file)
             break;
         struct rom_header *rom = deploy_romfile(file);
         if (rom) {
-            setRomSource(sources, rom, file);
+            setRomSource(sources, rom, (u32)file);
             init_optionrom(rom, 0, isvga);
         }
     }
diff --git a/src/paravirt.c b/src/paravirt.c
index 9cf77de..31759e8 100644
--- a/src/paravirt.c
+++ b/src/paravirt.c
@@ -305,126 +305,44 @@ u16 qemu_cfg_get_max_cpus(void)
     return cnt;
 }
 
-static QemuCfgFile LastFile;
-
-static u32
-__cfg_next_prefix_file(const char *prefix, int prefixlen, u32 prevselect)
-{
-    if (!qemu_cfg_present)
-        return 0;
-
-    u32 count;
-    qemu_cfg_read_entry(&count, QEMU_CFG_FILE_DIR, sizeof(count));
-    count = ntohl(count);
-    u32 e;
-    for (e = 0; e < count; e++) {
-        qemu_cfg_read((void*)&LastFile, sizeof(LastFile));
-        u32 select = ntohs(LastFile.select);
-        if (select <= prevselect)
-            continue;
-        if (memcmp(prefix, LastFile.name, prefixlen) == 0)
-            return select;
-    }
-    return 0;
-}
-
-u32 qemu_cfg_next_prefix_file(const char *prefix, u32 prevselect)
+int qemu_cfg_read_file(struct romfile_s *file, void *dst, u32 maxlen)
 {
-    return __cfg_next_prefix_file(prefix, strlen(prefix), prevselect);
+    if (file->size > maxlen)
+        return -1;
+    qemu_cfg_read_entry(dst, file->id, file->size);
+    return file->size;
 }
 
-u32 qemu_cfg_find_file(const char *name)
-{
-    return __cfg_next_prefix_file(name, strlen(name) + 1, 0);
-}
+struct QemuCfgFile {
+    u32  size;        /* file size */
+    u16  select;      /* write this to 0x510 to read it */
+    u16  reserved;
+    char name[56];
+};
 
-static int
-__qemu_cfg_set_file(u32 select)
+void qemu_cfg_romfile_setup(void)
 {
-    if (!qemu_cfg_present || !select)
-        return -1;
-    if (select == ntohs(LastFile.select))
-        return 0;
+    if (CONFIG_COREBOOT || !qemu_cfg_present)
+        return;
 
     u32 count;
     qemu_cfg_read_entry(&count, QEMU_CFG_FILE_DIR, sizeof(count));
     count = ntohl(count);
     u32 e;
     for (e = 0; e < count; e++) {
-        qemu_cfg_read((void*)&LastFile, sizeof(LastFile));
-        if (select == ntohs(LastFile.select))
-            return 0;
-    }
-    return -1;
-}
-
-int qemu_cfg_size_file(u32 select)
-{
-    if (__qemu_cfg_set_file(select))
-        return -1;
-    return ntohl(LastFile.size);
-}
-
-const char* qemu_cfg_name_file(u32 select)
-{
-    if (__qemu_cfg_set_file(select))
-        return NULL;
-    return LastFile.name;
-}
-
-int qemu_cfg_read_file(u32 select, void *dst, u32 maxlen)
-{
-    if (__qemu_cfg_set_file(select))
-        return -1;
-    int len = qemu_cfg_size_file(select);
-    if (len < 0 || len > maxlen)
-        return -1;
-    qemu_cfg_read_entry(dst, select, len);
-    return len;
-}
-
-// Helper function to find, malloc_tmphigh, and copy a romfile.  This
-// function adds a trailing zero to the malloc'd copy.
-void *
-romfile_loadfile(const char *name, int *psize)
-{
-    u32 file = romfile_find(name);
-    if (!file)
-        return NULL;
-
-    int filesize = romfile_size(file);
-    if (!filesize)
-        return NULL;
-
-    char *data = malloc_tmphigh(filesize+1);
-    if (!data) {
-        warn_noalloc();
-        return NULL;
+        struct QemuCfgFile qfile;
+        qemu_cfg_read((void*)&qfile, sizeof(qfile));
+        struct romfile_s *file = malloc_tmp(sizeof(*file));
+        if (!file) {
+            warn_noalloc();
+            return;
+        }
+        memset(file, 0, sizeof(*file));
+        strtcpy(file->name, qfile.name, sizeof(file->name));
+        file->size = qfile.size;
+        file->id = qfile.select;
+        file->copy = qemu_cfg_read_file;
+        romfile_add(file);
+        dprintf(3, "Found fw_cfg file: %s\n", file->name);
     }
-
-    dprintf(5, "Copying romfile '%s' (len %d)\n", name, filesize);
-    romfile_copy(file, data, filesize);
-    if (psize)
-        *psize = filesize;
-    data[filesize] = '\0';
-    return data;
-}
-
-// Attempt to load an integer from the given file - return 'defval'
-// if unsuccesful.
-u64
-romfile_loadint(const char *name, u64 defval)
-{
-    u32 file = romfile_find(name);
-    if (!file)
-        return defval;
-
-    int filesize = romfile_size(file);
-    if (!filesize || filesize > sizeof(u64) || (filesize & (filesize-1)))
-        // Doesn't look like a valid integer.
-        return defval;
-
-    u64 val = 0;
-    romfile_copy(file, &val, sizeof(val));
-    return val;
 }
diff --git a/src/paravirt.h b/src/paravirt.h
index f39e226..a284c41 100644
--- a/src/paravirt.h
+++ b/src/paravirt.h
@@ -57,56 +57,13 @@ int qemu_cfg_smbios_load_external(int type, char **p, unsigned *nr_structs,
 int qemu_cfg_get_numa_nodes(void);
 void qemu_cfg_get_numa_data(u64 *data, int n);
 u16 qemu_cfg_get_max_cpus(void);
-
-typedef struct QemuCfgFile {
-    u32  size;        /* file size */
-    u16  select;      /* write this to 0x510 to read it */
-    u16  reserved;
-    char name[56];
-} QemuCfgFile;
-
 struct e820_reservation {
     u64 address;
     u64 length;
     u32 type;
 };
-
-u32 qemu_cfg_next_prefix_file(const char *prefix, u32 prevselect);
-u32 qemu_cfg_find_file(const char *name);
-int qemu_cfg_size_file(u32 select);
-const char* qemu_cfg_name_file(u32 select);
-int qemu_cfg_read_file(u32 select, void *dst, u32 maxlen);
-
-// Wrappers that select cbfs or qemu_cfg file interface.
-static inline u32 romfile_findprefix(const char *prefix, u32 previd) {
-    if (CONFIG_COREBOOT)
-        return (u32)cbfs_findprefix(prefix, (void*)previd);
-    return qemu_cfg_next_prefix_file(prefix, previd);
-}
-static inline u32 romfile_find(const char *name) {
-    if (CONFIG_COREBOOT)
-        return (u32)cbfs_finddatafile(name);
-    return qemu_cfg_find_file(name);
-}
-static inline u32 romfile_size(u32 fileid) {
-    if (CONFIG_COREBOOT)
-        return cbfs_datasize((void*)fileid);
-    return qemu_cfg_size_file(fileid);
-}
-static inline int romfile_copy(u32 fileid, void *dst, u32 maxlen) {
-    if (CONFIG_COREBOOT)
-        return cbfs_copyfile((void*)fileid, dst, maxlen);
-    return qemu_cfg_read_file(fileid, dst, maxlen);
-}
-static inline const char* romfile_name(u32 fileid) {
-    if (CONFIG_COREBOOT)
-        return cbfs_filename((void*)fileid);
-    return qemu_cfg_name_file(fileid);
-}
-void *romfile_loadfile(const char *name, int *psize);
-u64 romfile_loadint(const char *name, u64 defval);
-
 u32 qemu_cfg_e820_entries(void);
 void* qemu_cfg_e820_load_next(void *addr);
+void qemu_cfg_romfile_setup(void);
 
 #endif
diff --git a/src/pci.c b/src/pci.c
index 49bc34e..071c302 100644
--- a/src/pci.c
+++ b/src/pci.c
@@ -5,10 +5,10 @@
 //
 // This file may be distributed under the terms of the GNU LGPLv3 license.
 
+#include "config.h" // CONFIG_*
 #include "pci.h" // pci_config_writel
 #include "ioport.h" // outl
 #include "util.h" // dprintf
-#include "paravirt.h" // romfile_loadint
 #include "farptr.h" // MAKE_FLATPTR
 #include "pci_regs.h" // PCI_VENDOR_ID
 #include "pci_ids.h" // PCI_CLASS_DISPLAY_VGA
diff --git a/src/post.c b/src/post.c
index d2f40f4..1d0d35a 100644
--- a/src/post.c
+++ b/src/post.c
@@ -214,6 +214,10 @@ startBoot(void)
 static void
 maininit(void)
 {
+    // Setup romfile items.
+    qemu_cfg_romfile_setup();
+    coreboot_cbfs_setup();
+
     // Setup ivt/bda/ebda
     init_ivt();
     init_bda();
diff --git a/src/ps2port.c b/src/ps2port.c
index c835e14..601e40d 100644
--- a/src/ps2port.c
+++ b/src/ps2port.c
@@ -7,7 +7,6 @@
 
 #include "ioport.h" // inb
 #include "util.h" // dprintf
-#include "paravirt.h" // romfile_loadint
 #include "biosvar.h" // GET_LOW
 #include "ps2port.h" // ps2_kbd_command
 #include "pic.h" // eoi_pic1
diff --git a/src/ramdisk.c b/src/ramdisk.c
index bae30e2..9249a49 100644
--- a/src/ramdisk.c
+++ b/src/ramdisk.c
@@ -14,15 +14,15 @@
 void
 ramdisk_setup(void)
 {
-    if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH || !CONFIG_FLASH_FLOPPY)
+    if (!CONFIG_FLASH_FLOPPY)
         return;
 
     // Find image.
-    struct cbfs_file *file = cbfs_findprefix("floppyimg/", NULL);
+    struct romfile_s *file = romfile_findprefix("floppyimg/", NULL);
     if (!file)
         return;
-    const char *filename = cbfs_filename(file);
-    u32 size = cbfs_datasize(file);
+    const char *filename = file->name;
+    u32 size = file->size;
     dprintf(3, "Found floppy file %s of size %d\n", filename, size);
     int ftype = find_floppy_type(size);
     if (ftype < 0) {
@@ -39,7 +39,9 @@ ramdisk_setup(void)
     add_e820((u32)pos, size, E820_RESERVED);
 
     // Copy image into ram.
-    cbfs_copyfile(file, pos, size);
+    int ret = file->copy(file, pos, size);
+    if (ret < 0)
+        return;
 
     // Setup driver.
     struct drive_s *drive_g = init_floppy((u32)pos, ftype);
diff --git a/src/romfile.c b/src/romfile.c
new file mode 100644
index 0000000..b732e29
--- /dev/null
+++ b/src/romfile.c
@@ -0,0 +1,96 @@
+// Access to pseudo "file" interface for configuration information.
+//
+// Copyright (C) 2012  Kevin O'Connor <kevin at koconnor.net>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "config.h" // CONFIG_*
+#include "util.h" // dprintf
+
+static struct romfile_s *RomfileRoot;
+
+void
+romfile_add(struct romfile_s *file)
+{
+    file->next = RomfileRoot;
+    RomfileRoot = file;
+}
+
+// Search for the specified file.
+static struct romfile_s *
+__romfile_findprefix(const char *prefix, int prefixlen, struct romfile_s *prev)
+{
+    struct romfile_s *cur = RomfileRoot;
+    if (prev)
+        cur = prev->next;
+    while (cur) {
+        if (memcmp(prefix, cur->name, prefixlen) == 0)
+            return cur;
+        cur = cur->next;
+    }
+    return NULL;
+}
+
+struct romfile_s *
+romfile_findprefix(const char *prefix, struct romfile_s *prev)
+{
+    return __romfile_findprefix(prefix, strlen(prefix), prev);
+}
+
+struct romfile_s *
+romfile_find(const char *name)
+{
+    return __romfile_findprefix(name, strlen(name) + 1, NULL);
+}
+
+// Helper function to find, malloc_tmphigh, and copy a romfile.  This
+// function adds a trailing zero to the malloc'd copy.
+void *
+romfile_loadfile(const char *name, int *psize)
+{
+    struct romfile_s *file = romfile_find(name);
+    if (!file)
+        return NULL;
+
+    int filesize = file->size;
+    if (!filesize)
+        return NULL;
+
+    char *data = malloc_tmphigh(filesize+1);
+    if (!data) {
+        warn_noalloc();
+        return NULL;
+    }
+
+    dprintf(5, "Copying romfile '%s' (len %d)\n", name, filesize);
+    int ret = file->copy(file, data, filesize);
+    if (ret < 0) {
+        free(data);
+        return NULL;
+    }
+    if (psize)
+        *psize = filesize;
+    data[filesize] = '\0';
+    return data;
+}
+
+// Attempt to load an integer from the given file - return 'defval'
+// if unsuccesful.
+u64
+romfile_loadint(const char *name, u64 defval)
+{
+    struct romfile_s *file = romfile_find(name);
+    if (!file)
+        return defval;
+
+    int filesize = file->size;
+    if (!filesize || filesize > sizeof(u64) || (filesize & (filesize-1)))
+        // Doesn't look like a valid integer.
+        return defval;
+
+    u64 val = 0;
+    int ret = file->copy(file, &val, sizeof(val));
+    if (ret < 0)
+        return defval;
+    return val;
+}
diff --git a/src/util.h b/src/util.h
index e5d494e..39350cc 100644
--- a/src/util.h
+++ b/src/util.h
@@ -353,15 +353,11 @@ void smp_probe(void);
 // coreboot.c
 extern const char *CBvendor, *CBpart;
 struct cbfs_file;
-struct cbfs_file *cbfs_finddatafile(const char *fname);
-struct cbfs_file *cbfs_findprefix(const char *prefix, struct cbfs_file *last);
-u32 cbfs_datasize(struct cbfs_file *file);
-const char *cbfs_filename(struct cbfs_file *file);
-int cbfs_copyfile(struct cbfs_file *file, void *dst, u32 maxlen);
 void cbfs_run_payload(struct cbfs_file *file);
 void coreboot_copy_biostable(void);
 void cbfs_payload_setup(void);
 void coreboot_setup(void);
+void coreboot_cbfs_setup(void);
 
 // biostable.c
 void copy_pir(void *pos);
@@ -458,6 +454,24 @@ static inline void free(void *data) {
 // mtrr.c
 void mtrr_setup(void);
 
+// romfile.c
+struct romfile_s {
+    struct romfile_s *next;
+    char name[128];
+    u32 size;
+    int (*copy)(struct romfile_s *file, void *dest, u32 maxlen);
+
+    u32 id;
+    u32 rawsize;
+    u32 flags;
+    void *data;
+};
+void romfile_add(struct romfile_s *file);
+struct romfile_s *romfile_findprefix(const char *prefix, struct romfile_s *prev);
+struct romfile_s *romfile_find(const char *name);
+void *romfile_loadfile(const char *name, int *psize);
+u64 romfile_loadint(const char *name, u64 defval);
+
 // romlayout.S
 void reset_vector(void) __noreturn;
 
-- 
1.7.6.5




More information about the SeaBIOS mailing list