diff --git a/hw/loader.c b/hw/loader.c index 1e983261c..eb198f672 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 1f82fc5e9..fc6bdff6b 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 e710bbb94..7cc305535 100644 --- a/hw/multiboot.c +++ b/hw/multiboot.c @@ -331,7 +331,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 a030106fa..596635985 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 04a028dc2..2f6f473d6 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. */ @@ -1341,7 +1341,7 @@ static void n8x0_init(ram_addr_t ram_size, const char *boot_device, * * The code above is for loading the `zImage' file from Nokia * images. */ - rom_size = load_image_targphys(option_rom[0], + rom_size = load_image_targphys(option_rom[0].name, OMAP2_Q2_BASE + 0x400000, sdram_size - 0x400000); printf("%i bytes of image loaded\n", rom_size); diff --git a/hw/palm.c b/hw/palm.c index dd8d1e51d..f22d7775e 100644 --- a/hw/palm.c +++ b/hw/palm.c @@ -238,20 +238,20 @@ static void palmte_init(ram_addr_t ram_size, /* Setup initial (reset) machine state */ if (nb_option_roms) { - rom_size = get_image_size(option_rom[0]); + rom_size = get_image_size(option_rom[0].name); if (rom_size > flash_size) { fprintf(stderr, "%s: ROM image too big (%x > %x)\n", __FUNCTION__, rom_size, flash_size); rom_size = 0; } if (rom_size > 0) { - rom_size = load_image_targphys(option_rom[0], OMAP_CS0_BASE, + rom_size = load_image_targphys(option_rom[0].name, OMAP_CS0_BASE, flash_size); rom_loaded = 1; } if (rom_size < 0) { fprintf(stderr, "%s: error loading '%s'\n", - __FUNCTION__, option_rom[0]); + __FUNCTION__, option_rom[0].name); } } diff --git a/hw/pc.c b/hw/pc.c index 119c1106c..e1b266743 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 e7ea90725..24e650a44 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -1832,7 +1832,7 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom) 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-pci.c b/hw/pcnet-pci.c index 5c5bd213e..339a40196 100644 --- a/hw/pcnet-pci.c +++ b/hw/pcnet-pci.c @@ -310,7 +310,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 52f18bef3..965fa46fd 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 fe9a5827b..48f8eeeda 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 dadc161fd..844d6a50b 100644 --- a/vl.c +++ b/vl.c @@ -218,7 +218,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; @@ -2520,7 +2520,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: