Add registration functions to manipulate MMIO mappings. Signed-off-by: Blue Swirl <blauwir...@gmail.com> --- hw/pci.c | 49 +++++++++++++++++++++++++++++++++++++------------ hw/pci.h | 7 +++++++ 2 files changed, 44 insertions(+), 12 deletions(-)
diff --git a/hw/pci.c b/hw/pci.c index 1b20c44..3555ef3 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -47,6 +47,9 @@ struct PCIBus { PCIDevice *devices[256]; PCIDevice *parent_dev; target_phys_addr_t mem_base; + pci_register_mem_fn register_mem; + pci_unregister_mem_fn unregister_mem; + void *register_mem_opaque; QLIST_HEAD(, PCIBus) child; /* this will be replaced by qdev later */ QLIST_ENTRY(PCIBus) sibling;/* this will be replaced by qdev later */ @@ -177,6 +180,18 @@ static void pci_device_reset(PCIDevice *dev) pci_update_mappings(dev); } +static void pci_bus_default_register_mem(void *opaque, pcibus_t addr, + pcibus_t size, int mm) +{ + cpu_register_physical_memory(addr, size, mm); +} + +static void pci_bus_default_unregister_mem(void *opaque, pcibus_t addr, + pcibus_t size) +{ + cpu_register_physical_memory(addr, size, IO_MEM_UNASSIGNED); +} + static void pci_bus_reset(void *opaque) { PCIBus *bus = opaque; @@ -240,6 +255,8 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent, qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name); assert(PCI_FUNC(devfn_min) == 0); bus->devfn_min = devfn_min; + bus->register_mem = pci_bus_default_register_mem; + bus->unregister_mem = pci_bus_default_unregister_mem; /* host bridge */ QLIST_INIT(&bus->child); @@ -761,10 +778,10 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev) if (r->type == PCI_BASE_ADDRESS_SPACE_IO) { isa_unassign_ioport(r->addr + s->offset, s->filtered_size); } else { - cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus, - r->addr + s->offset), - s->filtered_size, - IO_MEM_UNASSIGNED); + pci_dev->bus->unregister_mem(pci_dev->bus->register_mem_opaque, + pci_to_cpu_addr(pci_dev->bus, + r->addr + s->offset), + s->filtered_size); } } } @@ -1015,6 +1032,14 @@ static pcibus_t pci_bar_address(PCIDevice *d, return new_addr; } +void pci_bus_set_register_mem_fn(PCIBus *bus, pci_register_mem_fn regfn, + pci_unregister_mem_fn unregfn, void *opaque) +{ + bus->register_mem = regfn; + bus->unregister_mem = unregfn; + bus->register_mem_opaque = opaque; +} + static void pci_update_mappings(PCIDevice *d) { PCIIORegion *r; @@ -1066,11 +1091,11 @@ static void pci_update_mappings(PCIDevice *d) s->filtered_size); } } else { - cpu_register_physical_memory(pci_to_cpu_addr(d->bus, - r->addr + - s->offset), - s->filtered_size, - IO_MEM_UNASSIGNED); + d->bus->unregister_mem(d->bus->register_mem_opaque, + pci_to_cpu_addr(d->bus, + r->addr + + s->offset), + s->filtered_size); qemu_unregister_coalesced_mmio(r->addr + s->offset, s->filtered_size); } @@ -1092,9 +1117,9 @@ static void pci_update_mappings(PCIDevice *d) r->type); } } else { - cpu_register_physical_memory(pci_to_cpu_addr(d->bus, - new_addr), - s->filtered_size, s->ix); + d->bus->register_mem(d->bus->register_mem_opaque, + pci_to_cpu_addr(d->bus, new_addr), + s->filtered_size, s->ix); if (r->post_map_func) { r->post_map_func(d, i, pci_to_cpu_addr(d->bus, new_addr), diff --git a/hw/pci.h b/hw/pci.h index ac1836e..8c2b84c 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -228,6 +228,13 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name, void pci_bus_set_mem_base(PCIBus *bus, target_phys_addr_t base); +typedef void (*pci_register_mem_fn)(void *opaque, pcibus_t addr, pcibus_t size, + int mm); +typedef void (*pci_unregister_mem_fn)(void *opaque, pcibus_t addr, + pcibus_t size); +void pci_bus_set_register_mem_fn(PCIBus *bus, pci_register_mem_fn regfn, + pci_unregister_mem_fn unregfn, void *opaque); + PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model, const char *default_devaddr); PCIDevice *pci_nic_init_nofail(NICInfo *nd, const char *default_model, -- 1.6.2.4