#include "qmp-commands.h"
#include "msi.h"
#include "msix.h"
+#include "exec-memory.h"
//#define DEBUG_PCI
#ifdef DEBUG_PCI
pci_dev->bus = bus;
if (bus->dma_context_fn) {
pci_dev->dma = bus->dma_context_fn(bus, bus->dma_context_opaque, devfn);
+ } else {
+ /* FIXME: Make dma_context_fn use MemoryRegions instead, so this path is
+ * taken unconditionally */
+ /* FIXME: inherit memory region from bus creator */
+ memory_region_init_alias(&pci_dev->bus_master_enable_region, "bus master",
+ get_system_memory(), 0,
+ memory_region_size(get_system_memory()));
+ memory_region_set_enabled(&pci_dev->bus_master_enable_region, false);
+ address_space_init(&pci_dev->bus_master_as, &pci_dev->bus_master_enable_region);
+ pci_dev->dma = g_new(DMAContext, 1);
+ dma_context_init(pci_dev->dma, &pci_dev->bus_master_as, NULL, NULL, NULL);
}
pci_dev->devfn = devfn;
pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
qemu_free_irqs(pci_dev->irq);
pci_dev->bus->devices[pci_dev->devfn] = NULL;
pci_config_free(pci_dev);
+
+ if (!pci_dev->bus->dma_context_fn) {
+ address_space_destroy(&pci_dev->bus_master_as);
+ memory_region_destroy(&pci_dev->bus_master_enable_region);
+ g_free(pci_dev->dma);
+ pci_dev->dma = NULL;
+ }
}
static void pci_unregister_io_regions(PCIDevice *pci_dev)
* to >4G. Check it. TODO: we might need to support
* it in the future for e.g. PAE.
*/
- if (last_addr >= TARGET_PHYS_ADDR_MAX) {
+ if (last_addr >= HWADDR_MAX) {
return PCI_BAR_UNMAPPED;
}
range_covers_byte(addr, l, PCI_COMMAND))
pci_update_mappings(d);
- if (range_covers_byte(addr, l, PCI_COMMAND))
+ if (range_covers_byte(addr, l, PCI_COMMAND)) {
pci_update_irq_disabled(d, was_irq_disabled);
+ memory_region_set_enabled(&d->bus_master_enable_region,
+ pci_get_word(d->config + PCI_COMMAND)
+ & PCI_COMMAND_MASTER);
+ }
msi_write_config(d, addr, val, l);
msix_write_config(d, addr, val, l);
return res;
}
+PCIDevice *pci_vga_init(PCIBus *bus)
+{
+ switch (vga_interface_type) {
+ case VGA_CIRRUS:
+ return pci_create_simple(bus, -1, "cirrus-vga");
+ case VGA_QXL:
+ return pci_create_simple(bus, -1, "qxl-vga");
+ case VGA_STD:
+ return pci_create_simple(bus, -1, "VGA");
+ case VGA_VMWARE:
+ return pci_create_simple(bus, -1, "vmware-svga");
+ case VGA_NONE:
+ default: /* Other non-PCI types. Checking for unsupported types is already
+ done in vl.c. */
+ return NULL;
+ }
+}
+
/* Whether a given bus number is in range of the secondary
* bus of the given bridge device. */
static bool pci_secondary_bus_in_range(PCIDevice *dev, int bus_num)
PCI_SLOT(d->devfn));
if (PCI_FUNC(d->devfn))
snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn));
- return strdup(path);
+ return g_strdup(path);
}
static char *pcibus_get_dev_path(DeviceState *dev)