diff options
Diffstat (limited to 'qemu/roms/seabios/src/romfile.c')
-rw-r--r-- | qemu/roms/seabios/src/romfile.c | 100 |
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; +} |