aboutsummaryrefslogtreecommitdiff
path: root/hw/pci.c
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2009-12-18 12:01:07 +0100
committerAnthony Liguori <aliguori@us.ibm.com>2009-12-18 11:26:34 -0600
commitc2039bd0ffce8807e0eaac55254fde790825fa92 (patch)
treec3c35a7b5592ae1b882292e768e743129c8f9866 /hw/pci.c
parentec7efac4a967c650ae1cd8cebe28e7c69cbe3864 (diff)
Support PCI based option rom loading
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>
Diffstat (limited to 'hw/pci.c')
-rw-r--r--hw/pci.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/hw/pci.c b/hw/pci.c
index 086da4f834..b037fd8902 100644
--- 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)
{