Extend -option-rom command to have additional parameter ,bootindex=. Signed-off-by: Gleb Natapov <gleb@xxxxxxxxxx> --- hw/loader.c | 16 +++++++++++----- hw/loader.h | 8 ++++---- hw/multiboot.c | 3 ++- hw/ne2000.c | 2 +- hw/nseries.c | 2 +- hw/pc.c | 7 ++++--- hw/pci.c | 2 +- hw/pcnet.c | 2 +- qemu-config.c | 17 +++++++++++++++++ sysemu.h | 6 +++++- vl.c | 11 +++++++++-- 11 files changed, 56 insertions(+), 20 deletions(-) diff --git a/hw/loader.c b/hw/loader.c index 1e98326..eb198f6 100644 --- a/hw/loader.c +++ b/hw/loader.c @@ -107,7 +107,7 @@ int load_image_targphys(const char *filename, size = get_image_size(filename); if (size > 0) - rom_add_file_fixed(filename, addr); + rom_add_file_fixed(filename, addr, -1); return size; } @@ -557,10 +557,11 @@ static void rom_insert(Rom *rom) } int rom_add_file(const char *file, const char *fw_dir, - target_phys_addr_t addr) + target_phys_addr_t addr, int32_t bootindex) { Rom *rom; int rc, fd = -1; + char devpath[100]; rom = qemu_mallocz(sizeof(*rom)); rom->name = qemu_strdup(file); @@ -605,7 +606,12 @@ int rom_add_file(const char *file, const char *fw_dir, snprintf(fw_file_name, sizeof(fw_file_name), "%s/%s", rom->fw_dir, basename); fw_cfg_add_file(fw_cfg, fw_file_name, rom->data, rom->romsize); + snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name); + } else { + snprintf(devpath, sizeof(devpath), "/rom@" TARGET_FMT_plx, addr); } + + add_boot_device_path(bootindex, NULL, devpath); return 0; err: @@ -635,12 +641,12 @@ int rom_add_blob(const char *name, const void *blob, size_t len, int rom_add_vga(const char *file) { - return rom_add_file(file, "vgaroms", 0); + return rom_add_file(file, "vgaroms", 0, -1); } -int rom_add_option(const char *file) +int rom_add_option(const char *file, int32_t bootindex) { - return rom_add_file(file, "genroms", 0); + return rom_add_file(file, "genroms", 0, bootindex); } static void rom_reset(void *unused) diff --git a/hw/loader.h b/hw/loader.h index 1f82fc5..fc6bdff 100644 --- a/hw/loader.h +++ b/hw/loader.h @@ -22,7 +22,7 @@ void pstrcpy_targphys(const char *name, int rom_add_file(const char *file, const char *fw_dir, - target_phys_addr_t addr); + target_phys_addr_t addr, int32_t bootindex); int rom_add_blob(const char *name, const void *blob, size_t len, target_phys_addr_t addr); int rom_load_all(void); @@ -31,8 +31,8 @@ int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size); void *rom_ptr(target_phys_addr_t addr); void do_info_roms(Monitor *mon); -#define rom_add_file_fixed(_f, _a) \ - rom_add_file(_f, NULL, _a) +#define rom_add_file_fixed(_f, _a, _i) \ + rom_add_file(_f, NULL, _a, _i) #define rom_add_blob_fixed(_f, _b, _l, _a) \ rom_add_blob(_f, _b, _l, _a) @@ -43,6 +43,6 @@ void do_info_roms(Monitor *mon); #define PC_ROM_SIZE (PC_ROM_MAX - PC_ROM_MIN_VGA) int rom_add_vga(const char *file); -int rom_add_option(const char *file); +int rom_add_option(const char *file, int32_t bootindex); #endif diff --git a/hw/multiboot.c b/hw/multiboot.c index f9097a2..b438019 100644 --- a/hw/multiboot.c +++ b/hw/multiboot.c @@ -325,7 +325,8 @@ int load_multiboot(void *fw_cfg, fw_cfg_add_bytes(fw_cfg, FW_CFG_INITRD_DATA, mb_bootinfo_data, sizeof(bootinfo)); - option_rom[nb_option_roms] = "multiboot.bin"; + option_rom[nb_option_roms].name = "multiboot.bin"; + option_rom[nb_option_roms].bootindex = 0; nb_option_roms++; return 1; /* yes, we are multiboot */ diff --git a/hw/ne2000.c b/hw/ne2000.c index f4bbac2..67e0cb0 100644 --- a/hw/ne2000.c +++ b/hw/ne2000.c @@ -742,7 +742,7 @@ static int pci_ne2000_init(PCIDevice *pci_dev) if (!pci_dev->qdev.hotplugged) { static int loaded = 0; if (!loaded) { - rom_add_option("pxe-ne2k_pci.bin"); + rom_add_option("pxe-ne2k_pci.bin", -1); loaded = 1; } } diff --git a/hw/nseries.c b/hw/nseries.c index 04a028d..39780ef 100644 --- a/hw/nseries.c +++ b/hw/nseries.c @@ -1326,7 +1326,7 @@ static void n8x0_init(ram_addr_t ram_size, const char *boot_device, qemu_register_reset(n8x0_boot_init, s); } - if (option_rom[0] && (boot_device[0] == 'n' || !kernel_filename)) { + if (option_rom[0].name && (boot_device[0] == 'n' || !kernel_filename)) { int rom_size; uint8_t nolo_tags[0x10000]; /* No, wait, better start at the ROM. */ diff --git a/hw/pc.c b/hw/pc.c index 69b13bf..5111a76 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -733,7 +733,8 @@ static void load_linux(void *fw_cfg, fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size); fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size); - option_rom[nb_option_roms] = "linuxboot.bin"; + option_rom[nb_option_roms].name = "linuxboot.bin"; + option_rom[nb_option_roms].bootindex = 0; nb_option_roms++; } @@ -937,7 +938,7 @@ void pc_memory_init(ram_addr_t ram_size, goto bios_error; } bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size); - ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size)); + ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1); if (ret != 0) { bios_error: fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name); @@ -969,7 +970,7 @@ void pc_memory_init(ram_addr_t ram_size, } for (i = 0; i < nb_option_roms; i++) { - rom_add_option(option_rom[i]); + rom_add_option(option_rom[i].name, option_rom[i].bootindex); } } diff --git a/hw/pci.c b/hw/pci.c index 114b435..49e9298 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -1701,7 +1701,7 @@ static int pci_add_option_rom(PCIDevice *pdev) if (class == 0x0300) { rom_add_vga(pdev->romfile); } else { - rom_add_option(pdev->romfile); + rom_add_option(pdev->romfile, -1); } return 0; } diff --git a/hw/pcnet.c b/hw/pcnet.c index a988f4f..38e6591 100644 --- a/hw/pcnet.c +++ b/hw/pcnet.c @@ -2014,7 +2014,7 @@ static int pci_pcnet_init(PCIDevice *pci_dev) if (!pci_dev->qdev.hotplugged) { static int loaded = 0; if (!loaded) { - rom_add_option("pxe-pcnet.bin"); + rom_add_option("pxe-pcnet.bin", -1); loaded = 1; } } diff --git a/qemu-config.c b/qemu-config.c index 52f18be..965fa46 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -429,6 +429,22 @@ QemuOptsList qemu_spice_opts = { }, }; +QemuOptsList qemu_option_rom_opts = { + .name = "option-rom", + .implied_opt_name = "romfile", + .head = QTAILQ_HEAD_INITIALIZER(qemu_option_rom_opts.head), + .desc = { + { + .name = "bootindex", + .type = QEMU_OPT_NUMBER, + }, { + .name = "romfile", + .type = QEMU_OPT_STRING, + }, + { /* end if list */ } + }, +}; + static QemuOptsList *vm_config_groups[32] = { &qemu_drive_opts, &qemu_chardev_opts, @@ -442,6 +458,7 @@ static QemuOptsList *vm_config_groups[32] = { #ifdef CONFIG_SIMPLE_TRACE &qemu_trace_opts, #endif + &qemu_option_rom_opts, NULL, }; diff --git a/sysemu.h b/sysemu.h index fe9a582..48f8eee 100644 --- a/sysemu.h +++ b/sysemu.h @@ -139,7 +139,11 @@ extern uint64_t node_mem[MAX_NODES]; extern uint64_t node_cpumask[MAX_NODES]; #define MAX_OPTION_ROMS 16 -extern const char *option_rom[MAX_OPTION_ROMS]; +typedef struct QEMUOptionRom { + const char *name; + int32_t bootindex; +} QEMUOptionRom; +extern QEMUOptionRom option_rom[MAX_OPTION_ROMS]; extern int nb_option_roms; #define MAX_PROM_ENVS 128 diff --git a/vl.c b/vl.c index 4c159f0..e8ada75 100644 --- a/vl.c +++ b/vl.c @@ -217,7 +217,7 @@ int cursor_hide = 1; int graphic_rotate = 0; uint8_t irq0override = 1; const char *watchdog; -const char *option_rom[MAX_OPTION_ROMS]; +QEMUOptionRom option_rom[MAX_OPTION_ROMS]; int nb_option_roms; int semihosting_enabled = 0; int old_param = 0; @@ -2516,7 +2516,14 @@ int main(int argc, char **argv, char **envp) fprintf(stderr, "Too many option ROMs\n"); exit(1); } - option_rom[nb_option_roms] = optarg; + opts = qemu_opts_parse(qemu_find_opts("option-rom"), optarg, 1); + option_rom[nb_option_roms].name = qemu_opt_get(opts, "romfile"); + option_rom[nb_option_roms].bootindex = + qemu_opt_get_number(opts, "bootindex", -1); + if (!option_rom[nb_option_roms].name) { + fprintf(stderr, "Option ROM file is not specified\n"); + exit(1); + } nb_option_roms++; break; case QEMU_OPTION_semihosting: -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html