summaryrefslogtreecommitdiffstats
path: root/qemu/roms/seabios/src/romfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/seabios/src/romfile.c')
-rw-r--r--qemu/roms/seabios/src/romfile.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/qemu/roms/seabios/src/romfile.c b/qemu/roms/seabios/src/romfile.c
new file mode 100644
index 000000000..42261a624
--- /dev/null
+++ b/qemu/roms/seabios/src/romfile.c
@@ -0,0 +1,100 @@
+// Access to pseudo "file" interface for configuration information.
+//
+// Copyright (C) 2012 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "config.h" // CONFIG_*
+#include "malloc.h" // free
+#include "output.h" // dprintf
+#include "romfile.h" // struct romfile_s
+#include "string.h" // memcmp
+
+static struct romfile_s *RomfileRoot VARVERIFY32INIT;
+
+void
+romfile_add(struct romfile_s *file)
+{
+ dprintf(3, "Add romfile: %s (size=%d)\n", file->name, file->size);
+ 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 unsuccessful.
+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;
+}