diff options
-rw-r--r-- | hw/cirrus_vga.c | 2 | ||||
-rw-r--r-- | hw/e1000.c | 2 | ||||
-rw-r--r-- | hw/pci.c | 35 | ||||
-rw-r--r-- | hw/pci.h | 5 | ||||
-rw-r--r-- | hw/rtl8139.c | 2 | ||||
-rw-r--r-- | hw/virtio-pci.c | 2 |
6 files changed, 44 insertions, 4 deletions
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 24af81ceb1..b08d2aed75 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -3211,7 +3211,7 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev) } /* ROM BIOS */ - rom_add_vga(VGABIOS_CIRRUS_FILENAME); + pci_add_option_rom((PCIDevice *)d, VGABIOS_CIRRUS_FILENAME); return 0; } diff --git a/hw/e1000.c b/hw/e1000.c index 8566fe3276..f7956010f1 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -1125,7 +1125,7 @@ static int pci_e1000_init(PCIDevice *pci_dev) if (!pci_dev->qdev.hotplugged) { static int loaded = 0; if (!loaded) { - rom_add_option("pxe-e1000.bin"); + pci_add_option_rom(&d->dev, "pxe-e1000.bin"); loaded = 1; } } @@ -26,6 +26,7 @@ #include "monitor.h" #include "net.h" #include "sysemu.h" +#include "loader.h" //#define DEBUG_PCI #ifdef DEBUG_PCI @@ -1438,6 +1439,40 @@ static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id, return next; } +static void pci_map_option_rom(PCIDevice *pdev, int region_num, pcibus_t addr, pcibus_t size, int type) +{ + cpu_register_physical_memory(addr, size, pdev->rom_offset); +} + +/* Add an option rom for the device */ +int pci_add_option_rom(PCIDevice *pdev, const char *name) +{ + int size; + char *path; + void *ptr; + + path = qemu_find_file(QEMU_FILE_TYPE_BIOS, name); + if (path == NULL) { + path = qemu_strdup(name); + } + + size = get_image_size(path); + if (size & (size - 1)) { + size = 1 << qemu_fls(size); + } + + pdev->rom_offset = qemu_ram_alloc(size); + + ptr = qemu_get_ram_ptr(pdev->rom_offset); + load_image(path, ptr); + qemu_free(path); + + pci_register_bar(pdev, PCI_ROM_SLOT, size, + 0, pci_map_option_rom); + + return 0; +} + /* Reserve space and add capability to the linked list in pci config space */ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size) { @@ -242,6 +242,9 @@ struct PCIDevice { uint32_t msix_bar_size; /* Version id needed for VMState */ int32_t version_id; + + /* Location of option rom */ + ram_addr_t rom_offset; }; PCIDevice *pci_register_device(PCIBus *bus, const char *name, @@ -253,6 +256,8 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, pcibus_t size, int type, PCIMapIORegionFunc *map_func); +int pci_add_option_rom(PCIDevice *pdev, const char *name); + int pci_add_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size); void pci_del_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size); diff --git a/hw/rtl8139.c b/hw/rtl8139.c index 9fd05a8a1b..2cee97bb7f 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -3357,7 +3357,7 @@ static int pci_rtl8139_init(PCIDevice *dev) if (!dev->qdev.hotplugged) { static int loaded = 0; if (!loaded) { - rom_add_option("pxe-rtl8139.bin"); + pci_add_option_rom(&s->dev, "pxe-rtl8139.bin"); loaded = 1; } } diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 450013091c..85f14a2c23 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -522,7 +522,7 @@ static int virtio_net_init_pci(PCIDevice *pci_dev) if (!pci_dev->qdev.hotplugged) { static int loaded = 0; if (!loaded) { - rom_add_option("pxe-virtio.bin"); + pci_add_option_rom(pci_dev, "pxe-virtio.bin"); loaded = 1; } } |