X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fparavirt.c;h=9cf77def2892eb51ade6e445a7edb1706603631e;hb=60a348bfbd8c4d32d950f33b066376624845f43f;hp=5c77b5c7d06395893facaf1e16b83079ec468142;hpb=0360e8e69bb3a773ceb9d2b091b62c027bca862b;p=seabios.git diff --git a/src/paravirt.c b/src/paravirt.c index 5c77b5c..9cf77de 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -24,8 +24,7 @@ qemu_cfg_select(u16 f) static void qemu_cfg_read(u8 *buf, int len) { - while (len--) - *(buf++) = inb(PORT_QEMU_CFG_DATA); + insb(PORT_QEMU_CFG_DATA, buf, len); } static void @@ -306,38 +305,126 @@ u16 qemu_cfg_get_max_cpus(void) return cnt; } -u16 qemu_cfg_first_file(QemuCfgFile *entry) -{ - memset(entry, 0, sizeof(*entry)); - return qemu_cfg_next_file(entry); -} +static QemuCfgFile LastFile; -u16 qemu_cfg_next_file(QemuCfgFile *entry) +static u32 +__cfg_next_prefix_file(const char *prefix, int prefixlen, u32 prevselect) { - u16 last = ntohs(entry->select); - u32 e,count; - if (!qemu_cfg_present) return 0; + u32 count; qemu_cfg_read_entry(&count, QEMU_CFG_FILE_DIR, sizeof(count)); - for (e = 0; e < ntohl(count); e++) { - qemu_cfg_read((void*)entry, sizeof(*entry)); - if (ntohs(entry->select) > last) { - return 1; - } + 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_read_file(QemuCfgFile *entry, void *dst, u32 maxlen) +u32 qemu_cfg_next_prefix_file(const char *prefix, u32 prevselect) { - int len = ntohl(entry->size); + return __cfg_next_prefix_file(prefix, strlen(prefix), prevselect); +} - if (!qemu_cfg_present) - return 0; - if (len > maxlen) +u32 qemu_cfg_find_file(const char *name) +{ + return __cfg_next_prefix_file(name, strlen(name) + 1, 0); +} + +static int +__qemu_cfg_set_file(u32 select) +{ + if (!qemu_cfg_present || !select) + return -1; + if (select == ntohs(LastFile.select)) return 0; - qemu_cfg_read_entry(dst, ntohs(entry->select), len); + + 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; + } + + 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; +}