]> git.proxmox.com Git - qemu.git/commitdiff
Support PCI based option rom loading
authorAnthony Liguori <aliguori@us.ibm.com>
Fri, 18 Dec 2009 11:01:07 +0000 (12:01 +0100)
committerAnthony Liguori <aliguori@us.ibm.com>
Fri, 18 Dec 2009 17:26:34 +0000 (11:26 -0600)
Currently, we preload option roms into the option rom space in memory.  This
prevents DDIM from functioning correctly which severely limits the number
of roms we can support.

This patch introduces a pci_add_option_rom() which registers the
PCI_ROM_ADDRESS bar which points to our option rom.  It also converts over
the cirrus vga adapter, the rtl8139, virtio, and the e1000 to use this
new mechanism.

The result is that PXE boot functions even with three unique types of cards.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
hw/cirrus_vga.c
hw/e1000.c
hw/pci.c
hw/pci.h
hw/rtl8139.c
hw/virtio-pci.c

index 24af81ceb10799c25435896fc479fb527ddac01e..b08d2aed752122b0b79b1f736e9dc57fa392e62c 100644 (file)
@@ -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;
 }
 
index 8566fe327690e1efe060729b08b04384f10b1af2..f7956010f15db3551c9bd772f13b371337722488 100644 (file)
@@ -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;
         }
     }
index 086da4f834ce842c9e891586b1a1a19e6545b196..b037fd8902262b74415cc82b55c22ecf974af7b1 100644 (file)
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -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)
 {
index dc9b8604fee5c6d4f2906503c97cd96a105a9867..d25fe507e0e1c5f69fe92a2172a1f910537c5f55 100644 (file)
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -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);
index 9fd05a8a1b25553d549bc27aeed6143664bdbfc5..2cee97bb7f5a021521df36b8c754b651c2ddb1d2 100644 (file)
@@ -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;
         }
     }
index 450013091c522d8713a2d47e843837a6c3acead4..85f14a2c233c0202eef875e2b2dd8e5e76151d99 100644 (file)
@@ -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;
         }
     }