aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/pci_bridge.c22
-rw-r--r--hw/pci_internals.h15
2 files changed, 24 insertions, 13 deletions
diff --git a/hw/pci_bridge.c b/hw/pci_bridge.c
index 25e9b7c227..b6287cdc6d 100644
--- a/hw/pci_bridge.c
+++ b/hw/pci_bridge.c
@@ -160,26 +160,25 @@ static void pci_bridge_cleanup_alias(MemoryRegion *alias,
static void pci_bridge_region_init(PCIBridge *br)
{
- PCIBus *sec_bus = &br->sec_bus;
PCIBus *parent = br->dev.bus;
uint16_t cmd = pci_get_word(br->dev.config + PCI_COMMAND);
pci_bridge_init_alias(br, &br->alias_pref_mem,
PCI_BASE_ADDRESS_MEM_PREFETCH,
"pci_bridge_pref_mem",
- sec_bus->address_space_mem,
+ &br->address_space_mem,
parent->address_space_mem,
cmd & PCI_COMMAND_MEMORY);
pci_bridge_init_alias(br, &br->alias_mem,
PCI_BASE_ADDRESS_SPACE_MEMORY,
"pci_bridge_mem",
- sec_bus->address_space_mem,
+ &br->address_space_mem,
parent->address_space_mem,
cmd & PCI_COMMAND_MEMORY);
pci_bridge_init_alias(br, &br->alias_io,
PCI_BASE_ADDRESS_SPACE_IO,
"pci_bridge_io",
- sec_bus->address_space_io,
+ &br->address_space_io,
parent->address_space_io,
cmd & PCI_COMMAND_IO);
/* TODO: optinal VGA and VGA palette snooping support. */
@@ -319,10 +318,10 @@ int pci_bridge_initfn(PCIDevice *dev)
br->bus_name);
sec_bus->parent_dev = dev;
sec_bus->map_irq = br->map_irq;
- sec_bus->address_space_mem = g_new(MemoryRegion, 1);
- memory_region_init(sec_bus->address_space_mem, "pci_pridge_pci", INT64_MAX);
- sec_bus->address_space_io = g_new(MemoryRegion, 1);
- memory_region_init(sec_bus->address_space_io, "pci_bridge_io", 65536);
+ sec_bus->address_space_mem = &br->address_space_mem;
+ memory_region_init(&br->address_space_mem, "pci_pridge_pci", INT64_MAX);
+ sec_bus->address_space_io = &br->address_space_io;
+ memory_region_init(&br->address_space_io, "pci_bridge_io", 65536);
pci_bridge_region_init(br);
QLIST_INIT(&sec_bus->child);
QLIST_INSERT_HEAD(&parent->child, sec_bus, sibling);
@@ -333,14 +332,11 @@ int pci_bridge_initfn(PCIDevice *dev)
int pci_bridge_exitfn(PCIDevice *pci_dev)
{
PCIBridge *s = DO_UPCAST(PCIBridge, dev, pci_dev);
- PCIBus *sec_bus = &s->sec_bus;
assert(QLIST_EMPTY(&s->sec_bus.child));
QLIST_REMOVE(&s->sec_bus, sibling);
pci_bridge_region_cleanup(s);
- memory_region_destroy(sec_bus->address_space_mem);
- g_free(sec_bus->address_space_mem);
- memory_region_destroy(sec_bus->address_space_io);
- g_free(sec_bus->address_space_io);
+ memory_region_destroy(&s->address_space_mem);
+ memory_region_destroy(&s->address_space_io);
/* qbus_free() is called automatically by qdev_free() */
return 0;
}
diff --git a/hw/pci_internals.h b/hw/pci_internals.h
index 71c8b51fd0..96690b72d3 100644
--- a/hw/pci_internals.h
+++ b/hw/pci_internals.h
@@ -41,6 +41,21 @@ struct PCIBridge {
/* private member */
PCIBus sec_bus;
+ /*
+ * Memory regions for the bridge's address spaces. These regions are not
+ * directly added to system_memory/system_io or its descendants.
+ * Bridge's secondary bus points to these, so that devices
+ * under the bridge see these regions as its address spaces.
+ * The regions are as large as the entire address space -
+ * they don't take into account any windows.
+ */
+ MemoryRegion address_space_mem;
+ MemoryRegion address_space_io;
+ /*
+ * Aliases for each of the address space windows that the bridge
+ * can forward. Mapped into the bridge's parent's address space,
+ * as subregions.
+ */
MemoryRegion alias_pref_mem;
MemoryRegion alias_mem;
MemoryRegion alias_io;