diff options
author | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-05-18 13:18:31 +0300 |
---|---|---|
committer | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-05-18 13:42:15 +0300 |
commit | 437fd90c0250dee670290f9b714253671a990160 (patch) | |
tree | b871786c360704244a07411c69fb58da9ead4a06 /qemu/roms/seabios/src/fw/multiboot.c | |
parent | 5bbd6fe9b8bab2a93e548c5a53b032d1939eec05 (diff) |
These changes are the raw update to qemu-2.6.
Collission happened in the following patches:
migration: do cleanup operation after completion(738df5b9)
Bug fix.(1750c932f86)
kvmclock: add a new function to update env->tsc.(b52baab2)
The code provided by the patches was already in the upstreamed
version.
Change-Id: I3cc11841a6a76ae20887b2e245710199e1ea7f9a
Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'qemu/roms/seabios/src/fw/multiboot.c')
-rw-r--r-- | qemu/roms/seabios/src/fw/multiboot.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/qemu/roms/seabios/src/fw/multiboot.c b/qemu/roms/seabios/src/fw/multiboot.c new file mode 100644 index 000000000..d9df06764 --- /dev/null +++ b/qemu/roms/seabios/src/fw/multiboot.c @@ -0,0 +1,111 @@ +// Multiboot interface support. +// +// Copyright (C) 2015 Vladimir Serbinenko <phcoder@gmail.com> +// +// 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" // romfile_add +#include "std/multiboot.h" // MULTIBOOT_* +#include "string.h" // memset +#include "util.h" // multiboot_init + +struct mbfs_romfile_s { + struct romfile_s file; + void *data; +}; + +static int +extract_filename(char *dest, char *src, size_t lim) +{ + char *ptr; + for (ptr = src; *ptr; ptr++) { + if (!(ptr == src || ptr[-1] == ' ' || ptr[-1] == '\t')) + continue; + /* memcmp stops early if it encounters \0 as it doesn't match name=. */ + if (memcmp(ptr, "name=", 5) == 0) { + int i; + char *optr = dest; + for (i = 0, ptr += 5; *ptr && *ptr != ' ' && i < lim; i++) { + *optr++ = *ptr++; + } + *optr++ = '\0'; + return 1; + } + } + return 0; +} + +// Copy a file to memory +static int +mbfs_copyfile(struct romfile_s *file, void *dst, u32 maxlen) +{ + struct mbfs_romfile_s *cfile; + cfile = container_of(file, struct mbfs_romfile_s, file); + u32 size = cfile->file.size; + void *src = cfile->data; + + // Not compressed. + dprintf(3, "Copying data %d@%p to %d@%p\n", size, src, maxlen, dst); + if (size > maxlen) { + warn_noalloc(); + return -1; + } + iomemcpy(dst, src, size); + return size; +} + +u32 __VISIBLE entry_elf_eax, entry_elf_ebx; + +void +multiboot_init(void) +{ + struct multiboot_info *mbi; + if (!CONFIG_MULTIBOOT) + return; + dprintf(1, "multiboot: eax=%x, ebx=%x\n", entry_elf_eax, entry_elf_ebx); + if (entry_elf_eax != MULTIBOOT_BOOTLOADER_MAGIC) + return; + mbi = (void *)entry_elf_ebx; + dprintf(1, "mbptr=%p\n", mbi); + dprintf(1, "flags=0x%x, mods=0x%x, mods_c=%d\n", mbi->flags, mbi->mods_addr, + mbi->mods_count); + if (!(mbi->flags & MULTIBOOT_INFO_MODS)) + return; + int i; + struct multiboot_mod_list *mod = (void *)mbi->mods_addr; + for (i = 0; i < mbi->mods_count; i++) { + struct mbfs_romfile_s *cfile; + u8 *copy; + u32 len; + if (!mod[i].cmdline) + continue; + len = mod[i].mod_end - mod[i].mod_start; + cfile = malloc_tmp(sizeof(*cfile)); + if (!cfile) { + warn_noalloc(); + return; + } + memset(cfile, 0, sizeof(*cfile)); + dprintf(1, "module %s, size 0x%x\n", (char *)mod[i].cmdline, len); + if (!extract_filename(cfile->file.name, (char *)mod[i].cmdline, + sizeof(cfile->file.name))) { + free(cfile); + continue; + } + dprintf(1, "assigned file name <%s>\n", cfile->file.name); + cfile->file.size = len; + copy = malloc_tmp(len); + if (!copy) { + warn_noalloc(); + free(cfile); + return; + } + memcpy(copy, (void *)mod[i].mod_start, len); + cfile->file.copy = mbfs_copyfile; + cfile->data = copy; + romfile_add(&cfile->file); + } +} |