提交 c2039bd0 编写于 作者: A Anthony Liguori

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: NAnthony Liguori <aliguori@us.ibm.com>
Signed-off-by: NGerd Hoffmann <kraxel@redhat.com>
Signed-off-by: NAnthony Liguori <aliguori@us.ibm.com>
上级 ec7efac4
......@@ -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;
}
......
......@@ -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);
......
......@@ -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;
}
}
......
......@@ -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;
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册