Patchwork [26/34] pci: add registration for MMIO manipulation functions

login
register
mail settings
Submitter Blue Swirl
Date July 22, 2010, 10:01 p.m.
Message ID <AANLkTinqAuVW5962hVjWKd0vdQtJZL_CMz_IeJeOe_FE@mail.gmail.com>
Download mbox | patch
Permalink /patch/59658/
State New
Headers show

Comments

Blue Swirl - July 22, 2010, 10:01 p.m.
Add registration functions to manipulate MMIO mappings.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 hw/pci.c |   49 +++++++++++++++++++++++++++++++++++++------------
 hw/pci.h |    7 +++++++
 2 files changed, 44 insertions(+), 12 deletions(-)

 PCIDevice *pci_nic_init_nofail(NICInfo *nd, const char *default_model,

Patch

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);