All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC v3 00/56] Memory API
@ 2011-07-10 18:14 ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

New in this version:
- use opaque instead of container_of() in memory callbacks
   - turns out those container_of()s were hindering reuse
- I/O space access via memory API
- PCI fully converted
   - except bridge, which actually benefits most from the conversion
- ioeventfd support


Caveats:
- some devices still grab a global memory region instead of inheriting
  it from their bus.  Seen in the code as #include "exec-memory.h"
- the conversion from separate b/w/l functions to a single function with a
  size argument sometimes yields ugly dispatch functions.  In some cases
  I eliminated them, in others I left it to the device maintainer.

I also have an idea now how to kill off the page descriptor - use a page
table like x86, but with no offset bits, have a variable tree height and
allow any level to be a "large page".  This results in most accesses
terminating after one or two lookups.  MMIO will tend to take more (three to
five, depending on tree width), but they will be cached.

The subpage logic can be completely eliminated with this.

Avi Kivity (56):
  Hierarchical memory region API
  memory: implement dirty tracking
  memory: merge adjacent segments of a single memory region
  Internal interfaces for memory API
  memory: abstract address space operations
  memory: rename MemoryRegion::has_ram_addr to ::terminates
  memory: late initialization of ram_addr
  memory:  I/O address space support
  exec.c: initialize memory map
  ioport: register ranges by byte aligned addresses always
  pc: grab system_memory
  pc: convert pc_memory_init() to memory API
  pc: move global memory map out of pc_init1() and into its callers
  pci: pass address space to pci bus when created
  pci: add MemoryRegion based BAR management API
  sysbus: add MemoryRegion based memory management API
  usb-ohci: convert to MemoryRegion
  pci: add API to get a BAR's mapped address
  vmsvga: don't remember pci BAR address in callback any more
  vga: convert vga and its derivatives to the memory API
  cirrus: simplify mmio BAR access functions
  cirrus: simplify bitblt BAR access functions
  cirrus: simplify vga window mmio access functions
  vga: simplify vga window mmio access functions
  cirrus: simplify linear framebuffer access functions
  Integrate I/O memory regions into qemu
  exec.c: fix initialization of system I/O memory region
  pci: pass I/O address space to new PCI bus
  pci: allow I/O BARs to be registered with pci_register_bar_region()
  rtl8139: convert to memory API
  ac97: convert to memory API
  e1000: convert to memory API
  eepro100: convert to memory API
  es1370: convert to memory API
  ide: convert to memory API
  memory: add ioeventfd support
  ivshmem: convert to memory API
  virtio-pci: convert to memory API
  ahci: convert to memory API
  intel-hda: convert to memory API
  lsi53c895a: convert to memory API
  ppc: convert to memory API
  ne2000: convert to memory API
  pcnet: convert to memory API
  i6300esb: convert to memory API
  isa-mmio: concert to memory API
  sun4u: convert to memory API
  ehci: convert to memory API
  uhci: convert to memory API
  xen-platform: convert to memory API
  msix: convert to memory API
  pci: remove pci_register_bar_simple()
  pci: convert pci rom to memory API
  pci: remove pci_register_bar()
  pci: fold BAR mapping function into its caller
  pci: rename pci_register_bar_region() to pci_register_bar()

 Makefile.target    |    1 +
 exec-memory.h      |   28 ++
 exec.c             |   29 ++
 hw/ac97.c          |  126 +++++--
 hw/apb_pci.c       |    3 +
 hw/bonito.c        |    5 +-
 hw/cirrus_vga.c    |  460 ++++++++----------------
 hw/cuda.c          |    6 +-
 hw/e1000.c         |  113 +++----
 hw/eepro100.c      |  181 ++--------
 hw/es1370.c        |   62 +++-
 hw/escc.c          |   42 +--
 hw/escc.h          |    2 +-
 hw/grackle_pci.c   |    9 +-
 hw/gt64xxx.c       |    6 +-
 hw/heathrow_pic.c  |   29 +-
 hw/ide.h           |    2 +-
 hw/ide/ahci.c      |   31 +-
 hw/ide/ahci.h      |    2 +-
 hw/ide/cmd646.c    |  204 +++++++----
 hw/ide/ich.c       |    3 +-
 hw/ide/macio.c     |   50 ++-
 hw/ide/pci.c       |   25 +-
 hw/ide/pci.h       |   19 +-
 hw/ide/piix.c      |   63 +++-
 hw/ide/via.c       |   64 +++-
 hw/intel-hda.c     |   49 ++-
 hw/isa.h           |    2 +
 hw/isa_mmio.c      |   67 ++--
 hw/ivshmem.c       |  158 +++-----
 hw/lance.c         |   31 +-
 hw/lsi53c895a.c    |  257 +++----------
 hw/mac_dbdma.c     |   32 +-
 hw/mac_dbdma.h     |    4 +-
 hw/mac_nvram.c     |   39 +--
 hw/macio.c         |   73 ++--
 hw/msix.c          |   64 ++--
 hw/msix.h          |    6 +-
 hw/ne2000-isa.c    |   14 +-
 hw/ne2000.c        |   77 +++--
 hw/ne2000.h        |    8 +-
 hw/openpic.c       |   81 ++---
 hw/openpic.h       |    2 +-
 hw/pc.c            |   62 ++-
 hw/pc.h            |   11 +-
 hw/pc_piix.c       |   24 +-
 hw/pci.c           |  104 +++---
 hw/pci.h           |   30 +-
 hw/pci_host.h      |    1 +
 hw/pci_internals.h |    2 +
 hw/pcnet-pci.c     |   98 ++++--
 hw/pcnet.h         |    4 +-
 hw/piix_pci.c      |   17 +-
 hw/ppc4xx_pci.c    |    6 +-
 hw/ppc_mac.h       |   30 +-
 hw/ppc_newworld.c  |   35 +-
 hw/ppc_oldworld.c  |   28 +-
 hw/ppc_prep.c      |    3 +-
 hw/ppce500_pci.c   |    7 +-
 hw/prep_pci.c      |    9 +-
 hw/prep_pci.h      |    5 +-
 hw/qxl-render.c    |    2 +-
 hw/qxl.c           |  125 +++----
 hw/qxl.h           |    6 +-
 hw/rtl8139.c       |  170 +++------
 hw/sh_pci.c        |    6 +-
 hw/sun4u.c         |   53 ++--
 hw/sysbus.c        |   27 ++-
 hw/sysbus.h        |    3 +
 hw/unin_pci.c      |   18 +-
 hw/usb-ehci.c      |   53 ++--
 hw/usb-ohci.c      |   42 +--
 hw/usb-uhci.c      |   56 +++-
 hw/versatile_pci.c |    2 +
 hw/vga-isa-mm.c    |   61 +++-
 hw/vga-isa.c       |   11 +-
 hw/vga-pci.c       |   27 +--
 hw/vga.c           |  178 ++++------
 hw/vga_int.h       |   19 +-
 hw/virtio-pci.c    |   99 +++---
 hw/virtio-pci.h    |    3 +-
 hw/vmware_vga.c    |  175 +++++----
 hw/wdt_i6300esb.c  |   59 +++-
 hw/xen_platform.c  |  109 ++++--
 ioport.c           |    4 +-
 memory.c           | 1050 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 memory.h           |  224 +++++++++++
 87 files changed, 3403 insertions(+), 2184 deletions(-)
 create mode 100644 exec-memory.h
 create mode 100644 memory.c
 create mode 100644 memory.h

-- 
1.7.5.3


^ permalink raw reply	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 00/56] Memory API
@ 2011-07-10 18:14 ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

New in this version:
- use opaque instead of container_of() in memory callbacks
   - turns out those container_of()s were hindering reuse
- I/O space access via memory API
- PCI fully converted
   - except bridge, which actually benefits most from the conversion
- ioeventfd support


Caveats:
- some devices still grab a global memory region instead of inheriting
  it from their bus.  Seen in the code as #include "exec-memory.h"
- the conversion from separate b/w/l functions to a single function with a
  size argument sometimes yields ugly dispatch functions.  In some cases
  I eliminated them, in others I left it to the device maintainer.

I also have an idea now how to kill off the page descriptor - use a page
table like x86, but with no offset bits, have a variable tree height and
allow any level to be a "large page".  This results in most accesses
terminating after one or two lookups.  MMIO will tend to take more (three to
five, depending on tree width), but they will be cached.

The subpage logic can be completely eliminated with this.

Avi Kivity (56):
  Hierarchical memory region API
  memory: implement dirty tracking
  memory: merge adjacent segments of a single memory region
  Internal interfaces for memory API
  memory: abstract address space operations
  memory: rename MemoryRegion::has_ram_addr to ::terminates
  memory: late initialization of ram_addr
  memory:  I/O address space support
  exec.c: initialize memory map
  ioport: register ranges by byte aligned addresses always
  pc: grab system_memory
  pc: convert pc_memory_init() to memory API
  pc: move global memory map out of pc_init1() and into its callers
  pci: pass address space to pci bus when created
  pci: add MemoryRegion based BAR management API
  sysbus: add MemoryRegion based memory management API
  usb-ohci: convert to MemoryRegion
  pci: add API to get a BAR's mapped address
  vmsvga: don't remember pci BAR address in callback any more
  vga: convert vga and its derivatives to the memory API
  cirrus: simplify mmio BAR access functions
  cirrus: simplify bitblt BAR access functions
  cirrus: simplify vga window mmio access functions
  vga: simplify vga window mmio access functions
  cirrus: simplify linear framebuffer access functions
  Integrate I/O memory regions into qemu
  exec.c: fix initialization of system I/O memory region
  pci: pass I/O address space to new PCI bus
  pci: allow I/O BARs to be registered with pci_register_bar_region()
  rtl8139: convert to memory API
  ac97: convert to memory API
  e1000: convert to memory API
  eepro100: convert to memory API
  es1370: convert to memory API
  ide: convert to memory API
  memory: add ioeventfd support
  ivshmem: convert to memory API
  virtio-pci: convert to memory API
  ahci: convert to memory API
  intel-hda: convert to memory API
  lsi53c895a: convert to memory API
  ppc: convert to memory API
  ne2000: convert to memory API
  pcnet: convert to memory API
  i6300esb: convert to memory API
  isa-mmio: concert to memory API
  sun4u: convert to memory API
  ehci: convert to memory API
  uhci: convert to memory API
  xen-platform: convert to memory API
  msix: convert to memory API
  pci: remove pci_register_bar_simple()
  pci: convert pci rom to memory API
  pci: remove pci_register_bar()
  pci: fold BAR mapping function into its caller
  pci: rename pci_register_bar_region() to pci_register_bar()

 Makefile.target    |    1 +
 exec-memory.h      |   28 ++
 exec.c             |   29 ++
 hw/ac97.c          |  126 +++++--
 hw/apb_pci.c       |    3 +
 hw/bonito.c        |    5 +-
 hw/cirrus_vga.c    |  460 ++++++++----------------
 hw/cuda.c          |    6 +-
 hw/e1000.c         |  113 +++----
 hw/eepro100.c      |  181 ++--------
 hw/es1370.c        |   62 +++-
 hw/escc.c          |   42 +--
 hw/escc.h          |    2 +-
 hw/grackle_pci.c   |    9 +-
 hw/gt64xxx.c       |    6 +-
 hw/heathrow_pic.c  |   29 +-
 hw/ide.h           |    2 +-
 hw/ide/ahci.c      |   31 +-
 hw/ide/ahci.h      |    2 +-
 hw/ide/cmd646.c    |  204 +++++++----
 hw/ide/ich.c       |    3 +-
 hw/ide/macio.c     |   50 ++-
 hw/ide/pci.c       |   25 +-
 hw/ide/pci.h       |   19 +-
 hw/ide/piix.c      |   63 +++-
 hw/ide/via.c       |   64 +++-
 hw/intel-hda.c     |   49 ++-
 hw/isa.h           |    2 +
 hw/isa_mmio.c      |   67 ++--
 hw/ivshmem.c       |  158 +++-----
 hw/lance.c         |   31 +-
 hw/lsi53c895a.c    |  257 +++----------
 hw/mac_dbdma.c     |   32 +-
 hw/mac_dbdma.h     |    4 +-
 hw/mac_nvram.c     |   39 +--
 hw/macio.c         |   73 ++--
 hw/msix.c          |   64 ++--
 hw/msix.h          |    6 +-
 hw/ne2000-isa.c    |   14 +-
 hw/ne2000.c        |   77 +++--
 hw/ne2000.h        |    8 +-
 hw/openpic.c       |   81 ++---
 hw/openpic.h       |    2 +-
 hw/pc.c            |   62 ++-
 hw/pc.h            |   11 +-
 hw/pc_piix.c       |   24 +-
 hw/pci.c           |  104 +++---
 hw/pci.h           |   30 +-
 hw/pci_host.h      |    1 +
 hw/pci_internals.h |    2 +
 hw/pcnet-pci.c     |   98 ++++--
 hw/pcnet.h         |    4 +-
 hw/piix_pci.c      |   17 +-
 hw/ppc4xx_pci.c    |    6 +-
 hw/ppc_mac.h       |   30 +-
 hw/ppc_newworld.c  |   35 +-
 hw/ppc_oldworld.c  |   28 +-
 hw/ppc_prep.c      |    3 +-
 hw/ppce500_pci.c   |    7 +-
 hw/prep_pci.c      |    9 +-
 hw/prep_pci.h      |    5 +-
 hw/qxl-render.c    |    2 +-
 hw/qxl.c           |  125 +++----
 hw/qxl.h           |    6 +-
 hw/rtl8139.c       |  170 +++------
 hw/sh_pci.c        |    6 +-
 hw/sun4u.c         |   53 ++--
 hw/sysbus.c        |   27 ++-
 hw/sysbus.h        |    3 +
 hw/unin_pci.c      |   18 +-
 hw/usb-ehci.c      |   53 ++--
 hw/usb-ohci.c      |   42 +--
 hw/usb-uhci.c      |   56 +++-
 hw/versatile_pci.c |    2 +
 hw/vga-isa-mm.c    |   61 +++-
 hw/vga-isa.c       |   11 +-
 hw/vga-pci.c       |   27 +--
 hw/vga.c           |  178 ++++------
 hw/vga_int.h       |   19 +-
 hw/virtio-pci.c    |   99 +++---
 hw/virtio-pci.h    |    3 +-
 hw/vmware_vga.c    |  175 +++++----
 hw/wdt_i6300esb.c  |   59 +++-
 hw/xen_platform.c  |  109 ++++--
 ioport.c           |    4 +-
 memory.c           | 1050 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 memory.h           |  224 +++++++++++
 87 files changed, 3403 insertions(+), 2184 deletions(-)
 create mode 100644 exec-memory.h
 create mode 100644 memory.c
 create mode 100644 memory.h

-- 
1.7.5.3

^ permalink raw reply	[flat|nested] 131+ messages in thread

* [RFC v3 01/56] Hierarchical memory region API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

The memory API separates the attributes of a memory region (its size, how
reads or writes are handled, dirty logging, and coalescing) from where it
is mapped and whether it is enabled.  This allows a device to configure
a memory region once, then hand it off to its parent bus to map it according
to the bus configuration.

Hierarchical registration also allows a device to compose a region out of
a number of sub-regions with different properties; for example some may be
RAM while others may be MMIO.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 Makefile.target |    1 +
 memory.c        |  655 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 memory.h        |  200 +++++++++++++++++
 3 files changed, 856 insertions(+), 0 deletions(-)
 create mode 100644 memory.c
 create mode 100644 memory.h

diff --git a/Makefile.target b/Makefile.target
index a53a2ff..2cacd80 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -197,6 +197,7 @@ obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
 obj-y += rwhandler.o
 obj-$(CONFIG_KVM) += kvm.o kvm-all.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
+obj-y += memory.o
 LIBS+=-lz
 
 QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
diff --git a/memory.c b/memory.c
new file mode 100644
index 0000000..10591bf
--- /dev/null
+++ b/memory.c
@@ -0,0 +1,655 @@
+/*
+ * Physical memory management
+ *
+ * Copyright 2011 Red Hat, Inc. and/or its affiliates
+ *
+ * Authors:
+ *  Avi Kivity <avi@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "memory.h"
+#include <assert.h>
+
+typedef struct AddrRange AddrRange;
+
+struct AddrRange {
+    uint64_t start;
+    uint64_t size;
+};
+
+static AddrRange addrrange_make(uint64_t start, uint64_t size)
+{
+    return (AddrRange) { start, size };
+}
+
+static bool addrrange_equal(AddrRange r1, AddrRange r2)
+{
+    return r1.start == r2.start && r1.size == r2.size;
+}
+
+static uint64_t addrrange_end(AddrRange r)
+{
+    return r.start + r.size;
+}
+
+static AddrRange addrrange_shift(AddrRange range, int64_t delta)
+{
+    range.start += delta;
+    return range;
+}
+
+static bool addrrange_intersects(AddrRange r1, AddrRange r2)
+{
+    return (r1.start >= r2.start && r1.start < r2.start + r2.size)
+        || (r2.start >= r1.start && r2.start < r1.start + r1.size);
+}
+
+static AddrRange addrrange_intersection(AddrRange r1, AddrRange r2)
+{
+    uint64_t start = MAX(r1.start, r2.start);
+    /* off-by-one arithmetic to prevent overflow */
+    uint64_t end = MIN(addrrange_end(r1) - 1, addrrange_end(r2) - 1);
+    return addrrange_make(start, end - start + 1);
+}
+
+struct CoalescedMemoryRange {
+    AddrRange addr;
+    QTAILQ_ENTRY(CoalescedMemoryRange) link;
+};
+
+typedef struct FlatRange FlatRange;
+typedef struct FlatView FlatView;
+
+/* Range of memory in the global map.  Addresses are absolute. */
+struct FlatRange {
+    MemoryRegion *mr;
+    target_phys_addr_t offset_in_region;
+    AddrRange addr;
+};
+
+/* Flattened global view of current active memory hierarchy.  Kept in sorted
+ * order.
+ */
+struct FlatView {
+    FlatRange *ranges;
+    unsigned nr;
+    unsigned nr_allocated;
+};
+
+#define FOR_EACH_FLAT_RANGE(var, view)          \
+    for (var = (view)->ranges; var < (view)->ranges + (view)->nr; ++var)
+
+static FlatView current_memory_map;
+static MemoryRegion *root_memory_region;
+
+static bool flatrange_equal(FlatRange *a, FlatRange *b)
+{
+    return a->mr == b->mr
+        && addrrange_equal(a->addr, b->addr)
+        && a->offset_in_region == b->offset_in_region;
+}
+
+static void flatview_init(FlatView *view)
+{
+    view->ranges = NULL;
+    view->nr = 0;
+    view->nr_allocated = 0;
+}
+
+/* Insert a range into a given position.  Caller is responsible for maintaining
+ * sorting order.
+ */
+static void flatview_insert(FlatView *view, unsigned pos, FlatRange *range)
+{
+    if (view->nr == view->nr_allocated) {
+        view->nr_allocated = MAX(2 * view->nr, 10);
+        view->ranges = qemu_realloc(view->ranges,
+                                    view->nr_allocated * sizeof(*view->ranges));
+    }
+    memmove(view->ranges + pos + 1, view->ranges + pos,
+            (view->nr - pos) * sizeof(FlatRange));
+    view->ranges[pos] = *range;
+    ++view->nr;
+}
+
+static void flatview_destroy(FlatView *view)
+{
+    qemu_free(view->ranges);
+}
+
+/* Render a memory region into the global view.  Ranges in @view obscure
+ * ranges in @mr.
+ */
+static void render_memory_region(FlatView *view,
+                                 MemoryRegion *mr,
+                                 target_phys_addr_t base,
+                                 AddrRange clip)
+{
+    MemoryRegion *subregion;
+    unsigned i;
+    target_phys_addr_t offset_in_region;
+    uint64_t remain;
+    uint64_t now;
+    FlatRange fr;
+    AddrRange tmp;
+
+    base += mr->addr;
+
+    tmp = addrrange_make(base, mr->size);
+
+    if (!addrrange_intersects(tmp, clip)) {
+        return;
+    }
+
+    clip = addrrange_intersection(tmp, clip);
+
+    if (mr->alias) {
+        base -= mr->alias->addr;
+        base -= mr->alias_offset;
+        render_memory_region(view, mr->alias, base, clip);
+        return;
+    }
+
+    /* Render subregions in priority order. */
+    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
+        render_memory_region(view, subregion, base, clip);
+    }
+
+    if (!mr->has_ram_addr) {
+        return;
+    }
+
+    offset_in_region = clip.start - base;
+    base = clip.start;
+    remain = clip.size;
+
+    /* Render the region itself into any gaps left by the current view. */
+    for (i = 0; i < view->nr && remain; ++i) {
+        if (base >= addrrange_end(view->ranges[i].addr)) {
+            continue;
+        }
+        if (base < view->ranges[i].addr.start) {
+            now = MIN(remain, view->ranges[i].addr.start - base);
+            fr.mr = mr;
+            fr.offset_in_region = offset_in_region;
+            fr.addr = addrrange_make(base, now);
+            flatview_insert(view, i, &fr);
+            ++i;
+            base += now;
+            offset_in_region += now;
+            remain -= now;
+        }
+        if (base == view->ranges[i].addr.start) {
+            now = MIN(remain, view->ranges[i].addr.size);
+            base += now;
+            offset_in_region += now;
+            remain -= now;
+        }
+    }
+    if (remain) {
+        fr.mr = mr;
+        fr.offset_in_region = offset_in_region;
+        fr.addr = addrrange_make(base, remain);
+        flatview_insert(view, i, &fr);
+    }
+}
+
+/* Render a memory topology into a list of disjoint absolute ranges. */
+static FlatView generate_memory_topology(MemoryRegion *mr)
+{
+    FlatView view;
+
+    flatview_init(&view);
+
+    render_memory_region(&view, mr, 0, addrrange_make(0, UINT64_MAX));
+
+    return view;
+}
+
+static void memory_region_update_topology(void)
+{
+    FlatView old_view = current_memory_map;
+    FlatView new_view = generate_memory_topology(root_memory_region);
+    unsigned iold, inew;
+    FlatRange *frold, *frnew;
+    ram_addr_t phys_offset, region_offset;
+
+    /* Generate a symmetric difference of the old and new memory maps.
+     * Kill ranges in the old map, and instantiate ranges in the new map.
+     */
+    iold = inew = 0;
+    while (iold < old_view.nr || inew < new_view.nr) {
+        if (iold < old_view.nr) {
+            frold = &old_view.ranges[iold];
+        } else {
+            frold = NULL;
+        }
+        if (inew < new_view.nr) {
+            frnew = &new_view.ranges[inew];
+        } else {
+            frnew = NULL;
+        }
+
+        if (frold
+            && (!frnew
+                || frold->addr.start < frnew->addr.start
+                || (frold->addr.start == frnew->addr.start
+                    && !flatrange_equal(frold, frnew)))) {
+            /* In old, but (not in new, or in new but attributes changed). */
+
+            cpu_register_physical_memory(frold->addr.start, frold->addr.size,
+                                         IO_MEM_UNASSIGNED);
+            ++iold;
+        } else if (frold && frnew && flatrange_equal(frold, frnew)) {
+            /* In both (logging may have changed) */
+
+            ++iold;
+            ++inew;
+            /* FIXME: dirty logging */
+        } else {
+            /* In new */
+
+            phys_offset = frnew->mr->ram_addr;
+            region_offset = frnew->offset_in_region;
+            /* cpu_register_physical_memory_log() wants region_offset for
+             * mmio, but prefers offseting phys_offset for RAM.  Humour it.
+             */
+            if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) {
+                phys_offset += region_offset;
+                region_offset = 0;
+            }
+
+            cpu_register_physical_memory_log(frnew->addr.start,
+                                             frnew->addr.size,
+                                             phys_offset,
+                                             region_offset,
+                                             0);
+            ++inew;
+        }
+    }
+    current_memory_map = new_view;
+    flatview_destroy(&old_view);
+}
+
+void memory_region_init(MemoryRegion *mr,
+                        const char *name,
+                        uint64_t size)
+{
+    mr->ops = NULL;
+    mr->parent = NULL;
+    mr->size = size;
+    mr->addr = 0;
+    mr->offset = 0;
+    mr->has_ram_addr = false;
+    mr->priority = 0;
+    mr->may_overlap = false;
+    mr->alias = NULL;
+    QTAILQ_INIT(&mr->subregions);
+    memset(&mr->subregions_link, 0, sizeof mr->subregions_link);
+    QTAILQ_INIT(&mr->coalesced);
+    mr->name = qemu_strdup(name);
+}
+
+static bool memory_region_access_valid(MemoryRegion *mr,
+                                       target_phys_addr_t addr,
+                                       unsigned size)
+{
+    if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
+        return false;
+    }
+
+    /* Treat zero as compatibility all valid */
+    if (!mr->ops->valid.max_access_size) {
+        return true;
+    }
+
+    if (size > mr->ops->valid.max_access_size
+        || size < mr->ops->valid.min_access_size) {
+        return false;
+    }
+    return true;
+}
+
+static uint32_t memory_region_read_thunk_n(void *_mr,
+                                           target_phys_addr_t addr,
+                                           unsigned size)
+{
+    MemoryRegion *mr = _mr;
+    unsigned access_size, access_size_min, access_size_max;
+    uint64_t access_mask;
+    uint32_t data = 0, tmp;
+    unsigned i;
+
+    if (!memory_region_access_valid(mr, addr, size)) {
+        return -1U; /* FIXME: better signalling */
+    }
+
+    /* FIXME: support unaligned access */
+
+    access_size_min = mr->ops->impl.min_access_size;
+    if (!access_size_min) {
+        access_size_min = 1;
+    }
+    access_size_max = mr->ops->impl.max_access_size;
+    if (!access_size_max) {
+        access_size_max = 4;
+    }
+    access_size = MAX(MIN(size, access_size_max), access_size_min);
+    access_mask = -1ULL >> (64 - access_size * 8);
+    addr += mr->offset;
+    for (i = 0; i < size; i += access_size) {
+        /* FIXME: big-endian support */
+        tmp = mr->ops->read(mr->opaque, addr + i, access_size);
+        data |= (tmp & access_mask) << (i * 8);
+    }
+
+    return data;
+}
+
+static void memory_region_write_thunk_n(void *_mr,
+                                        target_phys_addr_t addr,
+                                        unsigned size,
+                                        uint64_t data)
+{
+    MemoryRegion *mr = _mr;
+    unsigned access_size, access_size_min, access_size_max;
+    uint64_t access_mask;
+    unsigned i;
+
+    if (!memory_region_access_valid(mr, addr, size)) {
+        return; /* FIXME: better signalling */
+    }
+
+    /* FIXME: support unaligned access */
+
+    access_size_min = mr->ops->impl.min_access_size;
+    if (!access_size_min) {
+        access_size_min = 1;
+    }
+    access_size_max = mr->ops->impl.max_access_size;
+    if (!access_size_max) {
+        access_size_max = 4;
+    }
+    access_size = MAX(MIN(size, access_size_max), access_size_min);
+    access_mask = -1ULL >> (64 - access_size * 8);
+    addr += mr->offset;
+    for (i = 0; i < size; i += access_size) {
+        /* FIXME: big-endian support */
+        mr->ops->write(mr->opaque, addr + i, (data >> (i * 8)) & access_mask,
+                       access_size);
+    }
+}
+
+static uint32_t memory_region_read_thunk_b(void *mr, target_phys_addr_t addr)
+{
+    return memory_region_read_thunk_n(mr, addr, 1);
+}
+
+static uint32_t memory_region_read_thunk_w(void *mr, target_phys_addr_t addr)
+{
+    return memory_region_read_thunk_n(mr, addr, 2);
+}
+
+static uint32_t memory_region_read_thunk_l(void *mr, target_phys_addr_t addr)
+{
+    return memory_region_read_thunk_n(mr, addr, 4);
+}
+
+static void memory_region_write_thunk_b(void *mr, target_phys_addr_t addr,
+                                        uint32_t data)
+{
+    memory_region_write_thunk_n(mr, addr, 1, data);
+}
+
+static void memory_region_write_thunk_w(void *mr, target_phys_addr_t addr,
+                                        uint32_t data)
+{
+    memory_region_write_thunk_n(mr, addr, 2, data);
+}
+
+static void memory_region_write_thunk_l(void *mr, target_phys_addr_t addr,
+                                        uint32_t data)
+{
+    memory_region_write_thunk_n(mr, addr, 4, data);
+}
+
+static CPUReadMemoryFunc * const memory_region_read_thunk[] = {
+    memory_region_read_thunk_b,
+    memory_region_read_thunk_w,
+    memory_region_read_thunk_l,
+};
+
+static CPUWriteMemoryFunc * const memory_region_write_thunk[] = {
+    memory_region_write_thunk_b,
+    memory_region_write_thunk_w,
+    memory_region_write_thunk_l,
+};
+
+void memory_region_init_io(MemoryRegion *mr,
+                           const MemoryRegionOps *ops,
+                           void *opaque,
+                           const char *name,
+                           uint64_t size)
+{
+    memory_region_init(mr, name, size);
+    mr->ops = ops;
+    mr->opaque = opaque;
+    mr->has_ram_addr = true;
+    mr->ram_addr = cpu_register_io_memory(memory_region_read_thunk,
+                                          memory_region_write_thunk,
+                                          mr,
+                                          mr->ops->endianness);
+}
+
+void memory_region_init_ram(MemoryRegion *mr,
+                            DeviceState *dev,
+                            const char *name,
+                            uint64_t size)
+{
+    memory_region_init(mr, name, size);
+    mr->has_ram_addr = true;
+    mr->ram_addr = qemu_ram_alloc(dev, name, size);
+}
+
+void memory_region_init_ram_ptr(MemoryRegion *mr,
+                                DeviceState *dev,
+                                const char *name,
+                                uint64_t size,
+                                void *ptr)
+{
+    memory_region_init(mr, name, size);
+    mr->has_ram_addr = true;
+    mr->ram_addr = qemu_ram_alloc_from_ptr(dev, name, size, ptr);
+}
+
+void memory_region_init_alias(MemoryRegion *mr,
+                              const char *name,
+                              MemoryRegion *orig,
+                              target_phys_addr_t offset,
+                              uint64_t size)
+{
+    memory_region_init(mr, name, size);
+    mr->alias = orig;
+    mr->alias_offset = offset;
+}
+
+void memory_region_destroy(MemoryRegion *mr)
+{
+    assert(QTAILQ_EMPTY(&mr->subregions));
+    memory_region_clear_coalescing(mr);
+    qemu_free((char *)mr->name);
+}
+
+target_phys_addr_t memory_region_size(MemoryRegion *mr)
+{
+    return mr->size;
+}
+
+void memory_region_set_offset(MemoryRegion *mr, target_phys_addr_t offset)
+{
+    mr->offset = offset;
+}
+
+void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
+{
+    /* FIXME */
+}
+
+bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr,
+                             unsigned client)
+{
+    /* FIXME */
+    return true;
+}
+
+void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr)
+{
+    /* FIXME */
+}
+
+void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
+{
+    /* FIXME */
+}
+
+void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
+{
+    /* FIXME */
+}
+
+void memory_region_reset_dirty(MemoryRegion *mr, target_phys_addr_t addr,
+                               target_phys_addr_t size, unsigned client)
+{
+    /* FIXME */
+}
+
+void *memory_region_get_ram_ptr(MemoryRegion *mr)
+{
+    if (mr->alias) {
+        return memory_region_get_ram_ptr(mr->alias) + mr->alias_offset;
+    }
+
+    if (!mr->has_ram_addr) {
+        abort();
+    }
+
+    return qemu_get_ram_ptr(mr->ram_addr);
+}
+
+static void memory_region_update_coalesced_range(MemoryRegion *mr)
+{
+    FlatRange *fr;
+    CoalescedMemoryRange *cmr;
+    AddrRange tmp;
+
+    FOR_EACH_FLAT_RANGE(fr, &current_memory_map) {
+        if (fr->mr == mr) {
+            qemu_unregister_coalesced_mmio(fr->addr.start, fr->addr.size);
+            QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
+                tmp = addrrange_shift(cmr->addr,
+                                      fr->addr.start - fr->offset_in_region);
+                if (!addrrange_intersects(tmp, fr->addr)) {
+                    continue;
+                }
+                tmp = addrrange_intersection(tmp, fr->addr);
+                qemu_register_coalesced_mmio(tmp.start, tmp.size);
+            }
+        }
+    }
+}
+
+void memory_region_set_coalescing(MemoryRegion *mr)
+{
+    memory_region_clear_coalescing(mr);
+    memory_region_add_coalescing(mr, 0, mr->size);
+}
+
+void memory_region_add_coalescing(MemoryRegion *mr,
+                                  target_phys_addr_t offset,
+                                  uint64_t size)
+{
+    CoalescedMemoryRange *cmr = qemu_malloc(sizeof(*cmr));
+
+    cmr->addr = addrrange_make(offset, size);
+    QTAILQ_INSERT_TAIL(&mr->coalesced, cmr, link);
+    memory_region_update_coalesced_range(mr);
+}
+
+void memory_region_clear_coalescing(MemoryRegion *mr)
+{
+    CoalescedMemoryRange *cmr;
+
+    while (!QTAILQ_EMPTY(&mr->coalesced)) {
+        cmr = QTAILQ_FIRST(&mr->coalesced);
+        QTAILQ_REMOVE(&mr->coalesced, cmr, link);
+        qemu_free(cmr);
+    }
+    memory_region_update_coalesced_range(mr);
+}
+
+static void memory_region_add_subregion_common(MemoryRegion *mr,
+                                               target_phys_addr_t offset,
+                                               MemoryRegion *subregion)
+{
+    MemoryRegion *other;
+
+    assert(!subregion->parent);
+    subregion->parent = mr;
+    subregion->addr = offset;
+    QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
+        if (subregion->may_overlap || other->may_overlap) {
+            continue;
+        }
+        if (offset >= other->offset + other->size
+            || offset + subregion->size <= other->offset) {
+            continue;
+        }
+        printf("warning: subregion collision %llx/%llx vs %llx/%llx\n",
+               (unsigned long long)offset,
+               (unsigned long long)subregion->size,
+               (unsigned long long)other->offset,
+               (unsigned long long)other->size);
+    }
+    QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
+        if (subregion->priority >= other->priority) {
+            QTAILQ_INSERT_BEFORE(other, subregion, subregions_link);
+            goto done;
+        }
+    }
+    QTAILQ_INSERT_TAIL(&mr->subregions, subregion, subregions_link);
+done:
+    memory_region_update_topology();
+}
+
+
+void memory_region_add_subregion(MemoryRegion *mr,
+                                 target_phys_addr_t offset,
+                                 MemoryRegion *subregion)
+{
+    subregion->may_overlap = false;
+    subregion->priority = 0;
+    memory_region_add_subregion_common(mr, offset, subregion);
+}
+
+void memory_region_add_subregion_overlap(MemoryRegion *mr,
+                                         target_phys_addr_t offset,
+                                         MemoryRegion *subregion,
+                                         unsigned priority)
+{
+    subregion->may_overlap = true;
+    subregion->priority = priority;
+    memory_region_add_subregion_common(mr, offset, subregion);
+}
+
+void memory_region_del_subregion(MemoryRegion *mr,
+                                 MemoryRegion *subregion)
+{
+    assert(subregion->parent == mr);
+    subregion->parent = NULL;
+    QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link);
+    memory_region_update_topology();
+}
diff --git a/memory.h b/memory.h
new file mode 100644
index 0000000..95270aa
--- /dev/null
+++ b/memory.h
@@ -0,0 +1,200 @@
+#ifndef MEMORY_H
+#define MEMORY_H
+
+#ifndef CONFIG_USER_ONLY
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "qemu-common.h"
+#include "cpu-common.h"
+#include "targphys.h"
+#include "qemu-queue.h"
+
+typedef struct MemoryRegionOps MemoryRegionOps;
+typedef struct MemoryRegion MemoryRegion;
+
+/* Must match *_DIRTY_FLAGS in cpu-all.h.  To be replaced with dynamic
+ * registration.
+ */
+#define DIRTY_MEMORY_VGA       0
+#define DIRTY_MEMORY_CODE      1
+#define DIRTY_MEMORY_MIGRATION 3
+
+/*
+ * Memory region callbacks
+ */
+struct MemoryRegionOps {
+    /* Read from the memory region. @addr is relative to @mr; @size is
+     * in bytes. */
+    uint64_t (*read)(void *opaque,
+                     target_phys_addr_t addr,
+                     unsigned size);
+    /* Write to the memory region. @addr is relative to @mr; @size is
+     * in bytes. */
+    void (*write)(void *opaque,
+                  target_phys_addr_t addr,
+                  uint64_t data,
+                  unsigned size);
+
+    enum device_endian endianness;
+    /* Guest-visible constraints: */
+    struct {
+        /* If nonzero, specify bounds on access sizes beyond which a machine
+         * check is thrown.
+         */
+        unsigned min_access_size;
+        unsigned max_access_size;
+        /* If true, unaligned accesses are supported.  Otherwise unaligned
+         * accesses throw machine checks.
+         */
+         bool unaligned;
+    } valid;
+    /* Internal implementation constraints: */
+    struct {
+        /* If nonzero, specifies the minimum size implemented.  Smaller sizes
+         * will be rounded upwards and a partial result will be returned.
+         */
+        unsigned min_access_size;
+        /* If nonzero, specifies the maximum size implemented.  Larger sizes
+         * will be done as a series of accesses with smaller sizes.
+         */
+        unsigned max_access_size;
+        /* If true, unaligned accesses are supported.  Otherwise all accesses
+         * are converted to (possibly multiple) naturally aligned accesses.
+         */
+         bool unaligned;
+    } impl;
+};
+
+typedef struct CoalescedMemoryRange CoalescedMemoryRange;
+
+struct MemoryRegion {
+    /* All fields are private - violators will be prosecuted */
+    const MemoryRegionOps *ops;
+    void *opaque;
+    MemoryRegion *parent;
+    uint64_t size;
+    target_phys_addr_t addr;
+    target_phys_addr_t offset;
+    ram_addr_t ram_addr;
+    bool has_ram_addr;
+    MemoryRegion *alias;
+    target_phys_addr_t alias_offset;
+    unsigned priority;
+    bool may_overlap;
+    QTAILQ_HEAD(subregions, MemoryRegion) subregions;
+    QTAILQ_ENTRY(MemoryRegion) subregions_link;
+    QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
+    const char *name;
+};
+
+/* Initialize a memory region
+ *
+ * The region typically acts as a container for other memory regions.
+ */
+void memory_region_init(MemoryRegion *mr,
+                        const char *name,
+                        uint64_t size);
+/* Initialize an I/O memory region.  Accesses into the region will be
+ * cause the callbacks in @ops to be called.
+ *
+ * if @size is nonzero, subregions will be clipped to @size.
+ */
+void memory_region_init_io(MemoryRegion *mr,
+                           const MemoryRegionOps *ops,
+                           void *opaque,
+                           const char *name,
+                           uint64_t size);
+/* Initialize an I/O memory region.  Accesses into the region will be
+ * modify memory directly.
+ */
+void memory_region_init_ram(MemoryRegion *mr,
+                            DeviceState *dev, /* FIXME: layering violation */
+                            const char *name,
+                            uint64_t size);
+/* Initialize a RAM memory region.  Accesses into the region will be
+ * modify memory in @ptr directly.
+ */
+void memory_region_init_ram_ptr(MemoryRegion *mr,
+                                DeviceState *dev, /* FIXME: layering violation */
+                                const char *name,
+                                uint64_t size,
+                                void *ptr);
+/* Initializes a memory region which aliases a section of another memory
+ * region.
+ */
+void memory_region_init_alias(MemoryRegion *mr,
+                              const char *name,
+                              MemoryRegion *orig,
+                              target_phys_addr_t offset,
+                              uint64_t size);
+
+/* Destroy a memory region.  The memory becomes inaccessible. */
+void memory_region_destroy(MemoryRegion *mr);
+
+target_phys_addr_t memory_region_size(MemoryRegion *mr);
+
+/* Get a pointer into a RAM memory region; use with care */
+void *memory_region_get_ram_ptr(MemoryRegion *mr);
+
+/* Sets an offset to be added to MemoryRegionOps callbacks.  This function
+ * is deprecated and should not be used in new code. */
+void memory_region_set_offset(MemoryRegion *mr, target_phys_addr_t offset);
+
+/* Turn logging on or off for specified client (display, migration) */
+void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client);
+
+/* Check whether a page is dirty for a specified client. */
+bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr,
+                             unsigned client);
+
+/* Mark a page as dirty in a memory region, after it has been dirtied outside
+ * guest code
+ */
+void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr);
+
+/* Synchronize a region's dirty bitmap with any external TLBs (e.g. kvm) */
+void memory_region_sync_dirty_bitmap(MemoryRegion *mr);
+
+/* Mark a range of pages as not dirty, for a specified client. */
+void memory_region_reset_dirty(MemoryRegion *mr, target_phys_addr_t addr,
+                               target_phys_addr_t size, unsigned client);
+
+/* Turn a memory region read-only (or read-write) */
+void memory_region_set_readonly(MemoryRegion *mr, bool readonly);
+
+/* Enable memory coalescing for the region.  MMIO ->write callbacks may be
+ * delayed until a non-coalesced MMIO is issued.
+ */
+void memory_region_set_coalescing(MemoryRegion *mr);
+
+/* Enable memory coalescing for a sub-range of the region.  MMIO ->write
+ * callbacks may be delayed until a non-coalesced MMIO is issued.
+ */
+void memory_region_add_coalescing(MemoryRegion *mr,
+                                  target_phys_addr_t offset,
+                                  uint64_t size);
+/* Disable MMIO coalescing for the region. */
+void memory_region_clear_coalescing(MemoryRegion *mr);
+
+/* Add a sub-region at @offset.  The sub-region may not overlap with other
+ * subregions (except for those explicitly marked as overlapping)
+ */
+void memory_region_add_subregion(MemoryRegion *mr,
+                                 target_phys_addr_t offset,
+                                 MemoryRegion *subregion);
+/* Add a sub-region at @offset.  The sub-region may overlap other subregions;
+ * conflicts are resolved by having a higher @priority hide a lower @priority.
+ * Subregions without priority are taken as @priority 0.
+ */
+void memory_region_add_subregion_overlap(MemoryRegion *mr,
+                                         target_phys_addr_t offset,
+                                         MemoryRegion *subregion,
+                                         unsigned priority);
+/* Remove a subregion. */
+void memory_region_del_subregion(MemoryRegion *mr,
+                                 MemoryRegion *subregion);
+
+#endif
+
+#endif
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 01/56] Hierarchical memory region API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

The memory API separates the attributes of a memory region (its size, how
reads or writes are handled, dirty logging, and coalescing) from where it
is mapped and whether it is enabled.  This allows a device to configure
a memory region once, then hand it off to its parent bus to map it according
to the bus configuration.

Hierarchical registration also allows a device to compose a region out of
a number of sub-regions with different properties; for example some may be
RAM while others may be MMIO.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 Makefile.target |    1 +
 memory.c        |  655 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 memory.h        |  200 +++++++++++++++++
 3 files changed, 856 insertions(+), 0 deletions(-)
 create mode 100644 memory.c
 create mode 100644 memory.h

diff --git a/Makefile.target b/Makefile.target
index a53a2ff..2cacd80 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -197,6 +197,7 @@ obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
 obj-y += rwhandler.o
 obj-$(CONFIG_KVM) += kvm.o kvm-all.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
+obj-y += memory.o
 LIBS+=-lz
 
 QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
diff --git a/memory.c b/memory.c
new file mode 100644
index 0000000..10591bf
--- /dev/null
+++ b/memory.c
@@ -0,0 +1,655 @@
+/*
+ * Physical memory management
+ *
+ * Copyright 2011 Red Hat, Inc. and/or its affiliates
+ *
+ * Authors:
+ *  Avi Kivity <avi@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "memory.h"
+#include <assert.h>
+
+typedef struct AddrRange AddrRange;
+
+struct AddrRange {
+    uint64_t start;
+    uint64_t size;
+};
+
+static AddrRange addrrange_make(uint64_t start, uint64_t size)
+{
+    return (AddrRange) { start, size };
+}
+
+static bool addrrange_equal(AddrRange r1, AddrRange r2)
+{
+    return r1.start == r2.start && r1.size == r2.size;
+}
+
+static uint64_t addrrange_end(AddrRange r)
+{
+    return r.start + r.size;
+}
+
+static AddrRange addrrange_shift(AddrRange range, int64_t delta)
+{
+    range.start += delta;
+    return range;
+}
+
+static bool addrrange_intersects(AddrRange r1, AddrRange r2)
+{
+    return (r1.start >= r2.start && r1.start < r2.start + r2.size)
+        || (r2.start >= r1.start && r2.start < r1.start + r1.size);
+}
+
+static AddrRange addrrange_intersection(AddrRange r1, AddrRange r2)
+{
+    uint64_t start = MAX(r1.start, r2.start);
+    /* off-by-one arithmetic to prevent overflow */
+    uint64_t end = MIN(addrrange_end(r1) - 1, addrrange_end(r2) - 1);
+    return addrrange_make(start, end - start + 1);
+}
+
+struct CoalescedMemoryRange {
+    AddrRange addr;
+    QTAILQ_ENTRY(CoalescedMemoryRange) link;
+};
+
+typedef struct FlatRange FlatRange;
+typedef struct FlatView FlatView;
+
+/* Range of memory in the global map.  Addresses are absolute. */
+struct FlatRange {
+    MemoryRegion *mr;
+    target_phys_addr_t offset_in_region;
+    AddrRange addr;
+};
+
+/* Flattened global view of current active memory hierarchy.  Kept in sorted
+ * order.
+ */
+struct FlatView {
+    FlatRange *ranges;
+    unsigned nr;
+    unsigned nr_allocated;
+};
+
+#define FOR_EACH_FLAT_RANGE(var, view)          \
+    for (var = (view)->ranges; var < (view)->ranges + (view)->nr; ++var)
+
+static FlatView current_memory_map;
+static MemoryRegion *root_memory_region;
+
+static bool flatrange_equal(FlatRange *a, FlatRange *b)
+{
+    return a->mr == b->mr
+        && addrrange_equal(a->addr, b->addr)
+        && a->offset_in_region == b->offset_in_region;
+}
+
+static void flatview_init(FlatView *view)
+{
+    view->ranges = NULL;
+    view->nr = 0;
+    view->nr_allocated = 0;
+}
+
+/* Insert a range into a given position.  Caller is responsible for maintaining
+ * sorting order.
+ */
+static void flatview_insert(FlatView *view, unsigned pos, FlatRange *range)
+{
+    if (view->nr == view->nr_allocated) {
+        view->nr_allocated = MAX(2 * view->nr, 10);
+        view->ranges = qemu_realloc(view->ranges,
+                                    view->nr_allocated * sizeof(*view->ranges));
+    }
+    memmove(view->ranges + pos + 1, view->ranges + pos,
+            (view->nr - pos) * sizeof(FlatRange));
+    view->ranges[pos] = *range;
+    ++view->nr;
+}
+
+static void flatview_destroy(FlatView *view)
+{
+    qemu_free(view->ranges);
+}
+
+/* Render a memory region into the global view.  Ranges in @view obscure
+ * ranges in @mr.
+ */
+static void render_memory_region(FlatView *view,
+                                 MemoryRegion *mr,
+                                 target_phys_addr_t base,
+                                 AddrRange clip)
+{
+    MemoryRegion *subregion;
+    unsigned i;
+    target_phys_addr_t offset_in_region;
+    uint64_t remain;
+    uint64_t now;
+    FlatRange fr;
+    AddrRange tmp;
+
+    base += mr->addr;
+
+    tmp = addrrange_make(base, mr->size);
+
+    if (!addrrange_intersects(tmp, clip)) {
+        return;
+    }
+
+    clip = addrrange_intersection(tmp, clip);
+
+    if (mr->alias) {
+        base -= mr->alias->addr;
+        base -= mr->alias_offset;
+        render_memory_region(view, mr->alias, base, clip);
+        return;
+    }
+
+    /* Render subregions in priority order. */
+    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
+        render_memory_region(view, subregion, base, clip);
+    }
+
+    if (!mr->has_ram_addr) {
+        return;
+    }
+
+    offset_in_region = clip.start - base;
+    base = clip.start;
+    remain = clip.size;
+
+    /* Render the region itself into any gaps left by the current view. */
+    for (i = 0; i < view->nr && remain; ++i) {
+        if (base >= addrrange_end(view->ranges[i].addr)) {
+            continue;
+        }
+        if (base < view->ranges[i].addr.start) {
+            now = MIN(remain, view->ranges[i].addr.start - base);
+            fr.mr = mr;
+            fr.offset_in_region = offset_in_region;
+            fr.addr = addrrange_make(base, now);
+            flatview_insert(view, i, &fr);
+            ++i;
+            base += now;
+            offset_in_region += now;
+            remain -= now;
+        }
+        if (base == view->ranges[i].addr.start) {
+            now = MIN(remain, view->ranges[i].addr.size);
+            base += now;
+            offset_in_region += now;
+            remain -= now;
+        }
+    }
+    if (remain) {
+        fr.mr = mr;
+        fr.offset_in_region = offset_in_region;
+        fr.addr = addrrange_make(base, remain);
+        flatview_insert(view, i, &fr);
+    }
+}
+
+/* Render a memory topology into a list of disjoint absolute ranges. */
+static FlatView generate_memory_topology(MemoryRegion *mr)
+{
+    FlatView view;
+
+    flatview_init(&view);
+
+    render_memory_region(&view, mr, 0, addrrange_make(0, UINT64_MAX));
+
+    return view;
+}
+
+static void memory_region_update_topology(void)
+{
+    FlatView old_view = current_memory_map;
+    FlatView new_view = generate_memory_topology(root_memory_region);
+    unsigned iold, inew;
+    FlatRange *frold, *frnew;
+    ram_addr_t phys_offset, region_offset;
+
+    /* Generate a symmetric difference of the old and new memory maps.
+     * Kill ranges in the old map, and instantiate ranges in the new map.
+     */
+    iold = inew = 0;
+    while (iold < old_view.nr || inew < new_view.nr) {
+        if (iold < old_view.nr) {
+            frold = &old_view.ranges[iold];
+        } else {
+            frold = NULL;
+        }
+        if (inew < new_view.nr) {
+            frnew = &new_view.ranges[inew];
+        } else {
+            frnew = NULL;
+        }
+
+        if (frold
+            && (!frnew
+                || frold->addr.start < frnew->addr.start
+                || (frold->addr.start == frnew->addr.start
+                    && !flatrange_equal(frold, frnew)))) {
+            /* In old, but (not in new, or in new but attributes changed). */
+
+            cpu_register_physical_memory(frold->addr.start, frold->addr.size,
+                                         IO_MEM_UNASSIGNED);
+            ++iold;
+        } else if (frold && frnew && flatrange_equal(frold, frnew)) {
+            /* In both (logging may have changed) */
+
+            ++iold;
+            ++inew;
+            /* FIXME: dirty logging */
+        } else {
+            /* In new */
+
+            phys_offset = frnew->mr->ram_addr;
+            region_offset = frnew->offset_in_region;
+            /* cpu_register_physical_memory_log() wants region_offset for
+             * mmio, but prefers offseting phys_offset for RAM.  Humour it.
+             */
+            if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) {
+                phys_offset += region_offset;
+                region_offset = 0;
+            }
+
+            cpu_register_physical_memory_log(frnew->addr.start,
+                                             frnew->addr.size,
+                                             phys_offset,
+                                             region_offset,
+                                             0);
+            ++inew;
+        }
+    }
+    current_memory_map = new_view;
+    flatview_destroy(&old_view);
+}
+
+void memory_region_init(MemoryRegion *mr,
+                        const char *name,
+                        uint64_t size)
+{
+    mr->ops = NULL;
+    mr->parent = NULL;
+    mr->size = size;
+    mr->addr = 0;
+    mr->offset = 0;
+    mr->has_ram_addr = false;
+    mr->priority = 0;
+    mr->may_overlap = false;
+    mr->alias = NULL;
+    QTAILQ_INIT(&mr->subregions);
+    memset(&mr->subregions_link, 0, sizeof mr->subregions_link);
+    QTAILQ_INIT(&mr->coalesced);
+    mr->name = qemu_strdup(name);
+}
+
+static bool memory_region_access_valid(MemoryRegion *mr,
+                                       target_phys_addr_t addr,
+                                       unsigned size)
+{
+    if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
+        return false;
+    }
+
+    /* Treat zero as compatibility all valid */
+    if (!mr->ops->valid.max_access_size) {
+        return true;
+    }
+
+    if (size > mr->ops->valid.max_access_size
+        || size < mr->ops->valid.min_access_size) {
+        return false;
+    }
+    return true;
+}
+
+static uint32_t memory_region_read_thunk_n(void *_mr,
+                                           target_phys_addr_t addr,
+                                           unsigned size)
+{
+    MemoryRegion *mr = _mr;
+    unsigned access_size, access_size_min, access_size_max;
+    uint64_t access_mask;
+    uint32_t data = 0, tmp;
+    unsigned i;
+
+    if (!memory_region_access_valid(mr, addr, size)) {
+        return -1U; /* FIXME: better signalling */
+    }
+
+    /* FIXME: support unaligned access */
+
+    access_size_min = mr->ops->impl.min_access_size;
+    if (!access_size_min) {
+        access_size_min = 1;
+    }
+    access_size_max = mr->ops->impl.max_access_size;
+    if (!access_size_max) {
+        access_size_max = 4;
+    }
+    access_size = MAX(MIN(size, access_size_max), access_size_min);
+    access_mask = -1ULL >> (64 - access_size * 8);
+    addr += mr->offset;
+    for (i = 0; i < size; i += access_size) {
+        /* FIXME: big-endian support */
+        tmp = mr->ops->read(mr->opaque, addr + i, access_size);
+        data |= (tmp & access_mask) << (i * 8);
+    }
+
+    return data;
+}
+
+static void memory_region_write_thunk_n(void *_mr,
+                                        target_phys_addr_t addr,
+                                        unsigned size,
+                                        uint64_t data)
+{
+    MemoryRegion *mr = _mr;
+    unsigned access_size, access_size_min, access_size_max;
+    uint64_t access_mask;
+    unsigned i;
+
+    if (!memory_region_access_valid(mr, addr, size)) {
+        return; /* FIXME: better signalling */
+    }
+
+    /* FIXME: support unaligned access */
+
+    access_size_min = mr->ops->impl.min_access_size;
+    if (!access_size_min) {
+        access_size_min = 1;
+    }
+    access_size_max = mr->ops->impl.max_access_size;
+    if (!access_size_max) {
+        access_size_max = 4;
+    }
+    access_size = MAX(MIN(size, access_size_max), access_size_min);
+    access_mask = -1ULL >> (64 - access_size * 8);
+    addr += mr->offset;
+    for (i = 0; i < size; i += access_size) {
+        /* FIXME: big-endian support */
+        mr->ops->write(mr->opaque, addr + i, (data >> (i * 8)) & access_mask,
+                       access_size);
+    }
+}
+
+static uint32_t memory_region_read_thunk_b(void *mr, target_phys_addr_t addr)
+{
+    return memory_region_read_thunk_n(mr, addr, 1);
+}
+
+static uint32_t memory_region_read_thunk_w(void *mr, target_phys_addr_t addr)
+{
+    return memory_region_read_thunk_n(mr, addr, 2);
+}
+
+static uint32_t memory_region_read_thunk_l(void *mr, target_phys_addr_t addr)
+{
+    return memory_region_read_thunk_n(mr, addr, 4);
+}
+
+static void memory_region_write_thunk_b(void *mr, target_phys_addr_t addr,
+                                        uint32_t data)
+{
+    memory_region_write_thunk_n(mr, addr, 1, data);
+}
+
+static void memory_region_write_thunk_w(void *mr, target_phys_addr_t addr,
+                                        uint32_t data)
+{
+    memory_region_write_thunk_n(mr, addr, 2, data);
+}
+
+static void memory_region_write_thunk_l(void *mr, target_phys_addr_t addr,
+                                        uint32_t data)
+{
+    memory_region_write_thunk_n(mr, addr, 4, data);
+}
+
+static CPUReadMemoryFunc * const memory_region_read_thunk[] = {
+    memory_region_read_thunk_b,
+    memory_region_read_thunk_w,
+    memory_region_read_thunk_l,
+};
+
+static CPUWriteMemoryFunc * const memory_region_write_thunk[] = {
+    memory_region_write_thunk_b,
+    memory_region_write_thunk_w,
+    memory_region_write_thunk_l,
+};
+
+void memory_region_init_io(MemoryRegion *mr,
+                           const MemoryRegionOps *ops,
+                           void *opaque,
+                           const char *name,
+                           uint64_t size)
+{
+    memory_region_init(mr, name, size);
+    mr->ops = ops;
+    mr->opaque = opaque;
+    mr->has_ram_addr = true;
+    mr->ram_addr = cpu_register_io_memory(memory_region_read_thunk,
+                                          memory_region_write_thunk,
+                                          mr,
+                                          mr->ops->endianness);
+}
+
+void memory_region_init_ram(MemoryRegion *mr,
+                            DeviceState *dev,
+                            const char *name,
+                            uint64_t size)
+{
+    memory_region_init(mr, name, size);
+    mr->has_ram_addr = true;
+    mr->ram_addr = qemu_ram_alloc(dev, name, size);
+}
+
+void memory_region_init_ram_ptr(MemoryRegion *mr,
+                                DeviceState *dev,
+                                const char *name,
+                                uint64_t size,
+                                void *ptr)
+{
+    memory_region_init(mr, name, size);
+    mr->has_ram_addr = true;
+    mr->ram_addr = qemu_ram_alloc_from_ptr(dev, name, size, ptr);
+}
+
+void memory_region_init_alias(MemoryRegion *mr,
+                              const char *name,
+                              MemoryRegion *orig,
+                              target_phys_addr_t offset,
+                              uint64_t size)
+{
+    memory_region_init(mr, name, size);
+    mr->alias = orig;
+    mr->alias_offset = offset;
+}
+
+void memory_region_destroy(MemoryRegion *mr)
+{
+    assert(QTAILQ_EMPTY(&mr->subregions));
+    memory_region_clear_coalescing(mr);
+    qemu_free((char *)mr->name);
+}
+
+target_phys_addr_t memory_region_size(MemoryRegion *mr)
+{
+    return mr->size;
+}
+
+void memory_region_set_offset(MemoryRegion *mr, target_phys_addr_t offset)
+{
+    mr->offset = offset;
+}
+
+void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
+{
+    /* FIXME */
+}
+
+bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr,
+                             unsigned client)
+{
+    /* FIXME */
+    return true;
+}
+
+void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr)
+{
+    /* FIXME */
+}
+
+void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
+{
+    /* FIXME */
+}
+
+void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
+{
+    /* FIXME */
+}
+
+void memory_region_reset_dirty(MemoryRegion *mr, target_phys_addr_t addr,
+                               target_phys_addr_t size, unsigned client)
+{
+    /* FIXME */
+}
+
+void *memory_region_get_ram_ptr(MemoryRegion *mr)
+{
+    if (mr->alias) {
+        return memory_region_get_ram_ptr(mr->alias) + mr->alias_offset;
+    }
+
+    if (!mr->has_ram_addr) {
+        abort();
+    }
+
+    return qemu_get_ram_ptr(mr->ram_addr);
+}
+
+static void memory_region_update_coalesced_range(MemoryRegion *mr)
+{
+    FlatRange *fr;
+    CoalescedMemoryRange *cmr;
+    AddrRange tmp;
+
+    FOR_EACH_FLAT_RANGE(fr, &current_memory_map) {
+        if (fr->mr == mr) {
+            qemu_unregister_coalesced_mmio(fr->addr.start, fr->addr.size);
+            QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
+                tmp = addrrange_shift(cmr->addr,
+                                      fr->addr.start - fr->offset_in_region);
+                if (!addrrange_intersects(tmp, fr->addr)) {
+                    continue;
+                }
+                tmp = addrrange_intersection(tmp, fr->addr);
+                qemu_register_coalesced_mmio(tmp.start, tmp.size);
+            }
+        }
+    }
+}
+
+void memory_region_set_coalescing(MemoryRegion *mr)
+{
+    memory_region_clear_coalescing(mr);
+    memory_region_add_coalescing(mr, 0, mr->size);
+}
+
+void memory_region_add_coalescing(MemoryRegion *mr,
+                                  target_phys_addr_t offset,
+                                  uint64_t size)
+{
+    CoalescedMemoryRange *cmr = qemu_malloc(sizeof(*cmr));
+
+    cmr->addr = addrrange_make(offset, size);
+    QTAILQ_INSERT_TAIL(&mr->coalesced, cmr, link);
+    memory_region_update_coalesced_range(mr);
+}
+
+void memory_region_clear_coalescing(MemoryRegion *mr)
+{
+    CoalescedMemoryRange *cmr;
+
+    while (!QTAILQ_EMPTY(&mr->coalesced)) {
+        cmr = QTAILQ_FIRST(&mr->coalesced);
+        QTAILQ_REMOVE(&mr->coalesced, cmr, link);
+        qemu_free(cmr);
+    }
+    memory_region_update_coalesced_range(mr);
+}
+
+static void memory_region_add_subregion_common(MemoryRegion *mr,
+                                               target_phys_addr_t offset,
+                                               MemoryRegion *subregion)
+{
+    MemoryRegion *other;
+
+    assert(!subregion->parent);
+    subregion->parent = mr;
+    subregion->addr = offset;
+    QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
+        if (subregion->may_overlap || other->may_overlap) {
+            continue;
+        }
+        if (offset >= other->offset + other->size
+            || offset + subregion->size <= other->offset) {
+            continue;
+        }
+        printf("warning: subregion collision %llx/%llx vs %llx/%llx\n",
+               (unsigned long long)offset,
+               (unsigned long long)subregion->size,
+               (unsigned long long)other->offset,
+               (unsigned long long)other->size);
+    }
+    QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
+        if (subregion->priority >= other->priority) {
+            QTAILQ_INSERT_BEFORE(other, subregion, subregions_link);
+            goto done;
+        }
+    }
+    QTAILQ_INSERT_TAIL(&mr->subregions, subregion, subregions_link);
+done:
+    memory_region_update_topology();
+}
+
+
+void memory_region_add_subregion(MemoryRegion *mr,
+                                 target_phys_addr_t offset,
+                                 MemoryRegion *subregion)
+{
+    subregion->may_overlap = false;
+    subregion->priority = 0;
+    memory_region_add_subregion_common(mr, offset, subregion);
+}
+
+void memory_region_add_subregion_overlap(MemoryRegion *mr,
+                                         target_phys_addr_t offset,
+                                         MemoryRegion *subregion,
+                                         unsigned priority)
+{
+    subregion->may_overlap = true;
+    subregion->priority = priority;
+    memory_region_add_subregion_common(mr, offset, subregion);
+}
+
+void memory_region_del_subregion(MemoryRegion *mr,
+                                 MemoryRegion *subregion)
+{
+    assert(subregion->parent == mr);
+    subregion->parent = NULL;
+    QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link);
+    memory_region_update_topology();
+}
diff --git a/memory.h b/memory.h
new file mode 100644
index 0000000..95270aa
--- /dev/null
+++ b/memory.h
@@ -0,0 +1,200 @@
+#ifndef MEMORY_H
+#define MEMORY_H
+
+#ifndef CONFIG_USER_ONLY
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "qemu-common.h"
+#include "cpu-common.h"
+#include "targphys.h"
+#include "qemu-queue.h"
+
+typedef struct MemoryRegionOps MemoryRegionOps;
+typedef struct MemoryRegion MemoryRegion;
+
+/* Must match *_DIRTY_FLAGS in cpu-all.h.  To be replaced with dynamic
+ * registration.
+ */
+#define DIRTY_MEMORY_VGA       0
+#define DIRTY_MEMORY_CODE      1
+#define DIRTY_MEMORY_MIGRATION 3
+
+/*
+ * Memory region callbacks
+ */
+struct MemoryRegionOps {
+    /* Read from the memory region. @addr is relative to @mr; @size is
+     * in bytes. */
+    uint64_t (*read)(void *opaque,
+                     target_phys_addr_t addr,
+                     unsigned size);
+    /* Write to the memory region. @addr is relative to @mr; @size is
+     * in bytes. */
+    void (*write)(void *opaque,
+                  target_phys_addr_t addr,
+                  uint64_t data,
+                  unsigned size);
+
+    enum device_endian endianness;
+    /* Guest-visible constraints: */
+    struct {
+        /* If nonzero, specify bounds on access sizes beyond which a machine
+         * check is thrown.
+         */
+        unsigned min_access_size;
+        unsigned max_access_size;
+        /* If true, unaligned accesses are supported.  Otherwise unaligned
+         * accesses throw machine checks.
+         */
+         bool unaligned;
+    } valid;
+    /* Internal implementation constraints: */
+    struct {
+        /* If nonzero, specifies the minimum size implemented.  Smaller sizes
+         * will be rounded upwards and a partial result will be returned.
+         */
+        unsigned min_access_size;
+        /* If nonzero, specifies the maximum size implemented.  Larger sizes
+         * will be done as a series of accesses with smaller sizes.
+         */
+        unsigned max_access_size;
+        /* If true, unaligned accesses are supported.  Otherwise all accesses
+         * are converted to (possibly multiple) naturally aligned accesses.
+         */
+         bool unaligned;
+    } impl;
+};
+
+typedef struct CoalescedMemoryRange CoalescedMemoryRange;
+
+struct MemoryRegion {
+    /* All fields are private - violators will be prosecuted */
+    const MemoryRegionOps *ops;
+    void *opaque;
+    MemoryRegion *parent;
+    uint64_t size;
+    target_phys_addr_t addr;
+    target_phys_addr_t offset;
+    ram_addr_t ram_addr;
+    bool has_ram_addr;
+    MemoryRegion *alias;
+    target_phys_addr_t alias_offset;
+    unsigned priority;
+    bool may_overlap;
+    QTAILQ_HEAD(subregions, MemoryRegion) subregions;
+    QTAILQ_ENTRY(MemoryRegion) subregions_link;
+    QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
+    const char *name;
+};
+
+/* Initialize a memory region
+ *
+ * The region typically acts as a container for other memory regions.
+ */
+void memory_region_init(MemoryRegion *mr,
+                        const char *name,
+                        uint64_t size);
+/* Initialize an I/O memory region.  Accesses into the region will be
+ * cause the callbacks in @ops to be called.
+ *
+ * if @size is nonzero, subregions will be clipped to @size.
+ */
+void memory_region_init_io(MemoryRegion *mr,
+                           const MemoryRegionOps *ops,
+                           void *opaque,
+                           const char *name,
+                           uint64_t size);
+/* Initialize an I/O memory region.  Accesses into the region will be
+ * modify memory directly.
+ */
+void memory_region_init_ram(MemoryRegion *mr,
+                            DeviceState *dev, /* FIXME: layering violation */
+                            const char *name,
+                            uint64_t size);
+/* Initialize a RAM memory region.  Accesses into the region will be
+ * modify memory in @ptr directly.
+ */
+void memory_region_init_ram_ptr(MemoryRegion *mr,
+                                DeviceState *dev, /* FIXME: layering violation */
+                                const char *name,
+                                uint64_t size,
+                                void *ptr);
+/* Initializes a memory region which aliases a section of another memory
+ * region.
+ */
+void memory_region_init_alias(MemoryRegion *mr,
+                              const char *name,
+                              MemoryRegion *orig,
+                              target_phys_addr_t offset,
+                              uint64_t size);
+
+/* Destroy a memory region.  The memory becomes inaccessible. */
+void memory_region_destroy(MemoryRegion *mr);
+
+target_phys_addr_t memory_region_size(MemoryRegion *mr);
+
+/* Get a pointer into a RAM memory region; use with care */
+void *memory_region_get_ram_ptr(MemoryRegion *mr);
+
+/* Sets an offset to be added to MemoryRegionOps callbacks.  This function
+ * is deprecated and should not be used in new code. */
+void memory_region_set_offset(MemoryRegion *mr, target_phys_addr_t offset);
+
+/* Turn logging on or off for specified client (display, migration) */
+void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client);
+
+/* Check whether a page is dirty for a specified client. */
+bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr,
+                             unsigned client);
+
+/* Mark a page as dirty in a memory region, after it has been dirtied outside
+ * guest code
+ */
+void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr);
+
+/* Synchronize a region's dirty bitmap with any external TLBs (e.g. kvm) */
+void memory_region_sync_dirty_bitmap(MemoryRegion *mr);
+
+/* Mark a range of pages as not dirty, for a specified client. */
+void memory_region_reset_dirty(MemoryRegion *mr, target_phys_addr_t addr,
+                               target_phys_addr_t size, unsigned client);
+
+/* Turn a memory region read-only (or read-write) */
+void memory_region_set_readonly(MemoryRegion *mr, bool readonly);
+
+/* Enable memory coalescing for the region.  MMIO ->write callbacks may be
+ * delayed until a non-coalesced MMIO is issued.
+ */
+void memory_region_set_coalescing(MemoryRegion *mr);
+
+/* Enable memory coalescing for a sub-range of the region.  MMIO ->write
+ * callbacks may be delayed until a non-coalesced MMIO is issued.
+ */
+void memory_region_add_coalescing(MemoryRegion *mr,
+                                  target_phys_addr_t offset,
+                                  uint64_t size);
+/* Disable MMIO coalescing for the region. */
+void memory_region_clear_coalescing(MemoryRegion *mr);
+
+/* Add a sub-region at @offset.  The sub-region may not overlap with other
+ * subregions (except for those explicitly marked as overlapping)
+ */
+void memory_region_add_subregion(MemoryRegion *mr,
+                                 target_phys_addr_t offset,
+                                 MemoryRegion *subregion);
+/* Add a sub-region at @offset.  The sub-region may overlap other subregions;
+ * conflicts are resolved by having a higher @priority hide a lower @priority.
+ * Subregions without priority are taken as @priority 0.
+ */
+void memory_region_add_subregion_overlap(MemoryRegion *mr,
+                                         target_phys_addr_t offset,
+                                         MemoryRegion *subregion,
+                                         unsigned priority);
+/* Remove a subregion. */
+void memory_region_del_subregion(MemoryRegion *mr,
+                                 MemoryRegion *subregion);
+
+#endif
+
+#endif
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 02/56] memory: implement dirty tracking
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Currently dirty tracking is implemented by passing through
all calls to the underlying cpu_physical_memory_*() calls.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |   39 +++++++++++++++++++++++++++++++--------
 memory.h |    1 +
 2 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/memory.c b/memory.c
index 10591bf..a569666 100644
--- a/memory.c
+++ b/memory.c
@@ -69,6 +69,7 @@ struct FlatRange {
     MemoryRegion *mr;
     target_phys_addr_t offset_in_region;
     AddrRange addr;
+    uint8_t dirty_log_mask;
 };
 
 /* Flattened global view of current active memory hierarchy.  Kept in sorted
@@ -177,6 +178,7 @@ static void render_memory_region(FlatView *view,
             fr.mr = mr;
             fr.offset_in_region = offset_in_region;
             fr.addr = addrrange_make(base, now);
+            fr.dirty_log_mask = mr->dirty_log_mask;
             flatview_insert(view, i, &fr);
             ++i;
             base += now;
@@ -194,6 +196,7 @@ static void render_memory_region(FlatView *view,
         fr.mr = mr;
         fr.offset_in_region = offset_in_region;
         fr.addr = addrrange_make(base, remain);
+        fr.dirty_log_mask = mr->dirty_log_mask;
         flatview_insert(view, i, &fr);
     }
 }
@@ -247,9 +250,14 @@ static void memory_region_update_topology(void)
         } else if (frold && frnew && flatrange_equal(frold, frnew)) {
             /* In both (logging may have changed) */
 
+            if (frold->dirty_log_mask && !frnew->dirty_log_mask) {
+                cpu_physical_log_stop(frnew->addr.start, frnew->addr.size);
+            } else if (frnew->dirty_log_mask && !frold->dirty_log_mask) {
+                cpu_physical_log_start(frnew->addr.start, frnew->addr.size);
+            }
+
             ++iold;
             ++inew;
-            /* FIXME: dirty logging */
         } else {
             /* In new */
 
@@ -267,7 +275,7 @@ static void memory_region_update_topology(void)
                                              frnew->addr.size,
                                              phys_offset,
                                              region_offset,
-                                             0);
+                                             frnew->dirty_log_mask);
             ++inew;
         }
     }
@@ -292,6 +300,7 @@ void memory_region_init(MemoryRegion *mr,
     memset(&mr->subregions_link, 0, sizeof mr->subregions_link);
     QTAILQ_INIT(&mr->coalesced);
     mr->name = qemu_strdup(name);
+    mr->dirty_log_mask = 0;
 }
 
 static bool memory_region_access_valid(MemoryRegion *mr,
@@ -496,24 +505,35 @@ void memory_region_set_offset(MemoryRegion *mr, target_phys_addr_t offset)
 
 void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
 {
-    /* FIXME */
+    uint8_t mask = 1 << client;
+
+    mr->dirty_log_mask = (mr->dirty_log_mask & ~mask) | (log * mask);
+    memory_region_update_topology();
 }
 
 bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr,
                              unsigned client)
 {
-    /* FIXME */
-    return true;
+    assert(mr->has_ram_addr);
+    return cpu_physical_memory_get_dirty(mr->ram_addr + addr, 1 << client);
 }
 
 void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr)
 {
-    /* FIXME */
+    assert(mr->has_ram_addr);
+    return cpu_physical_memory_set_dirty(mr->ram_addr + addr);
 }
 
 void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
 {
-    /* FIXME */
+    FlatRange *fr;
+
+    FOR_EACH_FLAT_RANGE(fr, &current_memory_map) {
+        if (fr->mr == mr) {
+            cpu_physical_sync_dirty_bitmap(fr->addr.start,
+                                           fr->addr.start + fr->addr.size);
+        }
+    }
 }
 
 void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
@@ -524,7 +544,10 @@ void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
 void memory_region_reset_dirty(MemoryRegion *mr, target_phys_addr_t addr,
                                target_phys_addr_t size, unsigned client)
 {
-    /* FIXME */
+    assert(mr->has_ram_addr);
+    cpu_physical_memory_reset_dirty(mr->ram_addr + addr,
+                                    mr->ram_addr + addr + size,
+                                    1 << client);
 }
 
 void *memory_region_get_ram_ptr(MemoryRegion *mr)
diff --git a/memory.h b/memory.h
index 95270aa..8873f75 100644
--- a/memory.h
+++ b/memory.h
@@ -86,6 +86,7 @@ struct MemoryRegion {
     QTAILQ_ENTRY(MemoryRegion) subregions_link;
     QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
     const char *name;
+    uint8_t dirty_log_mask;
 };
 
 /* Initialize a memory region
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 02/56] memory: implement dirty tracking
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Currently dirty tracking is implemented by passing through
all calls to the underlying cpu_physical_memory_*() calls.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |   39 +++++++++++++++++++++++++++++++--------
 memory.h |    1 +
 2 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/memory.c b/memory.c
index 10591bf..a569666 100644
--- a/memory.c
+++ b/memory.c
@@ -69,6 +69,7 @@ struct FlatRange {
     MemoryRegion *mr;
     target_phys_addr_t offset_in_region;
     AddrRange addr;
+    uint8_t dirty_log_mask;
 };
 
 /* Flattened global view of current active memory hierarchy.  Kept in sorted
@@ -177,6 +178,7 @@ static void render_memory_region(FlatView *view,
             fr.mr = mr;
             fr.offset_in_region = offset_in_region;
             fr.addr = addrrange_make(base, now);
+            fr.dirty_log_mask = mr->dirty_log_mask;
             flatview_insert(view, i, &fr);
             ++i;
             base += now;
@@ -194,6 +196,7 @@ static void render_memory_region(FlatView *view,
         fr.mr = mr;
         fr.offset_in_region = offset_in_region;
         fr.addr = addrrange_make(base, remain);
+        fr.dirty_log_mask = mr->dirty_log_mask;
         flatview_insert(view, i, &fr);
     }
 }
@@ -247,9 +250,14 @@ static void memory_region_update_topology(void)
         } else if (frold && frnew && flatrange_equal(frold, frnew)) {
             /* In both (logging may have changed) */
 
+            if (frold->dirty_log_mask && !frnew->dirty_log_mask) {
+                cpu_physical_log_stop(frnew->addr.start, frnew->addr.size);
+            } else if (frnew->dirty_log_mask && !frold->dirty_log_mask) {
+                cpu_physical_log_start(frnew->addr.start, frnew->addr.size);
+            }
+
             ++iold;
             ++inew;
-            /* FIXME: dirty logging */
         } else {
             /* In new */
 
@@ -267,7 +275,7 @@ static void memory_region_update_topology(void)
                                              frnew->addr.size,
                                              phys_offset,
                                              region_offset,
-                                             0);
+                                             frnew->dirty_log_mask);
             ++inew;
         }
     }
@@ -292,6 +300,7 @@ void memory_region_init(MemoryRegion *mr,
     memset(&mr->subregions_link, 0, sizeof mr->subregions_link);
     QTAILQ_INIT(&mr->coalesced);
     mr->name = qemu_strdup(name);
+    mr->dirty_log_mask = 0;
 }
 
 static bool memory_region_access_valid(MemoryRegion *mr,
@@ -496,24 +505,35 @@ void memory_region_set_offset(MemoryRegion *mr, target_phys_addr_t offset)
 
 void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
 {
-    /* FIXME */
+    uint8_t mask = 1 << client;
+
+    mr->dirty_log_mask = (mr->dirty_log_mask & ~mask) | (log * mask);
+    memory_region_update_topology();
 }
 
 bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr,
                              unsigned client)
 {
-    /* FIXME */
-    return true;
+    assert(mr->has_ram_addr);
+    return cpu_physical_memory_get_dirty(mr->ram_addr + addr, 1 << client);
 }
 
 void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr)
 {
-    /* FIXME */
+    assert(mr->has_ram_addr);
+    return cpu_physical_memory_set_dirty(mr->ram_addr + addr);
 }
 
 void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
 {
-    /* FIXME */
+    FlatRange *fr;
+
+    FOR_EACH_FLAT_RANGE(fr, &current_memory_map) {
+        if (fr->mr == mr) {
+            cpu_physical_sync_dirty_bitmap(fr->addr.start,
+                                           fr->addr.start + fr->addr.size);
+        }
+    }
 }
 
 void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
@@ -524,7 +544,10 @@ void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
 void memory_region_reset_dirty(MemoryRegion *mr, target_phys_addr_t addr,
                                target_phys_addr_t size, unsigned client)
 {
-    /* FIXME */
+    assert(mr->has_ram_addr);
+    cpu_physical_memory_reset_dirty(mr->ram_addr + addr,
+                                    mr->ram_addr + addr + size,
+                                    1 << client);
 }
 
 void *memory_region_get_ram_ptr(MemoryRegion *mr)
diff --git a/memory.h b/memory.h
index 95270aa..8873f75 100644
--- a/memory.h
+++ b/memory.h
@@ -86,6 +86,7 @@ struct MemoryRegion {
     QTAILQ_ENTRY(MemoryRegion) subregions_link;
     QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
     const char *name;
+    uint8_t dirty_log_mask;
 };
 
 /* Initialize a memory region
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 03/56] memory: merge adjacent segments of a single memory region
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Simple implementations of memory routers, for example the Cirrus VGA memory banks
or the 440FX PAM registers can generate adjacent memory regions which are contiguous.
Detect these and merge them; this saves kvm memory slots and shortens lookup times.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/memory.c b/memory.c
index a569666..339bea3 100644
--- a/memory.c
+++ b/memory.c
@@ -122,6 +122,27 @@ static void flatview_destroy(FlatView *view)
     qemu_free(view->ranges);
 }
 
+/* Attempt to simplify a view by merging ajacent ranges */
+static void flatview_simplify(FlatView *view)
+{
+    unsigned i;
+    FlatRange *r1, *r2;
+
+    for (i = 0; i + 1 < view->nr; ++i) {
+        r1 = &view->ranges[i];
+        r2 = &view->ranges[i+1];
+        if (addrrange_end(r1->addr) == r2->addr.start
+            && r1->mr == r2->mr
+            && r1->offset_in_region + r1->addr.size == r2->offset_in_region
+            && r1->dirty_log_mask == r2->dirty_log_mask) {
+            r1->addr.size += r2->addr.size;
+            memmove(r2, r2 + 1, (view->nr - (i + 2)) * sizeof(*r2));
+            --view->nr;
+            --i;
+        }
+    }
+}
+
 /* Render a memory region into the global view.  Ranges in @view obscure
  * ranges in @mr.
  */
@@ -209,6 +230,7 @@ static FlatView generate_memory_topology(MemoryRegion *mr)
     flatview_init(&view);
 
     render_memory_region(&view, mr, 0, addrrange_make(0, UINT64_MAX));
+    flatview_simplify(&view);
 
     return view;
 }
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 03/56] memory: merge adjacent segments of a single memory region
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Simple implementations of memory routers, for example the Cirrus VGA memory banks
or the 440FX PAM registers can generate adjacent memory regions which are contiguous.
Detect these and merge them; this saves kvm memory slots and shortens lookup times.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/memory.c b/memory.c
index a569666..339bea3 100644
--- a/memory.c
+++ b/memory.c
@@ -122,6 +122,27 @@ static void flatview_destroy(FlatView *view)
     qemu_free(view->ranges);
 }
 
+/* Attempt to simplify a view by merging ajacent ranges */
+static void flatview_simplify(FlatView *view)
+{
+    unsigned i;
+    FlatRange *r1, *r2;
+
+    for (i = 0; i + 1 < view->nr; ++i) {
+        r1 = &view->ranges[i];
+        r2 = &view->ranges[i+1];
+        if (addrrange_end(r1->addr) == r2->addr.start
+            && r1->mr == r2->mr
+            && r1->offset_in_region + r1->addr.size == r2->offset_in_region
+            && r1->dirty_log_mask == r2->dirty_log_mask) {
+            r1->addr.size += r2->addr.size;
+            memmove(r2, r2 + 1, (view->nr - (i + 2)) * sizeof(*r2));
+            --view->nr;
+            --i;
+        }
+    }
+}
+
 /* Render a memory region into the global view.  Ranges in @view obscure
  * ranges in @mr.
  */
@@ -209,6 +230,7 @@ static FlatView generate_memory_topology(MemoryRegion *mr)
     flatview_init(&view);
 
     render_memory_region(&view, mr, 0, addrrange_make(0, UINT64_MAX));
+    flatview_simplify(&view);
 
     return view;
 }
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 04/56] Internal interfaces for memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

get_system_memory() provides the root of the memory hierarchy.

This interface is intended to be private between memory.c and exec.c.
If this file is included elsewhere, it should be regarded as a bug (or
TODO item).  However, it will be temporarily needed for the conversion
to hierarchical memory routing.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec-memory.h |   23 +++++++++++++++++++++++
 memory.c      |    7 +++++++
 2 files changed, 30 insertions(+), 0 deletions(-)
 create mode 100644 exec-memory.h

diff --git a/exec-memory.h b/exec-memory.h
new file mode 100644
index 0000000..7eb9085
--- /dev/null
+++ b/exec-memory.h
@@ -0,0 +1,23 @@
+#ifndef EXEC_MEMORY_H
+#define EXEC_MEMORY_H
+
+/*
+ * Internal interfaces between memory.c/exec.c/vl.c.  Do not #include unless
+ * you're one of them.
+ */
+
+#include "memory.h"
+
+#ifndef CONFIG_USER_ONLY
+
+/* Get the root memory region.  This interface should only be used temporarily
+ * until a proper bus interface is available.
+ */
+MemoryRegion *get_system_memory(void);
+
+/* Set the root memory region.  This region is the system memory map. */
+void set_system_memory_map(MemoryRegion *mr);
+
+#endif
+
+#endif
diff --git a/memory.c b/memory.c
index 339bea3..48470d2 100644
--- a/memory.c
+++ b/memory.c
@@ -12,6 +12,7 @@
  */
 
 #include "memory.h"
+#include "exec-memory.h"
 #include <assert.h>
 
 typedef struct AddrRange AddrRange;
@@ -698,3 +699,9 @@ void memory_region_del_subregion(MemoryRegion *mr,
     QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link);
     memory_region_update_topology();
 }
+
+void set_system_memory_map(MemoryRegion *mr)
+{
+    root_memory_region = mr;
+    memory_region_update_topology();
+}
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 04/56] Internal interfaces for memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

get_system_memory() provides the root of the memory hierarchy.

This interface is intended to be private between memory.c and exec.c.
If this file is included elsewhere, it should be regarded as a bug (or
TODO item).  However, it will be temporarily needed for the conversion
to hierarchical memory routing.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec-memory.h |   23 +++++++++++++++++++++++
 memory.c      |    7 +++++++
 2 files changed, 30 insertions(+), 0 deletions(-)
 create mode 100644 exec-memory.h

diff --git a/exec-memory.h b/exec-memory.h
new file mode 100644
index 0000000..7eb9085
--- /dev/null
+++ b/exec-memory.h
@@ -0,0 +1,23 @@
+#ifndef EXEC_MEMORY_H
+#define EXEC_MEMORY_H
+
+/*
+ * Internal interfaces between memory.c/exec.c/vl.c.  Do not #include unless
+ * you're one of them.
+ */
+
+#include "memory.h"
+
+#ifndef CONFIG_USER_ONLY
+
+/* Get the root memory region.  This interface should only be used temporarily
+ * until a proper bus interface is available.
+ */
+MemoryRegion *get_system_memory(void);
+
+/* Set the root memory region.  This region is the system memory map. */
+void set_system_memory_map(MemoryRegion *mr);
+
+#endif
+
+#endif
diff --git a/memory.c b/memory.c
index 339bea3..48470d2 100644
--- a/memory.c
+++ b/memory.c
@@ -12,6 +12,7 @@
  */
 
 #include "memory.h"
+#include "exec-memory.h"
 #include <assert.h>
 
 typedef struct AddrRange AddrRange;
@@ -698,3 +699,9 @@ void memory_region_del_subregion(MemoryRegion *mr,
     QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link);
     memory_region_update_topology();
 }
+
+void set_system_memory_map(MemoryRegion *mr)
+{
+    root_memory_region = mr;
+    memory_region_update_topology();
+}
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 05/56] memory: abstract address space operations
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Prepare for multiple address space support by abstracting away the details
of registering a memory range with qemu's flat representation into an
AddressSpace object.

Note operations which are memory specific are not abstracted, since they will
never be called on I/O address spaces anyway.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |  111 +++++++++++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 81 insertions(+), 30 deletions(-)

diff --git a/memory.c b/memory.c
index 48470d2..7187223 100644
--- a/memory.c
+++ b/memory.c
@@ -82,12 +82,26 @@ struct FlatView {
     unsigned nr_allocated;
 };
 
+typedef struct AddressSpace AddressSpace;
+typedef struct AddressSpaceOps AddressSpaceOps;
+
+/* A system address space - I/O, memory, etc. */
+struct AddressSpace {
+    const AddressSpaceOps *ops;
+    MemoryRegion *root;
+    FlatView current_map;
+};
+
+struct AddressSpaceOps {
+    void (*range_add)(AddressSpace *as, FlatRange *fr);
+    void (*range_del)(AddressSpace *as, FlatRange *fr);
+    void (*log_start)(AddressSpace *as, FlatRange *fr);
+    void (*log_stop)(AddressSpace *as, FlatRange *fr);
+};
+
 #define FOR_EACH_FLAT_RANGE(var, view)          \
     for (var = (view)->ranges; var < (view)->ranges + (view)->nr; ++var)
 
-static FlatView current_memory_map;
-static MemoryRegion *root_memory_region;
-
 static bool flatrange_equal(FlatRange *a, FlatRange *b)
 {
     return a->mr == b->mr
@@ -144,6 +158,54 @@ static void flatview_simplify(FlatView *view)
     }
 }
 
+static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
+{
+    ram_addr_t phys_offset, region_offset;
+
+    phys_offset = fr->mr->ram_addr;
+    region_offset = fr->offset_in_region;
+    /* cpu_register_physical_memory_log() wants region_offset for
+     * mmio, but prefers offseting phys_offset for RAM.  Humour it.
+     */
+    if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) {
+        phys_offset += region_offset;
+        region_offset = 0;
+    }
+
+    cpu_register_physical_memory_log(fr->addr.start,
+                                     fr->addr.size,
+                                     phys_offset,
+                                     region_offset,
+                                     fr->dirty_log_mask);
+}
+
+static void as_memory_range_del(AddressSpace *as, FlatRange *fr)
+{
+    cpu_register_physical_memory(fr->addr.start, fr->addr.size,
+                                 IO_MEM_UNASSIGNED);
+}
+
+static void as_memory_log_start(AddressSpace *as, FlatRange *fr)
+{
+    cpu_physical_log_start(fr->addr.start, fr->addr.size);
+}
+
+static void as_memory_log_stop(AddressSpace *as, FlatRange *fr)
+{
+    cpu_physical_log_stop(fr->addr.start, fr->addr.size);
+}
+
+static const AddressSpaceOps address_space_ops_memory = {
+    .range_add = as_memory_range_add,
+    .range_del = as_memory_range_del,
+    .log_start = as_memory_log_start,
+    .log_stop = as_memory_log_stop,
+};
+
+static AddressSpace address_space_memory = {
+    .ops = &address_space_ops_memory,
+};
+
 /* Render a memory region into the global view.  Ranges in @view obscure
  * ranges in @mr.
  */
@@ -236,13 +298,12 @@ static FlatView generate_memory_topology(MemoryRegion *mr)
     return view;
 }
 
-static void memory_region_update_topology(void)
+static void address_space_update_topology(AddressSpace *as)
 {
-    FlatView old_view = current_memory_map;
-    FlatView new_view = generate_memory_topology(root_memory_region);
+    FlatView old_view = as->current_map;
+    FlatView new_view = generate_memory_topology(as->root);
     unsigned iold, inew;
     FlatRange *frold, *frnew;
-    ram_addr_t phys_offset, region_offset;
 
     /* Generate a symmetric difference of the old and new memory maps.
      * Kill ranges in the old map, and instantiate ranges in the new map.
@@ -267,16 +328,15 @@ static void memory_region_update_topology(void)
                     && !flatrange_equal(frold, frnew)))) {
             /* In old, but (not in new, or in new but attributes changed). */
 
-            cpu_register_physical_memory(frold->addr.start, frold->addr.size,
-                                         IO_MEM_UNASSIGNED);
+            as->ops->range_del(as, frold);
             ++iold;
         } else if (frold && frnew && flatrange_equal(frold, frnew)) {
             /* In both (logging may have changed) */
 
             if (frold->dirty_log_mask && !frnew->dirty_log_mask) {
-                cpu_physical_log_stop(frnew->addr.start, frnew->addr.size);
+                as->ops->log_stop(as, frnew);
             } else if (frnew->dirty_log_mask && !frold->dirty_log_mask) {
-                cpu_physical_log_start(frnew->addr.start, frnew->addr.size);
+                as->ops->log_start(as, frnew);
             }
 
             ++iold;
@@ -284,28 +344,19 @@ static void memory_region_update_topology(void)
         } else {
             /* In new */
 
-            phys_offset = frnew->mr->ram_addr;
-            region_offset = frnew->offset_in_region;
-            /* cpu_register_physical_memory_log() wants region_offset for
-             * mmio, but prefers offseting phys_offset for RAM.  Humour it.
-             */
-            if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) {
-                phys_offset += region_offset;
-                region_offset = 0;
-            }
-
-            cpu_register_physical_memory_log(frnew->addr.start,
-                                             frnew->addr.size,
-                                             phys_offset,
-                                             region_offset,
-                                             frnew->dirty_log_mask);
+            as->ops->range_add(as, frnew);
             ++inew;
         }
     }
-    current_memory_map = new_view;
+    as->current_map = new_view;
     flatview_destroy(&old_view);
 }
 
+static void memory_region_update_topology(void)
+{
+    address_space_update_topology(&address_space_memory);
+}
+
 void memory_region_init(MemoryRegion *mr,
                         const char *name,
                         uint64_t size)
@@ -551,7 +602,7 @@ void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
 {
     FlatRange *fr;
 
-    FOR_EACH_FLAT_RANGE(fr, &current_memory_map) {
+    FOR_EACH_FLAT_RANGE(fr, &address_space_memory.current_map) {
         if (fr->mr == mr) {
             cpu_physical_sync_dirty_bitmap(fr->addr.start,
                                            fr->addr.start + fr->addr.size);
@@ -592,7 +643,7 @@ static void memory_region_update_coalesced_range(MemoryRegion *mr)
     CoalescedMemoryRange *cmr;
     AddrRange tmp;
 
-    FOR_EACH_FLAT_RANGE(fr, &current_memory_map) {
+    FOR_EACH_FLAT_RANGE(fr, &address_space_memory.current_map) {
         if (fr->mr == mr) {
             qemu_unregister_coalesced_mmio(fr->addr.start, fr->addr.size);
             QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
@@ -702,6 +753,6 @@ void memory_region_del_subregion(MemoryRegion *mr,
 
 void set_system_memory_map(MemoryRegion *mr)
 {
-    root_memory_region = mr;
+    address_space_memory.root = mr;
     memory_region_update_topology();
 }
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 05/56] memory: abstract address space operations
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Prepare for multiple address space support by abstracting away the details
of registering a memory range with qemu's flat representation into an
AddressSpace object.

Note operations which are memory specific are not abstracted, since they will
never be called on I/O address spaces anyway.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |  111 +++++++++++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 81 insertions(+), 30 deletions(-)

diff --git a/memory.c b/memory.c
index 48470d2..7187223 100644
--- a/memory.c
+++ b/memory.c
@@ -82,12 +82,26 @@ struct FlatView {
     unsigned nr_allocated;
 };
 
+typedef struct AddressSpace AddressSpace;
+typedef struct AddressSpaceOps AddressSpaceOps;
+
+/* A system address space - I/O, memory, etc. */
+struct AddressSpace {
+    const AddressSpaceOps *ops;
+    MemoryRegion *root;
+    FlatView current_map;
+};
+
+struct AddressSpaceOps {
+    void (*range_add)(AddressSpace *as, FlatRange *fr);
+    void (*range_del)(AddressSpace *as, FlatRange *fr);
+    void (*log_start)(AddressSpace *as, FlatRange *fr);
+    void (*log_stop)(AddressSpace *as, FlatRange *fr);
+};
+
 #define FOR_EACH_FLAT_RANGE(var, view)          \
     for (var = (view)->ranges; var < (view)->ranges + (view)->nr; ++var)
 
-static FlatView current_memory_map;
-static MemoryRegion *root_memory_region;
-
 static bool flatrange_equal(FlatRange *a, FlatRange *b)
 {
     return a->mr == b->mr
@@ -144,6 +158,54 @@ static void flatview_simplify(FlatView *view)
     }
 }
 
+static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
+{
+    ram_addr_t phys_offset, region_offset;
+
+    phys_offset = fr->mr->ram_addr;
+    region_offset = fr->offset_in_region;
+    /* cpu_register_physical_memory_log() wants region_offset for
+     * mmio, but prefers offseting phys_offset for RAM.  Humour it.
+     */
+    if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) {
+        phys_offset += region_offset;
+        region_offset = 0;
+    }
+
+    cpu_register_physical_memory_log(fr->addr.start,
+                                     fr->addr.size,
+                                     phys_offset,
+                                     region_offset,
+                                     fr->dirty_log_mask);
+}
+
+static void as_memory_range_del(AddressSpace *as, FlatRange *fr)
+{
+    cpu_register_physical_memory(fr->addr.start, fr->addr.size,
+                                 IO_MEM_UNASSIGNED);
+}
+
+static void as_memory_log_start(AddressSpace *as, FlatRange *fr)
+{
+    cpu_physical_log_start(fr->addr.start, fr->addr.size);
+}
+
+static void as_memory_log_stop(AddressSpace *as, FlatRange *fr)
+{
+    cpu_physical_log_stop(fr->addr.start, fr->addr.size);
+}
+
+static const AddressSpaceOps address_space_ops_memory = {
+    .range_add = as_memory_range_add,
+    .range_del = as_memory_range_del,
+    .log_start = as_memory_log_start,
+    .log_stop = as_memory_log_stop,
+};
+
+static AddressSpace address_space_memory = {
+    .ops = &address_space_ops_memory,
+};
+
 /* Render a memory region into the global view.  Ranges in @view obscure
  * ranges in @mr.
  */
@@ -236,13 +298,12 @@ static FlatView generate_memory_topology(MemoryRegion *mr)
     return view;
 }
 
-static void memory_region_update_topology(void)
+static void address_space_update_topology(AddressSpace *as)
 {
-    FlatView old_view = current_memory_map;
-    FlatView new_view = generate_memory_topology(root_memory_region);
+    FlatView old_view = as->current_map;
+    FlatView new_view = generate_memory_topology(as->root);
     unsigned iold, inew;
     FlatRange *frold, *frnew;
-    ram_addr_t phys_offset, region_offset;
 
     /* Generate a symmetric difference of the old and new memory maps.
      * Kill ranges in the old map, and instantiate ranges in the new map.
@@ -267,16 +328,15 @@ static void memory_region_update_topology(void)
                     && !flatrange_equal(frold, frnew)))) {
             /* In old, but (not in new, or in new but attributes changed). */
 
-            cpu_register_physical_memory(frold->addr.start, frold->addr.size,
-                                         IO_MEM_UNASSIGNED);
+            as->ops->range_del(as, frold);
             ++iold;
         } else if (frold && frnew && flatrange_equal(frold, frnew)) {
             /* In both (logging may have changed) */
 
             if (frold->dirty_log_mask && !frnew->dirty_log_mask) {
-                cpu_physical_log_stop(frnew->addr.start, frnew->addr.size);
+                as->ops->log_stop(as, frnew);
             } else if (frnew->dirty_log_mask && !frold->dirty_log_mask) {
-                cpu_physical_log_start(frnew->addr.start, frnew->addr.size);
+                as->ops->log_start(as, frnew);
             }
 
             ++iold;
@@ -284,28 +344,19 @@ static void memory_region_update_topology(void)
         } else {
             /* In new */
 
-            phys_offset = frnew->mr->ram_addr;
-            region_offset = frnew->offset_in_region;
-            /* cpu_register_physical_memory_log() wants region_offset for
-             * mmio, but prefers offseting phys_offset for RAM.  Humour it.
-             */
-            if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) {
-                phys_offset += region_offset;
-                region_offset = 0;
-            }
-
-            cpu_register_physical_memory_log(frnew->addr.start,
-                                             frnew->addr.size,
-                                             phys_offset,
-                                             region_offset,
-                                             frnew->dirty_log_mask);
+            as->ops->range_add(as, frnew);
             ++inew;
         }
     }
-    current_memory_map = new_view;
+    as->current_map = new_view;
     flatview_destroy(&old_view);
 }
 
+static void memory_region_update_topology(void)
+{
+    address_space_update_topology(&address_space_memory);
+}
+
 void memory_region_init(MemoryRegion *mr,
                         const char *name,
                         uint64_t size)
@@ -551,7 +602,7 @@ void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
 {
     FlatRange *fr;
 
-    FOR_EACH_FLAT_RANGE(fr, &current_memory_map) {
+    FOR_EACH_FLAT_RANGE(fr, &address_space_memory.current_map) {
         if (fr->mr == mr) {
             cpu_physical_sync_dirty_bitmap(fr->addr.start,
                                            fr->addr.start + fr->addr.size);
@@ -592,7 +643,7 @@ static void memory_region_update_coalesced_range(MemoryRegion *mr)
     CoalescedMemoryRange *cmr;
     AddrRange tmp;
 
-    FOR_EACH_FLAT_RANGE(fr, &current_memory_map) {
+    FOR_EACH_FLAT_RANGE(fr, &address_space_memory.current_map) {
         if (fr->mr == mr) {
             qemu_unregister_coalesced_mmio(fr->addr.start, fr->addr.size);
             QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
@@ -702,6 +753,6 @@ void memory_region_del_subregion(MemoryRegion *mr,
 
 void set_system_memory_map(MemoryRegion *mr)
 {
-    root_memory_region = mr;
+    address_space_memory.root = mr;
     memory_region_update_topology();
 }
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 06/56] memory: rename MemoryRegion::has_ram_addr to ::terminates
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

I/O regions will not have ram_addrs, so this is a better name.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |   18 +++++++++---------
 memory.h |    2 +-
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/memory.c b/memory.c
index 7187223..5fda4a0 100644
--- a/memory.c
+++ b/memory.c
@@ -244,7 +244,7 @@ static void render_memory_region(FlatView *view,
         render_memory_region(view, subregion, base, clip);
     }
 
-    if (!mr->has_ram_addr) {
+    if (!mr->terminates) {
         return;
     }
 
@@ -366,7 +366,7 @@ void memory_region_init(MemoryRegion *mr,
     mr->size = size;
     mr->addr = 0;
     mr->offset = 0;
-    mr->has_ram_addr = false;
+    mr->terminates = false;
     mr->priority = 0;
     mr->may_overlap = false;
     mr->alias = NULL;
@@ -521,7 +521,7 @@ void memory_region_init_io(MemoryRegion *mr,
     memory_region_init(mr, name, size);
     mr->ops = ops;
     mr->opaque = opaque;
-    mr->has_ram_addr = true;
+    mr->terminates = true;
     mr->ram_addr = cpu_register_io_memory(memory_region_read_thunk,
                                           memory_region_write_thunk,
                                           mr,
@@ -534,7 +534,7 @@ void memory_region_init_ram(MemoryRegion *mr,
                             uint64_t size)
 {
     memory_region_init(mr, name, size);
-    mr->has_ram_addr = true;
+    mr->terminates = true;
     mr->ram_addr = qemu_ram_alloc(dev, name, size);
 }
 
@@ -545,7 +545,7 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
                                 void *ptr)
 {
     memory_region_init(mr, name, size);
-    mr->has_ram_addr = true;
+    mr->terminates = true;
     mr->ram_addr = qemu_ram_alloc_from_ptr(dev, name, size, ptr);
 }
 
@@ -588,13 +588,13 @@ void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
 bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr,
                              unsigned client)
 {
-    assert(mr->has_ram_addr);
+    assert(mr->terminates);
     return cpu_physical_memory_get_dirty(mr->ram_addr + addr, 1 << client);
 }
 
 void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr)
 {
-    assert(mr->has_ram_addr);
+    assert(mr->terminates);
     return cpu_physical_memory_set_dirty(mr->ram_addr + addr);
 }
 
@@ -618,7 +618,7 @@ void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
 void memory_region_reset_dirty(MemoryRegion *mr, target_phys_addr_t addr,
                                target_phys_addr_t size, unsigned client)
 {
-    assert(mr->has_ram_addr);
+    assert(mr->terminates);
     cpu_physical_memory_reset_dirty(mr->ram_addr + addr,
                                     mr->ram_addr + addr + size,
                                     1 << client);
@@ -630,7 +630,7 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr)
         return memory_region_get_ram_ptr(mr->alias) + mr->alias_offset;
     }
 
-    if (!mr->has_ram_addr) {
+    if (!mr->terminates) {
         abort();
     }
 
diff --git a/memory.h b/memory.h
index 8873f75..2ad7202 100644
--- a/memory.h
+++ b/memory.h
@@ -77,7 +77,7 @@ struct MemoryRegion {
     target_phys_addr_t addr;
     target_phys_addr_t offset;
     ram_addr_t ram_addr;
-    bool has_ram_addr;
+    bool terminates;
     MemoryRegion *alias;
     target_phys_addr_t alias_offset;
     unsigned priority;
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 06/56] memory: rename MemoryRegion::has_ram_addr to ::terminates
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

I/O regions will not have ram_addrs, so this is a better name.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |   18 +++++++++---------
 memory.h |    2 +-
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/memory.c b/memory.c
index 7187223..5fda4a0 100644
--- a/memory.c
+++ b/memory.c
@@ -244,7 +244,7 @@ static void render_memory_region(FlatView *view,
         render_memory_region(view, subregion, base, clip);
     }
 
-    if (!mr->has_ram_addr) {
+    if (!mr->terminates) {
         return;
     }
 
@@ -366,7 +366,7 @@ void memory_region_init(MemoryRegion *mr,
     mr->size = size;
     mr->addr = 0;
     mr->offset = 0;
-    mr->has_ram_addr = false;
+    mr->terminates = false;
     mr->priority = 0;
     mr->may_overlap = false;
     mr->alias = NULL;
@@ -521,7 +521,7 @@ void memory_region_init_io(MemoryRegion *mr,
     memory_region_init(mr, name, size);
     mr->ops = ops;
     mr->opaque = opaque;
-    mr->has_ram_addr = true;
+    mr->terminates = true;
     mr->ram_addr = cpu_register_io_memory(memory_region_read_thunk,
                                           memory_region_write_thunk,
                                           mr,
@@ -534,7 +534,7 @@ void memory_region_init_ram(MemoryRegion *mr,
                             uint64_t size)
 {
     memory_region_init(mr, name, size);
-    mr->has_ram_addr = true;
+    mr->terminates = true;
     mr->ram_addr = qemu_ram_alloc(dev, name, size);
 }
 
@@ -545,7 +545,7 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
                                 void *ptr)
 {
     memory_region_init(mr, name, size);
-    mr->has_ram_addr = true;
+    mr->terminates = true;
     mr->ram_addr = qemu_ram_alloc_from_ptr(dev, name, size, ptr);
 }
 
@@ -588,13 +588,13 @@ void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
 bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr,
                              unsigned client)
 {
-    assert(mr->has_ram_addr);
+    assert(mr->terminates);
     return cpu_physical_memory_get_dirty(mr->ram_addr + addr, 1 << client);
 }
 
 void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr)
 {
-    assert(mr->has_ram_addr);
+    assert(mr->terminates);
     return cpu_physical_memory_set_dirty(mr->ram_addr + addr);
 }
 
@@ -618,7 +618,7 @@ void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
 void memory_region_reset_dirty(MemoryRegion *mr, target_phys_addr_t addr,
                                target_phys_addr_t size, unsigned client)
 {
-    assert(mr->has_ram_addr);
+    assert(mr->terminates);
     cpu_physical_memory_reset_dirty(mr->ram_addr + addr,
                                     mr->ram_addr + addr + size,
                                     1 << client);
@@ -630,7 +630,7 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr)
         return memory_region_get_ram_ptr(mr->alias) + mr->alias_offset;
     }
 
-    if (!mr->has_ram_addr) {
+    if (!mr->terminates) {
         abort();
     }
 
diff --git a/memory.h b/memory.h
index 8873f75..2ad7202 100644
--- a/memory.h
+++ b/memory.h
@@ -77,7 +77,7 @@ struct MemoryRegion {
     target_phys_addr_t addr;
     target_phys_addr_t offset;
     ram_addr_t ram_addr;
-    bool has_ram_addr;
+    bool terminates;
     MemoryRegion *alias;
     target_phys_addr_t alias_offset;
     unsigned priority;
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 07/56] memory: late initialization of ram_addr
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

For non-RAM memory regions, we cannot tell whether this is an I/O region
or an MMIO region.  Since the qemu backing registration is different for
the two, we have to defer initialization until we know which address
space we are in.

These shenanigans will be removed once the backing registration is unified
with the memory API.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |   24 ++++++++++++++++++++----
 memory.h |    1 +
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/memory.c b/memory.c
index 5fda4a0..bc8bfa2 100644
--- a/memory.c
+++ b/memory.c
@@ -158,10 +158,14 @@ static void flatview_simplify(FlatView *view)
     }
 }
 
+static void memory_region_prepare_ram_addr(MemoryRegion *mr);
+
 static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
 {
     ram_addr_t phys_offset, region_offset;
 
+    memory_region_prepare_ram_addr(fr->mr);
+
     phys_offset = fr->mr->ram_addr;
     region_offset = fr->offset_in_region;
     /* cpu_register_physical_memory_log() wants region_offset for
@@ -512,6 +516,19 @@ static CPUWriteMemoryFunc * const memory_region_write_thunk[] = {
     memory_region_write_thunk_l,
 };
 
+static void memory_region_prepare_ram_addr(MemoryRegion *mr)
+{
+    if (mr->backend_registered) {
+        return;
+    }
+
+    mr->ram_addr = cpu_register_io_memory(memory_region_read_thunk,
+                                          memory_region_write_thunk,
+                                          mr,
+                                          mr->ops->endianness);
+    mr->backend_registered = true;
+}
+
 void memory_region_init_io(MemoryRegion *mr,
                            const MemoryRegionOps *ops,
                            void *opaque,
@@ -522,10 +539,7 @@ void memory_region_init_io(MemoryRegion *mr,
     mr->ops = ops;
     mr->opaque = opaque;
     mr->terminates = true;
-    mr->ram_addr = cpu_register_io_memory(memory_region_read_thunk,
-                                          memory_region_write_thunk,
-                                          mr,
-                                          mr->ops->endianness);
+    mr->backend_registered = false;
 }
 
 void memory_region_init_ram(MemoryRegion *mr,
@@ -536,6 +550,7 @@ void memory_region_init_ram(MemoryRegion *mr,
     memory_region_init(mr, name, size);
     mr->terminates = true;
     mr->ram_addr = qemu_ram_alloc(dev, name, size);
+    mr->backend_registered = true;
 }
 
 void memory_region_init_ram_ptr(MemoryRegion *mr,
@@ -547,6 +562,7 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
     memory_region_init(mr, name, size);
     mr->terminates = true;
     mr->ram_addr = qemu_ram_alloc_from_ptr(dev, name, size, ptr);
+    mr->backend_registered = true;
 }
 
 void memory_region_init_alias(MemoryRegion *mr,
diff --git a/memory.h b/memory.h
index 2ad7202..0994b18 100644
--- a/memory.h
+++ b/memory.h
@@ -76,6 +76,7 @@ struct MemoryRegion {
     uint64_t size;
     target_phys_addr_t addr;
     target_phys_addr_t offset;
+    bool backend_registered;
     ram_addr_t ram_addr;
     bool terminates;
     MemoryRegion *alias;
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 07/56] memory: late initialization of ram_addr
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

For non-RAM memory regions, we cannot tell whether this is an I/O region
or an MMIO region.  Since the qemu backing registration is different for
the two, we have to defer initialization until we know which address
space we are in.

These shenanigans will be removed once the backing registration is unified
with the memory API.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |   24 ++++++++++++++++++++----
 memory.h |    1 +
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/memory.c b/memory.c
index 5fda4a0..bc8bfa2 100644
--- a/memory.c
+++ b/memory.c
@@ -158,10 +158,14 @@ static void flatview_simplify(FlatView *view)
     }
 }
 
+static void memory_region_prepare_ram_addr(MemoryRegion *mr);
+
 static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
 {
     ram_addr_t phys_offset, region_offset;
 
+    memory_region_prepare_ram_addr(fr->mr);
+
     phys_offset = fr->mr->ram_addr;
     region_offset = fr->offset_in_region;
     /* cpu_register_physical_memory_log() wants region_offset for
@@ -512,6 +516,19 @@ static CPUWriteMemoryFunc * const memory_region_write_thunk[] = {
     memory_region_write_thunk_l,
 };
 
+static void memory_region_prepare_ram_addr(MemoryRegion *mr)
+{
+    if (mr->backend_registered) {
+        return;
+    }
+
+    mr->ram_addr = cpu_register_io_memory(memory_region_read_thunk,
+                                          memory_region_write_thunk,
+                                          mr,
+                                          mr->ops->endianness);
+    mr->backend_registered = true;
+}
+
 void memory_region_init_io(MemoryRegion *mr,
                            const MemoryRegionOps *ops,
                            void *opaque,
@@ -522,10 +539,7 @@ void memory_region_init_io(MemoryRegion *mr,
     mr->ops = ops;
     mr->opaque = opaque;
     mr->terminates = true;
-    mr->ram_addr = cpu_register_io_memory(memory_region_read_thunk,
-                                          memory_region_write_thunk,
-                                          mr,
-                                          mr->ops->endianness);
+    mr->backend_registered = false;
 }
 
 void memory_region_init_ram(MemoryRegion *mr,
@@ -536,6 +550,7 @@ void memory_region_init_ram(MemoryRegion *mr,
     memory_region_init(mr, name, size);
     mr->terminates = true;
     mr->ram_addr = qemu_ram_alloc(dev, name, size);
+    mr->backend_registered = true;
 }
 
 void memory_region_init_ram_ptr(MemoryRegion *mr,
@@ -547,6 +562,7 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
     memory_region_init(mr, name, size);
     mr->terminates = true;
     mr->ram_addr = qemu_ram_alloc_from_ptr(dev, name, size, ptr);
+    mr->backend_registered = true;
 }
 
 void memory_region_init_alias(MemoryRegion *mr,
diff --git a/memory.h b/memory.h
index 2ad7202..0994b18 100644
--- a/memory.h
+++ b/memory.h
@@ -76,6 +76,7 @@ struct MemoryRegion {
     uint64_t size;
     target_phys_addr_t addr;
     target_phys_addr_t offset;
+    bool backend_registered;
     ram_addr_t ram_addr;
     bool terminates;
     MemoryRegion *alias;
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 08/56] memory:  I/O address space support
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Allow registering I/O ports via the same mechanism as mmio ranges.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec-memory.h |    3 ++
 memory.c      |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 memory.h      |    2 +
 3 files changed, 64 insertions(+), 1 deletions(-)

diff --git a/exec-memory.h b/exec-memory.h
index 7eb9085..aad21b5 100644
--- a/exec-memory.h
+++ b/exec-memory.h
@@ -18,6 +18,9 @@ MemoryRegion *get_system_memory(void);
 /* Set the root memory region.  This region is the system memory map. */
 void set_system_memory_map(MemoryRegion *mr);
 
+/* Set the I/O memory region.  This region is the I/O memory map. */
+void set_system_io_map(MemoryRegion *mr);
+
 #endif
 
 #endif
diff --git a/memory.c b/memory.c
index bc8bfa2..62bd60b 100644
--- a/memory.c
+++ b/memory.c
@@ -13,6 +13,7 @@
 
 #include "memory.h"
 #include "exec-memory.h"
+#include "ioport.h"
 #include <assert.h>
 
 typedef struct AddrRange AddrRange;
@@ -210,6 +211,52 @@ static AddressSpace address_space_memory = {
     .ops = &address_space_ops_memory,
 };
 
+static void memory_region_iorange_read(IORange *iorange,
+                                       uint64_t offset,
+                                       unsigned width,
+                                       uint64_t *data)
+{
+    MemoryRegion *mr = container_of(iorange, MemoryRegion, iorange);
+
+    *data = mr->ops->read(mr->opaque, offset, width);
+}
+
+static void memory_region_iorange_write(IORange *iorange,
+                                        uint64_t offset,
+                                        unsigned width,
+                                        uint64_t data)
+{
+    MemoryRegion *mr = container_of(iorange, MemoryRegion, iorange);
+
+    mr->ops->write(mr->opaque, offset, data, width);
+}
+
+static const IORangeOps memory_region_iorange_ops = {
+    .read = memory_region_iorange_read,
+    .write = memory_region_iorange_write,
+};
+
+static void as_io_range_add(AddressSpace *as, FlatRange *fr)
+{
+    iorange_init(&fr->mr->iorange, &memory_region_iorange_ops,
+                 fr->addr.start,fr->addr.size);
+    ioport_register(&fr->mr->iorange);
+}
+
+static void as_io_range_del(AddressSpace *as, FlatRange *fr)
+{
+    isa_unassign_ioport(fr->addr.start, fr->addr.size);
+}
+
+static const AddressSpaceOps address_space_ops_io = {
+    .range_add = as_io_range_add,
+    .range_del = as_io_range_del,
+};
+
+static AddressSpace address_space_io = {
+    .ops = &address_space_ops_io,
+};
+
 /* Render a memory region into the global view.  Ranges in @view obscure
  * ranges in @mr.
  */
@@ -358,7 +405,12 @@ static void address_space_update_topology(AddressSpace *as)
 
 static void memory_region_update_topology(void)
 {
-    address_space_update_topology(&address_space_memory);
+    if (address_space_memory.root) {
+        address_space_update_topology(&address_space_memory);
+    }
+    if (address_space_io.root) {
+        address_space_update_topology(&address_space_io);
+    }
 }
 
 void memory_region_init(MemoryRegion *mr,
@@ -772,3 +824,9 @@ void set_system_memory_map(MemoryRegion *mr)
     address_space_memory.root = mr;
     memory_region_update_topology();
 }
+
+void set_system_io_map(MemoryRegion *mr)
+{
+    address_space_io.root = mr;
+    memory_region_update_topology();
+}
diff --git a/memory.h b/memory.h
index 0994b18..2afbf13 100644
--- a/memory.h
+++ b/memory.h
@@ -9,6 +9,7 @@
 #include "cpu-common.h"
 #include "targphys.h"
 #include "qemu-queue.h"
+#include "iorange.h"
 
 typedef struct MemoryRegionOps MemoryRegionOps;
 typedef struct MemoryRegion MemoryRegion;
@@ -78,6 +79,7 @@ struct MemoryRegion {
     target_phys_addr_t offset;
     bool backend_registered;
     ram_addr_t ram_addr;
+    IORange iorange;
     bool terminates;
     MemoryRegion *alias;
     target_phys_addr_t alias_offset;
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 08/56] memory:  I/O address space support
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Allow registering I/O ports via the same mechanism as mmio ranges.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec-memory.h |    3 ++
 memory.c      |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 memory.h      |    2 +
 3 files changed, 64 insertions(+), 1 deletions(-)

diff --git a/exec-memory.h b/exec-memory.h
index 7eb9085..aad21b5 100644
--- a/exec-memory.h
+++ b/exec-memory.h
@@ -18,6 +18,9 @@ MemoryRegion *get_system_memory(void);
 /* Set the root memory region.  This region is the system memory map. */
 void set_system_memory_map(MemoryRegion *mr);
 
+/* Set the I/O memory region.  This region is the I/O memory map. */
+void set_system_io_map(MemoryRegion *mr);
+
 #endif
 
 #endif
diff --git a/memory.c b/memory.c
index bc8bfa2..62bd60b 100644
--- a/memory.c
+++ b/memory.c
@@ -13,6 +13,7 @@
 
 #include "memory.h"
 #include "exec-memory.h"
+#include "ioport.h"
 #include <assert.h>
 
 typedef struct AddrRange AddrRange;
@@ -210,6 +211,52 @@ static AddressSpace address_space_memory = {
     .ops = &address_space_ops_memory,
 };
 
+static void memory_region_iorange_read(IORange *iorange,
+                                       uint64_t offset,
+                                       unsigned width,
+                                       uint64_t *data)
+{
+    MemoryRegion *mr = container_of(iorange, MemoryRegion, iorange);
+
+    *data = mr->ops->read(mr->opaque, offset, width);
+}
+
+static void memory_region_iorange_write(IORange *iorange,
+                                        uint64_t offset,
+                                        unsigned width,
+                                        uint64_t data)
+{
+    MemoryRegion *mr = container_of(iorange, MemoryRegion, iorange);
+
+    mr->ops->write(mr->opaque, offset, data, width);
+}
+
+static const IORangeOps memory_region_iorange_ops = {
+    .read = memory_region_iorange_read,
+    .write = memory_region_iorange_write,
+};
+
+static void as_io_range_add(AddressSpace *as, FlatRange *fr)
+{
+    iorange_init(&fr->mr->iorange, &memory_region_iorange_ops,
+                 fr->addr.start,fr->addr.size);
+    ioport_register(&fr->mr->iorange);
+}
+
+static void as_io_range_del(AddressSpace *as, FlatRange *fr)
+{
+    isa_unassign_ioport(fr->addr.start, fr->addr.size);
+}
+
+static const AddressSpaceOps address_space_ops_io = {
+    .range_add = as_io_range_add,
+    .range_del = as_io_range_del,
+};
+
+static AddressSpace address_space_io = {
+    .ops = &address_space_ops_io,
+};
+
 /* Render a memory region into the global view.  Ranges in @view obscure
  * ranges in @mr.
  */
@@ -358,7 +405,12 @@ static void address_space_update_topology(AddressSpace *as)
 
 static void memory_region_update_topology(void)
 {
-    address_space_update_topology(&address_space_memory);
+    if (address_space_memory.root) {
+        address_space_update_topology(&address_space_memory);
+    }
+    if (address_space_io.root) {
+        address_space_update_topology(&address_space_io);
+    }
 }
 
 void memory_region_init(MemoryRegion *mr,
@@ -772,3 +824,9 @@ void set_system_memory_map(MemoryRegion *mr)
     address_space_memory.root = mr;
     memory_region_update_topology();
 }
+
+void set_system_io_map(MemoryRegion *mr)
+{
+    address_space_io.root = mr;
+    memory_region_update_topology();
+}
diff --git a/memory.h b/memory.h
index 0994b18..2afbf13 100644
--- a/memory.h
+++ b/memory.h
@@ -9,6 +9,7 @@
 #include "cpu-common.h"
 #include "targphys.h"
 #include "qemu-queue.h"
+#include "iorange.h"
 
 typedef struct MemoryRegionOps MemoryRegionOps;
 typedef struct MemoryRegion MemoryRegion;
@@ -78,6 +79,7 @@ struct MemoryRegion {
     target_phys_addr_t offset;
     bool backend_registered;
     ram_addr_t ram_addr;
+    IORange iorange;
     bool terminates;
     MemoryRegion *alias;
     target_phys_addr_t alias_offset;
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 09/56] exec.c: initialize memory map
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Allocate the root memory region and initialize it.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/exec.c b/exec.c
index 4c45299..f274ec9 100644
--- a/exec.c
+++ b/exec.c
@@ -33,6 +33,8 @@
 #include "kvm.h"
 #include "hw/xen.h"
 #include "qemu-timer.h"
+#include "memory.h"
+#include "exec-memory.h"
 #if defined(CONFIG_USER_ONLY)
 #include <qemu.h>
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
@@ -109,6 +111,9 @@ int phys_ram_fd;
 static int in_migration;
 
 RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list) };
+
+static MemoryRegion *system_memory;
+
 #endif
 
 CPUState *first_cpu;
@@ -197,6 +202,7 @@ typedef struct PhysPageDesc {
 static void *l1_phys_map[P_L1_SIZE];
 
 static void io_mem_init(void);
+static void memory_map_init(void);
 
 /* io memory support */
 CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
@@ -571,6 +577,7 @@ void cpu_exec_init_all(unsigned long tb_size)
     code_gen_ptr = code_gen_buffer;
     page_init();
 #if !defined(CONFIG_USER_ONLY)
+    memory_map_init();
     io_mem_init();
 #endif
 #if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE)
@@ -3805,6 +3812,18 @@ static void io_mem_init(void)
                                           DEVICE_NATIVE_ENDIAN);
 }
 
+static void memory_map_init(void)
+{
+    system_memory = qemu_malloc(sizeof(*system_memory));
+    memory_region_init(system_memory, "system", UINT64_MAX);
+    set_system_memory_map(system_memory);
+}
+
+MemoryRegion *get_system_memory(void)
+{
+    return system_memory;
+}
+
 #endif /* !defined(CONFIG_USER_ONLY) */
 
 /* physical memory access (slow version, mainly for debug) */
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 09/56] exec.c: initialize memory map
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Allocate the root memory region and initialize it.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/exec.c b/exec.c
index 4c45299..f274ec9 100644
--- a/exec.c
+++ b/exec.c
@@ -33,6 +33,8 @@
 #include "kvm.h"
 #include "hw/xen.h"
 #include "qemu-timer.h"
+#include "memory.h"
+#include "exec-memory.h"
 #if defined(CONFIG_USER_ONLY)
 #include <qemu.h>
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
@@ -109,6 +111,9 @@ int phys_ram_fd;
 static int in_migration;
 
 RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list) };
+
+static MemoryRegion *system_memory;
+
 #endif
 
 CPUState *first_cpu;
@@ -197,6 +202,7 @@ typedef struct PhysPageDesc {
 static void *l1_phys_map[P_L1_SIZE];
 
 static void io_mem_init(void);
+static void memory_map_init(void);
 
 /* io memory support */
 CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
@@ -571,6 +577,7 @@ void cpu_exec_init_all(unsigned long tb_size)
     code_gen_ptr = code_gen_buffer;
     page_init();
 #if !defined(CONFIG_USER_ONLY)
+    memory_map_init();
     io_mem_init();
 #endif
 #if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE)
@@ -3805,6 +3812,18 @@ static void io_mem_init(void)
                                           DEVICE_NATIVE_ENDIAN);
 }
 
+static void memory_map_init(void)
+{
+    system_memory = qemu_malloc(sizeof(*system_memory));
+    memory_region_init(system_memory, "system", UINT64_MAX);
+    set_system_memory_map(system_memory);
+}
+
+MemoryRegion *get_system_memory(void)
+{
+    return system_memory;
+}
+
 #endif /* !defined(CONFIG_USER_ONLY) */
 
 /* physical memory access (slow version, mainly for debug) */
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 10/56] ioport: register ranges by byte aligned addresses always
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

The I/O port space is byte addressable, even for word and long accesses.

An example is the VMware svga card, which has long ports on offsets 0,
1, and 2.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 ioport.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/ioport.c b/ioport.c
index 2e971fa..9800223 100644
--- a/ioport.c
+++ b/ioport.c
@@ -146,7 +146,7 @@ int register_ioport_read(pio_addr_t start, int length, int size,
         hw_error("register_ioport_read: invalid size");
         return -1;
     }
-    for(i = start; i < start + length; i += size) {
+    for(i = start; i < start + length; ++i) {
         ioport_read_table[bsize][i] = func;
         if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
             hw_error("register_ioport_read: invalid opaque for address 0x%x",
@@ -166,7 +166,7 @@ int register_ioport_write(pio_addr_t start, int length, int size,
         hw_error("register_ioport_write: invalid size");
         return -1;
     }
-    for(i = start; i < start + length; i += size) {
+    for(i = start; i < start + length; ++i) {
         ioport_write_table[bsize][i] = func;
         if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
             hw_error("register_ioport_write: invalid opaque for address 0x%x",
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 10/56] ioport: register ranges by byte aligned addresses always
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

The I/O port space is byte addressable, even for word and long accesses.

An example is the VMware svga card, which has long ports on offsets 0,
1, and 2.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 ioport.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/ioport.c b/ioport.c
index 2e971fa..9800223 100644
--- a/ioport.c
+++ b/ioport.c
@@ -146,7 +146,7 @@ int register_ioport_read(pio_addr_t start, int length, int size,
         hw_error("register_ioport_read: invalid size");
         return -1;
     }
-    for(i = start; i < start + length; i += size) {
+    for(i = start; i < start + length; ++i) {
         ioport_read_table[bsize][i] = func;
         if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
             hw_error("register_ioport_read: invalid opaque for address 0x%x",
@@ -166,7 +166,7 @@ int register_ioport_write(pio_addr_t start, int length, int size,
         hw_error("register_ioport_write: invalid size");
         return -1;
     }
-    for(i = start; i < start + length; i += size) {
+    for(i = start; i < start + length; ++i) {
         ioport_write_table[bsize][i] = func;
         if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
             hw_error("register_ioport_write: invalid opaque for address 0x%x",
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 11/56] pc: grab system_memory
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

While eventually this should come from the machine initialization function,
take a short cut to avoid converting all machines now.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pc.c      |    3 ++-
 hw/pc.h      |    4 +++-
 hw/pc_piix.c |    8 +++++++-
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index a3e8539..369566a 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -957,7 +957,8 @@ void pc_cpus_init(const char *cpu_model)
     }
 }
 
-void pc_memory_init(const char *kernel_filename,
+void pc_memory_init(MemoryRegion *system_memory,
+                    const char *kernel_filename,
                     const char *kernel_cmdline,
                     const char *initrd_filename,
                     ram_addr_t below_4g_mem_size,
diff --git a/hw/pc.h b/hw/pc.h
index 6d5730b..fa57583 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -6,6 +6,7 @@
 #include "isa.h"
 #include "fdc.h"
 #include "net.h"
+#include "memory.h"
 
 /* PC-style peripherals (also used by other machines).  */
 
@@ -129,7 +130,8 @@ void pc_cmos_set_s3_resume(void *opaque, int irq, int level);
 void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
 
 void pc_cpus_init(const char *cpu_model);
-void pc_memory_init(const char *kernel_filename,
+void pc_memory_init(MemoryRegion *system_memory,
+                    const char *kernel_filename,
                     const char *kernel_cmdline,
                     const char *initrd_filename,
                     ram_addr_t below_4g_mem_size,
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index c5c16b4..d83854c 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -39,6 +39,8 @@
 #include "blockdev.h"
 #include "smbus.h"
 #include "xen.h"
+#include "memory.h"
+#include "exec-memory.h"
 #ifdef CONFIG_XEN
 #  include <xen/hvm/hvm_info_table.h>
 #endif
@@ -89,6 +91,9 @@ static void pc_init1(ram_addr_t ram_size,
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     BusState *idebus[MAX_IDE_BUS];
     ISADevice *rtc_state;
+    MemoryRegion *system_memory;
+
+    system_memory = get_system_memory();
 
     pc_cpus_init(cpu_model);
 
@@ -106,7 +111,8 @@ static void pc_init1(ram_addr_t ram_size,
 
     /* allocate ram and load rom/bios */
     if (!xen_enabled()) {
-        pc_memory_init(kernel_filename, kernel_cmdline, initrd_filename,
+        pc_memory_init(system_memory,
+                       kernel_filename, kernel_cmdline, initrd_filename,
                        below_4g_mem_size, above_4g_mem_size);
     }
 
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 11/56] pc: grab system_memory
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

While eventually this should come from the machine initialization function,
take a short cut to avoid converting all machines now.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pc.c      |    3 ++-
 hw/pc.h      |    4 +++-
 hw/pc_piix.c |    8 +++++++-
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index a3e8539..369566a 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -957,7 +957,8 @@ void pc_cpus_init(const char *cpu_model)
     }
 }
 
-void pc_memory_init(const char *kernel_filename,
+void pc_memory_init(MemoryRegion *system_memory,
+                    const char *kernel_filename,
                     const char *kernel_cmdline,
                     const char *initrd_filename,
                     ram_addr_t below_4g_mem_size,
diff --git a/hw/pc.h b/hw/pc.h
index 6d5730b..fa57583 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -6,6 +6,7 @@
 #include "isa.h"
 #include "fdc.h"
 #include "net.h"
+#include "memory.h"
 
 /* PC-style peripherals (also used by other machines).  */
 
@@ -129,7 +130,8 @@ void pc_cmos_set_s3_resume(void *opaque, int irq, int level);
 void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
 
 void pc_cpus_init(const char *cpu_model);
-void pc_memory_init(const char *kernel_filename,
+void pc_memory_init(MemoryRegion *system_memory,
+                    const char *kernel_filename,
                     const char *kernel_cmdline,
                     const char *initrd_filename,
                     ram_addr_t below_4g_mem_size,
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index c5c16b4..d83854c 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -39,6 +39,8 @@
 #include "blockdev.h"
 #include "smbus.h"
 #include "xen.h"
+#include "memory.h"
+#include "exec-memory.h"
 #ifdef CONFIG_XEN
 #  include <xen/hvm/hvm_info_table.h>
 #endif
@@ -89,6 +91,9 @@ static void pc_init1(ram_addr_t ram_size,
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     BusState *idebus[MAX_IDE_BUS];
     ISADevice *rtc_state;
+    MemoryRegion *system_memory;
+
+    system_memory = get_system_memory();
 
     pc_cpus_init(cpu_model);
 
@@ -106,7 +111,8 @@ static void pc_init1(ram_addr_t ram_size,
 
     /* allocate ram and load rom/bios */
     if (!xen_enabled()) {
-        pc_memory_init(kernel_filename, kernel_cmdline, initrd_filename,
+        pc_memory_init(system_memory,
+                       kernel_filename, kernel_cmdline, initrd_filename,
                        below_4g_mem_size, above_4g_mem_size);
     }
 
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 12/56] pc: convert pc_memory_init() to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pc.c |   59 ++++++++++++++++++++++++++++++++++++++++-------------------
 hw/pc.h |    1 +
 2 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 369566a..1c9d89a 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -41,6 +41,7 @@
 #include "sysemu.h"
 #include "blockdev.h"
 #include "ui/qemu-spice.h"
+#include "memory.h"
 
 /* output Bochs bios info messages */
 //#define DEBUG_BIOS
@@ -966,22 +967,30 @@ void pc_memory_init(MemoryRegion *system_memory,
 {
     char *filename;
     int ret, linux_boot, i;
-    ram_addr_t ram_addr, bios_offset, option_rom_offset;
+    MemoryRegion *ram, *bios, *isa_bios, *option_rom_mr;
+    MemoryRegion *ram_below_4g, *ram_above_4g;
     int bios_size, isa_bios_size;
     void *fw_cfg;
 
     linux_boot = (kernel_filename != NULL);
 
-    /* allocate RAM */
-    ram_addr = qemu_ram_alloc(NULL, "pc.ram",
-                              below_4g_mem_size + above_4g_mem_size);
-    cpu_register_physical_memory(0, 0xa0000, ram_addr);
-    cpu_register_physical_memory(0x100000,
-                 below_4g_mem_size - 0x100000,
-                 ram_addr + 0x100000);
+    /* Allocate RAM.  We allocate it as a single memory region and use
+     * aliases to address portions of it, mostly for backwards compatiblity
+     * with older qemus that used qemu_ram_alloc().
+     */
+    ram = qemu_malloc(sizeof(*ram));
+    memory_region_init_ram(ram, NULL, "pc.ram",
+                           below_4g_mem_size + above_4g_mem_size);
+    ram_below_4g = qemu_malloc(sizeof(*ram_below_4g));
+    memory_region_init_alias(ram_below_4g, "ram-below-4g", ram,
+                             0, below_4g_mem_size);
+    memory_region_add_subregion(system_memory, 0, ram_below_4g);
     if (above_4g_mem_size > 0) {
-        cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
-                                     ram_addr + below_4g_mem_size);
+        ram_above_4g = qemu_malloc(sizeof(*ram_above_4g));
+        memory_region_init_alias(ram_above_4g, "ram-above-4g", ram,
+                                 below_4g_mem_size, above_4g_mem_size);
+        memory_region_add_subregion(system_memory, 0x100000000ULL,
+                                    ram_above_4g);
     }
 
     /* BIOS load */
@@ -997,7 +1006,9 @@ void pc_memory_init(MemoryRegion *system_memory,
         (bios_size % 65536) != 0) {
         goto bios_error;
     }
-    bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
+    bios = qemu_malloc(sizeof(*bios));
+    memory_region_init_ram(bios, NULL, "pc.bios", bios_size);
+    memory_region_set_readonly(bios, true);
     ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
     if (ret != 0) {
     bios_error:
@@ -1011,16 +1022,26 @@ void pc_memory_init(MemoryRegion *system_memory,
     isa_bios_size = bios_size;
     if (isa_bios_size > (128 * 1024))
         isa_bios_size = 128 * 1024;
-    cpu_register_physical_memory(0x100000 - isa_bios_size,
-                                 isa_bios_size,
-                                 (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM);
-
-    option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
-    cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE, option_rom_offset);
+    isa_bios = qemu_malloc(sizeof(*isa_bios));
+    memory_region_init_alias(isa_bios, "isa-bios", bios,
+                             bios_size - isa_bios_size, isa_bios_size);
+    memory_region_add_subregion_overlap(system_memory,
+                                        0x100000 - isa_bios_size,
+                                        isa_bios,
+                                        1);
+    memory_region_set_readonly(isa_bios, true);
+
+    option_rom_mr = qemu_malloc(sizeof(*option_rom_mr));
+    memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE);
+    memory_region_add_subregion_overlap(system_memory,
+                                        PC_ROM_MIN_VGA,
+                                        option_rom_mr,
+                                        1);
 
     /* map all the bios at the top of memory */
-    cpu_register_physical_memory((uint32_t)(-bios_size),
-                                 bios_size, bios_offset | IO_MEM_ROM);
+    memory_region_add_subregion(system_memory,
+                                (uint32_t)(-bios_size),
+                                bios);
 
     fw_cfg = bochs_bios_init();
     rom_set_fw(fw_cfg);
diff --git a/hw/pc.h b/hw/pc.h
index fa57583..40684f4 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -2,6 +2,7 @@
 #define HW_PC_H
 
 #include "qemu-common.h"
+#include "memory.h"
 #include "ioport.h"
 #include "isa.h"
 #include "fdc.h"
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 12/56] pc: convert pc_memory_init() to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pc.c |   59 ++++++++++++++++++++++++++++++++++++++++-------------------
 hw/pc.h |    1 +
 2 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 369566a..1c9d89a 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -41,6 +41,7 @@
 #include "sysemu.h"
 #include "blockdev.h"
 #include "ui/qemu-spice.h"
+#include "memory.h"
 
 /* output Bochs bios info messages */
 //#define DEBUG_BIOS
@@ -966,22 +967,30 @@ void pc_memory_init(MemoryRegion *system_memory,
 {
     char *filename;
     int ret, linux_boot, i;
-    ram_addr_t ram_addr, bios_offset, option_rom_offset;
+    MemoryRegion *ram, *bios, *isa_bios, *option_rom_mr;
+    MemoryRegion *ram_below_4g, *ram_above_4g;
     int bios_size, isa_bios_size;
     void *fw_cfg;
 
     linux_boot = (kernel_filename != NULL);
 
-    /* allocate RAM */
-    ram_addr = qemu_ram_alloc(NULL, "pc.ram",
-                              below_4g_mem_size + above_4g_mem_size);
-    cpu_register_physical_memory(0, 0xa0000, ram_addr);
-    cpu_register_physical_memory(0x100000,
-                 below_4g_mem_size - 0x100000,
-                 ram_addr + 0x100000);
+    /* Allocate RAM.  We allocate it as a single memory region and use
+     * aliases to address portions of it, mostly for backwards compatiblity
+     * with older qemus that used qemu_ram_alloc().
+     */
+    ram = qemu_malloc(sizeof(*ram));
+    memory_region_init_ram(ram, NULL, "pc.ram",
+                           below_4g_mem_size + above_4g_mem_size);
+    ram_below_4g = qemu_malloc(sizeof(*ram_below_4g));
+    memory_region_init_alias(ram_below_4g, "ram-below-4g", ram,
+                             0, below_4g_mem_size);
+    memory_region_add_subregion(system_memory, 0, ram_below_4g);
     if (above_4g_mem_size > 0) {
-        cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
-                                     ram_addr + below_4g_mem_size);
+        ram_above_4g = qemu_malloc(sizeof(*ram_above_4g));
+        memory_region_init_alias(ram_above_4g, "ram-above-4g", ram,
+                                 below_4g_mem_size, above_4g_mem_size);
+        memory_region_add_subregion(system_memory, 0x100000000ULL,
+                                    ram_above_4g);
     }
 
     /* BIOS load */
@@ -997,7 +1006,9 @@ void pc_memory_init(MemoryRegion *system_memory,
         (bios_size % 65536) != 0) {
         goto bios_error;
     }
-    bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
+    bios = qemu_malloc(sizeof(*bios));
+    memory_region_init_ram(bios, NULL, "pc.bios", bios_size);
+    memory_region_set_readonly(bios, true);
     ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
     if (ret != 0) {
     bios_error:
@@ -1011,16 +1022,26 @@ void pc_memory_init(MemoryRegion *system_memory,
     isa_bios_size = bios_size;
     if (isa_bios_size > (128 * 1024))
         isa_bios_size = 128 * 1024;
-    cpu_register_physical_memory(0x100000 - isa_bios_size,
-                                 isa_bios_size,
-                                 (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM);
-
-    option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
-    cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE, option_rom_offset);
+    isa_bios = qemu_malloc(sizeof(*isa_bios));
+    memory_region_init_alias(isa_bios, "isa-bios", bios,
+                             bios_size - isa_bios_size, isa_bios_size);
+    memory_region_add_subregion_overlap(system_memory,
+                                        0x100000 - isa_bios_size,
+                                        isa_bios,
+                                        1);
+    memory_region_set_readonly(isa_bios, true);
+
+    option_rom_mr = qemu_malloc(sizeof(*option_rom_mr));
+    memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE);
+    memory_region_add_subregion_overlap(system_memory,
+                                        PC_ROM_MIN_VGA,
+                                        option_rom_mr,
+                                        1);
 
     /* map all the bios at the top of memory */
-    cpu_register_physical_memory((uint32_t)(-bios_size),
-                                 bios_size, bios_offset | IO_MEM_ROM);
+    memory_region_add_subregion(system_memory,
+                                (uint32_t)(-bios_size),
+                                bios);
 
     fw_cfg = bochs_bios_init();
     rom_set_fw(fw_cfg);
diff --git a/hw/pc.h b/hw/pc.h
index fa57583..40684f4 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -2,6 +2,7 @@
 #define HW_PC_H
 
 #include "qemu-common.h"
+#include "memory.h"
 #include "ioport.h"
 #include "isa.h"
 #include "fdc.h"
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 13/56] pc: move global memory map out of pc_init1() and into its callers
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pc_piix.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index d83854c..f2d0476 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -68,7 +68,8 @@ static void ioapic_init(IsaIrqState *isa_irq_state)
 }
 
 /* PC hardware initialisation */
-static void pc_init1(ram_addr_t ram_size,
+static void pc_init1(MemoryRegion *system_memory,
+                     ram_addr_t ram_size,
                      const char *boot_device,
                      const char *kernel_filename,
                      const char *kernel_cmdline,
@@ -91,9 +92,6 @@ static void pc_init1(ram_addr_t ram_size,
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     BusState *idebus[MAX_IDE_BUS];
     ISADevice *rtc_state;
-    MemoryRegion *system_memory;
-
-    system_memory = get_system_memory();
 
     pc_cpus_init(cpu_model);
 
@@ -214,7 +212,8 @@ static void pc_init_pci(ram_addr_t ram_size,
                         const char *initrd_filename,
                         const char *cpu_model)
 {
-    pc_init1(ram_size, boot_device,
+    pc_init1(get_system_memory(),
+             ram_size, boot_device,
              kernel_filename, kernel_cmdline,
              initrd_filename, cpu_model, 1, 1);
 }
@@ -226,7 +225,8 @@ static void pc_init_pci_no_kvmclock(ram_addr_t ram_size,
                                     const char *initrd_filename,
                                     const char *cpu_model)
 {
-    pc_init1(ram_size, boot_device,
+    pc_init1(get_system_memory(),
+             ram_size, boot_device,
              kernel_filename, kernel_cmdline,
              initrd_filename, cpu_model, 1, 0);
 }
@@ -240,7 +240,8 @@ static void pc_init_isa(ram_addr_t ram_size,
 {
     if (cpu_model == NULL)
         cpu_model = "486";
-    pc_init1(ram_size, boot_device,
+    pc_init1(get_system_memory(),
+             ram_size, boot_device,
              kernel_filename, kernel_cmdline,
              initrd_filename, cpu_model, 0, 1);
 }
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 13/56] pc: move global memory map out of pc_init1() and into its callers
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pc_piix.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index d83854c..f2d0476 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -68,7 +68,8 @@ static void ioapic_init(IsaIrqState *isa_irq_state)
 }
 
 /* PC hardware initialisation */
-static void pc_init1(ram_addr_t ram_size,
+static void pc_init1(MemoryRegion *system_memory,
+                     ram_addr_t ram_size,
                      const char *boot_device,
                      const char *kernel_filename,
                      const char *kernel_cmdline,
@@ -91,9 +92,6 @@ static void pc_init1(ram_addr_t ram_size,
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     BusState *idebus[MAX_IDE_BUS];
     ISADevice *rtc_state;
-    MemoryRegion *system_memory;
-
-    system_memory = get_system_memory();
 
     pc_cpus_init(cpu_model);
 
@@ -214,7 +212,8 @@ static void pc_init_pci(ram_addr_t ram_size,
                         const char *initrd_filename,
                         const char *cpu_model)
 {
-    pc_init1(ram_size, boot_device,
+    pc_init1(get_system_memory(),
+             ram_size, boot_device,
              kernel_filename, kernel_cmdline,
              initrd_filename, cpu_model, 1, 1);
 }
@@ -226,7 +225,8 @@ static void pc_init_pci_no_kvmclock(ram_addr_t ram_size,
                                     const char *initrd_filename,
                                     const char *cpu_model)
 {
-    pc_init1(ram_size, boot_device,
+    pc_init1(get_system_memory(),
+             ram_size, boot_device,
              kernel_filename, kernel_cmdline,
              initrd_filename, cpu_model, 1, 0);
 }
@@ -240,7 +240,8 @@ static void pc_init_isa(ram_addr_t ram_size,
 {
     if (cpu_model == NULL)
         cpu_model = "486";
-    pc_init1(ram_size, boot_device,
+    pc_init1(get_system_memory(),
+             ram_size, boot_device,
              kernel_filename, kernel_cmdline,
              initrd_filename, cpu_model, 0, 1);
 }
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 14/56] pci: pass address space to pci bus when created
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

This is now done sloppily, via get_system_memory().  Eventually callers
will be converted to stop using that.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/apb_pci.c       |    2 ++
 hw/bonito.c        |    4 +++-
 hw/grackle_pci.c   |    5 +++--
 hw/gt64xxx.c       |    4 +++-
 hw/pc.h            |    4 +++-
 hw/pc_piix.c       |    3 ++-
 hw/pci.c           |   16 +++++++++++-----
 hw/pci.h           |   12 +++++++++---
 hw/pci_host.h      |    1 +
 hw/pci_internals.h |    1 +
 hw/piix_pci.c      |   13 +++++++++----
 hw/ppc4xx_pci.c    |    5 ++++-
 hw/ppc_mac.h       |    9 ++++++---
 hw/ppc_newworld.c  |    5 +++--
 hw/ppc_oldworld.c  |    3 ++-
 hw/ppc_prep.c      |    3 ++-
 hw/ppce500_pci.c   |    6 +++++-
 hw/prep_pci.c      |    5 +++--
 hw/prep_pci.h      |    3 ++-
 hw/sh_pci.c        |    4 +++-
 hw/unin_pci.c      |   10 ++++++----
 hw/versatile_pci.c |    2 ++
 22 files changed, 85 insertions(+), 35 deletions(-)

diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 974c87a..8b9939c 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -34,6 +34,7 @@
 #include "rwhandler.h"
 #include "apb_pci.h"
 #include "sysemu.h"
+#include "exec-memory.h"
 
 /* debug APB */
 //#define DEBUG_APB
@@ -346,6 +347,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
 
     d->bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_apb_set_irq, pci_pbm_map_irq, d,
+                                         get_system_memory(),
                                          0, 32);
     pci_bus_set_mem_base(d->bus, mem_base);
 
diff --git a/hw/bonito.c b/hw/bonito.c
index e8c57a3..5f62dda 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -42,6 +42,7 @@
 #include "mips.h"
 #include "pci_host.h"
 #include "sysemu.h"
+#include "exec-memory.h"
 
 //#define DEBUG_BONITO
 
@@ -773,7 +774,8 @@ PCIBus *bonito_init(qemu_irq *pic)
     dev = qdev_create(NULL, "Bonito-pcihost");
     pcihost = FROM_SYSBUS(BonitoState, sysbus_from_qdev(dev));
     b = pci_register_bus(&pcihost->busdev.qdev, "pci", pci_bonito_set_irq,
-                         pci_bonito_map_irq, pic, 0x28, 32);
+                         pci_bonito_map_irq, pic, get_system_memory(),
+                         0x28, 32);
     pcihost->bus = b;
     qdev_init_nofail(dev);
 
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index cee07e0..da67cf9 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -61,7 +61,8 @@ static void pci_grackle_reset(void *opaque)
 {
 }
 
-PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic)
+PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
+                         MemoryRegion *address_space)
 {
     DeviceState *dev;
     SysBusDevice *s;
@@ -74,7 +75,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic)
     d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_grackle_set_irq,
                                          pci_grackle_map_irq,
-                                         pic, 0, 4);
+                                         pic, address_space, 0, 4);
 
     pci_create_simple(d->host_state.bus, 0, "grackle");
 
diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index 8e1f6a0..65e63dd 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -27,6 +27,7 @@
 #include "pci.h"
 #include "pci_host.h"
 #include "pc.h"
+#include "exec-memory.h"
 
 //#define DEBUG
 
@@ -1092,7 +1093,8 @@ PCIBus *gt64120_register(qemu_irq *pic)
     d = FROM_SYSBUS(GT64120State, s);
     d->pci.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                   gt64120_pci_set_irq, gt64120_pci_map_irq,
-                                  pic, PCI_DEVFN(18, 0), 4);
+                                  pic, get_system_memory(),
+                                  PCI_DEVFN(18, 0), 4);
     d->ISD_handle = cpu_register_io_memory(gt64120_read, gt64120_write, d,
                                            DEVICE_NATIVE_ENDIAN);
 
diff --git a/hw/pc.h b/hw/pc.h
index 40684f4..a2de0fe 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -178,7 +178,9 @@ int pcspk_audio_init(qemu_irq *pic);
 struct PCII440FXState;
 typedef struct PCII440FXState PCII440FXState;
 
-PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, qemu_irq *pic, ram_addr_t ram_size);
+PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn,
+                    qemu_irq *pic, MemoryRegion *address_space,
+                    ram_addr_t ram_size);
 void i440fx_init_memory_mappings(PCII440FXState *d);
 
 /* piix4.c */
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index f2d0476..2b9c2b1 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -128,7 +128,8 @@ static void pc_init1(MemoryRegion *system_memory,
     isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24);
 
     if (pci_enabled) {
-        pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size);
+        pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq,
+                              system_memory, ram_size);
     } else {
         pci_bus = NULL;
         i440fx_state = NULL;
diff --git a/hw/pci.c b/hw/pci.c
index b904a4e..cf16f3b 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -263,11 +263,14 @@ int pci_find_domain(const PCIBus *bus)
 }
 
 void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
-                         const char *name, uint8_t devfn_min)
+                         const char *name,
+                         MemoryRegion *address_space,
+                         uint8_t devfn_min)
 {
     qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
     assert(PCI_FUNC(devfn_min) == 0);
     bus->devfn_min = devfn_min;
+    bus->address_space = address_space;
 
     /* host bridge */
     QLIST_INIT(&bus->child);
@@ -276,13 +279,14 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
     vmstate_register(NULL, -1, &vmstate_pcibus, bus);
 }
 
-PCIBus *pci_bus_new(DeviceState *parent, const char *name, uint8_t devfn_min)
+PCIBus *pci_bus_new(DeviceState *parent, const char *name,
+                    MemoryRegion *address_space, uint8_t devfn_min)
 {
     PCIBus *bus;
 
     bus = qemu_mallocz(sizeof(*bus));
     bus->qbus.qdev_allocated = 1;
-    pci_bus_new_inplace(bus, parent, name, devfn_min);
+    pci_bus_new_inplace(bus, parent, name, address_space, devfn_min);
     return bus;
 }
 
@@ -310,11 +314,13 @@ void pci_bus_set_mem_base(PCIBus *bus, target_phys_addr_t base)
 
 PCIBus *pci_register_bus(DeviceState *parent, const char *name,
                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
-                         void *irq_opaque, uint8_t devfn_min, int nirq)
+                         void *irq_opaque,
+                         MemoryRegion *address_space,
+                         uint8_t devfn_min, int nirq)
 {
     PCIBus *bus;
 
-    bus = pci_bus_new(parent, name, devfn_min);
+    bus = pci_bus_new(parent, name, address_space, devfn_min);
     pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
     return bus;
 }
diff --git a/hw/pci.h b/hw/pci.h
index c220745..cfeb042 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -5,6 +5,7 @@
 #include "qobject.h"
 
 #include "qdev.h"
+#include "memory.h"
 
 /* PCI includes legacy ISA access.  */
 #include "isa.h"
@@ -233,15 +234,20 @@ typedef enum {
 typedef int (*pci_hotplug_fn)(DeviceState *qdev, PCIDevice *pci_dev,
                               PCIHotplugState state);
 void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
-                         const char *name, uint8_t devfn_min);
-PCIBus *pci_bus_new(DeviceState *parent, const char *name, uint8_t devfn_min);
+                         const char *name,
+                         MemoryRegion *address_space,
+                         uint8_t devfn_min);
+PCIBus *pci_bus_new(DeviceState *parent, const char *name,
+                    MemoryRegion *address_space, uint8_t devfn_min);
 void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                   void *irq_opaque, int nirq);
 int pci_bus_get_irq_level(PCIBus *bus, int irq_num);
 void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *dev);
 PCIBus *pci_register_bus(DeviceState *parent, const char *name,
                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
-                         void *irq_opaque, uint8_t devfn_min, int nirq);
+                         void *irq_opaque,
+                         MemoryRegion *address_space,
+                         uint8_t devfn_min, int nirq);
 void pci_device_reset(PCIDevice *dev);
 void pci_bus_reset(PCIBus *bus);
 
diff --git a/hw/pci_host.h b/hw/pci_host.h
index 0a58595..05dcb66 100644
--- a/hw/pci_host.h
+++ b/hw/pci_host.h
@@ -35,6 +35,7 @@ struct PCIHostState {
     SysBusDevice busdev;
     ReadWriteHandler conf_handler;
     ReadWriteHandler data_handler;
+    MemoryRegion *address_space;
     uint32_t config_reg;
     PCIBus *bus;
 };
diff --git a/hw/pci_internals.h b/hw/pci_internals.h
index fbe1866..c3a463a 100644
--- a/hw/pci_internals.h
+++ b/hw/pci_internals.h
@@ -25,6 +25,7 @@ struct PCIBus {
     PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX];
     PCIDevice *parent_dev;
     target_phys_addr_t mem_base;
+    MemoryRegion *address_space;
 
     QLIST_HEAD(, PCIBus) child; /* this will be replaced by qdev later */
     QLIST_ENTRY(PCIBus) sibling;/* this will be replaced by qdev later */
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 26ce904..445c6cb 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -241,7 +241,9 @@ static int i440fx_initfn(PCIDevice *dev)
 static PCIBus *i440fx_common_init(const char *device_name,
                                   PCII440FXState **pi440fx_state,
                                   int *piix3_devfn,
-                                  qemu_irq *pic, ram_addr_t ram_size)
+                                  qemu_irq *pic,
+                                  MemoryRegion *address_space,
+                                  ram_addr_t ram_size)
 {
     DeviceState *dev;
     PCIBus *b;
@@ -251,7 +253,8 @@ static PCIBus *i440fx_common_init(const char *device_name,
 
     dev = qdev_create(NULL, "i440FX-pcihost");
     s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev));
-    b = pci_bus_new(&s->busdev.qdev, NULL, 0);
+    s->address_space = address_space;
+    b = pci_bus_new(&s->busdev.qdev, NULL, s->address_space, 0);
     s->bus = b;
     qdev_init_nofail(dev);
 
@@ -288,11 +291,13 @@ static PCIBus *i440fx_common_init(const char *device_name,
 }
 
 PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn,
-                    qemu_irq *pic, ram_addr_t ram_size)
+                    qemu_irq *pic, MemoryRegion *address_space,
+                    ram_addr_t ram_size)
 {
     PCIBus *b;
 
-    b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic, ram_size);
+    b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic,
+                           address_space, ram_size);
     return b;
 }
 
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index 299473c..15c24f6 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -24,6 +24,7 @@
 #include "ppc4xx.h"
 #include "pci.h"
 #include "pci_host.h"
+#include "exec-memory.h"
 
 #undef DEBUG
 #ifdef DEBUG
@@ -345,7 +346,9 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
     controller->pci_state.bus = pci_register_bus(NULL, "pci",
                                                  ppc4xx_pci_set_irq,
                                                  ppc4xx_pci_map_irq,
-                                                 pci_irqs, 0, 4);
+                                                 pci_irqs,
+                                                 get_system_memory(),
+                                                 0, 4);
 
     controller->pci_dev = pci_register_device(controller->pci_state.bus,
                                               "host bridge", sizeof(PCIDevice),
diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h
index 68dade7..6fad20a 100644
--- a/hw/ppc_mac.h
+++ b/hw/ppc_mac.h
@@ -25,6 +25,8 @@
 #if !defined(__PPC_MAC_H__)
 #define __PPC_MAC_H__
 
+#include "memory.h"
+
 /* SMP is not enabled, for now */
 #define MAX_CPUS 1
 
@@ -52,11 +54,12 @@ qemu_irq *heathrow_pic_init(int *pmem_index,
                             int nb_cpus, qemu_irq **irqs);
 
 /* Grackle PCI */
-PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic);
+PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
+                         MemoryRegion *address_space);
 
 /* UniNorth PCI */
-PCIBus *pci_pmac_init(qemu_irq *pic);
-PCIBus *pci_pmac_u3_init(qemu_irq *pic);
+PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space);
+PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space);
 
 /* Mac NVRAM */
 typedef struct MacIONVRAMState MacIONVRAMState;
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 5bce709..2c0fae8 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -67,6 +67,7 @@
 #include "kvm_ppc.h"
 #include "hw/usb.h"
 #include "blockdev.h"
+#include "exec-memory.h"
 
 #define MAX_IDE_BUS 2
 #define CFG_ADDR 0xf0000510
@@ -317,10 +318,10 @@ static void ppc_core99_init (ram_addr_t ram_size,
     pic = openpic_init(NULL, &pic_mem_index, smp_cpus, openpic_irqs, NULL);
     if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
         /* 970 gets a U3 bus */
-        pci_bus = pci_pmac_u3_init(pic);
+        pci_bus = pci_pmac_u3_init(pic, get_system_memory());
         machine_arch = ARCH_MAC99_U3;
     } else {
-        pci_bus = pci_pmac_init(pic);
+        pci_bus = pci_pmac_init(pic, get_system_memory());
         machine_arch = ARCH_MAC99;
     }
     /* init basic PC hardware */
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 20cd8e1..585afd6 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -43,6 +43,7 @@
 #include "kvm.h"
 #include "kvm_ppc.h"
 #include "blockdev.h"
+#include "exec-memory.h"
 
 #define MAX_IDE_BUS 2
 #define CFG_ADDR 0xf0000510
@@ -233,7 +234,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
         hw_error("Only 6xx bus is supported on heathrow machine\n");
     }
     pic = heathrow_pic_init(&pic_mem_index, 1, heathrow_irqs);
-    pci_bus = pci_grackle_init(0xfec00000, pic);
+    pci_bus = pci_grackle_init(0xfec00000, pic, get_system_memory());
     pci_vga_init(pci_bus);
 
     escc_mem_index = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0],
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 0e9cfc2..91ebe07 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -38,6 +38,7 @@
 #include "loader.h"
 #include "mc146818rtc.h"
 #include "blockdev.h"
+#include "exec-memory.h"
 
 //#define HARD_DEBUG_PPC_IO
 //#define DEBUG_PPC_IO
@@ -648,7 +649,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
         hw_error("Only 6xx bus is supported on PREP machine\n");
     }
     i8259 = i8259_init(first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
-    pci_bus = pci_prep_init(i8259);
+    pci_bus = pci_prep_init(i8259, get_system_memory());
     /* Hmm, prep has no pci-isa bridge ??? */
     isa_bus_new(NULL);
     isa_bus_irqs(i8259);
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index fc11af4..1344539 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -274,12 +274,15 @@ static void e500_pci_map(SysBusDevice *dev, target_phys_addr_t base)
                                  s->reg);
 }
 
+#include "exec-memory.h"
+
 static int e500_pcihost_initfn(SysBusDevice *dev)
 {
     PCIHostState *h;
     PPCE500PCIState *s;
     PCIBus *b;
     int i;
+    MemoryRegion *address_space = get_system_memory();
 
     h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
     s = DO_UPCAST(PPCE500PCIState, pci_state, h);
@@ -289,7 +292,8 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
     }
 
     b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, mpc85xx_pci_set_irq,
-                         mpc85xx_pci_map_irq, s->irq, PCI_DEVFN(0x11, 0), 4);
+                         mpc85xx_pci_map_irq, s->irq, address_space,
+                         PCI_DEVFN(0x11, 0), 4);
     s->pci_state.bus = b;
 
     pci_create_simple(b, 0, "e500-host-bridge");
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index f88b825..da02f0e 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -110,7 +110,7 @@ static void prep_set_irq(void *opaque, int irq_num, int level)
     qemu_set_irq(pic[(irq_num & 1) ? 11 : 9] , level);
 }
 
-PCIBus *pci_prep_init(qemu_irq *pic)
+PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space)
 {
     PREPPCIState *s;
     PCIDevice *d;
@@ -118,7 +118,8 @@ PCIBus *pci_prep_init(qemu_irq *pic)
 
     s = qemu_mallocz(sizeof(PREPPCIState));
     s->bus = pci_register_bus(NULL, "pci",
-                              prep_set_irq, prep_map_irq, pic, 0, 4);
+                              prep_set_irq, prep_map_irq, pic,
+                              address_space, 0, 4);
 
     pci_host_conf_register_ioport(0xcf8, s);
 
diff --git a/hw/prep_pci.h b/hw/prep_pci.h
index cd68512..a27368b 100644
--- a/hw/prep_pci.h
+++ b/hw/prep_pci.h
@@ -2,7 +2,8 @@
 #define QEMU_PREP_PCI_H
 
 #include "qemu-common.h"
+#include "memory.h"
 
-PCIBus *pci_prep_init(qemu_irq *pic);
+PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space);
 
 #endif
diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index a076cf2..0ef93a0 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -26,6 +26,7 @@
 #include "pci.h"
 #include "pci_host.h"
 #include "bswap.h"
+#include "exec-memory.h"
 
 typedef struct SHPCIState {
     SysBusDevice busdev;
@@ -127,7 +128,8 @@ static int sh_pci_init_device(SysBusDevice *dev)
     }
     s->bus = pci_register_bus(&s->busdev.qdev, "pci",
                               sh_pci_set_irq, sh_pci_map_irq,
-                              s->irq, PCI_DEVFN(0, 0), 4);
+                              s->irq, get_system_memory(),
+                              PCI_DEVFN(0, 0), 4);
     s->memconfig = cpu_register_io_memory(sh_pci_reg.r, sh_pci_reg.w,
                                           s, DEVICE_NATIVE_ENDIAN);
     sysbus_init_mmio_cb(dev, 0x224, sh_pci_map);
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index d364daa..b499523 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -201,7 +201,7 @@ static int pci_unin_internal_init_device(SysBusDevice *dev)
     return 0;
 }
 
-PCIBus *pci_pmac_init(qemu_irq *pic)
+PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space)
 {
     DeviceState *dev;
     SysBusDevice *s;
@@ -215,7 +215,8 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
     d = FROM_SYSBUS(UNINState, s);
     d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_unin_set_irq, pci_unin_map_irq,
-                                         pic, PCI_DEVFN(11, 0), 4);
+                                         pic, address_space,
+                                         PCI_DEVFN(11, 0), 4);
 
 #if 0
     pci_create_simple(d->host_state.bus, PCI_DEVFN(11, 0), "uni-north");
@@ -252,7 +253,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
     return d->host_state.bus;
 }
 
-PCIBus *pci_pmac_u3_init(qemu_irq *pic)
+PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space)
 {
     DeviceState *dev;
     SysBusDevice *s;
@@ -267,7 +268,8 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic)
 
     d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_unin_set_irq, pci_unin_map_irq,
-                                         pic, PCI_DEVFN(11, 0), 4);
+                                         pic, address_space,
+                                         PCI_DEVFN(11, 0), 4);
 
     sysbus_mmio_map(s, 0, 0xf0800000);
     sysbus_mmio_map(s, 1, 0xf0c00000);
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index 8e75ffc..6b693df 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -10,6 +10,7 @@
 #include "sysbus.h"
 #include "pci.h"
 #include "pci_host.h"
+#include "exec-memory.h"
 
 typedef struct {
     SysBusDevice busdev;
@@ -111,6 +112,7 @@ static int pci_vpb_init(SysBusDevice *dev)
     }
     bus = pci_register_bus(&dev->qdev, "pci",
                            pci_vpb_set_irq, pci_vpb_map_irq, s->irq,
+                           get_system_memory(),
                            PCI_DEVFN(11, 0), 4);
 
     /* ??? Register memory space.  */
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 14/56] pci: pass address space to pci bus when created
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

This is now done sloppily, via get_system_memory().  Eventually callers
will be converted to stop using that.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/apb_pci.c       |    2 ++
 hw/bonito.c        |    4 +++-
 hw/grackle_pci.c   |    5 +++--
 hw/gt64xxx.c       |    4 +++-
 hw/pc.h            |    4 +++-
 hw/pc_piix.c       |    3 ++-
 hw/pci.c           |   16 +++++++++++-----
 hw/pci.h           |   12 +++++++++---
 hw/pci_host.h      |    1 +
 hw/pci_internals.h |    1 +
 hw/piix_pci.c      |   13 +++++++++----
 hw/ppc4xx_pci.c    |    5 ++++-
 hw/ppc_mac.h       |    9 ++++++---
 hw/ppc_newworld.c  |    5 +++--
 hw/ppc_oldworld.c  |    3 ++-
 hw/ppc_prep.c      |    3 ++-
 hw/ppce500_pci.c   |    6 +++++-
 hw/prep_pci.c      |    5 +++--
 hw/prep_pci.h      |    3 ++-
 hw/sh_pci.c        |    4 +++-
 hw/unin_pci.c      |   10 ++++++----
 hw/versatile_pci.c |    2 ++
 22 files changed, 85 insertions(+), 35 deletions(-)

diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 974c87a..8b9939c 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -34,6 +34,7 @@
 #include "rwhandler.h"
 #include "apb_pci.h"
 #include "sysemu.h"
+#include "exec-memory.h"
 
 /* debug APB */
 //#define DEBUG_APB
@@ -346,6 +347,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
 
     d->bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_apb_set_irq, pci_pbm_map_irq, d,
+                                         get_system_memory(),
                                          0, 32);
     pci_bus_set_mem_base(d->bus, mem_base);
 
diff --git a/hw/bonito.c b/hw/bonito.c
index e8c57a3..5f62dda 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -42,6 +42,7 @@
 #include "mips.h"
 #include "pci_host.h"
 #include "sysemu.h"
+#include "exec-memory.h"
 
 //#define DEBUG_BONITO
 
@@ -773,7 +774,8 @@ PCIBus *bonito_init(qemu_irq *pic)
     dev = qdev_create(NULL, "Bonito-pcihost");
     pcihost = FROM_SYSBUS(BonitoState, sysbus_from_qdev(dev));
     b = pci_register_bus(&pcihost->busdev.qdev, "pci", pci_bonito_set_irq,
-                         pci_bonito_map_irq, pic, 0x28, 32);
+                         pci_bonito_map_irq, pic, get_system_memory(),
+                         0x28, 32);
     pcihost->bus = b;
     qdev_init_nofail(dev);
 
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index cee07e0..da67cf9 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -61,7 +61,8 @@ static void pci_grackle_reset(void *opaque)
 {
 }
 
-PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic)
+PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
+                         MemoryRegion *address_space)
 {
     DeviceState *dev;
     SysBusDevice *s;
@@ -74,7 +75,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic)
     d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_grackle_set_irq,
                                          pci_grackle_map_irq,
-                                         pic, 0, 4);
+                                         pic, address_space, 0, 4);
 
     pci_create_simple(d->host_state.bus, 0, "grackle");
 
diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index 8e1f6a0..65e63dd 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -27,6 +27,7 @@
 #include "pci.h"
 #include "pci_host.h"
 #include "pc.h"
+#include "exec-memory.h"
 
 //#define DEBUG
 
@@ -1092,7 +1093,8 @@ PCIBus *gt64120_register(qemu_irq *pic)
     d = FROM_SYSBUS(GT64120State, s);
     d->pci.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                   gt64120_pci_set_irq, gt64120_pci_map_irq,
-                                  pic, PCI_DEVFN(18, 0), 4);
+                                  pic, get_system_memory(),
+                                  PCI_DEVFN(18, 0), 4);
     d->ISD_handle = cpu_register_io_memory(gt64120_read, gt64120_write, d,
                                            DEVICE_NATIVE_ENDIAN);
 
diff --git a/hw/pc.h b/hw/pc.h
index 40684f4..a2de0fe 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -178,7 +178,9 @@ int pcspk_audio_init(qemu_irq *pic);
 struct PCII440FXState;
 typedef struct PCII440FXState PCII440FXState;
 
-PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, qemu_irq *pic, ram_addr_t ram_size);
+PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn,
+                    qemu_irq *pic, MemoryRegion *address_space,
+                    ram_addr_t ram_size);
 void i440fx_init_memory_mappings(PCII440FXState *d);
 
 /* piix4.c */
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index f2d0476..2b9c2b1 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -128,7 +128,8 @@ static void pc_init1(MemoryRegion *system_memory,
     isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24);
 
     if (pci_enabled) {
-        pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size);
+        pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq,
+                              system_memory, ram_size);
     } else {
         pci_bus = NULL;
         i440fx_state = NULL;
diff --git a/hw/pci.c b/hw/pci.c
index b904a4e..cf16f3b 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -263,11 +263,14 @@ int pci_find_domain(const PCIBus *bus)
 }
 
 void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
-                         const char *name, uint8_t devfn_min)
+                         const char *name,
+                         MemoryRegion *address_space,
+                         uint8_t devfn_min)
 {
     qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
     assert(PCI_FUNC(devfn_min) == 0);
     bus->devfn_min = devfn_min;
+    bus->address_space = address_space;
 
     /* host bridge */
     QLIST_INIT(&bus->child);
@@ -276,13 +279,14 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
     vmstate_register(NULL, -1, &vmstate_pcibus, bus);
 }
 
-PCIBus *pci_bus_new(DeviceState *parent, const char *name, uint8_t devfn_min)
+PCIBus *pci_bus_new(DeviceState *parent, const char *name,
+                    MemoryRegion *address_space, uint8_t devfn_min)
 {
     PCIBus *bus;
 
     bus = qemu_mallocz(sizeof(*bus));
     bus->qbus.qdev_allocated = 1;
-    pci_bus_new_inplace(bus, parent, name, devfn_min);
+    pci_bus_new_inplace(bus, parent, name, address_space, devfn_min);
     return bus;
 }
 
@@ -310,11 +314,13 @@ void pci_bus_set_mem_base(PCIBus *bus, target_phys_addr_t base)
 
 PCIBus *pci_register_bus(DeviceState *parent, const char *name,
                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
-                         void *irq_opaque, uint8_t devfn_min, int nirq)
+                         void *irq_opaque,
+                         MemoryRegion *address_space,
+                         uint8_t devfn_min, int nirq)
 {
     PCIBus *bus;
 
-    bus = pci_bus_new(parent, name, devfn_min);
+    bus = pci_bus_new(parent, name, address_space, devfn_min);
     pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
     return bus;
 }
diff --git a/hw/pci.h b/hw/pci.h
index c220745..cfeb042 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -5,6 +5,7 @@
 #include "qobject.h"
 
 #include "qdev.h"
+#include "memory.h"
 
 /* PCI includes legacy ISA access.  */
 #include "isa.h"
@@ -233,15 +234,20 @@ typedef enum {
 typedef int (*pci_hotplug_fn)(DeviceState *qdev, PCIDevice *pci_dev,
                               PCIHotplugState state);
 void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
-                         const char *name, uint8_t devfn_min);
-PCIBus *pci_bus_new(DeviceState *parent, const char *name, uint8_t devfn_min);
+                         const char *name,
+                         MemoryRegion *address_space,
+                         uint8_t devfn_min);
+PCIBus *pci_bus_new(DeviceState *parent, const char *name,
+                    MemoryRegion *address_space, uint8_t devfn_min);
 void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                   void *irq_opaque, int nirq);
 int pci_bus_get_irq_level(PCIBus *bus, int irq_num);
 void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *dev);
 PCIBus *pci_register_bus(DeviceState *parent, const char *name,
                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
-                         void *irq_opaque, uint8_t devfn_min, int nirq);
+                         void *irq_opaque,
+                         MemoryRegion *address_space,
+                         uint8_t devfn_min, int nirq);
 void pci_device_reset(PCIDevice *dev);
 void pci_bus_reset(PCIBus *bus);
 
diff --git a/hw/pci_host.h b/hw/pci_host.h
index 0a58595..05dcb66 100644
--- a/hw/pci_host.h
+++ b/hw/pci_host.h
@@ -35,6 +35,7 @@ struct PCIHostState {
     SysBusDevice busdev;
     ReadWriteHandler conf_handler;
     ReadWriteHandler data_handler;
+    MemoryRegion *address_space;
     uint32_t config_reg;
     PCIBus *bus;
 };
diff --git a/hw/pci_internals.h b/hw/pci_internals.h
index fbe1866..c3a463a 100644
--- a/hw/pci_internals.h
+++ b/hw/pci_internals.h
@@ -25,6 +25,7 @@ struct PCIBus {
     PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX];
     PCIDevice *parent_dev;
     target_phys_addr_t mem_base;
+    MemoryRegion *address_space;
 
     QLIST_HEAD(, PCIBus) child; /* this will be replaced by qdev later */
     QLIST_ENTRY(PCIBus) sibling;/* this will be replaced by qdev later */
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 26ce904..445c6cb 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -241,7 +241,9 @@ static int i440fx_initfn(PCIDevice *dev)
 static PCIBus *i440fx_common_init(const char *device_name,
                                   PCII440FXState **pi440fx_state,
                                   int *piix3_devfn,
-                                  qemu_irq *pic, ram_addr_t ram_size)
+                                  qemu_irq *pic,
+                                  MemoryRegion *address_space,
+                                  ram_addr_t ram_size)
 {
     DeviceState *dev;
     PCIBus *b;
@@ -251,7 +253,8 @@ static PCIBus *i440fx_common_init(const char *device_name,
 
     dev = qdev_create(NULL, "i440FX-pcihost");
     s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev));
-    b = pci_bus_new(&s->busdev.qdev, NULL, 0);
+    s->address_space = address_space;
+    b = pci_bus_new(&s->busdev.qdev, NULL, s->address_space, 0);
     s->bus = b;
     qdev_init_nofail(dev);
 
@@ -288,11 +291,13 @@ static PCIBus *i440fx_common_init(const char *device_name,
 }
 
 PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn,
-                    qemu_irq *pic, ram_addr_t ram_size)
+                    qemu_irq *pic, MemoryRegion *address_space,
+                    ram_addr_t ram_size)
 {
     PCIBus *b;
 
-    b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic, ram_size);
+    b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic,
+                           address_space, ram_size);
     return b;
 }
 
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index 299473c..15c24f6 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -24,6 +24,7 @@
 #include "ppc4xx.h"
 #include "pci.h"
 #include "pci_host.h"
+#include "exec-memory.h"
 
 #undef DEBUG
 #ifdef DEBUG
@@ -345,7 +346,9 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
     controller->pci_state.bus = pci_register_bus(NULL, "pci",
                                                  ppc4xx_pci_set_irq,
                                                  ppc4xx_pci_map_irq,
-                                                 pci_irqs, 0, 4);
+                                                 pci_irqs,
+                                                 get_system_memory(),
+                                                 0, 4);
 
     controller->pci_dev = pci_register_device(controller->pci_state.bus,
                                               "host bridge", sizeof(PCIDevice),
diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h
index 68dade7..6fad20a 100644
--- a/hw/ppc_mac.h
+++ b/hw/ppc_mac.h
@@ -25,6 +25,8 @@
 #if !defined(__PPC_MAC_H__)
 #define __PPC_MAC_H__
 
+#include "memory.h"
+
 /* SMP is not enabled, for now */
 #define MAX_CPUS 1
 
@@ -52,11 +54,12 @@ qemu_irq *heathrow_pic_init(int *pmem_index,
                             int nb_cpus, qemu_irq **irqs);
 
 /* Grackle PCI */
-PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic);
+PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
+                         MemoryRegion *address_space);
 
 /* UniNorth PCI */
-PCIBus *pci_pmac_init(qemu_irq *pic);
-PCIBus *pci_pmac_u3_init(qemu_irq *pic);
+PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space);
+PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space);
 
 /* Mac NVRAM */
 typedef struct MacIONVRAMState MacIONVRAMState;
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 5bce709..2c0fae8 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -67,6 +67,7 @@
 #include "kvm_ppc.h"
 #include "hw/usb.h"
 #include "blockdev.h"
+#include "exec-memory.h"
 
 #define MAX_IDE_BUS 2
 #define CFG_ADDR 0xf0000510
@@ -317,10 +318,10 @@ static void ppc_core99_init (ram_addr_t ram_size,
     pic = openpic_init(NULL, &pic_mem_index, smp_cpus, openpic_irqs, NULL);
     if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
         /* 970 gets a U3 bus */
-        pci_bus = pci_pmac_u3_init(pic);
+        pci_bus = pci_pmac_u3_init(pic, get_system_memory());
         machine_arch = ARCH_MAC99_U3;
     } else {
-        pci_bus = pci_pmac_init(pic);
+        pci_bus = pci_pmac_init(pic, get_system_memory());
         machine_arch = ARCH_MAC99;
     }
     /* init basic PC hardware */
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 20cd8e1..585afd6 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -43,6 +43,7 @@
 #include "kvm.h"
 #include "kvm_ppc.h"
 #include "blockdev.h"
+#include "exec-memory.h"
 
 #define MAX_IDE_BUS 2
 #define CFG_ADDR 0xf0000510
@@ -233,7 +234,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
         hw_error("Only 6xx bus is supported on heathrow machine\n");
     }
     pic = heathrow_pic_init(&pic_mem_index, 1, heathrow_irqs);
-    pci_bus = pci_grackle_init(0xfec00000, pic);
+    pci_bus = pci_grackle_init(0xfec00000, pic, get_system_memory());
     pci_vga_init(pci_bus);
 
     escc_mem_index = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0],
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 0e9cfc2..91ebe07 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -38,6 +38,7 @@
 #include "loader.h"
 #include "mc146818rtc.h"
 #include "blockdev.h"
+#include "exec-memory.h"
 
 //#define HARD_DEBUG_PPC_IO
 //#define DEBUG_PPC_IO
@@ -648,7 +649,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
         hw_error("Only 6xx bus is supported on PREP machine\n");
     }
     i8259 = i8259_init(first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
-    pci_bus = pci_prep_init(i8259);
+    pci_bus = pci_prep_init(i8259, get_system_memory());
     /* Hmm, prep has no pci-isa bridge ??? */
     isa_bus_new(NULL);
     isa_bus_irqs(i8259);
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index fc11af4..1344539 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -274,12 +274,15 @@ static void e500_pci_map(SysBusDevice *dev, target_phys_addr_t base)
                                  s->reg);
 }
 
+#include "exec-memory.h"
+
 static int e500_pcihost_initfn(SysBusDevice *dev)
 {
     PCIHostState *h;
     PPCE500PCIState *s;
     PCIBus *b;
     int i;
+    MemoryRegion *address_space = get_system_memory();
 
     h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
     s = DO_UPCAST(PPCE500PCIState, pci_state, h);
@@ -289,7 +292,8 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
     }
 
     b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, mpc85xx_pci_set_irq,
-                         mpc85xx_pci_map_irq, s->irq, PCI_DEVFN(0x11, 0), 4);
+                         mpc85xx_pci_map_irq, s->irq, address_space,
+                         PCI_DEVFN(0x11, 0), 4);
     s->pci_state.bus = b;
 
     pci_create_simple(b, 0, "e500-host-bridge");
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index f88b825..da02f0e 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -110,7 +110,7 @@ static void prep_set_irq(void *opaque, int irq_num, int level)
     qemu_set_irq(pic[(irq_num & 1) ? 11 : 9] , level);
 }
 
-PCIBus *pci_prep_init(qemu_irq *pic)
+PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space)
 {
     PREPPCIState *s;
     PCIDevice *d;
@@ -118,7 +118,8 @@ PCIBus *pci_prep_init(qemu_irq *pic)
 
     s = qemu_mallocz(sizeof(PREPPCIState));
     s->bus = pci_register_bus(NULL, "pci",
-                              prep_set_irq, prep_map_irq, pic, 0, 4);
+                              prep_set_irq, prep_map_irq, pic,
+                              address_space, 0, 4);
 
     pci_host_conf_register_ioport(0xcf8, s);
 
diff --git a/hw/prep_pci.h b/hw/prep_pci.h
index cd68512..a27368b 100644
--- a/hw/prep_pci.h
+++ b/hw/prep_pci.h
@@ -2,7 +2,8 @@
 #define QEMU_PREP_PCI_H
 
 #include "qemu-common.h"
+#include "memory.h"
 
-PCIBus *pci_prep_init(qemu_irq *pic);
+PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space);
 
 #endif
diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index a076cf2..0ef93a0 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -26,6 +26,7 @@
 #include "pci.h"
 #include "pci_host.h"
 #include "bswap.h"
+#include "exec-memory.h"
 
 typedef struct SHPCIState {
     SysBusDevice busdev;
@@ -127,7 +128,8 @@ static int sh_pci_init_device(SysBusDevice *dev)
     }
     s->bus = pci_register_bus(&s->busdev.qdev, "pci",
                               sh_pci_set_irq, sh_pci_map_irq,
-                              s->irq, PCI_DEVFN(0, 0), 4);
+                              s->irq, get_system_memory(),
+                              PCI_DEVFN(0, 0), 4);
     s->memconfig = cpu_register_io_memory(sh_pci_reg.r, sh_pci_reg.w,
                                           s, DEVICE_NATIVE_ENDIAN);
     sysbus_init_mmio_cb(dev, 0x224, sh_pci_map);
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index d364daa..b499523 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -201,7 +201,7 @@ static int pci_unin_internal_init_device(SysBusDevice *dev)
     return 0;
 }
 
-PCIBus *pci_pmac_init(qemu_irq *pic)
+PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space)
 {
     DeviceState *dev;
     SysBusDevice *s;
@@ -215,7 +215,8 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
     d = FROM_SYSBUS(UNINState, s);
     d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_unin_set_irq, pci_unin_map_irq,
-                                         pic, PCI_DEVFN(11, 0), 4);
+                                         pic, address_space,
+                                         PCI_DEVFN(11, 0), 4);
 
 #if 0
     pci_create_simple(d->host_state.bus, PCI_DEVFN(11, 0), "uni-north");
@@ -252,7 +253,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
     return d->host_state.bus;
 }
 
-PCIBus *pci_pmac_u3_init(qemu_irq *pic)
+PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space)
 {
     DeviceState *dev;
     SysBusDevice *s;
@@ -267,7 +268,8 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic)
 
     d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_unin_set_irq, pci_unin_map_irq,
-                                         pic, PCI_DEVFN(11, 0), 4);
+                                         pic, address_space,
+                                         PCI_DEVFN(11, 0), 4);
 
     sysbus_mmio_map(s, 0, 0xf0800000);
     sysbus_mmio_map(s, 1, 0xf0c00000);
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index 8e75ffc..6b693df 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -10,6 +10,7 @@
 #include "sysbus.h"
 #include "pci.h"
 #include "pci_host.h"
+#include "exec-memory.h"
 
 typedef struct {
     SysBusDevice busdev;
@@ -111,6 +112,7 @@ static int pci_vpb_init(SysBusDevice *dev)
     }
     bus = pci_register_bus(&dev->qdev, "pci",
                            pci_vpb_set_irq, pci_vpb_map_irq, s->irq,
+                           get_system_memory(),
                            PCI_DEVFN(11, 0), 4);
 
     /* ??? Register memory space.  */
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 15/56] pci: add MemoryRegion based BAR management API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Allow registering a BAR using a MemoryRegion.  Once all users are converted,
pci_register_bar() and pci_register_bar_simple() will be removed.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pci.c |   47 +++++++++++++++++++++++++++++++++++++++--------
 hw/pci.h |    3 +++
 2 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index cf16f3b..36db58b 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -844,10 +844,15 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
         if (r->type == PCI_BASE_ADDRESS_SPACE_IO) {
             isa_unassign_ioport(r->addr, r->filtered_size);
         } else {
-            cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus,
-                                                         r->addr),
-                                         r->filtered_size,
-                                         IO_MEM_UNASSIGNED);
+            if (r->memory) {
+                memory_region_del_subregion(pci_dev->bus->address_space,
+                                            r->memory);
+            } else {
+                cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus,
+                                                             r->addr),
+                                             r->filtered_size,
+                                             IO_MEM_UNASSIGNED);
+            }
         }
     }
 }
@@ -893,6 +898,7 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
     r->type = type;
     r->map_func = map_func;
     r->ram_addr = IO_MEM_UNASSIGNED;
+    r->memory = NULL;
 
     wmask = ~(size - 1);
     addr = pci_bar(pci_dev, region_num);
@@ -918,6 +924,16 @@ static void pci_simple_bar_mapfunc(PCIDevice *pci_dev, int region_num,
                                  pci_dev->io_regions[region_num].ram_addr);
 }
 
+static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num,
+                                          pcibus_t addr, pcibus_t size,
+                                          int type)
+{
+    memory_region_add_subregion_overlap(pci_dev->bus->address_space,
+                                        addr,
+                                        pci_dev->io_regions[region_num].memory,
+                                        1);
+}
+
 void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
                              pcibus_t size,  uint8_t attr, ram_addr_t ram_addr)
 {
@@ -927,6 +943,15 @@ void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
     pci_dev->io_regions[region_num].ram_addr = ram_addr;
 }
 
+void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
+                             uint8_t attr, MemoryRegion *memory)
+{
+    pci_register_bar(pci_dev, region_num, memory_region_size(memory),
+                     PCI_BASE_ADDRESS_SPACE_MEMORY | attr,
+                     pci_simple_bar_mapfunc_region);
+    pci_dev->io_regions[region_num].memory = memory;
+}
+
 static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size,
                               uint8_t type)
 {
@@ -1065,10 +1090,16 @@ static void pci_update_mappings(PCIDevice *d)
                     isa_unassign_ioport(r->addr, r->filtered_size);
                 }
             } else {
-                cpu_register_physical_memory(pci_to_cpu_addr(d->bus, r->addr),
-                                             r->filtered_size,
-                                             IO_MEM_UNASSIGNED);
-                qemu_unregister_coalesced_mmio(r->addr, r->filtered_size);
+                if (r->memory) {
+                    memory_region_del_subregion(d->bus->address_space,
+                                                r->memory);
+                } else {
+                    cpu_register_physical_memory(pci_to_cpu_addr(d->bus,
+                                                                 r->addr),
+                                                 r->filtered_size,
+                                                 IO_MEM_UNASSIGNED);
+                    qemu_unregister_coalesced_mmio(r->addr, r->filtered_size);
+                }
             }
         }
         r->addr = new_addr;
diff --git a/hw/pci.h b/hw/pci.h
index cfeb042..c51156d 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -94,6 +94,7 @@ typedef struct PCIIORegion {
     uint8_t type;
     PCIMapIORegionFunc *map_func;
     ram_addr_t ram_addr;
+    MemoryRegion *memory;
 } PCIIORegion;
 
 #define PCI_ROM_SLOT 6
@@ -204,6 +205,8 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
                             PCIMapIORegionFunc *map_func);
 void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
                              pcibus_t size, uint8_t attr, ram_addr_t ram_addr);
+void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
+                             uint8_t attr, MemoryRegion *memory);
 
 int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
                        uint8_t offset, uint8_t size);
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 15/56] pci: add MemoryRegion based BAR management API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Allow registering a BAR using a MemoryRegion.  Once all users are converted,
pci_register_bar() and pci_register_bar_simple() will be removed.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pci.c |   47 +++++++++++++++++++++++++++++++++++++++--------
 hw/pci.h |    3 +++
 2 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index cf16f3b..36db58b 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -844,10 +844,15 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
         if (r->type == PCI_BASE_ADDRESS_SPACE_IO) {
             isa_unassign_ioport(r->addr, r->filtered_size);
         } else {
-            cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus,
-                                                         r->addr),
-                                         r->filtered_size,
-                                         IO_MEM_UNASSIGNED);
+            if (r->memory) {
+                memory_region_del_subregion(pci_dev->bus->address_space,
+                                            r->memory);
+            } else {
+                cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus,
+                                                             r->addr),
+                                             r->filtered_size,
+                                             IO_MEM_UNASSIGNED);
+            }
         }
     }
 }
@@ -893,6 +898,7 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
     r->type = type;
     r->map_func = map_func;
     r->ram_addr = IO_MEM_UNASSIGNED;
+    r->memory = NULL;
 
     wmask = ~(size - 1);
     addr = pci_bar(pci_dev, region_num);
@@ -918,6 +924,16 @@ static void pci_simple_bar_mapfunc(PCIDevice *pci_dev, int region_num,
                                  pci_dev->io_regions[region_num].ram_addr);
 }
 
+static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num,
+                                          pcibus_t addr, pcibus_t size,
+                                          int type)
+{
+    memory_region_add_subregion_overlap(pci_dev->bus->address_space,
+                                        addr,
+                                        pci_dev->io_regions[region_num].memory,
+                                        1);
+}
+
 void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
                              pcibus_t size,  uint8_t attr, ram_addr_t ram_addr)
 {
@@ -927,6 +943,15 @@ void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
     pci_dev->io_regions[region_num].ram_addr = ram_addr;
 }
 
+void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
+                             uint8_t attr, MemoryRegion *memory)
+{
+    pci_register_bar(pci_dev, region_num, memory_region_size(memory),
+                     PCI_BASE_ADDRESS_SPACE_MEMORY | attr,
+                     pci_simple_bar_mapfunc_region);
+    pci_dev->io_regions[region_num].memory = memory;
+}
+
 static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size,
                               uint8_t type)
 {
@@ -1065,10 +1090,16 @@ static void pci_update_mappings(PCIDevice *d)
                     isa_unassign_ioport(r->addr, r->filtered_size);
                 }
             } else {
-                cpu_register_physical_memory(pci_to_cpu_addr(d->bus, r->addr),
-                                             r->filtered_size,
-                                             IO_MEM_UNASSIGNED);
-                qemu_unregister_coalesced_mmio(r->addr, r->filtered_size);
+                if (r->memory) {
+                    memory_region_del_subregion(d->bus->address_space,
+                                                r->memory);
+                } else {
+                    cpu_register_physical_memory(pci_to_cpu_addr(d->bus,
+                                                                 r->addr),
+                                                 r->filtered_size,
+                                                 IO_MEM_UNASSIGNED);
+                    qemu_unregister_coalesced_mmio(r->addr, r->filtered_size);
+                }
             }
         }
         r->addr = new_addr;
diff --git a/hw/pci.h b/hw/pci.h
index cfeb042..c51156d 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -94,6 +94,7 @@ typedef struct PCIIORegion {
     uint8_t type;
     PCIMapIORegionFunc *map_func;
     ram_addr_t ram_addr;
+    MemoryRegion *memory;
 } PCIIORegion;
 
 #define PCI_ROM_SLOT 6
@@ -204,6 +205,8 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
                             PCIMapIORegionFunc *map_func);
 void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
                              pcibus_t size, uint8_t attr, ram_addr_t ram_addr);
+void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
+                             uint8_t attr, MemoryRegion *memory);
 
 int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
                        uint8_t offset, uint8_t size);
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 16/56] sysbus: add MemoryRegion based memory management API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Allow registering sysbus device memory using a MemoryRegion.  Once all users
are converted, sysbus_init_mmio() and sysbus_init_mmio_cb() will be removed.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/sysbus.c |   27 ++++++++++++++++++++++++---
 hw/sysbus.h |    3 +++
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/hw/sysbus.c b/hw/sysbus.c
index 2e22be7..ea442ac 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -19,6 +19,7 @@
 
 #include "sysbus.h"
 #include "monitor.h"
+#include "exec-memory.h"
 
 static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
 static char *sysbus_get_fw_dev_path(DeviceState *dev);
@@ -49,11 +50,20 @@ void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr)
     }
     if (dev->mmio[n].addr != (target_phys_addr_t)-1) {
         /* Unregister previous mapping.  */
-        cpu_register_physical_memory(dev->mmio[n].addr, dev->mmio[n].size,
-                                     IO_MEM_UNASSIGNED);
+        if (dev->mmio[n].memory) {
+            memory_region_del_subregion(get_system_memory(),
+                                        dev->mmio[n].memory);
+        } else {
+            cpu_register_physical_memory(dev->mmio[n].addr, dev->mmio[n].size,
+                                         IO_MEM_UNASSIGNED);
+        }
     }
     dev->mmio[n].addr = addr;
-    if (dev->mmio[n].cb) {
+    if (dev->mmio[n].memory) {
+        memory_region_add_subregion(get_system_memory(),
+                                    addr,
+                                    dev->mmio[n].memory);
+    } else if (dev->mmio[n].cb) {
         dev->mmio[n].cb(dev, addr);
     } else {
         cpu_register_physical_memory(addr, dev->mmio[n].size,
@@ -107,6 +117,17 @@ void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,
     dev->mmio[n].cb = cb;
 }
 
+void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory)
+{
+    int n;
+
+    assert(dev->num_mmio < QDEV_MAX_MMIO);
+    n = dev->num_mmio++;
+    dev->mmio[n].addr = -1;
+    dev->mmio[n].size = memory_region_size(memory);
+    dev->mmio[n].memory = memory;
+}
+
 void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size)
 {
     pio_addr_t i;
diff --git a/hw/sysbus.h b/hw/sysbus.h
index 4e8cb16..5f62e2d 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -4,6 +4,7 @@
 /* Devices attached directly to the main system bus.  */
 
 #include "qdev.h"
+#include "memory.h"
 
 #define QDEV_MAX_MMIO 32
 #define QDEV_MAX_PIO 32
@@ -23,6 +24,7 @@ struct SysBusDevice {
         target_phys_addr_t size;
         mmio_mapfunc cb;
         ram_addr_t iofunc;
+        MemoryRegion *memory;
     } mmio[QDEV_MAX_MMIO];
     int num_pio;
     pio_addr_t pio[QDEV_MAX_PIO];
@@ -46,6 +48,7 @@ void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size,
                       ram_addr_t iofunc);
 void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,
                             mmio_mapfunc cb);
+void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory);
 void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p);
 void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target);
 void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size);
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 16/56] sysbus: add MemoryRegion based memory management API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Allow registering sysbus device memory using a MemoryRegion.  Once all users
are converted, sysbus_init_mmio() and sysbus_init_mmio_cb() will be removed.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/sysbus.c |   27 ++++++++++++++++++++++++---
 hw/sysbus.h |    3 +++
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/hw/sysbus.c b/hw/sysbus.c
index 2e22be7..ea442ac 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -19,6 +19,7 @@
 
 #include "sysbus.h"
 #include "monitor.h"
+#include "exec-memory.h"
 
 static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
 static char *sysbus_get_fw_dev_path(DeviceState *dev);
@@ -49,11 +50,20 @@ void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr)
     }
     if (dev->mmio[n].addr != (target_phys_addr_t)-1) {
         /* Unregister previous mapping.  */
-        cpu_register_physical_memory(dev->mmio[n].addr, dev->mmio[n].size,
-                                     IO_MEM_UNASSIGNED);
+        if (dev->mmio[n].memory) {
+            memory_region_del_subregion(get_system_memory(),
+                                        dev->mmio[n].memory);
+        } else {
+            cpu_register_physical_memory(dev->mmio[n].addr, dev->mmio[n].size,
+                                         IO_MEM_UNASSIGNED);
+        }
     }
     dev->mmio[n].addr = addr;
-    if (dev->mmio[n].cb) {
+    if (dev->mmio[n].memory) {
+        memory_region_add_subregion(get_system_memory(),
+                                    addr,
+                                    dev->mmio[n].memory);
+    } else if (dev->mmio[n].cb) {
         dev->mmio[n].cb(dev, addr);
     } else {
         cpu_register_physical_memory(addr, dev->mmio[n].size,
@@ -107,6 +117,17 @@ void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,
     dev->mmio[n].cb = cb;
 }
 
+void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory)
+{
+    int n;
+
+    assert(dev->num_mmio < QDEV_MAX_MMIO);
+    n = dev->num_mmio++;
+    dev->mmio[n].addr = -1;
+    dev->mmio[n].size = memory_region_size(memory);
+    dev->mmio[n].memory = memory;
+}
+
 void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size)
 {
     pio_addr_t i;
diff --git a/hw/sysbus.h b/hw/sysbus.h
index 4e8cb16..5f62e2d 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -4,6 +4,7 @@
 /* Devices attached directly to the main system bus.  */
 
 #include "qdev.h"
+#include "memory.h"
 
 #define QDEV_MAX_MMIO 32
 #define QDEV_MAX_PIO 32
@@ -23,6 +24,7 @@ struct SysBusDevice {
         target_phys_addr_t size;
         mmio_mapfunc cb;
         ram_addr_t iofunc;
+        MemoryRegion *memory;
     } mmio[QDEV_MAX_MMIO];
     int num_pio;
     pio_addr_t pio[QDEV_MAX_PIO];
@@ -46,6 +48,7 @@ void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size,
                       ram_addr_t iofunc);
 void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,
                             mmio_mapfunc cb);
+void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory);
 void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p);
 void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target);
 void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size);
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 17/56] usb-ohci: convert to MemoryRegion
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/usb-ohci.c |   42 +++++++++++++++++-------------------------
 1 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 1c29b9f..36885cb 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -62,7 +62,7 @@ typedef struct OHCIPort {
 typedef struct {
     USBBus bus;
     qemu_irq irq;
-    int mem;
+    MemoryRegion mem;
     int num_ports;
     const char *name;
 
@@ -1426,13 +1426,13 @@ static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val)
     return;
 }
 
-static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr)
+static uint64_t ohci_mem_read(void *opaque,
+                              target_phys_addr_t addr,
+                              unsigned size)
 {
-    OHCIState *ohci = ptr;
+    OHCIState *ohci = opaque;
     uint32_t retval;
 
-    addr &= 0xff;
-
     /* Only aligned reads are allowed on OHCI */
     if (addr & 3) {
         fprintf(stderr, "usb-ohci: Mis-aligned read\n");
@@ -1549,11 +1549,12 @@ static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr)
     return retval;
 }
 
-static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val)
+static void ohci_mem_write(void *opaque,
+                           target_phys_addr_t addr,
+                           uint64_t val,
+                           unsigned size)
 {
-    OHCIState *ohci = ptr;
-
-    addr &= 0xff;
+    OHCIState *ohci = opaque;
 
     /* Only aligned reads are allowed on OHCI */
     if (addr & 3) {
@@ -1685,18 +1686,10 @@ static void ohci_device_destroy(USBBus *bus, USBDevice *dev)
     }
 }
 
-/* Only dword reads are defined on OHCI register space */
-static CPUReadMemoryFunc * const ohci_readfn[3]={
-    ohci_mem_read,
-    ohci_mem_read,
-    ohci_mem_read
-};
-
-/* Only dword writes are defined on OHCI register space */
-static CPUWriteMemoryFunc * const ohci_writefn[3]={
-    ohci_mem_write,
-    ohci_mem_write,
-    ohci_mem_write
+static const MemoryRegionOps ohci_mem_ops = {
+    .read = ohci_mem_read,
+    .write = ohci_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static USBPortOps ohci_port_ops = {
@@ -1731,8 +1724,7 @@ static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
                 usb_frame_time, usb_bit_time);
     }
 
-    ohci->mem = cpu_register_io_memory(ohci_readfn, ohci_writefn, ohci,
-                                       DEVICE_LITTLE_ENDIAN);
+    memory_region_init_io(&ohci->mem, &ohci_mem_ops, ohci, "ohci", 256);
     ohci->localmem_base = localmem_base;
 
     ohci->name = dev->info->name;
@@ -1767,7 +1759,7 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev)
     ohci->state.irq = ohci->pci_dev.irq[0];
 
     /* TODO: avoid cast below by using dev */
-    pci_register_bar_simple(&ohci->pci_dev, 0, 256, 0, ohci->state.mem);
+    pci_register_bar_region(&ohci->pci_dev, 0, 0, &ohci->state.mem);
     return 0;
 }
 
@@ -1789,7 +1781,7 @@ static int ohci_init_pxa(SysBusDevice *dev)
 
     usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset);
     sysbus_init_irq(dev, &s->ohci.irq);
-    sysbus_init_mmio(dev, 0x1000, s->ohci.mem);
+    sysbus_init_mmio_region(dev, &s->ohci.mem);
 
     return 0;
 }
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 17/56] usb-ohci: convert to MemoryRegion
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/usb-ohci.c |   42 +++++++++++++++++-------------------------
 1 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 1c29b9f..36885cb 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -62,7 +62,7 @@ typedef struct OHCIPort {
 typedef struct {
     USBBus bus;
     qemu_irq irq;
-    int mem;
+    MemoryRegion mem;
     int num_ports;
     const char *name;
 
@@ -1426,13 +1426,13 @@ static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val)
     return;
 }
 
-static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr)
+static uint64_t ohci_mem_read(void *opaque,
+                              target_phys_addr_t addr,
+                              unsigned size)
 {
-    OHCIState *ohci = ptr;
+    OHCIState *ohci = opaque;
     uint32_t retval;
 
-    addr &= 0xff;
-
     /* Only aligned reads are allowed on OHCI */
     if (addr & 3) {
         fprintf(stderr, "usb-ohci: Mis-aligned read\n");
@@ -1549,11 +1549,12 @@ static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr)
     return retval;
 }
 
-static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val)
+static void ohci_mem_write(void *opaque,
+                           target_phys_addr_t addr,
+                           uint64_t val,
+                           unsigned size)
 {
-    OHCIState *ohci = ptr;
-
-    addr &= 0xff;
+    OHCIState *ohci = opaque;
 
     /* Only aligned reads are allowed on OHCI */
     if (addr & 3) {
@@ -1685,18 +1686,10 @@ static void ohci_device_destroy(USBBus *bus, USBDevice *dev)
     }
 }
 
-/* Only dword reads are defined on OHCI register space */
-static CPUReadMemoryFunc * const ohci_readfn[3]={
-    ohci_mem_read,
-    ohci_mem_read,
-    ohci_mem_read
-};
-
-/* Only dword writes are defined on OHCI register space */
-static CPUWriteMemoryFunc * const ohci_writefn[3]={
-    ohci_mem_write,
-    ohci_mem_write,
-    ohci_mem_write
+static const MemoryRegionOps ohci_mem_ops = {
+    .read = ohci_mem_read,
+    .write = ohci_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static USBPortOps ohci_port_ops = {
@@ -1731,8 +1724,7 @@ static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
                 usb_frame_time, usb_bit_time);
     }
 
-    ohci->mem = cpu_register_io_memory(ohci_readfn, ohci_writefn, ohci,
-                                       DEVICE_LITTLE_ENDIAN);
+    memory_region_init_io(&ohci->mem, &ohci_mem_ops, ohci, "ohci", 256);
     ohci->localmem_base = localmem_base;
 
     ohci->name = dev->info->name;
@@ -1767,7 +1759,7 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev)
     ohci->state.irq = ohci->pci_dev.irq[0];
 
     /* TODO: avoid cast below by using dev */
-    pci_register_bar_simple(&ohci->pci_dev, 0, 256, 0, ohci->state.mem);
+    pci_register_bar_region(&ohci->pci_dev, 0, 0, &ohci->state.mem);
     return 0;
 }
 
@@ -1789,7 +1781,7 @@ static int ohci_init_pxa(SysBusDevice *dev)
 
     usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset);
     sysbus_init_irq(dev, &s->ohci.irq);
-    sysbus_init_mmio(dev, 0x1000, s->ohci.mem);
+    sysbus_init_mmio_region(dev, &s->ohci.mem);
 
     return 0;
 }
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 18/56] pci: add API to get a BAR's mapped address
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

This is a hack, for devices that have a back-channel to read this
address back outside the normal configuration mechanisms, such
as VMware svga.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pci.c |    5 +++++
 hw/pci.h |    1 +
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 36db58b..912f849 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -952,6 +952,11 @@ void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
     pci_dev->io_regions[region_num].memory = memory;
 }
 
+pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num)
+{
+    return pci_dev->io_regions[region_num].addr;
+}
+
 static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size,
                               uint8_t type)
 {
diff --git a/hw/pci.h b/hw/pci.h
index c51156d..64282ad 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -207,6 +207,7 @@ void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
                              pcibus_t size, uint8_t attr, ram_addr_t ram_addr);
 void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
                              uint8_t attr, MemoryRegion *memory);
+pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num);
 
 int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
                        uint8_t offset, uint8_t size);
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 18/56] pci: add API to get a BAR's mapped address
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

This is a hack, for devices that have a back-channel to read this
address back outside the normal configuration mechanisms, such
as VMware svga.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pci.c |    5 +++++
 hw/pci.h |    1 +
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 36db58b..912f849 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -952,6 +952,11 @@ void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
     pci_dev->io_regions[region_num].memory = memory;
 }
 
+pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num)
+{
+    return pci_dev->io_regions[region_num].addr;
+}
+
 static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size,
                               uint8_t type)
 {
diff --git a/hw/pci.h b/hw/pci.h
index c51156d..64282ad 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -207,6 +207,7 @@ void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
                              pcibus_t size, uint8_t attr, ram_addr_t ram_addr);
 void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
                              uint8_t attr, MemoryRegion *memory);
+pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num);
 
 int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
                        uint8_t offset, uint8_t size);
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 19/56] vmsvga: don't remember pci BAR address in callback any more
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

We're going to remove the callback, so we can't use it to save the
address.  Use the pci API instead.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/vmware_vga.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 354c221..190b005 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -52,8 +52,6 @@ struct vmsvga_state_s {
         int on;
     } cursor;
 
-    target_phys_addr_t vram_base;
-
     int index;
     int scratch_size;
     uint32_t *scratch;
@@ -761,8 +759,11 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
     case SVGA_REG_BYTES_PER_LINE:
         return ((s->depth + 7) >> 3) * s->new_width;
 
-    case SVGA_REG_FB_START:
-        return s->vram_base;
+    case SVGA_REG_FB_START: {
+        struct pci_vmsvga_state_s *pci_vmsvga
+            = container_of(s, struct pci_vmsvga_state_s, chip);
+        return pci_get_bar_addr(&pci_vmsvga->card, 1);
+    }
 
     case SVGA_REG_FB_OFFSET:
         return 0x0;
@@ -1247,14 +1248,13 @@ static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num,
     struct vmsvga_state_s *s = &d->chip;
     ram_addr_t iomemtype;
 
-    s->vram_base = addr;
 #ifdef DIRECT_VRAM
     iomemtype = cpu_register_io_memory(vmsvga_vram_read,
                     vmsvga_vram_write, s, DEVICE_NATIVE_ENDIAN);
 #else
     iomemtype = s->vga.vram_offset | IO_MEM_RAM;
 #endif
-    cpu_register_physical_memory(s->vram_base, s->vga.vram_size,
+    cpu_register_physical_memory(addr, s->vga.vram_size,
                     iomemtype);
 
     s->vga.map_addr = addr;
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 19/56] vmsvga: don't remember pci BAR address in callback any more
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

We're going to remove the callback, so we can't use it to save the
address.  Use the pci API instead.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/vmware_vga.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 354c221..190b005 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -52,8 +52,6 @@ struct vmsvga_state_s {
         int on;
     } cursor;
 
-    target_phys_addr_t vram_base;
-
     int index;
     int scratch_size;
     uint32_t *scratch;
@@ -761,8 +759,11 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
     case SVGA_REG_BYTES_PER_LINE:
         return ((s->depth + 7) >> 3) * s->new_width;
 
-    case SVGA_REG_FB_START:
-        return s->vram_base;
+    case SVGA_REG_FB_START: {
+        struct pci_vmsvga_state_s *pci_vmsvga
+            = container_of(s, struct pci_vmsvga_state_s, chip);
+        return pci_get_bar_addr(&pci_vmsvga->card, 1);
+    }
 
     case SVGA_REG_FB_OFFSET:
         return 0x0;
@@ -1247,14 +1248,13 @@ static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num,
     struct vmsvga_state_s *s = &d->chip;
     ram_addr_t iomemtype;
 
-    s->vram_base = addr;
 #ifdef DIRECT_VRAM
     iomemtype = cpu_register_io_memory(vmsvga_vram_read,
                     vmsvga_vram_write, s, DEVICE_NATIVE_ENDIAN);
 #else
     iomemtype = s->vga.vram_offset | IO_MEM_RAM;
 #endif
-    cpu_register_physical_memory(s->vram_base, s->vga.vram_size,
+    cpu_register_physical_memory(addr, s->vga.vram_size,
                     iomemtype);
 
     s->vga.map_addr = addr;
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 20/56] vga: convert vga and its derivatives to the memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Convert all vga memory to the memory API.  Note we need to fall back to
get_system_memory(), since the various buses don't pass the vga window
as a memory region.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/cirrus_vga.c |  345 +++++++++++++++++++++++++++++++++----------------------
 hw/qxl-render.c |    2 +-
 hw/qxl.c        |  131 ++++++++--------------
 hw/qxl.h        |    6 +-
 hw/vga-isa-mm.c |   61 +++++++---
 hw/vga-isa.c    |   11 +-
 hw/vga-pci.c    |   28 +----
 hw/vga.c        |  146 +++++++++++-------------
 hw/vga_int.h    |   15 +--
 hw/vmware_vga.c |  165 ++++++++++++++++-----------
 10 files changed, 478 insertions(+), 432 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index f39d1f8..0cd2aee 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -200,9 +200,14 @@ typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
 typedef struct CirrusVGAState {
     VGACommonState vga;
 
-    int cirrus_linear_io_addr;
-    int cirrus_linear_bitblt_io_addr;
-    int cirrus_mmio_io_addr;
+    MemoryRegion cirrus_linear_io;
+    MemoryRegion cirrus_linear_bitblt_io;
+    MemoryRegion cirrus_mmio_io;
+    MemoryRegion pci_bar;
+    bool linear_vram;  /* vga.vram mapped over cirrus_linear_io */
+    MemoryRegion low_mem_container; /* container for 0xa0000-0xc0000 */
+    MemoryRegion low_mem;           /* always mapped, overridden by: */
+    MemoryRegion *cirrus_bank[2];   /*   aliases at 0xa0000-0xb0000  */
     uint32_t cirrus_addr_mask;
     uint32_t linear_mmio_mask;
     uint8_t cirrus_shadow_gr0;
@@ -612,7 +617,7 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
 	off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
 	off_cur &= TARGET_PAGE_MASK;
 	while (off_cur < off_cur_end) {
-	    cpu_physical_memory_set_dirty(s->vga.vram_offset + off_cur);
+	    memory_region_set_dirty(&s->vga.vram, off_cur);
 	    off_cur += TARGET_PAGE_SIZE;
 	}
 	off_begin += off_pitch;
@@ -1177,12 +1182,6 @@ static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
     }
 
     if (limit > 0) {
-        /* Thinking about changing bank base? First, drop the dirty bitmap information
-         * on the current location, otherwise we lose this pointer forever */
-        if (s->vga.lfb_vram_mapped) {
-            target_phys_addr_t base_addr = isa_mem_base + 0xa0000 + bank_index * 0x8000;
-            cpu_physical_sync_dirty_bitmap(base_addr, base_addr + 0x8000);
-        }
 	s->cirrus_bank_base[bank_index] = offset;
 	s->cirrus_bank_limit[bank_index] = limit;
     } else {
@@ -1921,8 +1920,8 @@ static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
 	val <<= 1;
 	dst++;
     }
-    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset);
-    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 7);
+    memory_region_set_dirty(&s->vga.vram, offset);
+    memory_region_set_dirty(&s->vga.vram, offset + 7);
 }
 
 static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
@@ -1946,8 +1945,8 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
 	val <<= 1;
 	dst += 2;
     }
-    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset);
-    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 15);
+    memory_region_set_dirty(&s->vga.vram, offset);
+    memory_region_set_dirty(&s->vga.vram, offset + 15);
 }
 
 /***************************************
@@ -2057,8 +2056,7 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
 		mode = s->vga.gr[0x05] & 0x7;
 		if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
 		    *(s->vga.vram_ptr + bank_offset) = mem_value;
-		    cpu_physical_memory_set_dirty(s->vga.vram_offset +
-						  bank_offset);
+		    memory_region_set_dirty(&s->vga.vram, bank_offset);
 		} else {
 		    if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
 			cirrus_mem_writeb_mode4and5_8bpp(s, mode,
@@ -2099,16 +2097,37 @@ static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_
     cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
 }
 
-static CPUReadMemoryFunc * const cirrus_vga_mem_read[3] = {
-    cirrus_vga_mem_readb,
-    cirrus_vga_mem_readw,
-    cirrus_vga_mem_readl,
+static uint64_t cirrus_vga_mem_read(void *opaque,
+                                    target_phys_addr_t addr,
+                                    uint32_t size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_vga_mem_readb(s, addr);
+    case 2: return cirrus_vga_mem_readw(s, addr);
+    case 4: return cirrus_vga_mem_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void cirrus_vga_mem_write(void *opaque, target_phys_addr_t addr,
+                                 uint64_t data, unsigned size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_vga_mem_writeb(s, addr, data);
+    case 2: return cirrus_vga_mem_writew(s, addr, data);
+    case 4: return cirrus_vga_mem_writel(s, addr, data);
+    default: abort();
+    }
 };
 
-static CPUWriteMemoryFunc * const cirrus_vga_mem_write[3] = {
-    cirrus_vga_mem_writeb,
-    cirrus_vga_mem_writew,
-    cirrus_vga_mem_writel,
+static MemoryRegionOps cirrus_vga_mem_ops = {
+    .read = cirrus_vga_mem_read,
+    .write = cirrus_vga_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 /***************************************
@@ -2365,7 +2384,7 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
 	mode = s->vga.gr[0x05] & 0x7;
 	if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
 	    *(s->vga.vram_ptr + addr) = (uint8_t) val;
-	    cpu_physical_memory_set_dirty(s->vga.vram_offset + addr);
+	    memory_region_set_dirty(&s->vga.vram, addr);
 	} else {
 	    if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
 		cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
@@ -2393,17 +2412,31 @@ static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr,
 }
 
 
-static CPUReadMemoryFunc * const cirrus_linear_read[3] = {
-    cirrus_linear_readb,
-    cirrus_linear_readw,
-    cirrus_linear_readl,
-};
+static uint64_t cirrus_linear_read(void *opaque, target_phys_addr_t addr,
+                                   unsigned size)
+{
+    CirrusVGAState *s = opaque;
 
-static CPUWriteMemoryFunc * const cirrus_linear_write[3] = {
-    cirrus_linear_writeb,
-    cirrus_linear_writew,
-    cirrus_linear_writel,
-};
+    switch (size) {
+    case 1: return cirrus_linear_readb(s, addr);
+    case 2: return cirrus_linear_readw(s, addr);
+    case 4: return cirrus_linear_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void cirrus_linear_write(void *opaque, target_phys_addr_t addr,
+                                uint64_t data, unsigned size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_linear_writeb(s, addr, data);
+    case 2: return cirrus_linear_writew(s, addr, data);
+    case 4: return cirrus_linear_writel(s, addr, data);
+    default: abort();
+    }
+}
 
 /***************************************
  *
@@ -2471,67 +2504,97 @@ static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr,
     cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff);
 }
 
+static uint64_t cirrus_linear_bitblt_read(void *opaque,
+                                          target_phys_addr_t addr,
+                                          unsigned size)
+{
+    CirrusVGAState *s = opaque;
 
-static CPUReadMemoryFunc * const cirrus_linear_bitblt_read[3] = {
-    cirrus_linear_bitblt_readb,
-    cirrus_linear_bitblt_readw,
-    cirrus_linear_bitblt_readl,
+    switch (size) {
+    case 1: return cirrus_linear_bitblt_readb(s, addr);
+    case 2: return cirrus_linear_bitblt_readw(s, addr);
+    case 4: return cirrus_linear_bitblt_readl(s, addr);
+    default: abort();
+    }
 };
 
-static CPUWriteMemoryFunc * const cirrus_linear_bitblt_write[3] = {
-    cirrus_linear_bitblt_writeb,
-    cirrus_linear_bitblt_writew,
-    cirrus_linear_bitblt_writel,
+static void cirrus_linear_bitblt_write(void *opaque,
+                                       target_phys_addr_t addr,
+                                       uint64_t data,
+                                       unsigned size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_linear_bitblt_writeb(s, addr, data);
+    case 2: return cirrus_linear_bitblt_writew(s, addr, data);
+    case 4: return cirrus_linear_bitblt_writel(s, addr, data);
+    default: abort();
+    }
 };
 
-static void map_linear_vram(CirrusVGAState *s)
+static MemoryRegionOps cirrus_linear_bitblt_io_ops = {
+    .read = cirrus_linear_bitblt_read,
+    .write = cirrus_linear_bitblt_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+#include "exec-memory.h"
+
+static void unmap_bank(CirrusVGAState *s, unsigned bank)
 {
-    if (!s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) {
-        s->vga.map_addr = s->vga.lfb_addr;
-        s->vga.map_end = s->vga.lfb_end;
-        cpu_register_physical_memory_log(s->vga.map_addr,
-					 s->vga.map_end - s->vga.map_addr,
-					 s->vga.vram_offset, 0, true);
+    if (s->cirrus_bank[bank]) {
+        memory_region_del_subregion(&s->low_mem_container,
+                                    s->cirrus_bank[bank]);
+        memory_region_destroy(s->cirrus_bank[bank]);
+        qemu_free(s->cirrus_bank[bank]);
+        s->cirrus_bank[bank] = NULL;
     }
+}
 
-    if (!s->vga.map_addr)
-        return;
-
-    s->vga.lfb_vram_mapped = 0;
+static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank)
+{
+    MemoryRegion *mr;
+    static const char *names[] = { "vga.bank0", "vga.bank1" };
 
     if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)
         && !((s->vga.sr[0x07] & 0x01) == 0)
         && !((s->vga.gr[0x0B] & 0x14) == 0x14)
         && !(s->vga.gr[0x0B] & 0x02)) {
 
-        cpu_register_physical_memory_log(isa_mem_base + 0xa0000, 0x8000,
-					 (s->vga.vram_offset +
-					  s->cirrus_bank_base[0]) |
-					 IO_MEM_RAM, 0, true);
-        cpu_register_physical_memory_log(isa_mem_base + 0xa8000, 0x8000,
-					 (s->vga.vram_offset +
-					  s->cirrus_bank_base[1]) |
-					 IO_MEM_RAM, 0, true);
-
-        s->vga.lfb_vram_mapped = 1;
-    }
-    else {
-        cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
-                                     s->vga.vga_io_memory);
+        mr = qemu_malloc(sizeof(*mr));
+        memory_region_init_alias(mr, names[bank], &s->vga.vram,
+                                 s->cirrus_bank_base[bank], 0x8000);
+        memory_region_add_subregion_overlap(
+            &s->low_mem_container,
+            0x8000 * bank,
+            mr,
+            1);
+        unmap_bank(s, bank);
+        s->cirrus_bank[bank] = mr;
+    } else {
+        unmap_bank(s, bank);
     }
+}
 
-    vga_dirty_log_start(&s->vga);
+static void map_linear_vram(CirrusVGAState *s)
+{
+    if (!s->linear_vram) {
+        s->linear_vram = true;
+        memory_region_add_subregion_overlap(&s->pci_bar, 0, &s->vga.vram, 1);
+    }
+    map_linear_vram_bank(s, 0);
+    map_linear_vram_bank(s, 1);
 }
 
 static void unmap_linear_vram(CirrusVGAState *s)
 {
-    if (s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) {
-        s->vga.map_addr = s->vga.map_end = 0;
-         cpu_register_physical_memory(s->vga.lfb_addr, s->vga.vram_size,
-                                      s->cirrus_linear_io_addr);
+    if (s->linear_vram) {
+        s->linear_vram = false;
+        memory_region_del_subregion(&s->pci_bar, &s->vga.vram);
     }
-    cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
-                                 s->vga.vga_io_memory);
+    unmap_bank(s, 0);
+    unmap_bank(s, 1);
 }
 
 /* Compute the memory access functions */
@@ -2829,16 +2892,36 @@ static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr,
 }
 
 
-static CPUReadMemoryFunc * const cirrus_mmio_read[3] = {
-    cirrus_mmio_readb,
-    cirrus_mmio_readw,
-    cirrus_mmio_readl,
+static uint64_t cirrus_mmio_read(void *opaque, target_phys_addr_t addr,
+                                 unsigned size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_mmio_readb(s, addr);
+    case 2: return cirrus_mmio_readw(s, addr);
+    case 4: return cirrus_mmio_readl(s, addr);
+    default: abort();
+    }
 };
 
-static CPUWriteMemoryFunc * const cirrus_mmio_write[3] = {
-    cirrus_mmio_writeb,
-    cirrus_mmio_writew,
-    cirrus_mmio_writel,
+static void cirrus_mmio_write(void *opaque, target_phys_addr_t addr,
+                              uint64_t data, unsigned size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_mmio_writeb(s, addr, data);
+    case 2: return cirrus_mmio_writew(s, addr, data);
+    case 4: return cirrus_mmio_writel(s, addr, data);
+    default: abort();
+    }
+};
+
+static MemoryRegionOps cirrus_mmio_io_ops = {
+    .read = cirrus_mmio_read,
+    .write = cirrus_mmio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 /* load/save state */
@@ -2947,6 +3030,12 @@ static void cirrus_reset(void *opaque)
     s->cirrus_hidden_dac_data = 0;
 }
 
+static MemoryRegionOps cirrus_linear_io_ops = {
+    .read = cirrus_linear_read,
+    .write = cirrus_linear_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
 {
     int i;
@@ -2993,28 +3082,33 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
     register_ioport_read(0x3ba, 1, 1, cirrus_vga_ioport_read, s);
     register_ioport_read(0x3da, 1, 1, cirrus_vga_ioport_read, s);
 
-    s->vga.vga_io_memory = cpu_register_io_memory(cirrus_vga_mem_read,
-                                                  cirrus_vga_mem_write, s,
-                                                  DEVICE_LITTLE_ENDIAN);
-    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
-                                 s->vga.vga_io_memory);
-    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
+    memory_region_init(&s->low_mem_container,
+                       "cirrus-lowmem-container",
+                       0x20000);
+
+    memory_region_init_io(&s->low_mem, &cirrus_vga_mem_ops, s,
+                          "cirrus-low-memory", 0x20000);
+    memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem);
+    memory_region_add_subregion_overlap(get_system_memory(),
+                                        isa_mem_base + 0x000a0000,
+                                        &s->low_mem_container,
+                                        1);
+    memory_region_set_coalescing(&s->low_mem);
 
     /* I/O handler for LFB */
-    s->cirrus_linear_io_addr =
-        cpu_register_io_memory(cirrus_linear_read, cirrus_linear_write, s,
-                               DEVICE_LITTLE_ENDIAN);
+    memory_region_init_io(&s->cirrus_linear_io, &cirrus_linear_io_ops, s,
+                          "cirrus-linear-io", VGA_RAM_SIZE);
 
     /* I/O handler for LFB */
-    s->cirrus_linear_bitblt_io_addr =
-        cpu_register_io_memory(cirrus_linear_bitblt_read,
-                               cirrus_linear_bitblt_write, s,
-                               DEVICE_LITTLE_ENDIAN);
+    memory_region_init_io(&s->cirrus_linear_bitblt_io,
+                          &cirrus_linear_bitblt_io_ops,
+                          s,
+                          "cirrus-bitblt-mmio",
+                          0x400000);
 
     /* I/O handler for memory-mapped I/O */
-    s->cirrus_mmio_io_addr =
-        cpu_register_io_memory(cirrus_mmio_read, cirrus_mmio_write, s,
-                               DEVICE_LITTLE_ENDIAN);
+    memory_region_init_io(&s->cirrus_mmio_io, &cirrus_mmio_io_ops, s,
+                          "cirrus-mmio", CIRRUS_PNPMMIO_SIZE);
 
     s->real_vram_size =
         (s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024;
@@ -3060,42 +3154,6 @@ void isa_cirrus_vga_init(void)
  *
  ***************************************/
 
-static void cirrus_pci_lfb_map(PCIDevice *d, int region_num,
-			       pcibus_t addr, pcibus_t size, int type)
-{
-    CirrusVGAState *s = &DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga;
-
-    /* XXX: add byte swapping apertures */
-    cpu_register_physical_memory(addr, s->vga.vram_size,
-				 s->cirrus_linear_io_addr);
-    cpu_register_physical_memory(addr + 0x1000000, 0x400000,
-				 s->cirrus_linear_bitblt_io_addr);
-
-    s->vga.map_addr = s->vga.map_end = 0;
-    s->vga.lfb_addr = addr & TARGET_PAGE_MASK;
-    s->vga.lfb_end = ((addr + VGA_RAM_SIZE) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
-    /* account for overflow */
-    if (s->vga.lfb_end < addr + VGA_RAM_SIZE)
-        s->vga.lfb_end = addr + VGA_RAM_SIZE;
-
-    vga_dirty_log_start(&s->vga);
-}
-
-static void pci_cirrus_write_config(PCIDevice *d,
-                                    uint32_t address, uint32_t val, int len)
-{
-    PCICirrusVGAState *pvs = DO_UPCAST(PCICirrusVGAState, dev, d);
-    CirrusVGAState *s = &pvs->cirrus_vga;
-
-    pci_default_write_config(d, address, val, len);
-    if (s->vga.map_addr && d->io_regions[0].addr == PCI_BAR_UNMAPPED) {
-        s->vga.map_addr = 0;
-        s->vga.lfb_addr = 0;
-        s->vga.lfb_end = 0;
-    }
-    cirrus_update_memory_access(s);
-}
-
 static int pci_cirrus_vga_initfn(PCIDevice *dev)
 {
      PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);
@@ -3112,15 +3170,23 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
 
      /* setup PCI */
 
+    memory_region_init(&s->pci_bar, "cirrus-pci-bar0", 0x2000000);
+
+    /* XXX: add byte swapping apertures */
+    memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io);
+    memory_region_add_subregion(&s->pci_bar, 0x1000000,
+                                &s->cirrus_linear_bitblt_io);
+
+    vga_dirty_log_start(&s->vga);
+
      /* setup memory space */
      /* memory #0 LFB */
      /* memory #1 memory-mapped I/O */
      /* XXX: s->vga.vram_size must be a power of two */
-     pci_register_bar(&d->dev, 0, 0x2000000,
-                      PCI_BASE_ADDRESS_MEM_PREFETCH, cirrus_pci_lfb_map);
+     pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH,
+                             &s->pci_bar);
      if (device_id == CIRRUS_ID_CLGD5446) {
-         pci_register_bar_simple(&d->dev, 1, CIRRUS_PNPMMIO_SIZE, 0,
-                                 s->cirrus_mmio_io_addr);
+         pci_register_bar_region(&d->dev, 1, 0, &s->cirrus_mmio_io);
      }
      return 0;
 }
@@ -3138,7 +3204,6 @@ static PCIDeviceInfo cirrus_vga_info = {
     .no_hotplug   = 1,
     .init         = pci_cirrus_vga_initfn,
     .romfile      = VGABIOS_CIRRUS_FILENAME,
-    .config_write = pci_cirrus_write_config,
     .vendor_id    = PCI_VENDOR_ID_CIRRUS,
     .device_id    = CIRRUS_ID_CLGD5446,
     .class_id     = PCI_CLASS_DISPLAY_VGA,
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 1316066..4f626dc 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -86,7 +86,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
         }
         qemu_free_displaysurface(vga->ds);
 
-        qxl->guest_primary.data = qemu_get_ram_ptr(qxl->vga.vram_offset);
+        qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
         if (qxl->guest_primary.stride < 0) {
             /* spice surface is upside down -> need extra buffer to flip */
             qxl->guest_primary.stride = -qxl->guest_primary.stride;
diff --git a/hw/qxl.c b/hw/qxl.c
index 16316f2..da323f6 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -147,7 +147,7 @@ static ram_addr_t qxl_rom_size(void)
 
 static void init_qxl_rom(PCIQXLDevice *d)
 {
-    QXLRom *rom = qemu_get_ram_ptr(d->rom_offset);
+    QXLRom *rom = memory_region_get_ram_ptr(&d->rom_bar);
     QXLModes *modes = (QXLModes *)(rom + 1);
     uint32_t ram_header_size;
     uint32_t surface0_area_size;
@@ -223,39 +223,37 @@ static void init_qxl_ram(PCIQXLDevice *d)
 }
 
 /* can be called from spice server thread context */
-static void qxl_set_dirty(ram_addr_t addr, ram_addr_t end)
+static void qxl_set_dirty(MemoryRegion *mr, ram_addr_t addr, ram_addr_t end)
 {
     while (addr < end) {
-        cpu_physical_memory_set_dirty(addr);
+        memory_region_set_dirty(mr, addr);
         addr += TARGET_PAGE_SIZE;
     }
 }
 
 static void qxl_rom_set_dirty(PCIQXLDevice *qxl)
 {
-    ram_addr_t addr = qxl->rom_offset;
-    qxl_set_dirty(addr, addr + qxl->rom_size);
+    qxl_set_dirty(&qxl->rom_bar, 0, qxl->rom_size);
 }
 
 /* called from spice server thread context only */
 static void qxl_ram_set_dirty(PCIQXLDevice *qxl, void *ptr)
 {
-    ram_addr_t addr = qxl->vga.vram_offset;
     void *base = qxl->vga.vram_ptr;
     intptr_t offset;
 
     offset = ptr - base;
     offset &= ~(TARGET_PAGE_SIZE-1);
     assert(offset < qxl->vga.vram_size);
-    qxl_set_dirty(addr + offset, addr + offset + TARGET_PAGE_SIZE);
+    qxl_set_dirty(&qxl->vga.vram, offset, offset + TARGET_PAGE_SIZE);
 }
 
 /* can be called from spice server thread context */
 static void qxl_ring_set_dirty(PCIQXLDevice *qxl)
 {
-    ram_addr_t addr = qxl->vga.vram_offset + qxl->shadow_rom.ram_header_offset;
-    ram_addr_t end  = qxl->vga.vram_offset + qxl->vga.vram_size;
-    qxl_set_dirty(addr, end);
+    ram_addr_t addr = qxl->shadow_rom.ram_header_offset;
+    ram_addr_t end  = qxl->vga.vram_size;
+    qxl_set_dirty(&qxl->vga.vram, addr, end);
 }
 
 /*
@@ -613,20 +611,6 @@ static void qxl_set_irq(PCIQXLDevice *d)
     qxl_ring_set_dirty(d);
 }
 
-static void qxl_write_config(PCIDevice *d, uint32_t address,
-                             uint32_t val, int len)
-{
-    PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, d);
-    VGACommonState *vga = &qxl->vga;
-
-    vga_dirty_log_stop(vga);
-    pci_default_write_config(d, address, val, len);
-    if (vga->map_addr && qxl->pci.io_regions[0].addr == -1) {
-        vga->map_addr = 0;
-    }
-    vga_dirty_log_start(vga);
-}
-
 static void qxl_check_state(PCIQXLDevice *d)
 {
     QXLRam *ram = d->ram;
@@ -752,10 +736,10 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
 
     switch (pci_region) {
     case QXL_RAM_RANGE_INDEX:
-        virt_start = (intptr_t)qemu_get_ram_ptr(d->vga.vram_offset);
+        virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vga.vram);
         break;
     case QXL_VRAM_RANGE_INDEX:
-        virt_start = (intptr_t)qemu_get_ram_ptr(d->vram_offset);
+        virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vram_bar);
         break;
     default:
         /* should not happen */
@@ -915,10 +899,11 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
     qxl_rom_set_dirty(d);
 }
 
-static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void ioport_write(void *opaque, target_phys_addr_t addr,
+                         uint64_t val, unsigned size)
 {
     PCIQXLDevice *d = opaque;
-    uint32_t io_port = addr - d->io_base;
+    uint32_t io_port = addr;
 
     switch (io_port) {
     case QXL_IO_RESET:
@@ -964,7 +949,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
         d->oom_running = 0;
         break;
     case QXL_IO_SET_MODE:
-        dprint(d, 1, "QXL_SET_MODE %d\n", val);
+        dprint(d, 1, "QXL_SET_MODE %d\n", (int)val);
         qxl_set_mode(d, val, 0);
         break;
     case QXL_IO_LOG:
@@ -1008,7 +993,8 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
-static uint32_t ioport_read(void *opaque, uint32_t addr)
+static uint64_t ioport_read(void *opaque, target_phys_addr_t addr,
+                            unsigned size)
 {
     PCIQXLDevice *d = opaque;
 
@@ -1016,42 +1002,14 @@ static uint32_t ioport_read(void *opaque, uint32_t addr)
     return 0xff;
 }
 
-static void qxl_map(PCIDevice *pci, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
-{
-    static const char *names[] = {
-        [ QXL_IO_RANGE_INDEX ]   = "ioports",
-        [ QXL_RAM_RANGE_INDEX ]  = "devram",
-        [ QXL_ROM_RANGE_INDEX ]  = "rom",
-        [ QXL_VRAM_RANGE_INDEX ] = "vram",
-    };
-    PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, pci);
-
-    dprint(qxl, 1, "%s: bar %d [%s] addr 0x%lx size 0x%lx\n", __FUNCTION__,
-            region_num, names[region_num], addr, size);
-
-    switch (region_num) {
-    case QXL_IO_RANGE_INDEX:
-        register_ioport_write(addr, size, 1, ioport_write, pci);
-        register_ioport_read(addr, size, 1, ioport_read, pci);
-        qxl->io_base = addr;
-        break;
-    case QXL_RAM_RANGE_INDEX:
-        cpu_register_physical_memory(addr, size, qxl->vga.vram_offset | IO_MEM_RAM);
-        qxl->vga.map_addr = addr;
-        qxl->vga.map_end = addr + size;
-        if (qxl->id == 0) {
-            vga_dirty_log_start(&qxl->vga);
-        }
-        break;
-    case QXL_ROM_RANGE_INDEX:
-        cpu_register_physical_memory(addr, size, qxl->rom_offset | IO_MEM_ROM);
-        break;
-    case QXL_VRAM_RANGE_INDEX:
-        cpu_register_physical_memory(addr, size, qxl->vram_offset | IO_MEM_RAM);
-        break;
-    }
-}
+static MemoryRegionOps qxl_io_ops = {
+    .read = ioport_read,
+    .write = ioport_write,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
 
 static void pipe_read(void *opaque)
 {
@@ -1170,8 +1128,7 @@ static void qxl_vm_change_state_handler(void *opaque, int running, int reason)
         /* dirty all vram (which holds surfaces) to make sure it is saved */
         /* FIXME #1: should go out during "live" stage */
         /* FIXME #2: we only need to save the areas which are actually used */
-        ram_addr_t addr = qxl->vram_offset;
-        qxl_set_dirty(addr, addr + qxl->vram_size);
+        qxl_set_dirty(&qxl->vram_bar, 0, qxl->vram_size);
     }
 }
 
@@ -1236,7 +1193,8 @@ static int qxl_init_common(PCIQXLDevice *qxl)
     pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
 
     qxl->rom_size = qxl_rom_size();
-    qxl->rom_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vrom", qxl->rom_size);
+    memory_region_init_ram(&qxl->rom_bar, &qxl->pci.qdev, "qxl.vrom",
+                           qxl->rom_size);
     init_qxl_rom(qxl);
     init_qxl_ram(qxl);
 
@@ -1247,26 +1205,32 @@ static int qxl_init_common(PCIQXLDevice *qxl)
         qxl->vram_size = 4096;
     }
     qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1);
-    qxl->vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vram", qxl->vram_size);
+    memory_region_init_ram(&qxl->vram_bar, &qxl->pci.qdev, "qxl.vram",
+                           qxl->vram_size);
 
     io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1);
     if (qxl->revision == 1) {
         io_size = 8;
     }
 
-    pci_register_bar(&qxl->pci, QXL_IO_RANGE_INDEX,
-                     io_size, PCI_BASE_ADDRESS_SPACE_IO, qxl_map);
+    memory_region_init_io(&qxl->io_bar, &qxl_io_ops, qxl,
+                          "qxl-ioports", io_size);
+    if (qxl->id == 0) {
+        vga_dirty_log_start(&qxl->vga);
+    }
+
+
+    pci_register_bar_region(&qxl->pci, QXL_IO_RANGE_INDEX,
+                            PCI_BASE_ADDRESS_SPACE_IO, &qxl->io_bar);
 
-    pci_register_bar(&qxl->pci, QXL_ROM_RANGE_INDEX,
-                     qxl->rom_size, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                     qxl_map);
+    pci_register_bar_region(&qxl->pci, QXL_ROM_RANGE_INDEX,
+                            PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->rom_bar);
 
-    pci_register_bar(&qxl->pci, QXL_RAM_RANGE_INDEX,
-                     qxl->vga.vram_size, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                     qxl_map);
+    pci_register_bar_region(&qxl->pci, QXL_RAM_RANGE_INDEX,
+                            PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vga.vram);
 
-    pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX, qxl->vram_size,
-                     PCI_BASE_ADDRESS_SPACE_MEMORY, qxl_map);
+    pci_register_bar_region(&qxl->pci, QXL_VRAM_RANGE_INDEX,
+                            PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vram_bar);
 
     qxl->ssd.qxl.base.sif = &qxl_interface.base;
     qxl->ssd.qxl.id = qxl->id;
@@ -1325,9 +1289,9 @@ static int qxl_init_secondary(PCIDevice *dev)
         ram_size = 16 * 1024 * 1024;
     }
     qxl->vga.vram_size = ram_size;
-    qxl->vga.vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vgavram",
-                                          qxl->vga.vram_size);
-    qxl->vga.vram_ptr = qemu_get_ram_ptr(qxl->vga.vram_offset);
+    memory_region_init_ram(&qxl->vga.vram, &qxl->pci.qdev, "qxl.vgavram",
+                           qxl->vga.vram_size);
+    qxl->vga.vram_ptr = memory_region_get_ram_ptr(&qxl->vga.vram);
 
     return qxl_init_common(qxl);
 }
@@ -1489,7 +1453,6 @@ static PCIDeviceInfo qxl_info_primary = {
     .qdev.vmsd    = &qxl_vmstate,
     .no_hotplug   = 1,
     .init         = qxl_init_primary,
-    .config_write = qxl_write_config,
     .romfile      = "vgabios-qxl.bin",
     .vendor_id    = REDHAT_PCI_VENDOR_ID,
     .class_id     = PCI_CLASS_DISPLAY_VGA,
diff --git a/hw/qxl.h b/hw/qxl.h
index f6c450d..987a5e7 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -72,14 +72,14 @@ typedef struct PCIQXLDevice {
     QXLRom             *rom;
     QXLModes           *modes;
     uint32_t           rom_size;
-    uint64_t           rom_offset;
+    MemoryRegion       rom_bar;
 
     /* vram pci bar */
     uint32_t           vram_size;
-    uint64_t           vram_offset;
+    MemoryRegion       vram_bar;
 
     /* io bar */
-    uint32_t           io_base;
+    MemoryRegion       io_bar;
 } PCIQXLDevice;
 
 #define PANIC_ON(x) if ((x)) {                         \
diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c
index 4954bb1..d2661ef 100644
--- a/hw/vga-isa-mm.c
+++ b/hw/vga-isa-mm.c
@@ -79,35 +79,62 @@ static void vga_mm_writel (void *opaque,
     vga_ioport_write(&s->vga, addr >> s->it_shift, value);
 }
 
-static CPUReadMemoryFunc * const vga_mm_read_ctrl[] = {
-    &vga_mm_readb,
-    &vga_mm_readw,
-    &vga_mm_readl,
-};
+static uint64_t vga_mm_read_ctrl(void *opaque, target_phys_addr_t addr,
+                                 unsigned size)
+{
+    ISAVGAMMState *s = opaque;
+
+    switch (size) {
+    case 1: return vga_mm_readb(s, addr);
+    case 2: return vga_mm_readw(s, addr);
+    case 4: return vga_mm_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void vga_mm_write_ctrl(void *opaque, target_phys_addr_t addr,
+                              uint64_t data, unsigned size)
+{
+    ISAVGAMMState *s = opaque;
+
+    switch (size) {
+    case 1: return vga_mm_writeb(s, addr, data);
+    case 2: return vga_mm_writew(s, addr, data);
+    case 4: return vga_mm_writel(s, addr, data);
+    default: abort();
+    }
+}
 
-static CPUWriteMemoryFunc * const vga_mm_write_ctrl[] = {
-    &vga_mm_writeb,
-    &vga_mm_writew,
-    &vga_mm_writel,
+static MemoryRegionOps vga_mm_ctrl_ops = {
+    .read = vga_mm_read_ctrl,
+    .write = vga_mm_write_ctrl,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
+#include "exec-memory.h"
+
 static void vga_mm_init(ISAVGAMMState *s, target_phys_addr_t vram_base,
                         target_phys_addr_t ctrl_base, int it_shift)
 {
-    int s_ioport_ctrl, vga_io_memory;
+    MemoryRegion *s_ioport_ctrl, *vga_io_memory;
 
     s->it_shift = it_shift;
-    s_ioport_ctrl = cpu_register_io_memory(vga_mm_read_ctrl, vga_mm_write_ctrl, s,
-                                           DEVICE_NATIVE_ENDIAN);
-    vga_io_memory = cpu_register_io_memory(vga_mem_read, vga_mem_write, s,
-                                           DEVICE_NATIVE_ENDIAN);
+    s_ioport_ctrl = qemu_malloc(sizeof(*s_ioport_ctrl));
+    memory_region_init_io(s_ioport_ctrl, &vga_mm_ctrl_ops, s,
+                          "vga-mm-ctrl", 0x100000);
+
+    vga_io_memory = qemu_malloc(sizeof(*vga_io_memory));
+    /* XXX: endianness? */
+    memory_region_init_io(vga_io_memory, &vga_mem_ops, &s->vga,
+                          "vga-mem", 0x20000);
 
     vmstate_register(NULL, 0, &vmstate_vga_common, s);
 
-    cpu_register_physical_memory(ctrl_base, 0x100000, s_ioport_ctrl);
+    memory_region_add_subregion(get_system_memory(), ctrl_base, s_ioport_ctrl);
     s->vga.bank_offset = 0;
-    cpu_register_physical_memory(vram_base + 0x000a0000, 0x20000, vga_io_memory);
-    qemu_register_coalesced_mmio(vram_base + 0x000a0000, 0x20000);
+    memory_region_add_subregion(get_system_memory(),
+                                vram_base + 0x000a0000, vga_io_memory);
+    memory_region_set_coalescing(vga_io_memory);
 }
 
 int isa_vga_mm_init(target_phys_addr_t vram_base,
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index 245841f..518cecc 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -42,17 +42,20 @@ static void vga_reset_isa(DeviceState *dev)
     vga_common_reset(s);
 }
 
+#include "exec-memory.h"
+
 static int vga_initfn(ISADevice *dev)
 {
     ISAVGAState *d = DO_UPCAST(ISAVGAState, dev, dev);
     VGACommonState *s = &d->state;
-    int vga_io_memory;
+    MemoryRegion *vga_io_memory;
 
     vga_common_init(s, VGA_RAM_SIZE);
     vga_io_memory = vga_init_io(s);
-    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
-                                 vga_io_memory);
-    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
+    memory_region_add_subregion_overlap(get_system_memory(),
+                                        isa_mem_base + 0x000a0000,
+                                        vga_io_memory, 1);
+    memory_region_set_coalescing(vga_io_memory);
     isa_init_ioport(dev, 0x3c0);
     isa_init_ioport(dev, 0x3b4);
     isa_init_ioport(dev, 0x3ba);
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index 481f448..7062c4d 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -47,29 +47,6 @@ static const VMStateDescription vmstate_vga_pci = {
     }
 };
 
-static void vga_map(PCIDevice *pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
-{
-    PCIVGAState *d = (PCIVGAState *)pci_dev;
-    VGACommonState *s = &d->vga;
-
-    cpu_register_physical_memory(addr, s->vram_size, s->vram_offset);
-    s->map_addr = addr;
-    s->map_end = addr + s->vram_size;
-    vga_dirty_log_start(s);
-}
-
-static void pci_vga_write_config(PCIDevice *d,
-                                 uint32_t address, uint32_t val, int len)
-{
-    PCIVGAState *pvs = container_of(d, PCIVGAState, dev);
-    VGACommonState *s = &pvs->vga;
-
-    pci_default_write_config(d, address, val, len);
-    if (s->map_addr && pvs->dev.io_regions[0].addr == -1)
-        s->map_addr = 0;
-}
-
 static int pci_vga_initfn(PCIDevice *dev)
 {
      PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
@@ -83,8 +60,8 @@ static int pci_vga_initfn(PCIDevice *dev)
                                   s->screen_dump, s->text_update, s);
 
      /* XXX: VGA_RAM_SIZE must be a power of two */
-     pci_register_bar(&d->dev, 0, VGA_RAM_SIZE,
-                      PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map);
+     pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH,
+                             &s->vram);
 
      if (!dev->rom_bar) {
          /* compatibility with pc-0.13 and older */
@@ -106,7 +83,6 @@ static PCIDeviceInfo vga_info = {
     .qdev.vmsd    = &vmstate_vga_pci,
     .no_hotplug   = 1,
     .init         = pci_vga_initfn,
-    .config_write = pci_vga_write_config,
     .romfile      = "vgabios-stdvga.bin",
 
     /* dummy VGA (same as Bochs ID) */
diff --git a/hw/vga.c b/hw/vga.c
index 0f54734..b969e9f 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -825,7 +825,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
             printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
 #endif
             s->plane_updated |= mask; /* only used to detect font change */
-            cpu_physical_memory_set_dirty(s->vram_offset + addr);
+            memory_region_set_dirty(&s->vram, addr);
         }
     } else if (s->gr[5] & 0x10) {
         /* odd/even mode (aka text mode mapping) */
@@ -838,7 +838,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
             printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
 #endif
             s->plane_updated |= mask; /* only used to detect font change */
-            cpu_physical_memory_set_dirty(s->vram_offset + addr);
+            memory_region_set_dirty(&s->vram, addr);
         }
     } else {
         /* standard VGA latched access */
@@ -912,7 +912,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
         printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n",
                addr * 4, write_mask, val);
 #endif
-        cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2));
+        memory_region_set_dirty(&s->vram, addr << 2);
     }
 }
 
@@ -1553,57 +1553,17 @@ void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
 
 static void vga_sync_dirty_bitmap(VGACommonState *s)
 {
-    if (s->map_addr)
-        cpu_physical_sync_dirty_bitmap(s->map_addr, s->map_end);
-
-    if (s->lfb_vram_mapped) {
-        cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa0000, 0xa8000);
-        cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa8000, 0xb0000);
-    }
-
-#ifdef CONFIG_BOCHS_VBE
-    if (s->vbe_mapped) {
-        cpu_physical_sync_dirty_bitmap(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
-                                       VBE_DISPI_LFB_PHYSICAL_ADDRESS + s->vram_size);
-    }
-#endif
-
+    memory_region_sync_dirty_bitmap(&s->vram);
 }
 
 void vga_dirty_log_start(VGACommonState *s)
 {
-    if (s->map_addr) {
-        cpu_physical_log_start(s->map_addr, s->map_end - s->map_addr);
-    }
-
-    if (s->lfb_vram_mapped) {
-        cpu_physical_log_start(isa_mem_base + 0xa0000, 0x8000);
-        cpu_physical_log_start(isa_mem_base + 0xa8000, 0x8000);
-    }
-
-#ifdef CONFIG_BOCHS_VBE
-    if (s->vbe_mapped) {
-        cpu_physical_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size);
-    }
-#endif
+    memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
 }
 
 void vga_dirty_log_stop(VGACommonState *s)
 {
-    if (s->map_addr) {
-        cpu_physical_log_stop(s->map_addr, s->map_end - s->map_addr);
-    }
-
-    if (s->lfb_vram_mapped) {
-        cpu_physical_log_stop(isa_mem_base + 0xa0000, 0x8000);
-        cpu_physical_log_stop(isa_mem_base + 0xa8000, 0x8000);
-    }
-
-#ifdef CONFIG_BOCHS_VBE
-    if (s->vbe_mapped) {
-        cpu_physical_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size);
-    }
-#endif
+    memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
 }
 
 void vga_dirty_log_restart(VGACommonState *s)
@@ -1773,15 +1733,16 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
         if (!(s->cr[0x17] & 2)) {
             addr = (addr & ~0x8000) | ((y1 & 2) << 14);
         }
-        page0 = s->vram_offset + (addr & TARGET_PAGE_MASK);
-        page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK);
+        page0 = addr & TARGET_PAGE_MASK;
+        page1 = (addr + bwidth - 1) & TARGET_PAGE_MASK;
         update = full_update |
-            cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) |
-            cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG);
+            memory_region_get_dirty(&s->vram, page0, DIRTY_MEMORY_VGA) |
+            memory_region_get_dirty(&s->vram, page1, DIRTY_MEMORY_VGA);
         if ((page1 - page0) > TARGET_PAGE_SIZE) {
             /* if wide line, can use another page */
-            update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE,
-                                                    VGA_DIRTY_FLAG);
+            update |= memory_region_get_dirty(&s->vram,
+                                              page0 + TARGET_PAGE_SIZE,
+                                              DIRTY_MEMORY_VGA);
         }
         /* explicit invalidation for the hardware cursor */
         update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
@@ -1826,8 +1787,10 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     }
     /* reset modified pages */
     if (page_max >= page_min) {
-        cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE,
-                                        VGA_DIRTY_FLAG);
+        memory_region_reset_dirty(&s->vram,
+                                  page_min,
+                                  page_max + TARGET_PAGE_SIZE - page_min,
+                                  DIRTY_MEMORY_VGA);
     }
     memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
 }
@@ -1906,11 +1869,6 @@ static void vga_invalidate_display(void *opaque)
 
 void vga_common_reset(VGACommonState *s)
 {
-    s->lfb_addr = 0;
-    s->lfb_end = 0;
-    s->map_addr = 0;
-    s->map_end = 0;
-    s->lfb_vram_mapped = 0;
     s->sr_index = 0;
     memset(s->sr, '\0', sizeof(s->sr));
     s->gr_index = 0;
@@ -2141,16 +2099,36 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
     dpy_update(s->ds, 0, 0, s->last_width, height);
 }
 
-CPUReadMemoryFunc * const vga_mem_read[3] = {
-    vga_mem_readb,
-    vga_mem_readw,
-    vga_mem_readl,
-};
+static uint64_t vga_mem_read(void *opaque, target_phys_addr_t addr,
+                             unsigned size)
+{
+    VGACommonState *s = opaque;
+
+    switch (size) {
+    case 1: return vga_mem_readb(s, addr);
+    case 2: return vga_mem_readw(s, addr);
+    case 4: return vga_mem_readl(s, addr);
+    default: abort();
+    }
+}
 
-CPUWriteMemoryFunc * const vga_mem_write[3] = {
-    vga_mem_writeb,
-    vga_mem_writew,
-    vga_mem_writel,
+static void vga_mem_write(void *opaque, target_phys_addr_t addr,
+                          uint64_t data, unsigned size)
+{
+    VGACommonState *s = opaque;
+
+    switch (size) {
+    case 1: return vga_mem_writeb(s, addr, data);
+    case 2: return vga_mem_writew(s, addr, data);
+    case 4: return vga_mem_writel(s, addr, data);
+    default: abort();
+    }
+}
+
+MemoryRegionOps vga_mem_ops = {
+    .read = vga_mem_read,
+    .write = vga_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static int vga_common_post_load(void *opaque, int version_id)
@@ -2236,8 +2214,8 @@ void vga_common_init(VGACommonState *s, int vga_ram_size)
 #else
     s->is_vbe_vmstate = 0;
 #endif
-    s->vram_offset = qemu_ram_alloc(NULL, "vga.vram", vga_ram_size);
-    s->vram_ptr = qemu_get_ram_ptr(s->vram_offset);
+    memory_region_init_ram(&s->vram, NULL, "vga.vram", vga_ram_size);
+    s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
     s->vram_size = vga_ram_size;
     s->get_bpp = vga_get_bpp;
     s->get_offsets = vga_get_offsets;
@@ -2260,8 +2238,10 @@ void vga_common_init(VGACommonState *s, int vga_ram_size)
 }
 
 /* used by both ISA and PCI */
-int vga_init_io(VGACommonState *s)
+MemoryRegion *vga_init_io(VGACommonState *s)
 {
+    MemoryRegion *vga_mem;
+
     register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
 
     register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
@@ -2292,30 +2272,38 @@ int vga_init_io(VGACommonState *s)
 #endif
 #endif /* CONFIG_BOCHS_VBE */
 
-    return cpu_register_io_memory(vga_mem_read, vga_mem_write, s,
-                                  DEVICE_LITTLE_ENDIAN);
+    vga_mem = qemu_malloc(sizeof(*vga_mem));
+    memory_region_init_io(vga_mem, &vga_mem_ops, s,
+                          "vga-lowmem", 0x20000);
+
+    return vga_mem;
 }
 
+#include "exec-memory.h"
+
 void vga_init(VGACommonState *s)
 {
-    int vga_io_memory;
+    MemoryRegion *vga_io_memory;
 
     qemu_register_reset(vga_reset, s);
 
     s->bank_offset = 0;
 
     vga_io_memory = vga_init_io(s);
-    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
-                                 vga_io_memory);
-    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
+    memory_region_add_subregion_overlap(get_system_memory(),
+                                        isa_mem_base + 0x000a0000,
+                                        vga_io_memory,
+                                        1);
+    memory_region_set_coalescing(vga_io_memory);
 }
 
 void vga_init_vbe(VGACommonState *s)
 {
 #ifdef CONFIG_BOCHS_VBE
     /* XXX: use optimized standard vga accesses */
-    cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
-                                 VGA_RAM_SIZE, s->vram_offset);
+    memory_region_add_subregion(get_system_memory(),
+                                VBE_DISPI_LFB_PHYSICAL_ADDRESS,
+                                &s->vram);
     s->vbe_mapped = 1;
 #endif 
 }
diff --git a/hw/vga_int.h b/hw/vga_int.h
index d2811bd..f4e0d8d 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -23,6 +23,7 @@
  */
 
 #include <hw/hw.h>
+#include "memory.h"
 
 #define MSR_COLOR_EMULATION 0x01
 #define MSR_PAGE_SELECT     0x20
@@ -105,13 +106,8 @@ typedef void (* vga_update_retrace_info_fn)(struct VGACommonState *s);
 
 typedef struct VGACommonState {
     uint8_t *vram_ptr;
-    ram_addr_t vram_offset;
+    MemoryRegion vram;
     uint32_t vram_size;
-    uint32_t lfb_addr;
-    uint32_t lfb_end;
-    uint32_t map_addr;
-    uint32_t map_end;
-    uint32_t lfb_vram_mapped; /* whether 0xa0000 is mapped as ram */
     uint32_t latch;
     uint8_t sr_index;
     uint8_t sr[256];
@@ -134,7 +130,7 @@ typedef struct VGACommonState {
     int dac_8bit;
     uint8_t palette[768];
     int32_t bank_offset;
-    int vga_io_memory;
+    MemoryRegion *vga_io_memory;
     int (*get_bpp)(struct VGACommonState *s);
     void (*get_offsets)(struct VGACommonState *s,
                         uint32_t *pline_offset,
@@ -191,7 +187,7 @@ static inline int c6_to_8(int v)
 
 void vga_common_init(VGACommonState *s, int vga_ram_size);
 void vga_init(VGACommonState *s);
-int vga_init_io(VGACommonState *s);
+MemoryRegion *vga_init_io(VGACommonState *s);
 void vga_common_reset(VGACommonState *s);
 
 void vga_dirty_log_start(VGACommonState *s);
@@ -229,5 +225,4 @@ extern const uint8_t gr_mask[16];
 #define VGABIOS_FILENAME "vgabios.bin"
 #define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin"
 
-extern CPUReadMemoryFunc * const vga_mem_read[3];
-extern CPUWriteMemoryFunc * const vga_mem_write[3];
+extern MemoryRegionOps vga_mem_ops;
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 190b005..feb7197 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -65,10 +65,9 @@ struct vmsvga_state_s {
     int syncing;
     int fb_size;
 
-    ram_addr_t fifo_offset;
+    MemoryRegion fifo_ram;
     uint8_t *fifo_ptr;
     unsigned int fifo_size;
-    target_phys_addr_t fifo_base;
 
     union {
         uint32_t *fifo;
@@ -92,6 +91,7 @@ struct vmsvga_state_s {
 struct pci_vmsvga_state_s {
     PCIDevice card;
     struct vmsvga_state_s chip;
+    MemoryRegion io_bar;
 };
 
 #define SVGA_MAGIC		0x900000UL
@@ -789,8 +789,11 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
 #endif
         return caps;
 
-    case SVGA_REG_MEM_START:
-        return s->fifo_base;
+    case SVGA_REG_MEM_START: {
+        struct pci_vmsvga_state_s *pci_vmsvga
+            = container_of(s, struct pci_vmsvga_state_s, chip);
+        return pci_get_bar_addr(&pci_vmsvga->card, 2);
+    }
 
     case SVGA_REG_MEM_SIZE:
         return s->fifo_size;
@@ -1135,17 +1138,45 @@ static void vmsvga_vram_writel(void *opaque, target_phys_addr_t addr,
         *(uint32_t *) (s->vram_ptr + addr) = value;
 }
 
-static CPUReadMemoryFunc * const vmsvga_vram_read[] = {
-    vmsvga_vram_readb,
-    vmsvga_vram_readw,
-    vmsvga_vram_readl,
-};
+typedef struct DirectMem DirectMem;
 
-static CPUWriteMemoryFunc * const vmsvga_vram_write[] = {
-    vmsvga_vram_writeb,
-    vmsvga_vram_writew,
-    vmsvga_vram_writel,
+struct DirectMem {
+    MemoryRegion mr;
+    struct vmsvga_state_s *chip;
 };
+
+static uint64_t vmsvga_vram_read(void *opaque, target_phys_addr_t addr,
+                                 unsigned size)
+{
+    struct vmsvga_state_s *s = opaque;
+
+    switch (size) {
+    case 1: return vmsvga_vram_readb(s, addr);
+    case 2: return vmsvga_vram_readw(s, addr);
+    case 4: return vmsvga_vram_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void vmsvga_vram_read(void *opaque, target_phys_addr_t addr,
+                             unsigned size, uint64_t data)
+{
+    struct vmsvga_state_s *s = opaque;
+
+    switch (size) {
+    case 1: return vmsvga_vram_writeb(s, addr, data);
+    case 2: return vmsvga_vram_writew(s, addr, data);
+    case 4: return vmsvga_vram_writel(s, addr, data);
+    default: abort();
+    }
+}
+
+static MemoryRegionOps vmsvga_vram_io_ops = {
+    .read = vmsvga_vram_read,
+    .write = vmsvga_vram_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+}
+
 #endif
 
 static int vmsvga_post_load(void *opaque, int version_id)
@@ -1211,8 +1242,8 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
 
 
     s->fifo_size = SVGA_FIFO_SIZE;
-    s->fifo_offset = qemu_ram_alloc(NULL, "vmsvga.fifo", s->fifo_size);
-    s->fifo_ptr = qemu_get_ram_ptr(s->fifo_offset);
+    memory_region_init_ram(&s->fifo_ram, NULL, "vmsvga.fifo", s->fifo_size);
+    s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram);
 
     vga_common_init(&s->vga, vga_ram_size);
     vga_init(&s->vga);
@@ -1221,79 +1252,77 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
     vmsvga_reset(s);
 }
 
-static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num,
-                pcibus_t addr, pcibus_t size, int type)
+static uint64_t vmsvga_io_read(void *opaque, target_phys_addr_t addr,
+                               unsigned size)
 {
-    struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
-    struct vmsvga_state_s *s = &d->chip;
-
-    register_ioport_read(addr + SVGA_IO_MUL * SVGA_INDEX_PORT,
-                    1, 4, vmsvga_index_read, s);
-    register_ioport_write(addr + SVGA_IO_MUL * SVGA_INDEX_PORT,
-                    1, 4, vmsvga_index_write, s);
-    register_ioport_read(addr + SVGA_IO_MUL * SVGA_VALUE_PORT,
-                    1, 4, vmsvga_value_read, s);
-    register_ioport_write(addr + SVGA_IO_MUL * SVGA_VALUE_PORT,
-                    1, 4, vmsvga_value_write, s);
-    register_ioport_read(addr + SVGA_IO_MUL * SVGA_BIOS_PORT,
-                    1, 4, vmsvga_bios_read, s);
-    register_ioport_write(addr + SVGA_IO_MUL * SVGA_BIOS_PORT,
-                    1, 4, vmsvga_bios_write, s);
+    struct vmsvga_state_s *s = opaque;
+
+    switch (addr) {
+    case SVGA_IO_MUL * SVGA_INDEX_PORT: return vmsvga_index_read(s, addr);
+    case SVGA_IO_MUL * SVGA_VALUE_PORT: return vmsvga_value_read(s, addr);
+    case SVGA_IO_MUL * SVGA_BIOS_PORT: return vmsvga_bios_read(s, addr);
+    default: return -1u;
+    }
 }
 
-static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num,
-                pcibus_t addr, pcibus_t size, int type)
+static void vmsvga_io_write(void *opaque, target_phys_addr_t addr,
+                            uint64_t data, unsigned size)
 {
-    struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
-    struct vmsvga_state_s *s = &d->chip;
-    ram_addr_t iomemtype;
-
-#ifdef DIRECT_VRAM
-    iomemtype = cpu_register_io_memory(vmsvga_vram_read,
-                    vmsvga_vram_write, s, DEVICE_NATIVE_ENDIAN);
-#else
-    iomemtype = s->vga.vram_offset | IO_MEM_RAM;
-#endif
-    cpu_register_physical_memory(addr, s->vga.vram_size,
-                    iomemtype);
+    struct vmsvga_state_s *s = opaque;
 
-    s->vga.map_addr = addr;
-    s->vga.map_end = addr + s->vga.vram_size;
-    vga_dirty_log_restart(&s->vga);
+    switch (addr) {
+    case SVGA_IO_MUL * SVGA_INDEX_PORT:
+        return vmsvga_index_write(s, addr, data);
+    case SVGA_IO_MUL * SVGA_VALUE_PORT:
+        return vmsvga_value_write(s, addr, data);
+    case SVGA_IO_MUL * SVGA_BIOS_PORT:
+        return vmsvga_bios_write(s, addr, data);
+    }
 }
 
-static void pci_vmsvga_map_fifo(PCIDevice *pci_dev, int region_num,
-                pcibus_t addr, pcibus_t size, int type)
-{
-    struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
-    struct vmsvga_state_s *s = &d->chip;
-    ram_addr_t iomemtype;
-
-    s->fifo_base = addr;
-    iomemtype = s->fifo_offset | IO_MEM_RAM;
-    cpu_register_physical_memory(s->fifo_base, s->fifo_size,
-                    iomemtype);
-}
+static MemoryRegionOps vmsvga_io_ops = {
+    .read = vmsvga_io_read,
+    .write = vmsvga_io_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+};
 
 static int pci_vmsvga_initfn(PCIDevice *dev)
 {
     struct pci_vmsvga_state_s *s =
         DO_UPCAST(struct pci_vmsvga_state_s, card, dev);
+    MemoryRegion *iomem;
+
+#ifdef DIRECT_VRAM
+    DirectMem *directmem = qemu_malloc(sizeof(*directmem));
+
+    directmem->chip = &s->chip;
+    iomem = &directmem->mr;
+    memory_region_init_io(iomem, &vmsvga_vram_io_ops, "vmsvga", &s->chip,
+                          memory_region_size(&s->chip.vga.vram));
+#else
+    iomem = &s->chip.vga.vram;
+#endif
+
+    vga_dirty_log_restart(&s->chip.vga);
 
     s->card.config[PCI_CACHE_LINE_SIZE]	= 0x08;		/* Cache line size */
     s->card.config[PCI_LATENCY_TIMER] = 0x40;		/* Latency timer */
     s->card.config[PCI_INTERRUPT_LINE] = 0xff;		/* End */
 
-    pci_register_bar(&s->card, 0, 0x10,
-                    PCI_BASE_ADDRESS_SPACE_IO, pci_vmsvga_map_ioport);
-    pci_register_bar(&s->card, 1, VGA_RAM_SIZE,
-                    PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_mem);
-
-    pci_register_bar(&s->card, 2, SVGA_FIFO_SIZE,
-                    PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_fifo);
+    memory_region_init_io(&s->io_bar, &vmsvga_io_ops, &s->chip,
+                          "vmsvga-io", 0x10);
+    pci_register_bar_region(&s->card, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
 
     vmsvga_init(&s->chip, VGA_RAM_SIZE);
 
+    pci_register_bar_region(&s->card, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, iomem);
+    pci_register_bar_region(&s->card, 2, PCI_BASE_ADDRESS_MEM_PREFETCH,
+                            &s->chip.fifo_ram);
+
     if (!dev->rom_bar) {
         /* compatibility with pc-0.13 and older */
         vga_init_vbe(&s->chip.vga);
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 20/56] vga: convert vga and its derivatives to the memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Convert all vga memory to the memory API.  Note we need to fall back to
get_system_memory(), since the various buses don't pass the vga window
as a memory region.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/cirrus_vga.c |  345 +++++++++++++++++++++++++++++++++----------------------
 hw/qxl-render.c |    2 +-
 hw/qxl.c        |  131 ++++++++--------------
 hw/qxl.h        |    6 +-
 hw/vga-isa-mm.c |   61 +++++++---
 hw/vga-isa.c    |   11 +-
 hw/vga-pci.c    |   28 +----
 hw/vga.c        |  146 +++++++++++-------------
 hw/vga_int.h    |   15 +--
 hw/vmware_vga.c |  165 ++++++++++++++++-----------
 10 files changed, 478 insertions(+), 432 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index f39d1f8..0cd2aee 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -200,9 +200,14 @@ typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
 typedef struct CirrusVGAState {
     VGACommonState vga;
 
-    int cirrus_linear_io_addr;
-    int cirrus_linear_bitblt_io_addr;
-    int cirrus_mmio_io_addr;
+    MemoryRegion cirrus_linear_io;
+    MemoryRegion cirrus_linear_bitblt_io;
+    MemoryRegion cirrus_mmio_io;
+    MemoryRegion pci_bar;
+    bool linear_vram;  /* vga.vram mapped over cirrus_linear_io */
+    MemoryRegion low_mem_container; /* container for 0xa0000-0xc0000 */
+    MemoryRegion low_mem;           /* always mapped, overridden by: */
+    MemoryRegion *cirrus_bank[2];   /*   aliases at 0xa0000-0xb0000  */
     uint32_t cirrus_addr_mask;
     uint32_t linear_mmio_mask;
     uint8_t cirrus_shadow_gr0;
@@ -612,7 +617,7 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
 	off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
 	off_cur &= TARGET_PAGE_MASK;
 	while (off_cur < off_cur_end) {
-	    cpu_physical_memory_set_dirty(s->vga.vram_offset + off_cur);
+	    memory_region_set_dirty(&s->vga.vram, off_cur);
 	    off_cur += TARGET_PAGE_SIZE;
 	}
 	off_begin += off_pitch;
@@ -1177,12 +1182,6 @@ static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
     }
 
     if (limit > 0) {
-        /* Thinking about changing bank base? First, drop the dirty bitmap information
-         * on the current location, otherwise we lose this pointer forever */
-        if (s->vga.lfb_vram_mapped) {
-            target_phys_addr_t base_addr = isa_mem_base + 0xa0000 + bank_index * 0x8000;
-            cpu_physical_sync_dirty_bitmap(base_addr, base_addr + 0x8000);
-        }
 	s->cirrus_bank_base[bank_index] = offset;
 	s->cirrus_bank_limit[bank_index] = limit;
     } else {
@@ -1921,8 +1920,8 @@ static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
 	val <<= 1;
 	dst++;
     }
-    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset);
-    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 7);
+    memory_region_set_dirty(&s->vga.vram, offset);
+    memory_region_set_dirty(&s->vga.vram, offset + 7);
 }
 
 static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
@@ -1946,8 +1945,8 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
 	val <<= 1;
 	dst += 2;
     }
-    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset);
-    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 15);
+    memory_region_set_dirty(&s->vga.vram, offset);
+    memory_region_set_dirty(&s->vga.vram, offset + 15);
 }
 
 /***************************************
@@ -2057,8 +2056,7 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
 		mode = s->vga.gr[0x05] & 0x7;
 		if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
 		    *(s->vga.vram_ptr + bank_offset) = mem_value;
-		    cpu_physical_memory_set_dirty(s->vga.vram_offset +
-						  bank_offset);
+		    memory_region_set_dirty(&s->vga.vram, bank_offset);
 		} else {
 		    if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
 			cirrus_mem_writeb_mode4and5_8bpp(s, mode,
@@ -2099,16 +2097,37 @@ static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_
     cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
 }
 
-static CPUReadMemoryFunc * const cirrus_vga_mem_read[3] = {
-    cirrus_vga_mem_readb,
-    cirrus_vga_mem_readw,
-    cirrus_vga_mem_readl,
+static uint64_t cirrus_vga_mem_read(void *opaque,
+                                    target_phys_addr_t addr,
+                                    uint32_t size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_vga_mem_readb(s, addr);
+    case 2: return cirrus_vga_mem_readw(s, addr);
+    case 4: return cirrus_vga_mem_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void cirrus_vga_mem_write(void *opaque, target_phys_addr_t addr,
+                                 uint64_t data, unsigned size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_vga_mem_writeb(s, addr, data);
+    case 2: return cirrus_vga_mem_writew(s, addr, data);
+    case 4: return cirrus_vga_mem_writel(s, addr, data);
+    default: abort();
+    }
 };
 
-static CPUWriteMemoryFunc * const cirrus_vga_mem_write[3] = {
-    cirrus_vga_mem_writeb,
-    cirrus_vga_mem_writew,
-    cirrus_vga_mem_writel,
+static MemoryRegionOps cirrus_vga_mem_ops = {
+    .read = cirrus_vga_mem_read,
+    .write = cirrus_vga_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 /***************************************
@@ -2365,7 +2384,7 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
 	mode = s->vga.gr[0x05] & 0x7;
 	if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
 	    *(s->vga.vram_ptr + addr) = (uint8_t) val;
-	    cpu_physical_memory_set_dirty(s->vga.vram_offset + addr);
+	    memory_region_set_dirty(&s->vga.vram, addr);
 	} else {
 	    if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
 		cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
@@ -2393,17 +2412,31 @@ static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr,
 }
 
 
-static CPUReadMemoryFunc * const cirrus_linear_read[3] = {
-    cirrus_linear_readb,
-    cirrus_linear_readw,
-    cirrus_linear_readl,
-};
+static uint64_t cirrus_linear_read(void *opaque, target_phys_addr_t addr,
+                                   unsigned size)
+{
+    CirrusVGAState *s = opaque;
 
-static CPUWriteMemoryFunc * const cirrus_linear_write[3] = {
-    cirrus_linear_writeb,
-    cirrus_linear_writew,
-    cirrus_linear_writel,
-};
+    switch (size) {
+    case 1: return cirrus_linear_readb(s, addr);
+    case 2: return cirrus_linear_readw(s, addr);
+    case 4: return cirrus_linear_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void cirrus_linear_write(void *opaque, target_phys_addr_t addr,
+                                uint64_t data, unsigned size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_linear_writeb(s, addr, data);
+    case 2: return cirrus_linear_writew(s, addr, data);
+    case 4: return cirrus_linear_writel(s, addr, data);
+    default: abort();
+    }
+}
 
 /***************************************
  *
@@ -2471,67 +2504,97 @@ static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr,
     cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff);
 }
 
+static uint64_t cirrus_linear_bitblt_read(void *opaque,
+                                          target_phys_addr_t addr,
+                                          unsigned size)
+{
+    CirrusVGAState *s = opaque;
 
-static CPUReadMemoryFunc * const cirrus_linear_bitblt_read[3] = {
-    cirrus_linear_bitblt_readb,
-    cirrus_linear_bitblt_readw,
-    cirrus_linear_bitblt_readl,
+    switch (size) {
+    case 1: return cirrus_linear_bitblt_readb(s, addr);
+    case 2: return cirrus_linear_bitblt_readw(s, addr);
+    case 4: return cirrus_linear_bitblt_readl(s, addr);
+    default: abort();
+    }
 };
 
-static CPUWriteMemoryFunc * const cirrus_linear_bitblt_write[3] = {
-    cirrus_linear_bitblt_writeb,
-    cirrus_linear_bitblt_writew,
-    cirrus_linear_bitblt_writel,
+static void cirrus_linear_bitblt_write(void *opaque,
+                                       target_phys_addr_t addr,
+                                       uint64_t data,
+                                       unsigned size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_linear_bitblt_writeb(s, addr, data);
+    case 2: return cirrus_linear_bitblt_writew(s, addr, data);
+    case 4: return cirrus_linear_bitblt_writel(s, addr, data);
+    default: abort();
+    }
 };
 
-static void map_linear_vram(CirrusVGAState *s)
+static MemoryRegionOps cirrus_linear_bitblt_io_ops = {
+    .read = cirrus_linear_bitblt_read,
+    .write = cirrus_linear_bitblt_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+#include "exec-memory.h"
+
+static void unmap_bank(CirrusVGAState *s, unsigned bank)
 {
-    if (!s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) {
-        s->vga.map_addr = s->vga.lfb_addr;
-        s->vga.map_end = s->vga.lfb_end;
-        cpu_register_physical_memory_log(s->vga.map_addr,
-					 s->vga.map_end - s->vga.map_addr,
-					 s->vga.vram_offset, 0, true);
+    if (s->cirrus_bank[bank]) {
+        memory_region_del_subregion(&s->low_mem_container,
+                                    s->cirrus_bank[bank]);
+        memory_region_destroy(s->cirrus_bank[bank]);
+        qemu_free(s->cirrus_bank[bank]);
+        s->cirrus_bank[bank] = NULL;
     }
+}
 
-    if (!s->vga.map_addr)
-        return;
-
-    s->vga.lfb_vram_mapped = 0;
+static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank)
+{
+    MemoryRegion *mr;
+    static const char *names[] = { "vga.bank0", "vga.bank1" };
 
     if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)
         && !((s->vga.sr[0x07] & 0x01) == 0)
         && !((s->vga.gr[0x0B] & 0x14) == 0x14)
         && !(s->vga.gr[0x0B] & 0x02)) {
 
-        cpu_register_physical_memory_log(isa_mem_base + 0xa0000, 0x8000,
-					 (s->vga.vram_offset +
-					  s->cirrus_bank_base[0]) |
-					 IO_MEM_RAM, 0, true);
-        cpu_register_physical_memory_log(isa_mem_base + 0xa8000, 0x8000,
-					 (s->vga.vram_offset +
-					  s->cirrus_bank_base[1]) |
-					 IO_MEM_RAM, 0, true);
-
-        s->vga.lfb_vram_mapped = 1;
-    }
-    else {
-        cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
-                                     s->vga.vga_io_memory);
+        mr = qemu_malloc(sizeof(*mr));
+        memory_region_init_alias(mr, names[bank], &s->vga.vram,
+                                 s->cirrus_bank_base[bank], 0x8000);
+        memory_region_add_subregion_overlap(
+            &s->low_mem_container,
+            0x8000 * bank,
+            mr,
+            1);
+        unmap_bank(s, bank);
+        s->cirrus_bank[bank] = mr;
+    } else {
+        unmap_bank(s, bank);
     }
+}
 
-    vga_dirty_log_start(&s->vga);
+static void map_linear_vram(CirrusVGAState *s)
+{
+    if (!s->linear_vram) {
+        s->linear_vram = true;
+        memory_region_add_subregion_overlap(&s->pci_bar, 0, &s->vga.vram, 1);
+    }
+    map_linear_vram_bank(s, 0);
+    map_linear_vram_bank(s, 1);
 }
 
 static void unmap_linear_vram(CirrusVGAState *s)
 {
-    if (s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) {
-        s->vga.map_addr = s->vga.map_end = 0;
-         cpu_register_physical_memory(s->vga.lfb_addr, s->vga.vram_size,
-                                      s->cirrus_linear_io_addr);
+    if (s->linear_vram) {
+        s->linear_vram = false;
+        memory_region_del_subregion(&s->pci_bar, &s->vga.vram);
     }
-    cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
-                                 s->vga.vga_io_memory);
+    unmap_bank(s, 0);
+    unmap_bank(s, 1);
 }
 
 /* Compute the memory access functions */
@@ -2829,16 +2892,36 @@ static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr,
 }
 
 
-static CPUReadMemoryFunc * const cirrus_mmio_read[3] = {
-    cirrus_mmio_readb,
-    cirrus_mmio_readw,
-    cirrus_mmio_readl,
+static uint64_t cirrus_mmio_read(void *opaque, target_phys_addr_t addr,
+                                 unsigned size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_mmio_readb(s, addr);
+    case 2: return cirrus_mmio_readw(s, addr);
+    case 4: return cirrus_mmio_readl(s, addr);
+    default: abort();
+    }
 };
 
-static CPUWriteMemoryFunc * const cirrus_mmio_write[3] = {
-    cirrus_mmio_writeb,
-    cirrus_mmio_writew,
-    cirrus_mmio_writel,
+static void cirrus_mmio_write(void *opaque, target_phys_addr_t addr,
+                              uint64_t data, unsigned size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_mmio_writeb(s, addr, data);
+    case 2: return cirrus_mmio_writew(s, addr, data);
+    case 4: return cirrus_mmio_writel(s, addr, data);
+    default: abort();
+    }
+};
+
+static MemoryRegionOps cirrus_mmio_io_ops = {
+    .read = cirrus_mmio_read,
+    .write = cirrus_mmio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 /* load/save state */
@@ -2947,6 +3030,12 @@ static void cirrus_reset(void *opaque)
     s->cirrus_hidden_dac_data = 0;
 }
 
+static MemoryRegionOps cirrus_linear_io_ops = {
+    .read = cirrus_linear_read,
+    .write = cirrus_linear_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
 {
     int i;
@@ -2993,28 +3082,33 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
     register_ioport_read(0x3ba, 1, 1, cirrus_vga_ioport_read, s);
     register_ioport_read(0x3da, 1, 1, cirrus_vga_ioport_read, s);
 
-    s->vga.vga_io_memory = cpu_register_io_memory(cirrus_vga_mem_read,
-                                                  cirrus_vga_mem_write, s,
-                                                  DEVICE_LITTLE_ENDIAN);
-    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
-                                 s->vga.vga_io_memory);
-    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
+    memory_region_init(&s->low_mem_container,
+                       "cirrus-lowmem-container",
+                       0x20000);
+
+    memory_region_init_io(&s->low_mem, &cirrus_vga_mem_ops, s,
+                          "cirrus-low-memory", 0x20000);
+    memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem);
+    memory_region_add_subregion_overlap(get_system_memory(),
+                                        isa_mem_base + 0x000a0000,
+                                        &s->low_mem_container,
+                                        1);
+    memory_region_set_coalescing(&s->low_mem);
 
     /* I/O handler for LFB */
-    s->cirrus_linear_io_addr =
-        cpu_register_io_memory(cirrus_linear_read, cirrus_linear_write, s,
-                               DEVICE_LITTLE_ENDIAN);
+    memory_region_init_io(&s->cirrus_linear_io, &cirrus_linear_io_ops, s,
+                          "cirrus-linear-io", VGA_RAM_SIZE);
 
     /* I/O handler for LFB */
-    s->cirrus_linear_bitblt_io_addr =
-        cpu_register_io_memory(cirrus_linear_bitblt_read,
-                               cirrus_linear_bitblt_write, s,
-                               DEVICE_LITTLE_ENDIAN);
+    memory_region_init_io(&s->cirrus_linear_bitblt_io,
+                          &cirrus_linear_bitblt_io_ops,
+                          s,
+                          "cirrus-bitblt-mmio",
+                          0x400000);
 
     /* I/O handler for memory-mapped I/O */
-    s->cirrus_mmio_io_addr =
-        cpu_register_io_memory(cirrus_mmio_read, cirrus_mmio_write, s,
-                               DEVICE_LITTLE_ENDIAN);
+    memory_region_init_io(&s->cirrus_mmio_io, &cirrus_mmio_io_ops, s,
+                          "cirrus-mmio", CIRRUS_PNPMMIO_SIZE);
 
     s->real_vram_size =
         (s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024;
@@ -3060,42 +3154,6 @@ void isa_cirrus_vga_init(void)
  *
  ***************************************/
 
-static void cirrus_pci_lfb_map(PCIDevice *d, int region_num,
-			       pcibus_t addr, pcibus_t size, int type)
-{
-    CirrusVGAState *s = &DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga;
-
-    /* XXX: add byte swapping apertures */
-    cpu_register_physical_memory(addr, s->vga.vram_size,
-				 s->cirrus_linear_io_addr);
-    cpu_register_physical_memory(addr + 0x1000000, 0x400000,
-				 s->cirrus_linear_bitblt_io_addr);
-
-    s->vga.map_addr = s->vga.map_end = 0;
-    s->vga.lfb_addr = addr & TARGET_PAGE_MASK;
-    s->vga.lfb_end = ((addr + VGA_RAM_SIZE) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
-    /* account for overflow */
-    if (s->vga.lfb_end < addr + VGA_RAM_SIZE)
-        s->vga.lfb_end = addr + VGA_RAM_SIZE;
-
-    vga_dirty_log_start(&s->vga);
-}
-
-static void pci_cirrus_write_config(PCIDevice *d,
-                                    uint32_t address, uint32_t val, int len)
-{
-    PCICirrusVGAState *pvs = DO_UPCAST(PCICirrusVGAState, dev, d);
-    CirrusVGAState *s = &pvs->cirrus_vga;
-
-    pci_default_write_config(d, address, val, len);
-    if (s->vga.map_addr && d->io_regions[0].addr == PCI_BAR_UNMAPPED) {
-        s->vga.map_addr = 0;
-        s->vga.lfb_addr = 0;
-        s->vga.lfb_end = 0;
-    }
-    cirrus_update_memory_access(s);
-}
-
 static int pci_cirrus_vga_initfn(PCIDevice *dev)
 {
      PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);
@@ -3112,15 +3170,23 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
 
      /* setup PCI */
 
+    memory_region_init(&s->pci_bar, "cirrus-pci-bar0", 0x2000000);
+
+    /* XXX: add byte swapping apertures */
+    memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io);
+    memory_region_add_subregion(&s->pci_bar, 0x1000000,
+                                &s->cirrus_linear_bitblt_io);
+
+    vga_dirty_log_start(&s->vga);
+
      /* setup memory space */
      /* memory #0 LFB */
      /* memory #1 memory-mapped I/O */
      /* XXX: s->vga.vram_size must be a power of two */
-     pci_register_bar(&d->dev, 0, 0x2000000,
-                      PCI_BASE_ADDRESS_MEM_PREFETCH, cirrus_pci_lfb_map);
+     pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH,
+                             &s->pci_bar);
      if (device_id == CIRRUS_ID_CLGD5446) {
-         pci_register_bar_simple(&d->dev, 1, CIRRUS_PNPMMIO_SIZE, 0,
-                                 s->cirrus_mmio_io_addr);
+         pci_register_bar_region(&d->dev, 1, 0, &s->cirrus_mmio_io);
      }
      return 0;
 }
@@ -3138,7 +3204,6 @@ static PCIDeviceInfo cirrus_vga_info = {
     .no_hotplug   = 1,
     .init         = pci_cirrus_vga_initfn,
     .romfile      = VGABIOS_CIRRUS_FILENAME,
-    .config_write = pci_cirrus_write_config,
     .vendor_id    = PCI_VENDOR_ID_CIRRUS,
     .device_id    = CIRRUS_ID_CLGD5446,
     .class_id     = PCI_CLASS_DISPLAY_VGA,
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 1316066..4f626dc 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -86,7 +86,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
         }
         qemu_free_displaysurface(vga->ds);
 
-        qxl->guest_primary.data = qemu_get_ram_ptr(qxl->vga.vram_offset);
+        qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
         if (qxl->guest_primary.stride < 0) {
             /* spice surface is upside down -> need extra buffer to flip */
             qxl->guest_primary.stride = -qxl->guest_primary.stride;
diff --git a/hw/qxl.c b/hw/qxl.c
index 16316f2..da323f6 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -147,7 +147,7 @@ static ram_addr_t qxl_rom_size(void)
 
 static void init_qxl_rom(PCIQXLDevice *d)
 {
-    QXLRom *rom = qemu_get_ram_ptr(d->rom_offset);
+    QXLRom *rom = memory_region_get_ram_ptr(&d->rom_bar);
     QXLModes *modes = (QXLModes *)(rom + 1);
     uint32_t ram_header_size;
     uint32_t surface0_area_size;
@@ -223,39 +223,37 @@ static void init_qxl_ram(PCIQXLDevice *d)
 }
 
 /* can be called from spice server thread context */
-static void qxl_set_dirty(ram_addr_t addr, ram_addr_t end)
+static void qxl_set_dirty(MemoryRegion *mr, ram_addr_t addr, ram_addr_t end)
 {
     while (addr < end) {
-        cpu_physical_memory_set_dirty(addr);
+        memory_region_set_dirty(mr, addr);
         addr += TARGET_PAGE_SIZE;
     }
 }
 
 static void qxl_rom_set_dirty(PCIQXLDevice *qxl)
 {
-    ram_addr_t addr = qxl->rom_offset;
-    qxl_set_dirty(addr, addr + qxl->rom_size);
+    qxl_set_dirty(&qxl->rom_bar, 0, qxl->rom_size);
 }
 
 /* called from spice server thread context only */
 static void qxl_ram_set_dirty(PCIQXLDevice *qxl, void *ptr)
 {
-    ram_addr_t addr = qxl->vga.vram_offset;
     void *base = qxl->vga.vram_ptr;
     intptr_t offset;
 
     offset = ptr - base;
     offset &= ~(TARGET_PAGE_SIZE-1);
     assert(offset < qxl->vga.vram_size);
-    qxl_set_dirty(addr + offset, addr + offset + TARGET_PAGE_SIZE);
+    qxl_set_dirty(&qxl->vga.vram, offset, offset + TARGET_PAGE_SIZE);
 }
 
 /* can be called from spice server thread context */
 static void qxl_ring_set_dirty(PCIQXLDevice *qxl)
 {
-    ram_addr_t addr = qxl->vga.vram_offset + qxl->shadow_rom.ram_header_offset;
-    ram_addr_t end  = qxl->vga.vram_offset + qxl->vga.vram_size;
-    qxl_set_dirty(addr, end);
+    ram_addr_t addr = qxl->shadow_rom.ram_header_offset;
+    ram_addr_t end  = qxl->vga.vram_size;
+    qxl_set_dirty(&qxl->vga.vram, addr, end);
 }
 
 /*
@@ -613,20 +611,6 @@ static void qxl_set_irq(PCIQXLDevice *d)
     qxl_ring_set_dirty(d);
 }
 
-static void qxl_write_config(PCIDevice *d, uint32_t address,
-                             uint32_t val, int len)
-{
-    PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, d);
-    VGACommonState *vga = &qxl->vga;
-
-    vga_dirty_log_stop(vga);
-    pci_default_write_config(d, address, val, len);
-    if (vga->map_addr && qxl->pci.io_regions[0].addr == -1) {
-        vga->map_addr = 0;
-    }
-    vga_dirty_log_start(vga);
-}
-
 static void qxl_check_state(PCIQXLDevice *d)
 {
     QXLRam *ram = d->ram;
@@ -752,10 +736,10 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
 
     switch (pci_region) {
     case QXL_RAM_RANGE_INDEX:
-        virt_start = (intptr_t)qemu_get_ram_ptr(d->vga.vram_offset);
+        virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vga.vram);
         break;
     case QXL_VRAM_RANGE_INDEX:
-        virt_start = (intptr_t)qemu_get_ram_ptr(d->vram_offset);
+        virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vram_bar);
         break;
     default:
         /* should not happen */
@@ -915,10 +899,11 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
     qxl_rom_set_dirty(d);
 }
 
-static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void ioport_write(void *opaque, target_phys_addr_t addr,
+                         uint64_t val, unsigned size)
 {
     PCIQXLDevice *d = opaque;
-    uint32_t io_port = addr - d->io_base;
+    uint32_t io_port = addr;
 
     switch (io_port) {
     case QXL_IO_RESET:
@@ -964,7 +949,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
         d->oom_running = 0;
         break;
     case QXL_IO_SET_MODE:
-        dprint(d, 1, "QXL_SET_MODE %d\n", val);
+        dprint(d, 1, "QXL_SET_MODE %d\n", (int)val);
         qxl_set_mode(d, val, 0);
         break;
     case QXL_IO_LOG:
@@ -1008,7 +993,8 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
-static uint32_t ioport_read(void *opaque, uint32_t addr)
+static uint64_t ioport_read(void *opaque, target_phys_addr_t addr,
+                            unsigned size)
 {
     PCIQXLDevice *d = opaque;
 
@@ -1016,42 +1002,14 @@ static uint32_t ioport_read(void *opaque, uint32_t addr)
     return 0xff;
 }
 
-static void qxl_map(PCIDevice *pci, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
-{
-    static const char *names[] = {
-        [ QXL_IO_RANGE_INDEX ]   = "ioports",
-        [ QXL_RAM_RANGE_INDEX ]  = "devram",
-        [ QXL_ROM_RANGE_INDEX ]  = "rom",
-        [ QXL_VRAM_RANGE_INDEX ] = "vram",
-    };
-    PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, pci);
-
-    dprint(qxl, 1, "%s: bar %d [%s] addr 0x%lx size 0x%lx\n", __FUNCTION__,
-            region_num, names[region_num], addr, size);
-
-    switch (region_num) {
-    case QXL_IO_RANGE_INDEX:
-        register_ioport_write(addr, size, 1, ioport_write, pci);
-        register_ioport_read(addr, size, 1, ioport_read, pci);
-        qxl->io_base = addr;
-        break;
-    case QXL_RAM_RANGE_INDEX:
-        cpu_register_physical_memory(addr, size, qxl->vga.vram_offset | IO_MEM_RAM);
-        qxl->vga.map_addr = addr;
-        qxl->vga.map_end = addr + size;
-        if (qxl->id == 0) {
-            vga_dirty_log_start(&qxl->vga);
-        }
-        break;
-    case QXL_ROM_RANGE_INDEX:
-        cpu_register_physical_memory(addr, size, qxl->rom_offset | IO_MEM_ROM);
-        break;
-    case QXL_VRAM_RANGE_INDEX:
-        cpu_register_physical_memory(addr, size, qxl->vram_offset | IO_MEM_RAM);
-        break;
-    }
-}
+static MemoryRegionOps qxl_io_ops = {
+    .read = ioport_read,
+    .write = ioport_write,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
 
 static void pipe_read(void *opaque)
 {
@@ -1170,8 +1128,7 @@ static void qxl_vm_change_state_handler(void *opaque, int running, int reason)
         /* dirty all vram (which holds surfaces) to make sure it is saved */
         /* FIXME #1: should go out during "live" stage */
         /* FIXME #2: we only need to save the areas which are actually used */
-        ram_addr_t addr = qxl->vram_offset;
-        qxl_set_dirty(addr, addr + qxl->vram_size);
+        qxl_set_dirty(&qxl->vram_bar, 0, qxl->vram_size);
     }
 }
 
@@ -1236,7 +1193,8 @@ static int qxl_init_common(PCIQXLDevice *qxl)
     pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
 
     qxl->rom_size = qxl_rom_size();
-    qxl->rom_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vrom", qxl->rom_size);
+    memory_region_init_ram(&qxl->rom_bar, &qxl->pci.qdev, "qxl.vrom",
+                           qxl->rom_size);
     init_qxl_rom(qxl);
     init_qxl_ram(qxl);
 
@@ -1247,26 +1205,32 @@ static int qxl_init_common(PCIQXLDevice *qxl)
         qxl->vram_size = 4096;
     }
     qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1);
-    qxl->vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vram", qxl->vram_size);
+    memory_region_init_ram(&qxl->vram_bar, &qxl->pci.qdev, "qxl.vram",
+                           qxl->vram_size);
 
     io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1);
     if (qxl->revision == 1) {
         io_size = 8;
     }
 
-    pci_register_bar(&qxl->pci, QXL_IO_RANGE_INDEX,
-                     io_size, PCI_BASE_ADDRESS_SPACE_IO, qxl_map);
+    memory_region_init_io(&qxl->io_bar, &qxl_io_ops, qxl,
+                          "qxl-ioports", io_size);
+    if (qxl->id == 0) {
+        vga_dirty_log_start(&qxl->vga);
+    }
+
+
+    pci_register_bar_region(&qxl->pci, QXL_IO_RANGE_INDEX,
+                            PCI_BASE_ADDRESS_SPACE_IO, &qxl->io_bar);
 
-    pci_register_bar(&qxl->pci, QXL_ROM_RANGE_INDEX,
-                     qxl->rom_size, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                     qxl_map);
+    pci_register_bar_region(&qxl->pci, QXL_ROM_RANGE_INDEX,
+                            PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->rom_bar);
 
-    pci_register_bar(&qxl->pci, QXL_RAM_RANGE_INDEX,
-                     qxl->vga.vram_size, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                     qxl_map);
+    pci_register_bar_region(&qxl->pci, QXL_RAM_RANGE_INDEX,
+                            PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vga.vram);
 
-    pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX, qxl->vram_size,
-                     PCI_BASE_ADDRESS_SPACE_MEMORY, qxl_map);
+    pci_register_bar_region(&qxl->pci, QXL_VRAM_RANGE_INDEX,
+                            PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vram_bar);
 
     qxl->ssd.qxl.base.sif = &qxl_interface.base;
     qxl->ssd.qxl.id = qxl->id;
@@ -1325,9 +1289,9 @@ static int qxl_init_secondary(PCIDevice *dev)
         ram_size = 16 * 1024 * 1024;
     }
     qxl->vga.vram_size = ram_size;
-    qxl->vga.vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vgavram",
-                                          qxl->vga.vram_size);
-    qxl->vga.vram_ptr = qemu_get_ram_ptr(qxl->vga.vram_offset);
+    memory_region_init_ram(&qxl->vga.vram, &qxl->pci.qdev, "qxl.vgavram",
+                           qxl->vga.vram_size);
+    qxl->vga.vram_ptr = memory_region_get_ram_ptr(&qxl->vga.vram);
 
     return qxl_init_common(qxl);
 }
@@ -1489,7 +1453,6 @@ static PCIDeviceInfo qxl_info_primary = {
     .qdev.vmsd    = &qxl_vmstate,
     .no_hotplug   = 1,
     .init         = qxl_init_primary,
-    .config_write = qxl_write_config,
     .romfile      = "vgabios-qxl.bin",
     .vendor_id    = REDHAT_PCI_VENDOR_ID,
     .class_id     = PCI_CLASS_DISPLAY_VGA,
diff --git a/hw/qxl.h b/hw/qxl.h
index f6c450d..987a5e7 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -72,14 +72,14 @@ typedef struct PCIQXLDevice {
     QXLRom             *rom;
     QXLModes           *modes;
     uint32_t           rom_size;
-    uint64_t           rom_offset;
+    MemoryRegion       rom_bar;
 
     /* vram pci bar */
     uint32_t           vram_size;
-    uint64_t           vram_offset;
+    MemoryRegion       vram_bar;
 
     /* io bar */
-    uint32_t           io_base;
+    MemoryRegion       io_bar;
 } PCIQXLDevice;
 
 #define PANIC_ON(x) if ((x)) {                         \
diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c
index 4954bb1..d2661ef 100644
--- a/hw/vga-isa-mm.c
+++ b/hw/vga-isa-mm.c
@@ -79,35 +79,62 @@ static void vga_mm_writel (void *opaque,
     vga_ioport_write(&s->vga, addr >> s->it_shift, value);
 }
 
-static CPUReadMemoryFunc * const vga_mm_read_ctrl[] = {
-    &vga_mm_readb,
-    &vga_mm_readw,
-    &vga_mm_readl,
-};
+static uint64_t vga_mm_read_ctrl(void *opaque, target_phys_addr_t addr,
+                                 unsigned size)
+{
+    ISAVGAMMState *s = opaque;
+
+    switch (size) {
+    case 1: return vga_mm_readb(s, addr);
+    case 2: return vga_mm_readw(s, addr);
+    case 4: return vga_mm_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void vga_mm_write_ctrl(void *opaque, target_phys_addr_t addr,
+                              uint64_t data, unsigned size)
+{
+    ISAVGAMMState *s = opaque;
+
+    switch (size) {
+    case 1: return vga_mm_writeb(s, addr, data);
+    case 2: return vga_mm_writew(s, addr, data);
+    case 4: return vga_mm_writel(s, addr, data);
+    default: abort();
+    }
+}
 
-static CPUWriteMemoryFunc * const vga_mm_write_ctrl[] = {
-    &vga_mm_writeb,
-    &vga_mm_writew,
-    &vga_mm_writel,
+static MemoryRegionOps vga_mm_ctrl_ops = {
+    .read = vga_mm_read_ctrl,
+    .write = vga_mm_write_ctrl,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
+#include "exec-memory.h"
+
 static void vga_mm_init(ISAVGAMMState *s, target_phys_addr_t vram_base,
                         target_phys_addr_t ctrl_base, int it_shift)
 {
-    int s_ioport_ctrl, vga_io_memory;
+    MemoryRegion *s_ioport_ctrl, *vga_io_memory;
 
     s->it_shift = it_shift;
-    s_ioport_ctrl = cpu_register_io_memory(vga_mm_read_ctrl, vga_mm_write_ctrl, s,
-                                           DEVICE_NATIVE_ENDIAN);
-    vga_io_memory = cpu_register_io_memory(vga_mem_read, vga_mem_write, s,
-                                           DEVICE_NATIVE_ENDIAN);
+    s_ioport_ctrl = qemu_malloc(sizeof(*s_ioport_ctrl));
+    memory_region_init_io(s_ioport_ctrl, &vga_mm_ctrl_ops, s,
+                          "vga-mm-ctrl", 0x100000);
+
+    vga_io_memory = qemu_malloc(sizeof(*vga_io_memory));
+    /* XXX: endianness? */
+    memory_region_init_io(vga_io_memory, &vga_mem_ops, &s->vga,
+                          "vga-mem", 0x20000);
 
     vmstate_register(NULL, 0, &vmstate_vga_common, s);
 
-    cpu_register_physical_memory(ctrl_base, 0x100000, s_ioport_ctrl);
+    memory_region_add_subregion(get_system_memory(), ctrl_base, s_ioport_ctrl);
     s->vga.bank_offset = 0;
-    cpu_register_physical_memory(vram_base + 0x000a0000, 0x20000, vga_io_memory);
-    qemu_register_coalesced_mmio(vram_base + 0x000a0000, 0x20000);
+    memory_region_add_subregion(get_system_memory(),
+                                vram_base + 0x000a0000, vga_io_memory);
+    memory_region_set_coalescing(vga_io_memory);
 }
 
 int isa_vga_mm_init(target_phys_addr_t vram_base,
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index 245841f..518cecc 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -42,17 +42,20 @@ static void vga_reset_isa(DeviceState *dev)
     vga_common_reset(s);
 }
 
+#include "exec-memory.h"
+
 static int vga_initfn(ISADevice *dev)
 {
     ISAVGAState *d = DO_UPCAST(ISAVGAState, dev, dev);
     VGACommonState *s = &d->state;
-    int vga_io_memory;
+    MemoryRegion *vga_io_memory;
 
     vga_common_init(s, VGA_RAM_SIZE);
     vga_io_memory = vga_init_io(s);
-    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
-                                 vga_io_memory);
-    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
+    memory_region_add_subregion_overlap(get_system_memory(),
+                                        isa_mem_base + 0x000a0000,
+                                        vga_io_memory, 1);
+    memory_region_set_coalescing(vga_io_memory);
     isa_init_ioport(dev, 0x3c0);
     isa_init_ioport(dev, 0x3b4);
     isa_init_ioport(dev, 0x3ba);
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index 481f448..7062c4d 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -47,29 +47,6 @@ static const VMStateDescription vmstate_vga_pci = {
     }
 };
 
-static void vga_map(PCIDevice *pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
-{
-    PCIVGAState *d = (PCIVGAState *)pci_dev;
-    VGACommonState *s = &d->vga;
-
-    cpu_register_physical_memory(addr, s->vram_size, s->vram_offset);
-    s->map_addr = addr;
-    s->map_end = addr + s->vram_size;
-    vga_dirty_log_start(s);
-}
-
-static void pci_vga_write_config(PCIDevice *d,
-                                 uint32_t address, uint32_t val, int len)
-{
-    PCIVGAState *pvs = container_of(d, PCIVGAState, dev);
-    VGACommonState *s = &pvs->vga;
-
-    pci_default_write_config(d, address, val, len);
-    if (s->map_addr && pvs->dev.io_regions[0].addr == -1)
-        s->map_addr = 0;
-}
-
 static int pci_vga_initfn(PCIDevice *dev)
 {
      PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
@@ -83,8 +60,8 @@ static int pci_vga_initfn(PCIDevice *dev)
                                   s->screen_dump, s->text_update, s);
 
      /* XXX: VGA_RAM_SIZE must be a power of two */
-     pci_register_bar(&d->dev, 0, VGA_RAM_SIZE,
-                      PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map);
+     pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH,
+                             &s->vram);
 
      if (!dev->rom_bar) {
          /* compatibility with pc-0.13 and older */
@@ -106,7 +83,6 @@ static PCIDeviceInfo vga_info = {
     .qdev.vmsd    = &vmstate_vga_pci,
     .no_hotplug   = 1,
     .init         = pci_vga_initfn,
-    .config_write = pci_vga_write_config,
     .romfile      = "vgabios-stdvga.bin",
 
     /* dummy VGA (same as Bochs ID) */
diff --git a/hw/vga.c b/hw/vga.c
index 0f54734..b969e9f 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -825,7 +825,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
             printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
 #endif
             s->plane_updated |= mask; /* only used to detect font change */
-            cpu_physical_memory_set_dirty(s->vram_offset + addr);
+            memory_region_set_dirty(&s->vram, addr);
         }
     } else if (s->gr[5] & 0x10) {
         /* odd/even mode (aka text mode mapping) */
@@ -838,7 +838,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
             printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
 #endif
             s->plane_updated |= mask; /* only used to detect font change */
-            cpu_physical_memory_set_dirty(s->vram_offset + addr);
+            memory_region_set_dirty(&s->vram, addr);
         }
     } else {
         /* standard VGA latched access */
@@ -912,7 +912,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
         printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n",
                addr * 4, write_mask, val);
 #endif
-        cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2));
+        memory_region_set_dirty(&s->vram, addr << 2);
     }
 }
 
@@ -1553,57 +1553,17 @@ void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
 
 static void vga_sync_dirty_bitmap(VGACommonState *s)
 {
-    if (s->map_addr)
-        cpu_physical_sync_dirty_bitmap(s->map_addr, s->map_end);
-
-    if (s->lfb_vram_mapped) {
-        cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa0000, 0xa8000);
-        cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa8000, 0xb0000);
-    }
-
-#ifdef CONFIG_BOCHS_VBE
-    if (s->vbe_mapped) {
-        cpu_physical_sync_dirty_bitmap(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
-                                       VBE_DISPI_LFB_PHYSICAL_ADDRESS + s->vram_size);
-    }
-#endif
-
+    memory_region_sync_dirty_bitmap(&s->vram);
 }
 
 void vga_dirty_log_start(VGACommonState *s)
 {
-    if (s->map_addr) {
-        cpu_physical_log_start(s->map_addr, s->map_end - s->map_addr);
-    }
-
-    if (s->lfb_vram_mapped) {
-        cpu_physical_log_start(isa_mem_base + 0xa0000, 0x8000);
-        cpu_physical_log_start(isa_mem_base + 0xa8000, 0x8000);
-    }
-
-#ifdef CONFIG_BOCHS_VBE
-    if (s->vbe_mapped) {
-        cpu_physical_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size);
-    }
-#endif
+    memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
 }
 
 void vga_dirty_log_stop(VGACommonState *s)
 {
-    if (s->map_addr) {
-        cpu_physical_log_stop(s->map_addr, s->map_end - s->map_addr);
-    }
-
-    if (s->lfb_vram_mapped) {
-        cpu_physical_log_stop(isa_mem_base + 0xa0000, 0x8000);
-        cpu_physical_log_stop(isa_mem_base + 0xa8000, 0x8000);
-    }
-
-#ifdef CONFIG_BOCHS_VBE
-    if (s->vbe_mapped) {
-        cpu_physical_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size);
-    }
-#endif
+    memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
 }
 
 void vga_dirty_log_restart(VGACommonState *s)
@@ -1773,15 +1733,16 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
         if (!(s->cr[0x17] & 2)) {
             addr = (addr & ~0x8000) | ((y1 & 2) << 14);
         }
-        page0 = s->vram_offset + (addr & TARGET_PAGE_MASK);
-        page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK);
+        page0 = addr & TARGET_PAGE_MASK;
+        page1 = (addr + bwidth - 1) & TARGET_PAGE_MASK;
         update = full_update |
-            cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) |
-            cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG);
+            memory_region_get_dirty(&s->vram, page0, DIRTY_MEMORY_VGA) |
+            memory_region_get_dirty(&s->vram, page1, DIRTY_MEMORY_VGA);
         if ((page1 - page0) > TARGET_PAGE_SIZE) {
             /* if wide line, can use another page */
-            update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE,
-                                                    VGA_DIRTY_FLAG);
+            update |= memory_region_get_dirty(&s->vram,
+                                              page0 + TARGET_PAGE_SIZE,
+                                              DIRTY_MEMORY_VGA);
         }
         /* explicit invalidation for the hardware cursor */
         update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
@@ -1826,8 +1787,10 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     }
     /* reset modified pages */
     if (page_max >= page_min) {
-        cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE,
-                                        VGA_DIRTY_FLAG);
+        memory_region_reset_dirty(&s->vram,
+                                  page_min,
+                                  page_max + TARGET_PAGE_SIZE - page_min,
+                                  DIRTY_MEMORY_VGA);
     }
     memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
 }
@@ -1906,11 +1869,6 @@ static void vga_invalidate_display(void *opaque)
 
 void vga_common_reset(VGACommonState *s)
 {
-    s->lfb_addr = 0;
-    s->lfb_end = 0;
-    s->map_addr = 0;
-    s->map_end = 0;
-    s->lfb_vram_mapped = 0;
     s->sr_index = 0;
     memset(s->sr, '\0', sizeof(s->sr));
     s->gr_index = 0;
@@ -2141,16 +2099,36 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
     dpy_update(s->ds, 0, 0, s->last_width, height);
 }
 
-CPUReadMemoryFunc * const vga_mem_read[3] = {
-    vga_mem_readb,
-    vga_mem_readw,
-    vga_mem_readl,
-};
+static uint64_t vga_mem_read(void *opaque, target_phys_addr_t addr,
+                             unsigned size)
+{
+    VGACommonState *s = opaque;
+
+    switch (size) {
+    case 1: return vga_mem_readb(s, addr);
+    case 2: return vga_mem_readw(s, addr);
+    case 4: return vga_mem_readl(s, addr);
+    default: abort();
+    }
+}
 
-CPUWriteMemoryFunc * const vga_mem_write[3] = {
-    vga_mem_writeb,
-    vga_mem_writew,
-    vga_mem_writel,
+static void vga_mem_write(void *opaque, target_phys_addr_t addr,
+                          uint64_t data, unsigned size)
+{
+    VGACommonState *s = opaque;
+
+    switch (size) {
+    case 1: return vga_mem_writeb(s, addr, data);
+    case 2: return vga_mem_writew(s, addr, data);
+    case 4: return vga_mem_writel(s, addr, data);
+    default: abort();
+    }
+}
+
+MemoryRegionOps vga_mem_ops = {
+    .read = vga_mem_read,
+    .write = vga_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static int vga_common_post_load(void *opaque, int version_id)
@@ -2236,8 +2214,8 @@ void vga_common_init(VGACommonState *s, int vga_ram_size)
 #else
     s->is_vbe_vmstate = 0;
 #endif
-    s->vram_offset = qemu_ram_alloc(NULL, "vga.vram", vga_ram_size);
-    s->vram_ptr = qemu_get_ram_ptr(s->vram_offset);
+    memory_region_init_ram(&s->vram, NULL, "vga.vram", vga_ram_size);
+    s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
     s->vram_size = vga_ram_size;
     s->get_bpp = vga_get_bpp;
     s->get_offsets = vga_get_offsets;
@@ -2260,8 +2238,10 @@ void vga_common_init(VGACommonState *s, int vga_ram_size)
 }
 
 /* used by both ISA and PCI */
-int vga_init_io(VGACommonState *s)
+MemoryRegion *vga_init_io(VGACommonState *s)
 {
+    MemoryRegion *vga_mem;
+
     register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
 
     register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
@@ -2292,30 +2272,38 @@ int vga_init_io(VGACommonState *s)
 #endif
 #endif /* CONFIG_BOCHS_VBE */
 
-    return cpu_register_io_memory(vga_mem_read, vga_mem_write, s,
-                                  DEVICE_LITTLE_ENDIAN);
+    vga_mem = qemu_malloc(sizeof(*vga_mem));
+    memory_region_init_io(vga_mem, &vga_mem_ops, s,
+                          "vga-lowmem", 0x20000);
+
+    return vga_mem;
 }
 
+#include "exec-memory.h"
+
 void vga_init(VGACommonState *s)
 {
-    int vga_io_memory;
+    MemoryRegion *vga_io_memory;
 
     qemu_register_reset(vga_reset, s);
 
     s->bank_offset = 0;
 
     vga_io_memory = vga_init_io(s);
-    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
-                                 vga_io_memory);
-    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
+    memory_region_add_subregion_overlap(get_system_memory(),
+                                        isa_mem_base + 0x000a0000,
+                                        vga_io_memory,
+                                        1);
+    memory_region_set_coalescing(vga_io_memory);
 }
 
 void vga_init_vbe(VGACommonState *s)
 {
 #ifdef CONFIG_BOCHS_VBE
     /* XXX: use optimized standard vga accesses */
-    cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
-                                 VGA_RAM_SIZE, s->vram_offset);
+    memory_region_add_subregion(get_system_memory(),
+                                VBE_DISPI_LFB_PHYSICAL_ADDRESS,
+                                &s->vram);
     s->vbe_mapped = 1;
 #endif 
 }
diff --git a/hw/vga_int.h b/hw/vga_int.h
index d2811bd..f4e0d8d 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -23,6 +23,7 @@
  */
 
 #include <hw/hw.h>
+#include "memory.h"
 
 #define MSR_COLOR_EMULATION 0x01
 #define MSR_PAGE_SELECT     0x20
@@ -105,13 +106,8 @@ typedef void (* vga_update_retrace_info_fn)(struct VGACommonState *s);
 
 typedef struct VGACommonState {
     uint8_t *vram_ptr;
-    ram_addr_t vram_offset;
+    MemoryRegion vram;
     uint32_t vram_size;
-    uint32_t lfb_addr;
-    uint32_t lfb_end;
-    uint32_t map_addr;
-    uint32_t map_end;
-    uint32_t lfb_vram_mapped; /* whether 0xa0000 is mapped as ram */
     uint32_t latch;
     uint8_t sr_index;
     uint8_t sr[256];
@@ -134,7 +130,7 @@ typedef struct VGACommonState {
     int dac_8bit;
     uint8_t palette[768];
     int32_t bank_offset;
-    int vga_io_memory;
+    MemoryRegion *vga_io_memory;
     int (*get_bpp)(struct VGACommonState *s);
     void (*get_offsets)(struct VGACommonState *s,
                         uint32_t *pline_offset,
@@ -191,7 +187,7 @@ static inline int c6_to_8(int v)
 
 void vga_common_init(VGACommonState *s, int vga_ram_size);
 void vga_init(VGACommonState *s);
-int vga_init_io(VGACommonState *s);
+MemoryRegion *vga_init_io(VGACommonState *s);
 void vga_common_reset(VGACommonState *s);
 
 void vga_dirty_log_start(VGACommonState *s);
@@ -229,5 +225,4 @@ extern const uint8_t gr_mask[16];
 #define VGABIOS_FILENAME "vgabios.bin"
 #define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin"
 
-extern CPUReadMemoryFunc * const vga_mem_read[3];
-extern CPUWriteMemoryFunc * const vga_mem_write[3];
+extern MemoryRegionOps vga_mem_ops;
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 190b005..feb7197 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -65,10 +65,9 @@ struct vmsvga_state_s {
     int syncing;
     int fb_size;
 
-    ram_addr_t fifo_offset;
+    MemoryRegion fifo_ram;
     uint8_t *fifo_ptr;
     unsigned int fifo_size;
-    target_phys_addr_t fifo_base;
 
     union {
         uint32_t *fifo;
@@ -92,6 +91,7 @@ struct vmsvga_state_s {
 struct pci_vmsvga_state_s {
     PCIDevice card;
     struct vmsvga_state_s chip;
+    MemoryRegion io_bar;
 };
 
 #define SVGA_MAGIC		0x900000UL
@@ -789,8 +789,11 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
 #endif
         return caps;
 
-    case SVGA_REG_MEM_START:
-        return s->fifo_base;
+    case SVGA_REG_MEM_START: {
+        struct pci_vmsvga_state_s *pci_vmsvga
+            = container_of(s, struct pci_vmsvga_state_s, chip);
+        return pci_get_bar_addr(&pci_vmsvga->card, 2);
+    }
 
     case SVGA_REG_MEM_SIZE:
         return s->fifo_size;
@@ -1135,17 +1138,45 @@ static void vmsvga_vram_writel(void *opaque, target_phys_addr_t addr,
         *(uint32_t *) (s->vram_ptr + addr) = value;
 }
 
-static CPUReadMemoryFunc * const vmsvga_vram_read[] = {
-    vmsvga_vram_readb,
-    vmsvga_vram_readw,
-    vmsvga_vram_readl,
-};
+typedef struct DirectMem DirectMem;
 
-static CPUWriteMemoryFunc * const vmsvga_vram_write[] = {
-    vmsvga_vram_writeb,
-    vmsvga_vram_writew,
-    vmsvga_vram_writel,
+struct DirectMem {
+    MemoryRegion mr;
+    struct vmsvga_state_s *chip;
 };
+
+static uint64_t vmsvga_vram_read(void *opaque, target_phys_addr_t addr,
+                                 unsigned size)
+{
+    struct vmsvga_state_s *s = opaque;
+
+    switch (size) {
+    case 1: return vmsvga_vram_readb(s, addr);
+    case 2: return vmsvga_vram_readw(s, addr);
+    case 4: return vmsvga_vram_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void vmsvga_vram_read(void *opaque, target_phys_addr_t addr,
+                             unsigned size, uint64_t data)
+{
+    struct vmsvga_state_s *s = opaque;
+
+    switch (size) {
+    case 1: return vmsvga_vram_writeb(s, addr, data);
+    case 2: return vmsvga_vram_writew(s, addr, data);
+    case 4: return vmsvga_vram_writel(s, addr, data);
+    default: abort();
+    }
+}
+
+static MemoryRegionOps vmsvga_vram_io_ops = {
+    .read = vmsvga_vram_read,
+    .write = vmsvga_vram_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+}
+
 #endif
 
 static int vmsvga_post_load(void *opaque, int version_id)
@@ -1211,8 +1242,8 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
 
 
     s->fifo_size = SVGA_FIFO_SIZE;
-    s->fifo_offset = qemu_ram_alloc(NULL, "vmsvga.fifo", s->fifo_size);
-    s->fifo_ptr = qemu_get_ram_ptr(s->fifo_offset);
+    memory_region_init_ram(&s->fifo_ram, NULL, "vmsvga.fifo", s->fifo_size);
+    s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram);
 
     vga_common_init(&s->vga, vga_ram_size);
     vga_init(&s->vga);
@@ -1221,79 +1252,77 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
     vmsvga_reset(s);
 }
 
-static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num,
-                pcibus_t addr, pcibus_t size, int type)
+static uint64_t vmsvga_io_read(void *opaque, target_phys_addr_t addr,
+                               unsigned size)
 {
-    struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
-    struct vmsvga_state_s *s = &d->chip;
-
-    register_ioport_read(addr + SVGA_IO_MUL * SVGA_INDEX_PORT,
-                    1, 4, vmsvga_index_read, s);
-    register_ioport_write(addr + SVGA_IO_MUL * SVGA_INDEX_PORT,
-                    1, 4, vmsvga_index_write, s);
-    register_ioport_read(addr + SVGA_IO_MUL * SVGA_VALUE_PORT,
-                    1, 4, vmsvga_value_read, s);
-    register_ioport_write(addr + SVGA_IO_MUL * SVGA_VALUE_PORT,
-                    1, 4, vmsvga_value_write, s);
-    register_ioport_read(addr + SVGA_IO_MUL * SVGA_BIOS_PORT,
-                    1, 4, vmsvga_bios_read, s);
-    register_ioport_write(addr + SVGA_IO_MUL * SVGA_BIOS_PORT,
-                    1, 4, vmsvga_bios_write, s);
+    struct vmsvga_state_s *s = opaque;
+
+    switch (addr) {
+    case SVGA_IO_MUL * SVGA_INDEX_PORT: return vmsvga_index_read(s, addr);
+    case SVGA_IO_MUL * SVGA_VALUE_PORT: return vmsvga_value_read(s, addr);
+    case SVGA_IO_MUL * SVGA_BIOS_PORT: return vmsvga_bios_read(s, addr);
+    default: return -1u;
+    }
 }
 
-static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num,
-                pcibus_t addr, pcibus_t size, int type)
+static void vmsvga_io_write(void *opaque, target_phys_addr_t addr,
+                            uint64_t data, unsigned size)
 {
-    struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
-    struct vmsvga_state_s *s = &d->chip;
-    ram_addr_t iomemtype;
-
-#ifdef DIRECT_VRAM
-    iomemtype = cpu_register_io_memory(vmsvga_vram_read,
-                    vmsvga_vram_write, s, DEVICE_NATIVE_ENDIAN);
-#else
-    iomemtype = s->vga.vram_offset | IO_MEM_RAM;
-#endif
-    cpu_register_physical_memory(addr, s->vga.vram_size,
-                    iomemtype);
+    struct vmsvga_state_s *s = opaque;
 
-    s->vga.map_addr = addr;
-    s->vga.map_end = addr + s->vga.vram_size;
-    vga_dirty_log_restart(&s->vga);
+    switch (addr) {
+    case SVGA_IO_MUL * SVGA_INDEX_PORT:
+        return vmsvga_index_write(s, addr, data);
+    case SVGA_IO_MUL * SVGA_VALUE_PORT:
+        return vmsvga_value_write(s, addr, data);
+    case SVGA_IO_MUL * SVGA_BIOS_PORT:
+        return vmsvga_bios_write(s, addr, data);
+    }
 }
 
-static void pci_vmsvga_map_fifo(PCIDevice *pci_dev, int region_num,
-                pcibus_t addr, pcibus_t size, int type)
-{
-    struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
-    struct vmsvga_state_s *s = &d->chip;
-    ram_addr_t iomemtype;
-
-    s->fifo_base = addr;
-    iomemtype = s->fifo_offset | IO_MEM_RAM;
-    cpu_register_physical_memory(s->fifo_base, s->fifo_size,
-                    iomemtype);
-}
+static MemoryRegionOps vmsvga_io_ops = {
+    .read = vmsvga_io_read,
+    .write = vmsvga_io_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+};
 
 static int pci_vmsvga_initfn(PCIDevice *dev)
 {
     struct pci_vmsvga_state_s *s =
         DO_UPCAST(struct pci_vmsvga_state_s, card, dev);
+    MemoryRegion *iomem;
+
+#ifdef DIRECT_VRAM
+    DirectMem *directmem = qemu_malloc(sizeof(*directmem));
+
+    directmem->chip = &s->chip;
+    iomem = &directmem->mr;
+    memory_region_init_io(iomem, &vmsvga_vram_io_ops, "vmsvga", &s->chip,
+                          memory_region_size(&s->chip.vga.vram));
+#else
+    iomem = &s->chip.vga.vram;
+#endif
+
+    vga_dirty_log_restart(&s->chip.vga);
 
     s->card.config[PCI_CACHE_LINE_SIZE]	= 0x08;		/* Cache line size */
     s->card.config[PCI_LATENCY_TIMER] = 0x40;		/* Latency timer */
     s->card.config[PCI_INTERRUPT_LINE] = 0xff;		/* End */
 
-    pci_register_bar(&s->card, 0, 0x10,
-                    PCI_BASE_ADDRESS_SPACE_IO, pci_vmsvga_map_ioport);
-    pci_register_bar(&s->card, 1, VGA_RAM_SIZE,
-                    PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_mem);
-
-    pci_register_bar(&s->card, 2, SVGA_FIFO_SIZE,
-                    PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_fifo);
+    memory_region_init_io(&s->io_bar, &vmsvga_io_ops, &s->chip,
+                          "vmsvga-io", 0x10);
+    pci_register_bar_region(&s->card, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
 
     vmsvga_init(&s->chip, VGA_RAM_SIZE);
 
+    pci_register_bar_region(&s->card, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, iomem);
+    pci_register_bar_region(&s->card, 2, PCI_BASE_ADDRESS_MEM_PREFETCH,
+                            &s->chip.fifo_ram);
+
     if (!dev->rom_bar) {
         /* compatibility with pc-0.13 and older */
         vga_init_vbe(&s->chip.vga);
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 21/56] cirrus: simplify mmio BAR access functions
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Make use of the memory API's ability to satisfy multi-byte accesses via
multiple single-byte accesses.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/cirrus_vga.c |   78 +++++-------------------------------------------------
 1 files changed, 8 insertions(+), 70 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 0cd2aee..5ff0ec8 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2828,12 +2828,11 @@ static void cirrus_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
  *
  ***************************************/
 
-static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t cirrus_mmio_read(void *opaque, target_phys_addr_t addr,
+                                 unsigned size)
 {
     CirrusVGAState *s = opaque;
 
-    addr &= CIRRUS_PNPMMIO_SIZE - 1;
-
     if (addr >= 0x100) {
         return cirrus_mmio_blt_read(s, addr - 0x100);
     } else {
@@ -2841,33 +2840,11 @@ static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr)
     }
 }
 
-static uint32_t cirrus_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-
-    v = cirrus_mmio_readb(opaque, addr);
-    v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
-    return v;
-}
-
-static uint32_t cirrus_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-
-    v = cirrus_mmio_readb(opaque, addr);
-    v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
-    v |= cirrus_mmio_readb(opaque, addr + 2) << 16;
-    v |= cirrus_mmio_readb(opaque, addr + 3) << 24;
-    return v;
-}
-
-static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr,
-			       uint32_t val)
+static void cirrus_mmio_write(void *opaque, target_phys_addr_t addr,
+                              uint64_t val, unsigned size)
 {
     CirrusVGAState *s = opaque;
 
-    addr &= CIRRUS_PNPMMIO_SIZE - 1;
-
     if (addr >= 0x100) {
 	cirrus_mmio_blt_write(s, addr - 0x100, val);
     } else {
@@ -2875,53 +2852,14 @@ static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static void cirrus_mmio_writew(void *opaque, target_phys_addr_t addr,
-			       uint32_t val)
-{
-    cirrus_mmio_writeb(opaque, addr, val & 0xff);
-    cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr,
-			       uint32_t val)
-{
-    cirrus_mmio_writeb(opaque, addr, val & 0xff);
-    cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-    cirrus_mmio_writeb(opaque, addr + 2, (val >> 16) & 0xff);
-    cirrus_mmio_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
-
-static uint64_t cirrus_mmio_read(void *opaque, target_phys_addr_t addr,
-                                 unsigned size)
-{
-    CirrusVGAState *s = opaque;
-
-    switch (size) {
-    case 1: return cirrus_mmio_readb(s, addr);
-    case 2: return cirrus_mmio_readw(s, addr);
-    case 4: return cirrus_mmio_readl(s, addr);
-    default: abort();
-    }
-};
-
-static void cirrus_mmio_write(void *opaque, target_phys_addr_t addr,
-                              uint64_t data, unsigned size)
-{
-    CirrusVGAState *s = opaque;
-
-    switch (size) {
-    case 1: return cirrus_mmio_writeb(s, addr, data);
-    case 2: return cirrus_mmio_writew(s, addr, data);
-    case 4: return cirrus_mmio_writel(s, addr, data);
-    default: abort();
-    }
-};
-
 static MemoryRegionOps cirrus_mmio_io_ops = {
     .read = cirrus_mmio_read,
     .write = cirrus_mmio_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
 };
 
 /* load/save state */
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 21/56] cirrus: simplify mmio BAR access functions
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Make use of the memory API's ability to satisfy multi-byte accesses via
multiple single-byte accesses.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/cirrus_vga.c |   78 +++++-------------------------------------------------
 1 files changed, 8 insertions(+), 70 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 0cd2aee..5ff0ec8 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2828,12 +2828,11 @@ static void cirrus_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
  *
  ***************************************/
 
-static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t cirrus_mmio_read(void *opaque, target_phys_addr_t addr,
+                                 unsigned size)
 {
     CirrusVGAState *s = opaque;
 
-    addr &= CIRRUS_PNPMMIO_SIZE - 1;
-
     if (addr >= 0x100) {
         return cirrus_mmio_blt_read(s, addr - 0x100);
     } else {
@@ -2841,33 +2840,11 @@ static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr)
     }
 }
 
-static uint32_t cirrus_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-
-    v = cirrus_mmio_readb(opaque, addr);
-    v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
-    return v;
-}
-
-static uint32_t cirrus_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-
-    v = cirrus_mmio_readb(opaque, addr);
-    v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
-    v |= cirrus_mmio_readb(opaque, addr + 2) << 16;
-    v |= cirrus_mmio_readb(opaque, addr + 3) << 24;
-    return v;
-}
-
-static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr,
-			       uint32_t val)
+static void cirrus_mmio_write(void *opaque, target_phys_addr_t addr,
+                              uint64_t val, unsigned size)
 {
     CirrusVGAState *s = opaque;
 
-    addr &= CIRRUS_PNPMMIO_SIZE - 1;
-
     if (addr >= 0x100) {
 	cirrus_mmio_blt_write(s, addr - 0x100, val);
     } else {
@@ -2875,53 +2852,14 @@ static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static void cirrus_mmio_writew(void *opaque, target_phys_addr_t addr,
-			       uint32_t val)
-{
-    cirrus_mmio_writeb(opaque, addr, val & 0xff);
-    cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr,
-			       uint32_t val)
-{
-    cirrus_mmio_writeb(opaque, addr, val & 0xff);
-    cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-    cirrus_mmio_writeb(opaque, addr + 2, (val >> 16) & 0xff);
-    cirrus_mmio_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
-
-static uint64_t cirrus_mmio_read(void *opaque, target_phys_addr_t addr,
-                                 unsigned size)
-{
-    CirrusVGAState *s = opaque;
-
-    switch (size) {
-    case 1: return cirrus_mmio_readb(s, addr);
-    case 2: return cirrus_mmio_readw(s, addr);
-    case 4: return cirrus_mmio_readl(s, addr);
-    default: abort();
-    }
-};
-
-static void cirrus_mmio_write(void *opaque, target_phys_addr_t addr,
-                              uint64_t data, unsigned size)
-{
-    CirrusVGAState *s = opaque;
-
-    switch (size) {
-    case 1: return cirrus_mmio_writeb(s, addr, data);
-    case 2: return cirrus_mmio_writew(s, addr, data);
-    case 4: return cirrus_mmio_writel(s, addr, data);
-    default: abort();
-    }
-};
-
 static MemoryRegionOps cirrus_mmio_io_ops = {
     .read = cirrus_mmio_read,
     .write = cirrus_mmio_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
 };
 
 /* load/save state */
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 22/56] cirrus: simplify bitblt BAR access functions
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Make use of the memory API's ability to satisfy multi-byte accesses via
multiple single-byte accesses.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/cirrus_vga.c |   81 +++++++++----------------------------------------------
 1 files changed, 13 insertions(+), 68 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 5ff0ec8..d0db28d 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2445,37 +2445,23 @@ static void cirrus_linear_write(void *opaque, target_phys_addr_t addr,
  ***************************************/
 
 
-static uint32_t cirrus_linear_bitblt_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t cirrus_linear_bitblt_read(void *opaque,
+                                          target_phys_addr_t addr,
+                                          unsigned size)
 {
+    CirrusVGAState *s = opaque;
     uint32_t ret;
 
     /* XXX handle bitblt */
+    (void)s;
     ret = 0xff;
     return ret;
 }
 
-static uint32_t cirrus_linear_bitblt_readw(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-
-    v = cirrus_linear_bitblt_readb(opaque, addr);
-    v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
-    return v;
-}
-
-static uint32_t cirrus_linear_bitblt_readl(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-
-    v = cirrus_linear_bitblt_readb(opaque, addr);
-    v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
-    v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 16;
-    v |= cirrus_linear_bitblt_readb(opaque, addr + 3) << 24;
-    return v;
-}
-
-static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr,
-				 uint32_t val)
+static void cirrus_linear_bitblt_write(void *opaque,
+                                       target_phys_addr_t addr,
+                                       uint64_t val,
+                                       unsigned size)
 {
     CirrusVGAState *s = opaque;
 
@@ -2488,55 +2474,14 @@ static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static void cirrus_linear_bitblt_writew(void *opaque, target_phys_addr_t addr,
-				 uint32_t val)
-{
-    cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
-    cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr,
-				 uint32_t val)
-{
-    cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
-    cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-    cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 16) & 0xff);
-    cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
-static uint64_t cirrus_linear_bitblt_read(void *opaque,
-                                          target_phys_addr_t addr,
-                                          unsigned size)
-{
-    CirrusVGAState *s = opaque;
-
-    switch (size) {
-    case 1: return cirrus_linear_bitblt_readb(s, addr);
-    case 2: return cirrus_linear_bitblt_readw(s, addr);
-    case 4: return cirrus_linear_bitblt_readl(s, addr);
-    default: abort();
-    }
-};
-
-static void cirrus_linear_bitblt_write(void *opaque,
-                                       target_phys_addr_t addr,
-                                       uint64_t data,
-                                       unsigned size)
-{
-    CirrusVGAState *s = opaque;
-
-    switch (size) {
-    case 1: return cirrus_linear_bitblt_writeb(s, addr, data);
-    case 2: return cirrus_linear_bitblt_writew(s, addr, data);
-    case 4: return cirrus_linear_bitblt_writel(s, addr, data);
-    default: abort();
-    }
-};
-
 static MemoryRegionOps cirrus_linear_bitblt_io_ops = {
     .read = cirrus_linear_bitblt_read,
     .write = cirrus_linear_bitblt_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
 };
 
 #include "exec-memory.h"
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 22/56] cirrus: simplify bitblt BAR access functions
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Make use of the memory API's ability to satisfy multi-byte accesses via
multiple single-byte accesses.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/cirrus_vga.c |   81 +++++++++----------------------------------------------
 1 files changed, 13 insertions(+), 68 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 5ff0ec8..d0db28d 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2445,37 +2445,23 @@ static void cirrus_linear_write(void *opaque, target_phys_addr_t addr,
  ***************************************/
 
 
-static uint32_t cirrus_linear_bitblt_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t cirrus_linear_bitblt_read(void *opaque,
+                                          target_phys_addr_t addr,
+                                          unsigned size)
 {
+    CirrusVGAState *s = opaque;
     uint32_t ret;
 
     /* XXX handle bitblt */
+    (void)s;
     ret = 0xff;
     return ret;
 }
 
-static uint32_t cirrus_linear_bitblt_readw(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-
-    v = cirrus_linear_bitblt_readb(opaque, addr);
-    v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
-    return v;
-}
-
-static uint32_t cirrus_linear_bitblt_readl(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-
-    v = cirrus_linear_bitblt_readb(opaque, addr);
-    v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
-    v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 16;
-    v |= cirrus_linear_bitblt_readb(opaque, addr + 3) << 24;
-    return v;
-}
-
-static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr,
-				 uint32_t val)
+static void cirrus_linear_bitblt_write(void *opaque,
+                                       target_phys_addr_t addr,
+                                       uint64_t val,
+                                       unsigned size)
 {
     CirrusVGAState *s = opaque;
 
@@ -2488,55 +2474,14 @@ static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static void cirrus_linear_bitblt_writew(void *opaque, target_phys_addr_t addr,
-				 uint32_t val)
-{
-    cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
-    cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr,
-				 uint32_t val)
-{
-    cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
-    cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-    cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 16) & 0xff);
-    cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
-static uint64_t cirrus_linear_bitblt_read(void *opaque,
-                                          target_phys_addr_t addr,
-                                          unsigned size)
-{
-    CirrusVGAState *s = opaque;
-
-    switch (size) {
-    case 1: return cirrus_linear_bitblt_readb(s, addr);
-    case 2: return cirrus_linear_bitblt_readw(s, addr);
-    case 4: return cirrus_linear_bitblt_readl(s, addr);
-    default: abort();
-    }
-};
-
-static void cirrus_linear_bitblt_write(void *opaque,
-                                       target_phys_addr_t addr,
-                                       uint64_t data,
-                                       unsigned size)
-{
-    CirrusVGAState *s = opaque;
-
-    switch (size) {
-    case 1: return cirrus_linear_bitblt_writeb(s, addr, data);
-    case 2: return cirrus_linear_bitblt_writew(s, addr, data);
-    case 4: return cirrus_linear_bitblt_writel(s, addr, data);
-    default: abort();
-    }
-};
-
 static MemoryRegionOps cirrus_linear_bitblt_io_ops = {
     .read = cirrus_linear_bitblt_read,
     .write = cirrus_linear_bitblt_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
 };
 
 #include "exec-memory.h"
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 23/56] cirrus: simplify vga window mmio access functions
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Make use of the memory API's ability to satisfy multi-byte accesses via
multiple single-byte accesses.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/cirrus_vga.c |   79 +++++++-----------------------------------------------
 1 files changed, 11 insertions(+), 68 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index d0db28d..d7cb69e 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -1955,7 +1955,9 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
  *
  ***************************************/
 
-static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t cirrus_vga_mem_read(void *opaque,
+                                    target_phys_addr_t addr,
+                                    uint32_t size)
 {
     CirrusVGAState *s = opaque;
     unsigned bank_index;
@@ -1966,8 +1968,6 @@ static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
 	return vga_mem_readb(s, addr);
     }
 
-    addr &= 0x1ffff;
-
     if (addr < 0x10000) {
 	/* XXX handle bitblt */
 	/* video memory */
@@ -1999,28 +1999,10 @@ static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
     return val;
 }
 
-static uint32_t cirrus_vga_mem_readw(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-
-    v = cirrus_vga_mem_readb(opaque, addr);
-    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
-    return v;
-}
-
-static uint32_t cirrus_vga_mem_readl(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-
-    v = cirrus_vga_mem_readb(opaque, addr);
-    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
-    v |= cirrus_vga_mem_readb(opaque, addr + 2) << 16;
-    v |= cirrus_vga_mem_readb(opaque, addr + 3) << 24;
-    return v;
-}
-
-static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
-                                  uint32_t mem_value)
+static void cirrus_vga_mem_write(void *opaque,
+                                 target_phys_addr_t addr,
+                                 uint64_t mem_value,
+                                 uint32_t size)
 {
     CirrusVGAState *s = opaque;
     unsigned bank_index;
@@ -2032,8 +2014,6 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
         return;
     }
 
-    addr &= 0x1ffff;
-
     if (addr < 0x10000) {
 	if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
 	    /* bitblt */
@@ -2083,51 +2063,14 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
-    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
-    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-    cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
-    cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
-static uint64_t cirrus_vga_mem_read(void *opaque,
-                                    target_phys_addr_t addr,
-                                    uint32_t size)
-{
-    CirrusVGAState *s = opaque;
-
-    switch (size) {
-    case 1: return cirrus_vga_mem_readb(s, addr);
-    case 2: return cirrus_vga_mem_readw(s, addr);
-    case 4: return cirrus_vga_mem_readl(s, addr);
-    default: abort();
-    }
-}
-
-static void cirrus_vga_mem_write(void *opaque, target_phys_addr_t addr,
-                                 uint64_t data, unsigned size)
-{
-    CirrusVGAState *s = opaque;
-
-    switch (size) {
-    case 1: return cirrus_vga_mem_writeb(s, addr, data);
-    case 2: return cirrus_vga_mem_writew(s, addr, data);
-    case 4: return cirrus_vga_mem_writel(s, addr, data);
-    default: abort();
-    }
-};
-
 static MemoryRegionOps cirrus_vga_mem_ops = {
     .read = cirrus_vga_mem_read,
     .write = cirrus_vga_mem_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
 };
 
 /***************************************
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 23/56] cirrus: simplify vga window mmio access functions
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Make use of the memory API's ability to satisfy multi-byte accesses via
multiple single-byte accesses.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/cirrus_vga.c |   79 +++++++-----------------------------------------------
 1 files changed, 11 insertions(+), 68 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index d0db28d..d7cb69e 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -1955,7 +1955,9 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
  *
  ***************************************/
 
-static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t cirrus_vga_mem_read(void *opaque,
+                                    target_phys_addr_t addr,
+                                    uint32_t size)
 {
     CirrusVGAState *s = opaque;
     unsigned bank_index;
@@ -1966,8 +1968,6 @@ static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
 	return vga_mem_readb(s, addr);
     }
 
-    addr &= 0x1ffff;
-
     if (addr < 0x10000) {
 	/* XXX handle bitblt */
 	/* video memory */
@@ -1999,28 +1999,10 @@ static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
     return val;
 }
 
-static uint32_t cirrus_vga_mem_readw(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-
-    v = cirrus_vga_mem_readb(opaque, addr);
-    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
-    return v;
-}
-
-static uint32_t cirrus_vga_mem_readl(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-
-    v = cirrus_vga_mem_readb(opaque, addr);
-    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
-    v |= cirrus_vga_mem_readb(opaque, addr + 2) << 16;
-    v |= cirrus_vga_mem_readb(opaque, addr + 3) << 24;
-    return v;
-}
-
-static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
-                                  uint32_t mem_value)
+static void cirrus_vga_mem_write(void *opaque,
+                                 target_phys_addr_t addr,
+                                 uint64_t mem_value,
+                                 uint32_t size)
 {
     CirrusVGAState *s = opaque;
     unsigned bank_index;
@@ -2032,8 +2014,6 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
         return;
     }
 
-    addr &= 0x1ffff;
-
     if (addr < 0x10000) {
 	if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
 	    /* bitblt */
@@ -2083,51 +2063,14 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
-    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
-    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-    cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
-    cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
-static uint64_t cirrus_vga_mem_read(void *opaque,
-                                    target_phys_addr_t addr,
-                                    uint32_t size)
-{
-    CirrusVGAState *s = opaque;
-
-    switch (size) {
-    case 1: return cirrus_vga_mem_readb(s, addr);
-    case 2: return cirrus_vga_mem_readw(s, addr);
-    case 4: return cirrus_vga_mem_readl(s, addr);
-    default: abort();
-    }
-}
-
-static void cirrus_vga_mem_write(void *opaque, target_phys_addr_t addr,
-                                 uint64_t data, unsigned size)
-{
-    CirrusVGAState *s = opaque;
-
-    switch (size) {
-    case 1: return cirrus_vga_mem_writeb(s, addr, data);
-    case 2: return cirrus_vga_mem_writew(s, addr, data);
-    case 4: return cirrus_vga_mem_writel(s, addr, data);
-    default: abort();
-    }
-};
-
 static MemoryRegionOps cirrus_vga_mem_ops = {
     .read = cirrus_vga_mem_read,
     .write = cirrus_vga_mem_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
 };
 
 /***************************************
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 24/56] vga: simplify vga window mmio access functions
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Make use of the memory API's ability to satisfy multi-byte accesses via
multiple single-byte accesses.

We have to keep vga_mem_{read,write}b() since they're used by cirrus.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/cirrus_vga.c |    4 +-
 hw/vga.c        |   56 +++++++-----------------------------------------------
 hw/vga_int.h    |    4 +-
 3 files changed, 12 insertions(+), 52 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index d7cb69e..615e101 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -1965,7 +1965,7 @@ static uint64_t cirrus_vga_mem_read(void *opaque,
     uint32_t val;
 
     if ((s->vga.sr[0x07] & 0x01) == 0) {
-	return vga_mem_readb(s, addr);
+        return vga_mem_readb(&s->vga, addr);
     }
 
     if (addr < 0x10000) {
@@ -2010,7 +2010,7 @@ static void cirrus_vga_mem_write(void *opaque,
     unsigned mode;
 
     if ((s->vga.sr[0x07] & 0x01) == 0) {
-	vga_mem_writeb(s, addr, mem_value);
+        vga_mem_writeb(&s->vga, addr, mem_value);
         return;
     }
 
diff --git a/hw/vga.c b/hw/vga.c
index b969e9f..16c857f 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -707,9 +707,8 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
 #endif
 
 /* called for accesses between 0xa0000 and 0xc0000 */
-uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr)
+uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr)
 {
-    VGACommonState *s = opaque;
     int memory_map_mode, plane;
     uint32_t ret;
 
@@ -763,28 +762,9 @@ uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr)
     return ret;
 }
 
-static uint32_t vga_mem_readw(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-    v = vga_mem_readb(opaque, addr);
-    v |= vga_mem_readb(opaque, addr + 1) << 8;
-    return v;
-}
-
-static uint32_t vga_mem_readl(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-    v = vga_mem_readb(opaque, addr);
-    v |= vga_mem_readb(opaque, addr + 1) << 8;
-    v |= vga_mem_readb(opaque, addr + 2) << 16;
-    v |= vga_mem_readb(opaque, addr + 3) << 24;
-    return v;
-}
-
 /* called for accesses between 0xa0000 and 0xc0000 */
-void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val)
 {
-    VGACommonState *s = opaque;
     int memory_map_mode, plane, write_mode, b, func_select, mask;
     uint32_t write_mask, bit_mask, set_mask;
 
@@ -916,20 +896,6 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
     }
 }
 
-static void vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    vga_mem_writeb(opaque, addr, val & 0xff);
-    vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    vga_mem_writeb(opaque, addr, val & 0xff);
-    vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-    vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
-    vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
 typedef void vga_draw_glyph8_func(uint8_t *d, int linesize,
                              const uint8_t *font_ptr, int h,
                              uint32_t fgcol, uint32_t bgcol);
@@ -2104,12 +2070,7 @@ static uint64_t vga_mem_read(void *opaque, target_phys_addr_t addr,
 {
     VGACommonState *s = opaque;
 
-    switch (size) {
-    case 1: return vga_mem_readb(s, addr);
-    case 2: return vga_mem_readw(s, addr);
-    case 4: return vga_mem_readl(s, addr);
-    default: abort();
-    }
+    return vga_mem_readb(s, addr);
 }
 
 static void vga_mem_write(void *opaque, target_phys_addr_t addr,
@@ -2117,18 +2078,17 @@ static void vga_mem_write(void *opaque, target_phys_addr_t addr,
 {
     VGACommonState *s = opaque;
 
-    switch (size) {
-    case 1: return vga_mem_writeb(s, addr, data);
-    case 2: return vga_mem_writew(s, addr, data);
-    case 4: return vga_mem_writel(s, addr, data);
-    default: abort();
-    }
+    return vga_mem_writeb(s, addr, data);
 }
 
 MemoryRegionOps vga_mem_ops = {
     .read = vga_mem_read,
     .write = vga_mem_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
 };
 
 static int vga_common_post_load(void *opaque, int version_id)
diff --git a/hw/vga_int.h b/hw/vga_int.h
index f4e0d8d..485a872 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -197,8 +197,8 @@ void vga_dirty_log_restart(VGACommonState *s);
 extern const VMStateDescription vmstate_vga_common;
 uint32_t vga_ioport_read(void *opaque, uint32_t addr);
 void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val);
-uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr);
-void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val);
+uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr);
+void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val);
 void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2);
 int ppm_save(const char *filename, struct DisplaySurface *ds);
 
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 24/56] vga: simplify vga window mmio access functions
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Make use of the memory API's ability to satisfy multi-byte accesses via
multiple single-byte accesses.

We have to keep vga_mem_{read,write}b() since they're used by cirrus.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/cirrus_vga.c |    4 +-
 hw/vga.c        |   56 +++++++-----------------------------------------------
 hw/vga_int.h    |    4 +-
 3 files changed, 12 insertions(+), 52 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index d7cb69e..615e101 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -1965,7 +1965,7 @@ static uint64_t cirrus_vga_mem_read(void *opaque,
     uint32_t val;
 
     if ((s->vga.sr[0x07] & 0x01) == 0) {
-	return vga_mem_readb(s, addr);
+        return vga_mem_readb(&s->vga, addr);
     }
 
     if (addr < 0x10000) {
@@ -2010,7 +2010,7 @@ static void cirrus_vga_mem_write(void *opaque,
     unsigned mode;
 
     if ((s->vga.sr[0x07] & 0x01) == 0) {
-	vga_mem_writeb(s, addr, mem_value);
+        vga_mem_writeb(&s->vga, addr, mem_value);
         return;
     }
 
diff --git a/hw/vga.c b/hw/vga.c
index b969e9f..16c857f 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -707,9 +707,8 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
 #endif
 
 /* called for accesses between 0xa0000 and 0xc0000 */
-uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr)
+uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr)
 {
-    VGACommonState *s = opaque;
     int memory_map_mode, plane;
     uint32_t ret;
 
@@ -763,28 +762,9 @@ uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr)
     return ret;
 }
 
-static uint32_t vga_mem_readw(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-    v = vga_mem_readb(opaque, addr);
-    v |= vga_mem_readb(opaque, addr + 1) << 8;
-    return v;
-}
-
-static uint32_t vga_mem_readl(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-    v = vga_mem_readb(opaque, addr);
-    v |= vga_mem_readb(opaque, addr + 1) << 8;
-    v |= vga_mem_readb(opaque, addr + 2) << 16;
-    v |= vga_mem_readb(opaque, addr + 3) << 24;
-    return v;
-}
-
 /* called for accesses between 0xa0000 and 0xc0000 */
-void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val)
 {
-    VGACommonState *s = opaque;
     int memory_map_mode, plane, write_mode, b, func_select, mask;
     uint32_t write_mask, bit_mask, set_mask;
 
@@ -916,20 +896,6 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
     }
 }
 
-static void vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    vga_mem_writeb(opaque, addr, val & 0xff);
-    vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    vga_mem_writeb(opaque, addr, val & 0xff);
-    vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-    vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
-    vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
 typedef void vga_draw_glyph8_func(uint8_t *d, int linesize,
                              const uint8_t *font_ptr, int h,
                              uint32_t fgcol, uint32_t bgcol);
@@ -2104,12 +2070,7 @@ static uint64_t vga_mem_read(void *opaque, target_phys_addr_t addr,
 {
     VGACommonState *s = opaque;
 
-    switch (size) {
-    case 1: return vga_mem_readb(s, addr);
-    case 2: return vga_mem_readw(s, addr);
-    case 4: return vga_mem_readl(s, addr);
-    default: abort();
-    }
+    return vga_mem_readb(s, addr);
 }
 
 static void vga_mem_write(void *opaque, target_phys_addr_t addr,
@@ -2117,18 +2078,17 @@ static void vga_mem_write(void *opaque, target_phys_addr_t addr,
 {
     VGACommonState *s = opaque;
 
-    switch (size) {
-    case 1: return vga_mem_writeb(s, addr, data);
-    case 2: return vga_mem_writew(s, addr, data);
-    case 4: return vga_mem_writel(s, addr, data);
-    default: abort();
-    }
+    return vga_mem_writeb(s, addr, data);
 }
 
 MemoryRegionOps vga_mem_ops = {
     .read = vga_mem_read,
     .write = vga_mem_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
 };
 
 static int vga_common_post_load(void *opaque, int version_id)
diff --git a/hw/vga_int.h b/hw/vga_int.h
index f4e0d8d..485a872 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -197,8 +197,8 @@ void vga_dirty_log_restart(VGACommonState *s);
 extern const VMStateDescription vmstate_vga_common;
 uint32_t vga_ioport_read(void *opaque, uint32_t addr);
 void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val);
-uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr);
-void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val);
+uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr);
+void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val);
 void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2);
 int ppm_save(const char *filename, struct DisplaySurface *ds);
 
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 25/56] cirrus: simplify linear framebuffer access functions
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Make use of the memory API's ability to satisfy multi-byte accesses via
multiple single-byte accesses.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/cirrus_vga.c |   74 ++++++-------------------------------------------------
 1 files changed, 8 insertions(+), 66 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 615e101..3fac365 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2249,7 +2249,8 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
  *
  ***************************************/
 
-static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t cirrus_linear_read(void *opaque, target_phys_addr_t addr,
+                                   unsigned size)
 {
     CirrusVGAState *s = opaque;
     uint32_t ret;
@@ -2277,28 +2278,8 @@ static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr)
     return ret;
 }
 
-static uint32_t cirrus_linear_readw(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-
-    v = cirrus_linear_readb(opaque, addr);
-    v |= cirrus_linear_readb(opaque, addr + 1) << 8;
-    return v;
-}
-
-static uint32_t cirrus_linear_readl(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-
-    v = cirrus_linear_readb(opaque, addr);
-    v |= cirrus_linear_readb(opaque, addr + 1) << 8;
-    v |= cirrus_linear_readb(opaque, addr + 2) << 16;
-    v |= cirrus_linear_readb(opaque, addr + 3) << 24;
-    return v;
-}
-
-static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
-				 uint32_t val)
+static void cirrus_linear_write(void *opaque, target_phys_addr_t addr,
+                                uint64_t val, unsigned size)
 {
     CirrusVGAState *s = opaque;
     unsigned mode;
@@ -2338,49 +2319,6 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static void cirrus_linear_writew(void *opaque, target_phys_addr_t addr,
-				 uint32_t val)
-{
-    cirrus_linear_writeb(opaque, addr, val & 0xff);
-    cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr,
-				 uint32_t val)
-{
-    cirrus_linear_writeb(opaque, addr, val & 0xff);
-    cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-    cirrus_linear_writeb(opaque, addr + 2, (val >> 16) & 0xff);
-    cirrus_linear_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
-
-static uint64_t cirrus_linear_read(void *opaque, target_phys_addr_t addr,
-                                   unsigned size)
-{
-    CirrusVGAState *s = opaque;
-
-    switch (size) {
-    case 1: return cirrus_linear_readb(s, addr);
-    case 2: return cirrus_linear_readw(s, addr);
-    case 4: return cirrus_linear_readl(s, addr);
-    default: abort();
-    }
-}
-
-static void cirrus_linear_write(void *opaque, target_phys_addr_t addr,
-                                uint64_t data, unsigned size)
-{
-    CirrusVGAState *s = opaque;
-
-    switch (size) {
-    case 1: return cirrus_linear_writeb(s, addr, data);
-    case 2: return cirrus_linear_writew(s, addr, data);
-    case 4: return cirrus_linear_writel(s, addr, data);
-    default: abort();
-    }
-}
-
 /***************************************
  *
  *  system to screen memory access
@@ -2860,6 +2798,10 @@ static MemoryRegionOps cirrus_linear_io_ops = {
     .read = cirrus_linear_read,
     .write = cirrus_linear_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
 };
 
 static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 25/56] cirrus: simplify linear framebuffer access functions
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Make use of the memory API's ability to satisfy multi-byte accesses via
multiple single-byte accesses.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/cirrus_vga.c |   74 ++++++-------------------------------------------------
 1 files changed, 8 insertions(+), 66 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 615e101..3fac365 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2249,7 +2249,8 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
  *
  ***************************************/
 
-static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t cirrus_linear_read(void *opaque, target_phys_addr_t addr,
+                                   unsigned size)
 {
     CirrusVGAState *s = opaque;
     uint32_t ret;
@@ -2277,28 +2278,8 @@ static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr)
     return ret;
 }
 
-static uint32_t cirrus_linear_readw(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-
-    v = cirrus_linear_readb(opaque, addr);
-    v |= cirrus_linear_readb(opaque, addr + 1) << 8;
-    return v;
-}
-
-static uint32_t cirrus_linear_readl(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v;
-
-    v = cirrus_linear_readb(opaque, addr);
-    v |= cirrus_linear_readb(opaque, addr + 1) << 8;
-    v |= cirrus_linear_readb(opaque, addr + 2) << 16;
-    v |= cirrus_linear_readb(opaque, addr + 3) << 24;
-    return v;
-}
-
-static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
-				 uint32_t val)
+static void cirrus_linear_write(void *opaque, target_phys_addr_t addr,
+                                uint64_t val, unsigned size)
 {
     CirrusVGAState *s = opaque;
     unsigned mode;
@@ -2338,49 +2319,6 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static void cirrus_linear_writew(void *opaque, target_phys_addr_t addr,
-				 uint32_t val)
-{
-    cirrus_linear_writeb(opaque, addr, val & 0xff);
-    cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr,
-				 uint32_t val)
-{
-    cirrus_linear_writeb(opaque, addr, val & 0xff);
-    cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-    cirrus_linear_writeb(opaque, addr + 2, (val >> 16) & 0xff);
-    cirrus_linear_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
-
-static uint64_t cirrus_linear_read(void *opaque, target_phys_addr_t addr,
-                                   unsigned size)
-{
-    CirrusVGAState *s = opaque;
-
-    switch (size) {
-    case 1: return cirrus_linear_readb(s, addr);
-    case 2: return cirrus_linear_readw(s, addr);
-    case 4: return cirrus_linear_readl(s, addr);
-    default: abort();
-    }
-}
-
-static void cirrus_linear_write(void *opaque, target_phys_addr_t addr,
-                                uint64_t data, unsigned size)
-{
-    CirrusVGAState *s = opaque;
-
-    switch (size) {
-    case 1: return cirrus_linear_writeb(s, addr, data);
-    case 2: return cirrus_linear_writew(s, addr, data);
-    case 4: return cirrus_linear_writel(s, addr, data);
-    default: abort();
-    }
-}
-
 /***************************************
  *
  *  system to screen memory access
@@ -2860,6 +2798,10 @@ static MemoryRegionOps cirrus_linear_io_ops = {
     .read = cirrus_linear_read,
     .write = cirrus_linear_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
 };
 
 static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 26/56] Integrate I/O memory regions into qemu
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

get_system_io() returns the root I/O memory region.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec-memory.h |    2 ++
 exec.c        |   10 ++++++++++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/exec-memory.h b/exec-memory.h
index aad21b5..3acb15f 100644
--- a/exec-memory.h
+++ b/exec-memory.h
@@ -15,6 +15,8 @@
  */
 MemoryRegion *get_system_memory(void);
 
+MemoryRegion *get_system_io(void);
+
 /* Set the root memory region.  This region is the system memory map. */
 void set_system_memory_map(MemoryRegion *mr);
 
diff --git a/exec.c b/exec.c
index f274ec9..e949c91 100644
--- a/exec.c
+++ b/exec.c
@@ -113,6 +113,7 @@ static int in_migration;
 RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list) };
 
 static MemoryRegion *system_memory;
+static MemoryRegion *system_io;
 
 #endif
 
@@ -3817,6 +3818,10 @@ static void memory_map_init(void)
     system_memory = qemu_malloc(sizeof(*system_memory));
     memory_region_init(system_memory, "system", UINT64_MAX);
     set_system_memory_map(system_memory);
+
+    system_io = qemu_malloc(sizeof(*system_io));
+    memory_region_init(system_memory, "io", 65536);
+    set_system_io_map(system_io);
 }
 
 MemoryRegion *get_system_memory(void)
@@ -3824,6 +3829,11 @@ MemoryRegion *get_system_memory(void)
     return system_memory;
 }
 
+MemoryRegion *get_system_io(void)
+{
+    return system_io;
+}
+
 #endif /* !defined(CONFIG_USER_ONLY) */
 
 /* physical memory access (slow version, mainly for debug) */
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 26/56] Integrate I/O memory regions into qemu
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

get_system_io() returns the root I/O memory region.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec-memory.h |    2 ++
 exec.c        |   10 ++++++++++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/exec-memory.h b/exec-memory.h
index aad21b5..3acb15f 100644
--- a/exec-memory.h
+++ b/exec-memory.h
@@ -15,6 +15,8 @@
  */
 MemoryRegion *get_system_memory(void);
 
+MemoryRegion *get_system_io(void);
+
 /* Set the root memory region.  This region is the system memory map. */
 void set_system_memory_map(MemoryRegion *mr);
 
diff --git a/exec.c b/exec.c
index f274ec9..e949c91 100644
--- a/exec.c
+++ b/exec.c
@@ -113,6 +113,7 @@ static int in_migration;
 RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list) };
 
 static MemoryRegion *system_memory;
+static MemoryRegion *system_io;
 
 #endif
 
@@ -3817,6 +3818,10 @@ static void memory_map_init(void)
     system_memory = qemu_malloc(sizeof(*system_memory));
     memory_region_init(system_memory, "system", UINT64_MAX);
     set_system_memory_map(system_memory);
+
+    system_io = qemu_malloc(sizeof(*system_io));
+    memory_region_init(system_memory, "io", 65536);
+    set_system_io_map(system_io);
 }
 
 MemoryRegion *get_system_memory(void)
@@ -3824,6 +3829,11 @@ MemoryRegion *get_system_memory(void)
     return system_memory;
 }
 
+MemoryRegion *get_system_io(void)
+{
+    return system_io;
+}
+
 #endif /* !defined(CONFIG_USER_ONLY) */
 
 /* physical memory access (slow version, mainly for debug) */
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 27/56] exec.c: fix initialization of system I/O memory region
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/exec.c b/exec.c
index e949c91..10ed931 100644
--- a/exec.c
+++ b/exec.c
@@ -3820,7 +3820,7 @@ static void memory_map_init(void)
     set_system_memory_map(system_memory);
 
     system_io = qemu_malloc(sizeof(*system_io));
-    memory_region_init(system_memory, "io", 65536);
+    memory_region_init(system_io, "io", 65536);
     set_system_io_map(system_io);
 }
 
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 27/56] exec.c: fix initialization of system I/O memory region
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/exec.c b/exec.c
index e949c91..10ed931 100644
--- a/exec.c
+++ b/exec.c
@@ -3820,7 +3820,7 @@ static void memory_map_init(void)
     set_system_memory_map(system_memory);
 
     system_io = qemu_malloc(sizeof(*system_io));
-    memory_region_init(system_memory, "io", 65536);
+    memory_region_init(system_io, "io", 65536);
     set_system_io_map(system_io);
 }
 
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 28/56] pci: pass I/O address space to new PCI bus
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

This lets us register BARs in the I/O address space.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/apb_pci.c       |    1 +
 hw/bonito.c        |    1 +
 hw/grackle_pci.c   |    8 ++++++--
 hw/gt64xxx.c       |    4 +++-
 hw/pc.h            |    4 +++-
 hw/pc_piix.c       |    6 +++++-
 hw/pci.c           |   18 ++++++++++++------
 hw/pci.h           |   10 +++++++---
 hw/piix_pci.c      |   14 +++++++++-----
 hw/ppc4xx_pci.c    |    1 +
 hw/ppc_mac.h       |   11 ++++++++---
 hw/ppc_newworld.c  |    4 ++--
 hw/ppc_oldworld.c  |    4 +++-
 hw/ppc_prep.c      |    2 +-
 hw/ppce500_pci.c   |    7 ++++---
 hw/prep_pci.c      |    8 ++++++--
 hw/prep_pci.h      |    4 +++-
 hw/sh_pci.c        |    4 +++-
 hw/unin_pci.c      |   16 ++++++++++++----
 hw/versatile_pci.c |    2 +-
 20 files changed, 91 insertions(+), 38 deletions(-)

diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 8b9939c..1638226 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -348,6 +348,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
     d->bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_apb_set_irq, pci_pbm_map_irq, d,
                                          get_system_memory(),
+                                         get_system_io(),
                                          0, 32);
     pci_bus_set_mem_base(d->bus, mem_base);
 
diff --git a/hw/bonito.c b/hw/bonito.c
index 5f62dda..8708e95 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -775,6 +775,7 @@ PCIBus *bonito_init(qemu_irq *pic)
     pcihost = FROM_SYSBUS(BonitoState, sysbus_from_qdev(dev));
     b = pci_register_bus(&pcihost->busdev.qdev, "pci", pci_bonito_set_irq,
                          pci_bonito_map_irq, pic, get_system_memory(),
+                         get_system_io(),
                          0x28, 32);
     pcihost->bus = b;
     qdev_init_nofail(dev);
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index da67cf9..9a823e1 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -62,7 +62,8 @@ static void pci_grackle_reset(void *opaque)
 }
 
 PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
-                         MemoryRegion *address_space)
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io)
 {
     DeviceState *dev;
     SysBusDevice *s;
@@ -75,7 +76,10 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
     d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_grackle_set_irq,
                                          pci_grackle_map_irq,
-                                         pic, address_space, 0, 4);
+                                         pic,
+                                         address_space_mem,
+                                         address_space_io,
+                                         0, 4);
 
     pci_create_simple(d->host_state.bus, 0, "grackle");
 
diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index 65e63dd..d541558 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -1093,7 +1093,9 @@ PCIBus *gt64120_register(qemu_irq *pic)
     d = FROM_SYSBUS(GT64120State, s);
     d->pci.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                   gt64120_pci_set_irq, gt64120_pci_map_irq,
-                                  pic, get_system_memory(),
+                                  pic,
+                                  get_system_memory(),
+                                  get_system_io(),
                                   PCI_DEVFN(18, 0), 4);
     d->ISD_handle = cpu_register_io_memory(gt64120_read, gt64120_write, d,
                                            DEVICE_NATIVE_ENDIAN);
diff --git a/hw/pc.h b/hw/pc.h
index a2de0fe..ec34db7 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -179,7 +179,9 @@ struct PCII440FXState;
 typedef struct PCII440FXState PCII440FXState;
 
 PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn,
-                    qemu_irq *pic, MemoryRegion *address_space,
+                    qemu_irq *pic,
+                    MemoryRegion *address_space_mem,
+                    MemoryRegion *address_space_io,
                     ram_addr_t ram_size);
 void i440fx_init_memory_mappings(PCII440FXState *d);
 
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 2b9c2b1..fb92035 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -69,6 +69,7 @@ static void ioapic_init(IsaIrqState *isa_irq_state)
 
 /* PC hardware initialisation */
 static void pc_init1(MemoryRegion *system_memory,
+                     MemoryRegion *system_io,
                      ram_addr_t ram_size,
                      const char *boot_device,
                      const char *kernel_filename,
@@ -129,7 +130,7 @@ static void pc_init1(MemoryRegion *system_memory,
 
     if (pci_enabled) {
         pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq,
-                              system_memory, ram_size);
+                              system_memory, system_io, ram_size);
     } else {
         pci_bus = NULL;
         i440fx_state = NULL;
@@ -214,6 +215,7 @@ static void pc_init_pci(ram_addr_t ram_size,
                         const char *cpu_model)
 {
     pc_init1(get_system_memory(),
+             get_system_io(),
              ram_size, boot_device,
              kernel_filename, kernel_cmdline,
              initrd_filename, cpu_model, 1, 1);
@@ -227,6 +229,7 @@ static void pc_init_pci_no_kvmclock(ram_addr_t ram_size,
                                     const char *cpu_model)
 {
     pc_init1(get_system_memory(),
+             get_system_io(),
              ram_size, boot_device,
              kernel_filename, kernel_cmdline,
              initrd_filename, cpu_model, 1, 0);
@@ -242,6 +245,7 @@ static void pc_init_isa(ram_addr_t ram_size,
     if (cpu_model == NULL)
         cpu_model = "486";
     pc_init1(get_system_memory(),
+             get_system_io(),
              ram_size, boot_device,
              kernel_filename, kernel_cmdline,
              initrd_filename, cpu_model, 0, 1);
diff --git a/hw/pci.c b/hw/pci.c
index 912f849..2659d96 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -264,13 +264,14 @@ int pci_find_domain(const PCIBus *bus)
 
 void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
                          const char *name,
-                         MemoryRegion *address_space,
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io,
                          uint8_t devfn_min)
 {
     qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
     assert(PCI_FUNC(devfn_min) == 0);
     bus->devfn_min = devfn_min;
-    bus->address_space = address_space;
+    bus->address_space = address_space_mem;
 
     /* host bridge */
     QLIST_INIT(&bus->child);
@@ -280,13 +281,16 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
 }
 
 PCIBus *pci_bus_new(DeviceState *parent, const char *name,
-                    MemoryRegion *address_space, uint8_t devfn_min)
+                    MemoryRegion *address_space_mem,
+                    MemoryRegion *address_space_io,
+                    uint8_t devfn_min)
 {
     PCIBus *bus;
 
     bus = qemu_mallocz(sizeof(*bus));
     bus->qbus.qdev_allocated = 1;
-    pci_bus_new_inplace(bus, parent, name, address_space, devfn_min);
+    pci_bus_new_inplace(bus, parent, name, address_space_mem,
+                        address_space_io, devfn_min);
     return bus;
 }
 
@@ -315,12 +319,14 @@ void pci_bus_set_mem_base(PCIBus *bus, target_phys_addr_t base)
 PCIBus *pci_register_bus(DeviceState *parent, const char *name,
                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                          void *irq_opaque,
-                         MemoryRegion *address_space,
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io,
                          uint8_t devfn_min, int nirq)
 {
     PCIBus *bus;
 
-    bus = pci_bus_new(parent, name, address_space, devfn_min);
+    bus = pci_bus_new(parent, name, address_space_mem,
+                      address_space_io, devfn_min);
     pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
     return bus;
 }
diff --git a/hw/pci.h b/hw/pci.h
index 64282ad..45b30fa 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -239,10 +239,13 @@ typedef int (*pci_hotplug_fn)(DeviceState *qdev, PCIDevice *pci_dev,
                               PCIHotplugState state);
 void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
                          const char *name,
-                         MemoryRegion *address_space,
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io,
                          uint8_t devfn_min);
 PCIBus *pci_bus_new(DeviceState *parent, const char *name,
-                    MemoryRegion *address_space, uint8_t devfn_min);
+                    MemoryRegion *address_space_mem,
+                    MemoryRegion *address_space_io,
+                    uint8_t devfn_min);
 void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                   void *irq_opaque, int nirq);
 int pci_bus_get_irq_level(PCIBus *bus, int irq_num);
@@ -250,7 +253,8 @@ void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *dev);
 PCIBus *pci_register_bus(DeviceState *parent, const char *name,
                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                          void *irq_opaque,
-                         MemoryRegion *address_space,
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io,
                          uint8_t devfn_min, int nirq);
 void pci_device_reset(PCIDevice *dev);
 void pci_bus_reset(PCIBus *bus);
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 445c6cb..2c106a4 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -242,7 +242,8 @@ static PCIBus *i440fx_common_init(const char *device_name,
                                   PCII440FXState **pi440fx_state,
                                   int *piix3_devfn,
                                   qemu_irq *pic,
-                                  MemoryRegion *address_space,
+                                  MemoryRegion *address_space_mem,
+                                  MemoryRegion *address_space_io,
                                   ram_addr_t ram_size)
 {
     DeviceState *dev;
@@ -253,8 +254,9 @@ static PCIBus *i440fx_common_init(const char *device_name,
 
     dev = qdev_create(NULL, "i440FX-pcihost");
     s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev));
-    s->address_space = address_space;
-    b = pci_bus_new(&s->busdev.qdev, NULL, s->address_space, 0);
+    s->address_space = address_space_mem;
+    b = pci_bus_new(&s->busdev.qdev, NULL, s->address_space,
+                    address_space_io, 0);
     s->bus = b;
     qdev_init_nofail(dev);
 
@@ -291,13 +293,15 @@ static PCIBus *i440fx_common_init(const char *device_name,
 }
 
 PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn,
-                    qemu_irq *pic, MemoryRegion *address_space,
+                    qemu_irq *pic,
+                    MemoryRegion *address_space_mem,
+                    MemoryRegion *address_space_io,
                     ram_addr_t ram_size)
 {
     PCIBus *b;
 
     b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic,
-                           address_space, ram_size);
+                           address_space_mem, address_space_io, ram_size);
     return b;
 }
 
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index 15c24f6..c7696b0 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -348,6 +348,7 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
                                                  ppc4xx_pci_map_irq,
                                                  pci_irqs,
                                                  get_system_memory(),
+                                                 get_system_io(),
                                                  0, 4);
 
     controller->pci_dev = pci_register_device(controller->pci_state.bus,
diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h
index 6fad20a..25a2274 100644
--- a/hw/ppc_mac.h
+++ b/hw/ppc_mac.h
@@ -55,11 +55,16 @@ qemu_irq *heathrow_pic_init(int *pmem_index,
 
 /* Grackle PCI */
 PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
-                         MemoryRegion *address_space);
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io);
 
 /* UniNorth PCI */
-PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space);
-PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space);
+PCIBus *pci_pmac_init(qemu_irq *pic,
+                      MemoryRegion *address_space_mem,
+                      MemoryRegion *address_space_io);
+PCIBus *pci_pmac_u3_init(qemu_irq *pic,
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io);
 
 /* Mac NVRAM */
 typedef struct MacIONVRAMState MacIONVRAMState;
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 2c0fae8..94a21f9 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -318,10 +318,10 @@ static void ppc_core99_init (ram_addr_t ram_size,
     pic = openpic_init(NULL, &pic_mem_index, smp_cpus, openpic_irqs, NULL);
     if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
         /* 970 gets a U3 bus */
-        pci_bus = pci_pmac_u3_init(pic, get_system_memory());
+        pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io());
         machine_arch = ARCH_MAC99_U3;
     } else {
-        pci_bus = pci_pmac_init(pic, get_system_memory());
+        pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io());
         machine_arch = ARCH_MAC99;
     }
     /* init basic PC hardware */
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 585afd6..0f99eef 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -234,7 +234,9 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
         hw_error("Only 6xx bus is supported on heathrow machine\n");
     }
     pic = heathrow_pic_init(&pic_mem_index, 1, heathrow_irqs);
-    pci_bus = pci_grackle_init(0xfec00000, pic, get_system_memory());
+    pci_bus = pci_grackle_init(0xfec00000, pic,
+                               get_system_memory(),
+                               get_system_io());
     pci_vga_init(pci_bus);
 
     escc_mem_index = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0],
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 91ebe07..38d8573 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -649,7 +649,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
         hw_error("Only 6xx bus is supported on PREP machine\n");
     }
     i8259 = i8259_init(first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
-    pci_bus = pci_prep_init(i8259, get_system_memory());
+    pci_bus = pci_prep_init(i8259, get_system_memory(), get_system_io());
     /* Hmm, prep has no pci-isa bridge ??? */
     isa_bus_new(NULL);
     isa_bus_irqs(i8259);
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 1344539..6a9f979 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -282,7 +282,8 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
     PPCE500PCIState *s;
     PCIBus *b;
     int i;
-    MemoryRegion *address_space = get_system_memory();
+    MemoryRegion *address_space_mem = get_system_memory();
+    MemoryRegion *address_space_io = get_system_io();
 
     h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
     s = DO_UPCAST(PPCE500PCIState, pci_state, h);
@@ -292,8 +293,8 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
     }
 
     b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, mpc85xx_pci_set_irq,
-                         mpc85xx_pci_map_irq, s->irq, address_space,
-                         PCI_DEVFN(0x11, 0), 4);
+                         mpc85xx_pci_map_irq, s->irq, address_space_mem,
+                         address_space_io, PCI_DEVFN(0x11, 0), 4);
     s->pci_state.bus = b;
 
     pci_create_simple(b, 0, "e500-host-bridge");
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index da02f0e..58619dd 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -110,7 +110,9 @@ static void prep_set_irq(void *opaque, int irq_num, int level)
     qemu_set_irq(pic[(irq_num & 1) ? 11 : 9] , level);
 }
 
-PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space)
+PCIBus *pci_prep_init(qemu_irq *pic,
+                      MemoryRegion *address_space_mem,
+                      MemoryRegion *address_space_io)
 {
     PREPPCIState *s;
     PCIDevice *d;
@@ -119,7 +121,9 @@ PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space)
     s = qemu_mallocz(sizeof(PREPPCIState));
     s->bus = pci_register_bus(NULL, "pci",
                               prep_set_irq, prep_map_irq, pic,
-                              address_space, 0, 4);
+                              address_space_mem,
+                              address_space_io,
+                              0, 4);
 
     pci_host_conf_register_ioport(0xcf8, s);
 
diff --git a/hw/prep_pci.h b/hw/prep_pci.h
index a27368b..b6b481a 100644
--- a/hw/prep_pci.h
+++ b/hw/prep_pci.h
@@ -4,6 +4,8 @@
 #include "qemu-common.h"
 #include "memory.h"
 
-PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space);
+PCIBus *pci_prep_init(qemu_irq *pic,
+                      MemoryRegion *address_space_mem,
+                      MemoryRegion *address_space_io);
 
 #endif
diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index 0ef93a0..cd86501 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -128,7 +128,9 @@ static int sh_pci_init_device(SysBusDevice *dev)
     }
     s->bus = pci_register_bus(&s->busdev.qdev, "pci",
                               sh_pci_set_irq, sh_pci_map_irq,
-                              s->irq, get_system_memory(),
+                              s->irq,
+                              get_system_memory(),
+                              get_system_io(),
                               PCI_DEVFN(0, 0), 4);
     s->memconfig = cpu_register_io_memory(sh_pci_reg.r, sh_pci_reg.w,
                                           s, DEVICE_NATIVE_ENDIAN);
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index b499523..f896f8c 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -201,7 +201,9 @@ static int pci_unin_internal_init_device(SysBusDevice *dev)
     return 0;
 }
 
-PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space)
+PCIBus *pci_pmac_init(qemu_irq *pic,
+                      MemoryRegion *address_space_mem,
+                      MemoryRegion *address_space_io)
 {
     DeviceState *dev;
     SysBusDevice *s;
@@ -215,7 +217,9 @@ PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space)
     d = FROM_SYSBUS(UNINState, s);
     d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_unin_set_irq, pci_unin_map_irq,
-                                         pic, address_space,
+                                         pic,
+                                         address_space_mem,
+                                         address_space_io,
                                          PCI_DEVFN(11, 0), 4);
 
 #if 0
@@ -253,7 +257,9 @@ PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space)
     return d->host_state.bus;
 }
 
-PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space)
+PCIBus *pci_pmac_u3_init(qemu_irq *pic,
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io)
 {
     DeviceState *dev;
     SysBusDevice *s;
@@ -268,7 +274,9 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space)
 
     d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_unin_set_irq, pci_unin_map_irq,
-                                         pic, address_space,
+                                         pic,
+                                         address_space_mem,
+                                         address_space_io,
                                          PCI_DEVFN(11, 0), 4);
 
     sysbus_mmio_map(s, 0, 0xf0800000);
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index 6b693df..bf7fadd 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -112,7 +112,7 @@ static int pci_vpb_init(SysBusDevice *dev)
     }
     bus = pci_register_bus(&dev->qdev, "pci",
                            pci_vpb_set_irq, pci_vpb_map_irq, s->irq,
-                           get_system_memory(),
+                           get_system_memory(), get_system_io(),
                            PCI_DEVFN(11, 0), 4);
 
     /* ??? Register memory space.  */
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 28/56] pci: pass I/O address space to new PCI bus
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

This lets us register BARs in the I/O address space.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/apb_pci.c       |    1 +
 hw/bonito.c        |    1 +
 hw/grackle_pci.c   |    8 ++++++--
 hw/gt64xxx.c       |    4 +++-
 hw/pc.h            |    4 +++-
 hw/pc_piix.c       |    6 +++++-
 hw/pci.c           |   18 ++++++++++++------
 hw/pci.h           |   10 +++++++---
 hw/piix_pci.c      |   14 +++++++++-----
 hw/ppc4xx_pci.c    |    1 +
 hw/ppc_mac.h       |   11 ++++++++---
 hw/ppc_newworld.c  |    4 ++--
 hw/ppc_oldworld.c  |    4 +++-
 hw/ppc_prep.c      |    2 +-
 hw/ppce500_pci.c   |    7 ++++---
 hw/prep_pci.c      |    8 ++++++--
 hw/prep_pci.h      |    4 +++-
 hw/sh_pci.c        |    4 +++-
 hw/unin_pci.c      |   16 ++++++++++++----
 hw/versatile_pci.c |    2 +-
 20 files changed, 91 insertions(+), 38 deletions(-)

diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 8b9939c..1638226 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -348,6 +348,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
     d->bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_apb_set_irq, pci_pbm_map_irq, d,
                                          get_system_memory(),
+                                         get_system_io(),
                                          0, 32);
     pci_bus_set_mem_base(d->bus, mem_base);
 
diff --git a/hw/bonito.c b/hw/bonito.c
index 5f62dda..8708e95 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -775,6 +775,7 @@ PCIBus *bonito_init(qemu_irq *pic)
     pcihost = FROM_SYSBUS(BonitoState, sysbus_from_qdev(dev));
     b = pci_register_bus(&pcihost->busdev.qdev, "pci", pci_bonito_set_irq,
                          pci_bonito_map_irq, pic, get_system_memory(),
+                         get_system_io(),
                          0x28, 32);
     pcihost->bus = b;
     qdev_init_nofail(dev);
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index da67cf9..9a823e1 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -62,7 +62,8 @@ static void pci_grackle_reset(void *opaque)
 }
 
 PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
-                         MemoryRegion *address_space)
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io)
 {
     DeviceState *dev;
     SysBusDevice *s;
@@ -75,7 +76,10 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
     d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_grackle_set_irq,
                                          pci_grackle_map_irq,
-                                         pic, address_space, 0, 4);
+                                         pic,
+                                         address_space_mem,
+                                         address_space_io,
+                                         0, 4);
 
     pci_create_simple(d->host_state.bus, 0, "grackle");
 
diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index 65e63dd..d541558 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -1093,7 +1093,9 @@ PCIBus *gt64120_register(qemu_irq *pic)
     d = FROM_SYSBUS(GT64120State, s);
     d->pci.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                   gt64120_pci_set_irq, gt64120_pci_map_irq,
-                                  pic, get_system_memory(),
+                                  pic,
+                                  get_system_memory(),
+                                  get_system_io(),
                                   PCI_DEVFN(18, 0), 4);
     d->ISD_handle = cpu_register_io_memory(gt64120_read, gt64120_write, d,
                                            DEVICE_NATIVE_ENDIAN);
diff --git a/hw/pc.h b/hw/pc.h
index a2de0fe..ec34db7 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -179,7 +179,9 @@ struct PCII440FXState;
 typedef struct PCII440FXState PCII440FXState;
 
 PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn,
-                    qemu_irq *pic, MemoryRegion *address_space,
+                    qemu_irq *pic,
+                    MemoryRegion *address_space_mem,
+                    MemoryRegion *address_space_io,
                     ram_addr_t ram_size);
 void i440fx_init_memory_mappings(PCII440FXState *d);
 
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 2b9c2b1..fb92035 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -69,6 +69,7 @@ static void ioapic_init(IsaIrqState *isa_irq_state)
 
 /* PC hardware initialisation */
 static void pc_init1(MemoryRegion *system_memory,
+                     MemoryRegion *system_io,
                      ram_addr_t ram_size,
                      const char *boot_device,
                      const char *kernel_filename,
@@ -129,7 +130,7 @@ static void pc_init1(MemoryRegion *system_memory,
 
     if (pci_enabled) {
         pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq,
-                              system_memory, ram_size);
+                              system_memory, system_io, ram_size);
     } else {
         pci_bus = NULL;
         i440fx_state = NULL;
@@ -214,6 +215,7 @@ static void pc_init_pci(ram_addr_t ram_size,
                         const char *cpu_model)
 {
     pc_init1(get_system_memory(),
+             get_system_io(),
              ram_size, boot_device,
              kernel_filename, kernel_cmdline,
              initrd_filename, cpu_model, 1, 1);
@@ -227,6 +229,7 @@ static void pc_init_pci_no_kvmclock(ram_addr_t ram_size,
                                     const char *cpu_model)
 {
     pc_init1(get_system_memory(),
+             get_system_io(),
              ram_size, boot_device,
              kernel_filename, kernel_cmdline,
              initrd_filename, cpu_model, 1, 0);
@@ -242,6 +245,7 @@ static void pc_init_isa(ram_addr_t ram_size,
     if (cpu_model == NULL)
         cpu_model = "486";
     pc_init1(get_system_memory(),
+             get_system_io(),
              ram_size, boot_device,
              kernel_filename, kernel_cmdline,
              initrd_filename, cpu_model, 0, 1);
diff --git a/hw/pci.c b/hw/pci.c
index 912f849..2659d96 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -264,13 +264,14 @@ int pci_find_domain(const PCIBus *bus)
 
 void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
                          const char *name,
-                         MemoryRegion *address_space,
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io,
                          uint8_t devfn_min)
 {
     qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
     assert(PCI_FUNC(devfn_min) == 0);
     bus->devfn_min = devfn_min;
-    bus->address_space = address_space;
+    bus->address_space = address_space_mem;
 
     /* host bridge */
     QLIST_INIT(&bus->child);
@@ -280,13 +281,16 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
 }
 
 PCIBus *pci_bus_new(DeviceState *parent, const char *name,
-                    MemoryRegion *address_space, uint8_t devfn_min)
+                    MemoryRegion *address_space_mem,
+                    MemoryRegion *address_space_io,
+                    uint8_t devfn_min)
 {
     PCIBus *bus;
 
     bus = qemu_mallocz(sizeof(*bus));
     bus->qbus.qdev_allocated = 1;
-    pci_bus_new_inplace(bus, parent, name, address_space, devfn_min);
+    pci_bus_new_inplace(bus, parent, name, address_space_mem,
+                        address_space_io, devfn_min);
     return bus;
 }
 
@@ -315,12 +319,14 @@ void pci_bus_set_mem_base(PCIBus *bus, target_phys_addr_t base)
 PCIBus *pci_register_bus(DeviceState *parent, const char *name,
                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                          void *irq_opaque,
-                         MemoryRegion *address_space,
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io,
                          uint8_t devfn_min, int nirq)
 {
     PCIBus *bus;
 
-    bus = pci_bus_new(parent, name, address_space, devfn_min);
+    bus = pci_bus_new(parent, name, address_space_mem,
+                      address_space_io, devfn_min);
     pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
     return bus;
 }
diff --git a/hw/pci.h b/hw/pci.h
index 64282ad..45b30fa 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -239,10 +239,13 @@ typedef int (*pci_hotplug_fn)(DeviceState *qdev, PCIDevice *pci_dev,
                               PCIHotplugState state);
 void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
                          const char *name,
-                         MemoryRegion *address_space,
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io,
                          uint8_t devfn_min);
 PCIBus *pci_bus_new(DeviceState *parent, const char *name,
-                    MemoryRegion *address_space, uint8_t devfn_min);
+                    MemoryRegion *address_space_mem,
+                    MemoryRegion *address_space_io,
+                    uint8_t devfn_min);
 void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                   void *irq_opaque, int nirq);
 int pci_bus_get_irq_level(PCIBus *bus, int irq_num);
@@ -250,7 +253,8 @@ void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *dev);
 PCIBus *pci_register_bus(DeviceState *parent, const char *name,
                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                          void *irq_opaque,
-                         MemoryRegion *address_space,
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io,
                          uint8_t devfn_min, int nirq);
 void pci_device_reset(PCIDevice *dev);
 void pci_bus_reset(PCIBus *bus);
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 445c6cb..2c106a4 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -242,7 +242,8 @@ static PCIBus *i440fx_common_init(const char *device_name,
                                   PCII440FXState **pi440fx_state,
                                   int *piix3_devfn,
                                   qemu_irq *pic,
-                                  MemoryRegion *address_space,
+                                  MemoryRegion *address_space_mem,
+                                  MemoryRegion *address_space_io,
                                   ram_addr_t ram_size)
 {
     DeviceState *dev;
@@ -253,8 +254,9 @@ static PCIBus *i440fx_common_init(const char *device_name,
 
     dev = qdev_create(NULL, "i440FX-pcihost");
     s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev));
-    s->address_space = address_space;
-    b = pci_bus_new(&s->busdev.qdev, NULL, s->address_space, 0);
+    s->address_space = address_space_mem;
+    b = pci_bus_new(&s->busdev.qdev, NULL, s->address_space,
+                    address_space_io, 0);
     s->bus = b;
     qdev_init_nofail(dev);
 
@@ -291,13 +293,15 @@ static PCIBus *i440fx_common_init(const char *device_name,
 }
 
 PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn,
-                    qemu_irq *pic, MemoryRegion *address_space,
+                    qemu_irq *pic,
+                    MemoryRegion *address_space_mem,
+                    MemoryRegion *address_space_io,
                     ram_addr_t ram_size)
 {
     PCIBus *b;
 
     b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic,
-                           address_space, ram_size);
+                           address_space_mem, address_space_io, ram_size);
     return b;
 }
 
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index 15c24f6..c7696b0 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -348,6 +348,7 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
                                                  ppc4xx_pci_map_irq,
                                                  pci_irqs,
                                                  get_system_memory(),
+                                                 get_system_io(),
                                                  0, 4);
 
     controller->pci_dev = pci_register_device(controller->pci_state.bus,
diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h
index 6fad20a..25a2274 100644
--- a/hw/ppc_mac.h
+++ b/hw/ppc_mac.h
@@ -55,11 +55,16 @@ qemu_irq *heathrow_pic_init(int *pmem_index,
 
 /* Grackle PCI */
 PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
-                         MemoryRegion *address_space);
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io);
 
 /* UniNorth PCI */
-PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space);
-PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space);
+PCIBus *pci_pmac_init(qemu_irq *pic,
+                      MemoryRegion *address_space_mem,
+                      MemoryRegion *address_space_io);
+PCIBus *pci_pmac_u3_init(qemu_irq *pic,
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io);
 
 /* Mac NVRAM */
 typedef struct MacIONVRAMState MacIONVRAMState;
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 2c0fae8..94a21f9 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -318,10 +318,10 @@ static void ppc_core99_init (ram_addr_t ram_size,
     pic = openpic_init(NULL, &pic_mem_index, smp_cpus, openpic_irqs, NULL);
     if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
         /* 970 gets a U3 bus */
-        pci_bus = pci_pmac_u3_init(pic, get_system_memory());
+        pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io());
         machine_arch = ARCH_MAC99_U3;
     } else {
-        pci_bus = pci_pmac_init(pic, get_system_memory());
+        pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io());
         machine_arch = ARCH_MAC99;
     }
     /* init basic PC hardware */
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 585afd6..0f99eef 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -234,7 +234,9 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
         hw_error("Only 6xx bus is supported on heathrow machine\n");
     }
     pic = heathrow_pic_init(&pic_mem_index, 1, heathrow_irqs);
-    pci_bus = pci_grackle_init(0xfec00000, pic, get_system_memory());
+    pci_bus = pci_grackle_init(0xfec00000, pic,
+                               get_system_memory(),
+                               get_system_io());
     pci_vga_init(pci_bus);
 
     escc_mem_index = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0],
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 91ebe07..38d8573 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -649,7 +649,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
         hw_error("Only 6xx bus is supported on PREP machine\n");
     }
     i8259 = i8259_init(first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
-    pci_bus = pci_prep_init(i8259, get_system_memory());
+    pci_bus = pci_prep_init(i8259, get_system_memory(), get_system_io());
     /* Hmm, prep has no pci-isa bridge ??? */
     isa_bus_new(NULL);
     isa_bus_irqs(i8259);
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 1344539..6a9f979 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -282,7 +282,8 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
     PPCE500PCIState *s;
     PCIBus *b;
     int i;
-    MemoryRegion *address_space = get_system_memory();
+    MemoryRegion *address_space_mem = get_system_memory();
+    MemoryRegion *address_space_io = get_system_io();
 
     h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
     s = DO_UPCAST(PPCE500PCIState, pci_state, h);
@@ -292,8 +293,8 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
     }
 
     b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, mpc85xx_pci_set_irq,
-                         mpc85xx_pci_map_irq, s->irq, address_space,
-                         PCI_DEVFN(0x11, 0), 4);
+                         mpc85xx_pci_map_irq, s->irq, address_space_mem,
+                         address_space_io, PCI_DEVFN(0x11, 0), 4);
     s->pci_state.bus = b;
 
     pci_create_simple(b, 0, "e500-host-bridge");
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index da02f0e..58619dd 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -110,7 +110,9 @@ static void prep_set_irq(void *opaque, int irq_num, int level)
     qemu_set_irq(pic[(irq_num & 1) ? 11 : 9] , level);
 }
 
-PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space)
+PCIBus *pci_prep_init(qemu_irq *pic,
+                      MemoryRegion *address_space_mem,
+                      MemoryRegion *address_space_io)
 {
     PREPPCIState *s;
     PCIDevice *d;
@@ -119,7 +121,9 @@ PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space)
     s = qemu_mallocz(sizeof(PREPPCIState));
     s->bus = pci_register_bus(NULL, "pci",
                               prep_set_irq, prep_map_irq, pic,
-                              address_space, 0, 4);
+                              address_space_mem,
+                              address_space_io,
+                              0, 4);
 
     pci_host_conf_register_ioport(0xcf8, s);
 
diff --git a/hw/prep_pci.h b/hw/prep_pci.h
index a27368b..b6b481a 100644
--- a/hw/prep_pci.h
+++ b/hw/prep_pci.h
@@ -4,6 +4,8 @@
 #include "qemu-common.h"
 #include "memory.h"
 
-PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space);
+PCIBus *pci_prep_init(qemu_irq *pic,
+                      MemoryRegion *address_space_mem,
+                      MemoryRegion *address_space_io);
 
 #endif
diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index 0ef93a0..cd86501 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -128,7 +128,9 @@ static int sh_pci_init_device(SysBusDevice *dev)
     }
     s->bus = pci_register_bus(&s->busdev.qdev, "pci",
                               sh_pci_set_irq, sh_pci_map_irq,
-                              s->irq, get_system_memory(),
+                              s->irq,
+                              get_system_memory(),
+                              get_system_io(),
                               PCI_DEVFN(0, 0), 4);
     s->memconfig = cpu_register_io_memory(sh_pci_reg.r, sh_pci_reg.w,
                                           s, DEVICE_NATIVE_ENDIAN);
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index b499523..f896f8c 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -201,7 +201,9 @@ static int pci_unin_internal_init_device(SysBusDevice *dev)
     return 0;
 }
 
-PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space)
+PCIBus *pci_pmac_init(qemu_irq *pic,
+                      MemoryRegion *address_space_mem,
+                      MemoryRegion *address_space_io)
 {
     DeviceState *dev;
     SysBusDevice *s;
@@ -215,7 +217,9 @@ PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space)
     d = FROM_SYSBUS(UNINState, s);
     d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_unin_set_irq, pci_unin_map_irq,
-                                         pic, address_space,
+                                         pic,
+                                         address_space_mem,
+                                         address_space_io,
                                          PCI_DEVFN(11, 0), 4);
 
 #if 0
@@ -253,7 +257,9 @@ PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space)
     return d->host_state.bus;
 }
 
-PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space)
+PCIBus *pci_pmac_u3_init(qemu_irq *pic,
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io)
 {
     DeviceState *dev;
     SysBusDevice *s;
@@ -268,7 +274,9 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space)
 
     d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_unin_set_irq, pci_unin_map_irq,
-                                         pic, address_space,
+                                         pic,
+                                         address_space_mem,
+                                         address_space_io,
                                          PCI_DEVFN(11, 0), 4);
 
     sysbus_mmio_map(s, 0, 0xf0800000);
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index 6b693df..bf7fadd 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -112,7 +112,7 @@ static int pci_vpb_init(SysBusDevice *dev)
     }
     bus = pci_register_bus(&dev->qdev, "pci",
                            pci_vpb_set_irq, pci_vpb_map_irq, s->irq,
-                           get_system_memory(),
+                           get_system_memory(), get_system_io(),
                            PCI_DEVFN(11, 0), 4);
 
     /* ??? Register memory space.  */
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 29/56] pci: allow I/O BARs to be registered with pci_register_bar_region()
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pci.c           |   43 +++++++++++++++++++++++--------------------
 hw/pci.h           |    1 +
 hw/pci_internals.h |    3 ++-
 3 files changed, 26 insertions(+), 21 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 2659d96..980840f 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -271,7 +271,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->address_space = address_space_mem;
+    bus->address_space_mem = address_space_mem;
+    bus->address_space_io = address_space_io;
 
     /* host bridge */
     QLIST_INIT(&bus->child);
@@ -847,12 +848,11 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
         r = &pci_dev->io_regions[i];
         if (!r->size || r->addr == PCI_BAR_UNMAPPED)
             continue;
-        if (r->type == PCI_BASE_ADDRESS_SPACE_IO) {
-            isa_unassign_ioport(r->addr, r->filtered_size);
+        if (r->memory) {
+            memory_region_del_subregion(r->address_space, r->memory);
         } else {
-            if (r->memory) {
-                memory_region_del_subregion(pci_dev->bus->address_space,
-                                            r->memory);
+            if (r->type == PCI_BASE_ADDRESS_SPACE_IO) {
+                isa_unassign_ioport(r->addr, r->filtered_size);
             } else {
                 cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus,
                                                              r->addr),
@@ -934,9 +934,11 @@ static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num,
                                           pcibus_t addr, pcibus_t size,
                                           int type)
 {
-    memory_region_add_subregion_overlap(pci_dev->bus->address_space,
+    PCIIORegion *r = &pci_dev->io_regions[region_num];
+
+    memory_region_add_subregion_overlap(r->address_space,
                                         addr,
-                                        pci_dev->io_regions[region_num].memory,
+                                        r->memory,
                                         1);
 }
 
@@ -953,9 +955,13 @@ void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
                              uint8_t attr, MemoryRegion *memory)
 {
     pci_register_bar(pci_dev, region_num, memory_region_size(memory),
-                     PCI_BASE_ADDRESS_SPACE_MEMORY | attr,
+                     attr,
                      pci_simple_bar_mapfunc_region);
     pci_dev->io_regions[region_num].memory = memory;
+    pci_dev->io_regions[region_num].address_space
+        = attr & PCI_BASE_ADDRESS_SPACE_IO
+        ? pci_dev->bus->address_space_io
+        : pci_dev->bus->address_space_mem;
 }
 
 pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num)
@@ -1090,7 +1096,9 @@ static void pci_update_mappings(PCIDevice *d)
 
         /* now do the real mapping */
         if (r->addr != PCI_BAR_UNMAPPED) {
-            if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
+            if (r->memory) {
+                memory_region_del_subregion(r->address_space, r->memory);
+            } else if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
                 int class;
                 /* NOTE: specific hack for IDE in PC case:
                    only one byte must be mapped. */
@@ -1101,16 +1109,11 @@ static void pci_update_mappings(PCIDevice *d)
                     isa_unassign_ioport(r->addr, r->filtered_size);
                 }
             } else {
-                if (r->memory) {
-                    memory_region_del_subregion(d->bus->address_space,
-                                                r->memory);
-                } else {
-                    cpu_register_physical_memory(pci_to_cpu_addr(d->bus,
-                                                                 r->addr),
-                                                 r->filtered_size,
-                                                 IO_MEM_UNASSIGNED);
-                    qemu_unregister_coalesced_mmio(r->addr, r->filtered_size);
-                }
+                cpu_register_physical_memory(pci_to_cpu_addr(d->bus,
+                                                             r->addr),
+                                             r->filtered_size,
+                                             IO_MEM_UNASSIGNED);
+                qemu_unregister_coalesced_mmio(r->addr, r->filtered_size);
             }
         }
         r->addr = new_addr;
diff --git a/hw/pci.h b/hw/pci.h
index 45b30fa..928e96c 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -95,6 +95,7 @@ typedef struct PCIIORegion {
     PCIMapIORegionFunc *map_func;
     ram_addr_t ram_addr;
     MemoryRegion *memory;
+    MemoryRegion *address_space;
 } PCIIORegion;
 
 #define PCI_ROM_SLOT 6
diff --git a/hw/pci_internals.h b/hw/pci_internals.h
index c3a463a..c7fd23d 100644
--- a/hw/pci_internals.h
+++ b/hw/pci_internals.h
@@ -25,7 +25,8 @@ struct PCIBus {
     PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX];
     PCIDevice *parent_dev;
     target_phys_addr_t mem_base;
-    MemoryRegion *address_space;
+    MemoryRegion *address_space_mem;
+    MemoryRegion *address_space_io;
 
     QLIST_HEAD(, PCIBus) child; /* this will be replaced by qdev later */
     QLIST_ENTRY(PCIBus) sibling;/* this will be replaced by qdev later */
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 29/56] pci: allow I/O BARs to be registered with pci_register_bar_region()
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pci.c           |   43 +++++++++++++++++++++++--------------------
 hw/pci.h           |    1 +
 hw/pci_internals.h |    3 ++-
 3 files changed, 26 insertions(+), 21 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 2659d96..980840f 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -271,7 +271,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->address_space = address_space_mem;
+    bus->address_space_mem = address_space_mem;
+    bus->address_space_io = address_space_io;
 
     /* host bridge */
     QLIST_INIT(&bus->child);
@@ -847,12 +848,11 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
         r = &pci_dev->io_regions[i];
         if (!r->size || r->addr == PCI_BAR_UNMAPPED)
             continue;
-        if (r->type == PCI_BASE_ADDRESS_SPACE_IO) {
-            isa_unassign_ioport(r->addr, r->filtered_size);
+        if (r->memory) {
+            memory_region_del_subregion(r->address_space, r->memory);
         } else {
-            if (r->memory) {
-                memory_region_del_subregion(pci_dev->bus->address_space,
-                                            r->memory);
+            if (r->type == PCI_BASE_ADDRESS_SPACE_IO) {
+                isa_unassign_ioport(r->addr, r->filtered_size);
             } else {
                 cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus,
                                                              r->addr),
@@ -934,9 +934,11 @@ static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num,
                                           pcibus_t addr, pcibus_t size,
                                           int type)
 {
-    memory_region_add_subregion_overlap(pci_dev->bus->address_space,
+    PCIIORegion *r = &pci_dev->io_regions[region_num];
+
+    memory_region_add_subregion_overlap(r->address_space,
                                         addr,
-                                        pci_dev->io_regions[region_num].memory,
+                                        r->memory,
                                         1);
 }
 
@@ -953,9 +955,13 @@ void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
                              uint8_t attr, MemoryRegion *memory)
 {
     pci_register_bar(pci_dev, region_num, memory_region_size(memory),
-                     PCI_BASE_ADDRESS_SPACE_MEMORY | attr,
+                     attr,
                      pci_simple_bar_mapfunc_region);
     pci_dev->io_regions[region_num].memory = memory;
+    pci_dev->io_regions[region_num].address_space
+        = attr & PCI_BASE_ADDRESS_SPACE_IO
+        ? pci_dev->bus->address_space_io
+        : pci_dev->bus->address_space_mem;
 }
 
 pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num)
@@ -1090,7 +1096,9 @@ static void pci_update_mappings(PCIDevice *d)
 
         /* now do the real mapping */
         if (r->addr != PCI_BAR_UNMAPPED) {
-            if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
+            if (r->memory) {
+                memory_region_del_subregion(r->address_space, r->memory);
+            } else if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
                 int class;
                 /* NOTE: specific hack for IDE in PC case:
                    only one byte must be mapped. */
@@ -1101,16 +1109,11 @@ static void pci_update_mappings(PCIDevice *d)
                     isa_unassign_ioport(r->addr, r->filtered_size);
                 }
             } else {
-                if (r->memory) {
-                    memory_region_del_subregion(d->bus->address_space,
-                                                r->memory);
-                } else {
-                    cpu_register_physical_memory(pci_to_cpu_addr(d->bus,
-                                                                 r->addr),
-                                                 r->filtered_size,
-                                                 IO_MEM_UNASSIGNED);
-                    qemu_unregister_coalesced_mmio(r->addr, r->filtered_size);
-                }
+                cpu_register_physical_memory(pci_to_cpu_addr(d->bus,
+                                                             r->addr),
+                                             r->filtered_size,
+                                             IO_MEM_UNASSIGNED);
+                qemu_unregister_coalesced_mmio(r->addr, r->filtered_size);
             }
         }
         r->addr = new_addr;
diff --git a/hw/pci.h b/hw/pci.h
index 45b30fa..928e96c 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -95,6 +95,7 @@ typedef struct PCIIORegion {
     PCIMapIORegionFunc *map_func;
     ram_addr_t ram_addr;
     MemoryRegion *memory;
+    MemoryRegion *address_space;
 } PCIIORegion;
 
 #define PCI_ROM_SLOT 6
diff --git a/hw/pci_internals.h b/hw/pci_internals.h
index c3a463a..c7fd23d 100644
--- a/hw/pci_internals.h
+++ b/hw/pci_internals.h
@@ -25,7 +25,8 @@ struct PCIBus {
     PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX];
     PCIDevice *parent_dev;
     target_phys_addr_t mem_base;
-    MemoryRegion *address_space;
+    MemoryRegion *address_space_mem;
+    MemoryRegion *address_space_io;
 
     QLIST_HEAD(, PCIBus) child; /* this will be replaced by qdev later */
     QLIST_ENTRY(PCIBus) sibling;/* this will be replaced by qdev later */
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 30/56] rtl8139: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/rtl8139.c |  172 +++++++++++++++++-----------------------------------------
 1 files changed, 51 insertions(+), 121 deletions(-)

diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 5214b8c..fa661fc 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -474,7 +474,6 @@ typedef struct RTL8139State {
 
     NICState *nic;
     NICConf conf;
-    int rtl8139_mmio_io_addr;
 
     /* C ring mode */
     uint32_t   currTxDesc;
@@ -506,6 +505,9 @@ typedef struct RTL8139State {
     QEMUTimer *timer;
     int64_t TimerExpire;
 
+    MemoryRegion bar_io;
+    MemoryRegion bar_mem;
+
     /* Support migration to/from old versions */
     int rtl8139_mmio_io_addr_dummy;
 } RTL8139State;
@@ -2705,12 +2707,8 @@ static uint32_t rtl8139_MultiIntr_read(RTL8139State *s)
     return ret;
 }
 
-static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
+static void rtl8139_io_writeb(RTL8139State *s, uint8_t addr, uint32_t val)
 {
-    RTL8139State *s = opaque;
-
-    addr &= 0xff;
-
     switch (addr)
     {
         case MAC0 ... MAC0+5:
@@ -2792,10 +2790,8 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
     }
 }
 
-static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
+static void rtl8139_io_writew(RTL8139State *s, uint8_t addr, uint32_t val)
 {
-    RTL8139State *s = opaque;
-
     addr &= 0xfe;
 
     switch (addr)
@@ -2846,8 +2842,8 @@ static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
             DPRINTF("ioport write(w) addr=0x%x val=0x%04x via write(b)\n",
                 addr, val);
 
-            rtl8139_io_writeb(opaque, addr, val & 0xff);
-            rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
+            rtl8139_io_writeb(s, addr, val & 0xff);
+            rtl8139_io_writeb(s, addr + 1, (val >> 8) & 0xff);
             break;
     }
 }
@@ -2892,10 +2888,8 @@ static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time)
     }
 }
 
-static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
+static void rtl8139_io_writel(RTL8139State *s, uint8_t addr, uint32_t val)
 {
-    RTL8139State *s = opaque;
-
     addr &= 0xfc;
 
     switch (addr)
@@ -2952,21 +2946,18 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
         default:
             DPRINTF("ioport write(l) addr=0x%x val=0x%08x via write(b)\n",
                 addr, val);
-            rtl8139_io_writeb(opaque, addr, val & 0xff);
-            rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-            rtl8139_io_writeb(opaque, addr + 2, (val >> 16) & 0xff);
-            rtl8139_io_writeb(opaque, addr + 3, (val >> 24) & 0xff);
+            rtl8139_io_writeb(s, addr, val & 0xff);
+            rtl8139_io_writeb(s, addr + 1, (val >> 8) & 0xff);
+            rtl8139_io_writeb(s, addr + 2, (val >> 16) & 0xff);
+            rtl8139_io_writeb(s, addr + 3, (val >> 24) & 0xff);
             break;
     }
 }
 
-static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
+static uint32_t rtl8139_io_readb(RTL8139State *s, uint8_t addr)
 {
-    RTL8139State *s = opaque;
     int ret;
 
-    addr &= 0xff;
-
     switch (addr)
     {
         case MAC0 ... MAC0+5:
@@ -3034,9 +3025,8 @@ static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
     return ret;
 }
 
-static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
+static uint32_t rtl8139_io_readw(RTL8139State *s, uint8_t addr)
 {
-    RTL8139State *s = opaque;
     uint32_t ret;
 
     addr &= 0xfe; /* mask lower bit */
@@ -3101,8 +3091,8 @@ static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
         default:
             DPRINTF("ioport read(w) addr=0x%x via read(b)\n", addr);
 
-            ret  = rtl8139_io_readb(opaque, addr);
-            ret |= rtl8139_io_readb(opaque, addr + 1) << 8;
+            ret  = rtl8139_io_readb(s, addr);
+            ret |= rtl8139_io_readb(s, addr + 1) << 8;
 
             DPRINTF("ioport read(w) addr=0x%x val=0x%04x\n", addr, ret);
             break;
@@ -3182,71 +3172,40 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
     return ret;
 }
 
-/* */
-
-static void rtl8139_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
-    rtl8139_io_writeb(opaque, addr & 0xFF, val);
-}
-
-static void rtl8139_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
-{
-    rtl8139_io_writew(opaque, addr & 0xFF, val);
-}
-
-static void rtl8139_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
-{
-    rtl8139_io_writel(opaque, addr & 0xFF, val);
-}
-
-static uint32_t rtl8139_ioport_readb(void *opaque, uint32_t addr)
+static uint64_t rtl8139_io_read(void *opaque,
+                                target_phys_addr_t addr,
+                                unsigned size)
 {
-    return rtl8139_io_readb(opaque, addr & 0xFF);
-}
-
-static uint32_t rtl8139_ioport_readw(void *opaque, uint32_t addr)
-{
-    return rtl8139_io_readw(opaque, addr & 0xFF);
-}
-
-static uint32_t rtl8139_ioport_readl(void *opaque, uint32_t addr)
-{
-    return rtl8139_io_readl(opaque, addr & 0xFF);
-}
-
-/* */
-
-static void rtl8139_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    rtl8139_io_writeb(opaque, addr & 0xFF, val);
-}
-
-static void rtl8139_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    rtl8139_io_writew(opaque, addr & 0xFF, val);
-}
+    RTL8139State *s = opaque;
 
-static void rtl8139_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    rtl8139_io_writel(opaque, addr & 0xFF, val);
+    switch (size) {
+    case 1: return rtl8139_io_readb(s, addr);
+    case 2: return rtl8139_io_readw(s, addr);
+    case 4: return rtl8139_io_readl(s, addr);
+    default: abort();
+    }
 }
 
-static uint32_t rtl8139_mmio_readb(void *opaque, target_phys_addr_t addr)
+static void rtl8139_io_write(void *opaque,
+                             target_phys_addr_t addr,
+                             uint64_t data,
+                             unsigned size)
 {
-    return rtl8139_io_readb(opaque, addr & 0xFF);
-}
+    RTL8139State *s = opaque;
 
-static uint32_t rtl8139_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t val = rtl8139_io_readw(opaque, addr & 0xFF);
-    return val;
+    switch (size) {
+    case 1: return rtl8139_io_writeb(s, addr, data);
+    case 2: return rtl8139_io_writew(s, addr, data);
+    case 4: return rtl8139_io_writel(s, addr, data);
+    default: abort();
+    }
 }
 
-static uint32_t rtl8139_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t val = rtl8139_io_readl(opaque, addr & 0xFF);
-    return val;
-}
+static MemoryRegionOps rtl8139_io_ops = {
+    .read = rtl8139_io_read,
+    .write = rtl8139_io_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
 
 static int rtl8139_post_load(void *opaque, int version_id)
 {
@@ -3283,7 +3242,7 @@ static void rtl8139_pre_save(void *opaque)
     rtl8139_set_next_tctr_time(s, current_time);
     s->TCTR = muldiv64(current_time - s->TCTR_base, PCI_FREQUENCY,
                        get_ticks_per_sec());
-    s->rtl8139_mmio_io_addr_dummy = s->rtl8139_mmio_io_addr;
+    s->rtl8139_mmio_io_addr_dummy = 0;
 }
 
 static const VMStateDescription vmstate_rtl8139 = {
@@ -3379,33 +3338,6 @@ static const VMStateDescription vmstate_rtl8139 = {
 /***********************************************************/
 /* PCI RTL8139 definitions */
 
-static void rtl8139_ioport_map(PCIDevice *pci_dev, int region_num,
-                       pcibus_t addr, pcibus_t size, int type)
-{
-    RTL8139State *s = DO_UPCAST(RTL8139State, dev, pci_dev);
-
-    register_ioport_write(addr, 0x100, 1, rtl8139_ioport_writeb, s);
-    register_ioport_read( addr, 0x100, 1, rtl8139_ioport_readb,  s);
-
-    register_ioport_write(addr, 0x100, 2, rtl8139_ioport_writew, s);
-    register_ioport_read( addr, 0x100, 2, rtl8139_ioport_readw,  s);
-
-    register_ioport_write(addr, 0x100, 4, rtl8139_ioport_writel, s);
-    register_ioport_read( addr, 0x100, 4, rtl8139_ioport_readl,  s);
-}
-
-static CPUReadMemoryFunc * const rtl8139_mmio_read[3] = {
-    rtl8139_mmio_readb,
-    rtl8139_mmio_readw,
-    rtl8139_mmio_readl,
-};
-
-static CPUWriteMemoryFunc * const rtl8139_mmio_write[3] = {
-    rtl8139_mmio_writeb,
-    rtl8139_mmio_writew,
-    rtl8139_mmio_writel,
-};
-
 static void rtl8139_timer(void *opaque)
 {
     RTL8139State *s = opaque;
@@ -3432,7 +3364,8 @@ static int pci_rtl8139_uninit(PCIDevice *dev)
 {
     RTL8139State *s = DO_UPCAST(RTL8139State, dev, dev);
 
-    cpu_unregister_io_memory(s->rtl8139_mmio_io_addr);
+    memory_region_destroy(&s->bar_io);
+    memory_region_destroy(&s->bar_mem);
     if (s->cplus_txbuffer) {
         qemu_free(s->cplus_txbuffer);
         s->cplus_txbuffer = NULL;
@@ -3462,15 +3395,12 @@ static int pci_rtl8139_init(PCIDevice *dev)
      * list bit in status register, and offset 0xdc seems unused. */
     pci_conf[PCI_CAPABILITY_LIST] = 0xdc;
 
-    /* I/O handler for memory-mapped I/O */
-    s->rtl8139_mmio_io_addr =
-        cpu_register_io_memory(rtl8139_mmio_read, rtl8139_mmio_write, s,
-                               DEVICE_LITTLE_ENDIAN);
-
-    pci_register_bar(&s->dev, 0, 0x100,
-                           PCI_BASE_ADDRESS_SPACE_IO,  rtl8139_ioport_map);
-
-    pci_register_bar_simple(&s->dev, 1, 0x100, 0, s->rtl8139_mmio_io_addr);
+    memory_region_init_io(&s->bar_io, &rtl8139_io_ops, s, "rtl8139", 0x100);
+    memory_region_init_io(&s->bar_mem, &rtl8139_io_ops, s, "rtl8139", 0x100);
+    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
+                            &s->bar_io);
+    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                            &s->bar_mem);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 30/56] rtl8139: convert to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/rtl8139.c |  172 +++++++++++++++++-----------------------------------------
 1 files changed, 51 insertions(+), 121 deletions(-)

diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 5214b8c..fa661fc 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -474,7 +474,6 @@ typedef struct RTL8139State {
 
     NICState *nic;
     NICConf conf;
-    int rtl8139_mmio_io_addr;
 
     /* C ring mode */
     uint32_t   currTxDesc;
@@ -506,6 +505,9 @@ typedef struct RTL8139State {
     QEMUTimer *timer;
     int64_t TimerExpire;
 
+    MemoryRegion bar_io;
+    MemoryRegion bar_mem;
+
     /* Support migration to/from old versions */
     int rtl8139_mmio_io_addr_dummy;
 } RTL8139State;
@@ -2705,12 +2707,8 @@ static uint32_t rtl8139_MultiIntr_read(RTL8139State *s)
     return ret;
 }
 
-static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
+static void rtl8139_io_writeb(RTL8139State *s, uint8_t addr, uint32_t val)
 {
-    RTL8139State *s = opaque;
-
-    addr &= 0xff;
-
     switch (addr)
     {
         case MAC0 ... MAC0+5:
@@ -2792,10 +2790,8 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
     }
 }
 
-static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
+static void rtl8139_io_writew(RTL8139State *s, uint8_t addr, uint32_t val)
 {
-    RTL8139State *s = opaque;
-
     addr &= 0xfe;
 
     switch (addr)
@@ -2846,8 +2842,8 @@ static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
             DPRINTF("ioport write(w) addr=0x%x val=0x%04x via write(b)\n",
                 addr, val);
 
-            rtl8139_io_writeb(opaque, addr, val & 0xff);
-            rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
+            rtl8139_io_writeb(s, addr, val & 0xff);
+            rtl8139_io_writeb(s, addr + 1, (val >> 8) & 0xff);
             break;
     }
 }
@@ -2892,10 +2888,8 @@ static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time)
     }
 }
 
-static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
+static void rtl8139_io_writel(RTL8139State *s, uint8_t addr, uint32_t val)
 {
-    RTL8139State *s = opaque;
-
     addr &= 0xfc;
 
     switch (addr)
@@ -2952,21 +2946,18 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
         default:
             DPRINTF("ioport write(l) addr=0x%x val=0x%08x via write(b)\n",
                 addr, val);
-            rtl8139_io_writeb(opaque, addr, val & 0xff);
-            rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-            rtl8139_io_writeb(opaque, addr + 2, (val >> 16) & 0xff);
-            rtl8139_io_writeb(opaque, addr + 3, (val >> 24) & 0xff);
+            rtl8139_io_writeb(s, addr, val & 0xff);
+            rtl8139_io_writeb(s, addr + 1, (val >> 8) & 0xff);
+            rtl8139_io_writeb(s, addr + 2, (val >> 16) & 0xff);
+            rtl8139_io_writeb(s, addr + 3, (val >> 24) & 0xff);
             break;
     }
 }
 
-static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
+static uint32_t rtl8139_io_readb(RTL8139State *s, uint8_t addr)
 {
-    RTL8139State *s = opaque;
     int ret;
 
-    addr &= 0xff;
-
     switch (addr)
     {
         case MAC0 ... MAC0+5:
@@ -3034,9 +3025,8 @@ static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
     return ret;
 }
 
-static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
+static uint32_t rtl8139_io_readw(RTL8139State *s, uint8_t addr)
 {
-    RTL8139State *s = opaque;
     uint32_t ret;
 
     addr &= 0xfe; /* mask lower bit */
@@ -3101,8 +3091,8 @@ static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
         default:
             DPRINTF("ioport read(w) addr=0x%x via read(b)\n", addr);
 
-            ret  = rtl8139_io_readb(opaque, addr);
-            ret |= rtl8139_io_readb(opaque, addr + 1) << 8;
+            ret  = rtl8139_io_readb(s, addr);
+            ret |= rtl8139_io_readb(s, addr + 1) << 8;
 
             DPRINTF("ioport read(w) addr=0x%x val=0x%04x\n", addr, ret);
             break;
@@ -3182,71 +3172,40 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
     return ret;
 }
 
-/* */
-
-static void rtl8139_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
-    rtl8139_io_writeb(opaque, addr & 0xFF, val);
-}
-
-static void rtl8139_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
-{
-    rtl8139_io_writew(opaque, addr & 0xFF, val);
-}
-
-static void rtl8139_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
-{
-    rtl8139_io_writel(opaque, addr & 0xFF, val);
-}
-
-static uint32_t rtl8139_ioport_readb(void *opaque, uint32_t addr)
+static uint64_t rtl8139_io_read(void *opaque,
+                                target_phys_addr_t addr,
+                                unsigned size)
 {
-    return rtl8139_io_readb(opaque, addr & 0xFF);
-}
-
-static uint32_t rtl8139_ioport_readw(void *opaque, uint32_t addr)
-{
-    return rtl8139_io_readw(opaque, addr & 0xFF);
-}
-
-static uint32_t rtl8139_ioport_readl(void *opaque, uint32_t addr)
-{
-    return rtl8139_io_readl(opaque, addr & 0xFF);
-}
-
-/* */
-
-static void rtl8139_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    rtl8139_io_writeb(opaque, addr & 0xFF, val);
-}
-
-static void rtl8139_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    rtl8139_io_writew(opaque, addr & 0xFF, val);
-}
+    RTL8139State *s = opaque;
 
-static void rtl8139_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    rtl8139_io_writel(opaque, addr & 0xFF, val);
+    switch (size) {
+    case 1: return rtl8139_io_readb(s, addr);
+    case 2: return rtl8139_io_readw(s, addr);
+    case 4: return rtl8139_io_readl(s, addr);
+    default: abort();
+    }
 }
 
-static uint32_t rtl8139_mmio_readb(void *opaque, target_phys_addr_t addr)
+static void rtl8139_io_write(void *opaque,
+                             target_phys_addr_t addr,
+                             uint64_t data,
+                             unsigned size)
 {
-    return rtl8139_io_readb(opaque, addr & 0xFF);
-}
+    RTL8139State *s = opaque;
 
-static uint32_t rtl8139_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t val = rtl8139_io_readw(opaque, addr & 0xFF);
-    return val;
+    switch (size) {
+    case 1: return rtl8139_io_writeb(s, addr, data);
+    case 2: return rtl8139_io_writew(s, addr, data);
+    case 4: return rtl8139_io_writel(s, addr, data);
+    default: abort();
+    }
 }
 
-static uint32_t rtl8139_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t val = rtl8139_io_readl(opaque, addr & 0xFF);
-    return val;
-}
+static MemoryRegionOps rtl8139_io_ops = {
+    .read = rtl8139_io_read,
+    .write = rtl8139_io_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
 
 static int rtl8139_post_load(void *opaque, int version_id)
 {
@@ -3283,7 +3242,7 @@ static void rtl8139_pre_save(void *opaque)
     rtl8139_set_next_tctr_time(s, current_time);
     s->TCTR = muldiv64(current_time - s->TCTR_base, PCI_FREQUENCY,
                        get_ticks_per_sec());
-    s->rtl8139_mmio_io_addr_dummy = s->rtl8139_mmio_io_addr;
+    s->rtl8139_mmio_io_addr_dummy = 0;
 }
 
 static const VMStateDescription vmstate_rtl8139 = {
@@ -3379,33 +3338,6 @@ static const VMStateDescription vmstate_rtl8139 = {
 /***********************************************************/
 /* PCI RTL8139 definitions */
 
-static void rtl8139_ioport_map(PCIDevice *pci_dev, int region_num,
-                       pcibus_t addr, pcibus_t size, int type)
-{
-    RTL8139State *s = DO_UPCAST(RTL8139State, dev, pci_dev);
-
-    register_ioport_write(addr, 0x100, 1, rtl8139_ioport_writeb, s);
-    register_ioport_read( addr, 0x100, 1, rtl8139_ioport_readb,  s);
-
-    register_ioport_write(addr, 0x100, 2, rtl8139_ioport_writew, s);
-    register_ioport_read( addr, 0x100, 2, rtl8139_ioport_readw,  s);
-
-    register_ioport_write(addr, 0x100, 4, rtl8139_ioport_writel, s);
-    register_ioport_read( addr, 0x100, 4, rtl8139_ioport_readl,  s);
-}
-
-static CPUReadMemoryFunc * const rtl8139_mmio_read[3] = {
-    rtl8139_mmio_readb,
-    rtl8139_mmio_readw,
-    rtl8139_mmio_readl,
-};
-
-static CPUWriteMemoryFunc * const rtl8139_mmio_write[3] = {
-    rtl8139_mmio_writeb,
-    rtl8139_mmio_writew,
-    rtl8139_mmio_writel,
-};
-
 static void rtl8139_timer(void *opaque)
 {
     RTL8139State *s = opaque;
@@ -3432,7 +3364,8 @@ static int pci_rtl8139_uninit(PCIDevice *dev)
 {
     RTL8139State *s = DO_UPCAST(RTL8139State, dev, dev);
 
-    cpu_unregister_io_memory(s->rtl8139_mmio_io_addr);
+    memory_region_destroy(&s->bar_io);
+    memory_region_destroy(&s->bar_mem);
     if (s->cplus_txbuffer) {
         qemu_free(s->cplus_txbuffer);
         s->cplus_txbuffer = NULL;
@@ -3462,15 +3395,12 @@ static int pci_rtl8139_init(PCIDevice *dev)
      * list bit in status register, and offset 0xdc seems unused. */
     pci_conf[PCI_CAPABILITY_LIST] = 0xdc;
 
-    /* I/O handler for memory-mapped I/O */
-    s->rtl8139_mmio_io_addr =
-        cpu_register_io_memory(rtl8139_mmio_read, rtl8139_mmio_write, s,
-                               DEVICE_LITTLE_ENDIAN);
-
-    pci_register_bar(&s->dev, 0, 0x100,
-                           PCI_BASE_ADDRESS_SPACE_IO,  rtl8139_ioport_map);
-
-    pci_register_bar_simple(&s->dev, 1, 0x100, 0, s->rtl8139_mmio_io_addr);
+    memory_region_init_io(&s->bar_io, &rtl8139_io_ops, s, "rtl8139", 0x100);
+    memory_region_init_io(&s->bar_mem, &rtl8139_io_ops, s, "rtl8139", 0x100);
+    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
+                            &s->bar_io);
+    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                            &s->bar_mem);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 31/56] ac97: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

fixes BAR sizing as well.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/ac97.c |  126 ++++++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 88 insertions(+), 38 deletions(-)

diff --git a/hw/ac97.c b/hw/ac97.c
index 0b59896..72a0667 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -160,8 +160,9 @@ typedef struct AC97LinkState {
     SWVoiceIn *voice_mc;
     int invalid_freq[3];
     uint8_t silence[128];
-    uint32_t base[2];
     int bup_flag;
+    MemoryRegion io_nam;
+    MemoryRegion io_nabm;
 } AC97LinkState;
 
 enum {
@@ -583,7 +584,7 @@ static uint32_t nam_readw (void *opaque, uint32_t addr)
 {
     AC97LinkState *s = opaque;
     uint32_t val = ~0U;
-    uint32_t index = addr - s->base[0];
+    uint32_t index = addr;
     s->cas = 0;
     val = mixer_load (s, index);
     return val;
@@ -611,7 +612,7 @@ static void nam_writeb (void *opaque, uint32_t addr, uint32_t val)
 static void nam_writew (void *opaque, uint32_t addr, uint32_t val)
 {
     AC97LinkState *s = opaque;
-    uint32_t index = addr - s->base[0];
+    uint32_t index = addr;
     s->cas = 0;
     switch (index) {
     case AC97_Reset:
@@ -706,6 +707,37 @@ static void nam_writel (void *opaque, uint32_t addr, uint32_t val)
     s->cas = 0;
 }
 
+static uint64_t nam_read(void *opaque, target_phys_addr_t addr, unsigned size)
+{
+    AC97LinkState *s = opaque;
+
+    switch (size) {
+    case 1: return nam_readb(s, addr);
+    case 2: return nam_readw(s, addr);
+    case 4: return nam_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void nam_write(void *opaque, target_phys_addr_t addr,
+                      uint64_t data, unsigned size)
+{
+    AC97LinkState *s = opaque;
+
+    switch (size) {
+    case 1: return nam_writeb(s, addr, data);
+    case 2: return nam_writew(s, addr, data);
+    case 4: return nam_writel(s, addr, data);
+    default: abort();
+    }
+}
+
+static MemoryRegionOps ac97_io_nam_ops = {
+    .read = nam_read,
+    .write = nam_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 /**
  * Native audio bus master
  * I/O Reads
@@ -714,7 +746,7 @@ static uint32_t nabm_readb (void *opaque, uint32_t addr)
 {
     AC97LinkState *s = opaque;
     AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
     uint32_t val = ~0U;
 
     switch (index) {
@@ -769,7 +801,7 @@ static uint32_t nabm_readw (void *opaque, uint32_t addr)
 {
     AC97LinkState *s = opaque;
     AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
     uint32_t val = ~0U;
 
     switch (index) {
@@ -798,7 +830,7 @@ static uint32_t nabm_readl (void *opaque, uint32_t addr)
 {
     AC97LinkState *s = opaque;
     AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
     uint32_t val = ~0U;
 
     switch (index) {
@@ -848,7 +880,7 @@ static void nabm_writeb (void *opaque, uint32_t addr, uint32_t val)
 {
     AC97LinkState *s = opaque;
     AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
     switch (index) {
     case PI_LVI:
     case PO_LVI:
@@ -904,7 +936,7 @@ static void nabm_writew (void *opaque, uint32_t addr, uint32_t val)
 {
     AC97LinkState *s = opaque;
     AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
     switch (index) {
     case PI_SR:
     case PO_SR:
@@ -924,7 +956,7 @@ static void nabm_writel (void *opaque, uint32_t addr, uint32_t val)
 {
     AC97LinkState *s = opaque;
     AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
     switch (index) {
     case PI_BDBAR:
     case PO_BDBAR:
@@ -954,6 +986,38 @@ static void nabm_writel (void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
+static uint64_t nabm_read(void *opaque, target_phys_addr_t addr,
+                         unsigned size)
+{
+    AC97LinkState *s = opaque;
+
+    switch (size) {
+    case 1: return nabm_readb(s, addr);
+    case 2: return nabm_readw(s, addr);
+    case 4: return nabm_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void nabm_write(void *opaque, target_phys_addr_t addr,
+                       uint64_t data, unsigned size)
+{
+    AC97LinkState *s = opaque;
+
+    switch (size) {
+    case 1: return nabm_writeb(s, addr, data);
+    case 2: return nabm_writew(s, addr, data);
+    case 4: return nabm_writel(s, addr, data);
+    default: abort();
+    }
+}
+
+static MemoryRegionOps ac97_io_nabm_ops = {
+    .read = nabm_read,
+    .write = nabm_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static int write_audio (AC97LinkState *s, AC97BusMasterRegs *r,
                         int max, int *stop)
 {
@@ -1230,32 +1294,6 @@ static const VMStateDescription vmstate_ac97 = {
     }
 };
 
-static void ac97_map (PCIDevice *pci_dev, int region_num,
-                      pcibus_t addr, pcibus_t size, int type)
-{
-    AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, pci_dev);
-    PCIDevice *d = &s->dev;
-
-    if (!region_num) {
-        s->base[0] = addr;
-        register_ioport_read (addr, 256 * 1, 1, nam_readb, d);
-        register_ioport_read (addr, 256 * 2, 2, nam_readw, d);
-        register_ioport_read (addr, 256 * 4, 4, nam_readl, d);
-        register_ioport_write (addr, 256 * 1, 1, nam_writeb, d);
-        register_ioport_write (addr, 256 * 2, 2, nam_writew, d);
-        register_ioport_write (addr, 256 * 4, 4, nam_writel, d);
-    }
-    else {
-        s->base[1] = addr;
-        register_ioport_read (addr, 64 * 1, 1, nabm_readb, d);
-        register_ioport_read (addr, 64 * 2, 2, nabm_readw, d);
-        register_ioport_read (addr, 64 * 4, 4, nabm_readl, d);
-        register_ioport_write (addr, 64 * 1, 1, nabm_writeb, d);
-        register_ioport_write (addr, 64 * 2, 2, nabm_writew, d);
-        register_ioport_write (addr, 64 * 4, 4, nabm_writel, d);
-    }
-}
-
 static void ac97_on_reset (void *opaque)
 {
     AC97LinkState *s = opaque;
@@ -1311,15 +1349,26 @@ static int ac97_initfn (PCIDevice *dev)
     /* TODO: RST# value should be 0. */
     c[PCI_INTERRUPT_PIN] = 0x01;      /* intr_pn interrupt pin ro */
 
-    pci_register_bar (&s->dev, 0, 256 * 4, PCI_BASE_ADDRESS_SPACE_IO,
-                      ac97_map);
-    pci_register_bar (&s->dev, 1, 64 * 4, PCI_BASE_ADDRESS_SPACE_IO, ac97_map);
+    memory_region_init_io(&s->io_nam, &ac97_io_nam_ops, s, "ac97-nam", 1024);
+    memory_region_init_io(&s->io_nabm, &ac97_io_nabm_ops, s, "ac97-nabm", 256);
+
+    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nam);
+    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nabm);
     qemu_register_reset (ac97_on_reset, s);
     AUD_register_card ("ac97", &s->card);
     ac97_on_reset (s);
     return 0;
 }
 
+static int ac97_exitfn(PCIDevice *dev)
+{
+    AC97LinkState *s = DO_UPCAST(AC97LinkState, dev, dev);
+
+    memory_region_destroy(&s->io_nam);
+    memory_region_destroy(&s->io_nabm);
+    return 0;
+}
+
 int ac97_init (PCIBus *bus)
 {
     pci_create_simple (bus, -1, "AC97");
@@ -1332,6 +1381,7 @@ static PCIDeviceInfo ac97_info = {
     .qdev.size    = sizeof (AC97LinkState),
     .qdev.vmsd    = &vmstate_ac97,
     .init         = ac97_initfn,
+    .exit         = ac97_exitfn,
     .vendor_id    = PCI_VENDOR_ID_INTEL,
     .device_id    = PCI_DEVICE_ID_INTEL_82801AA_5,
     .revision     = 0x01,
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 31/56] ac97: convert to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

fixes BAR sizing as well.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/ac97.c |  126 ++++++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 88 insertions(+), 38 deletions(-)

diff --git a/hw/ac97.c b/hw/ac97.c
index 0b59896..72a0667 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -160,8 +160,9 @@ typedef struct AC97LinkState {
     SWVoiceIn *voice_mc;
     int invalid_freq[3];
     uint8_t silence[128];
-    uint32_t base[2];
     int bup_flag;
+    MemoryRegion io_nam;
+    MemoryRegion io_nabm;
 } AC97LinkState;
 
 enum {
@@ -583,7 +584,7 @@ static uint32_t nam_readw (void *opaque, uint32_t addr)
 {
     AC97LinkState *s = opaque;
     uint32_t val = ~0U;
-    uint32_t index = addr - s->base[0];
+    uint32_t index = addr;
     s->cas = 0;
     val = mixer_load (s, index);
     return val;
@@ -611,7 +612,7 @@ static void nam_writeb (void *opaque, uint32_t addr, uint32_t val)
 static void nam_writew (void *opaque, uint32_t addr, uint32_t val)
 {
     AC97LinkState *s = opaque;
-    uint32_t index = addr - s->base[0];
+    uint32_t index = addr;
     s->cas = 0;
     switch (index) {
     case AC97_Reset:
@@ -706,6 +707,37 @@ static void nam_writel (void *opaque, uint32_t addr, uint32_t val)
     s->cas = 0;
 }
 
+static uint64_t nam_read(void *opaque, target_phys_addr_t addr, unsigned size)
+{
+    AC97LinkState *s = opaque;
+
+    switch (size) {
+    case 1: return nam_readb(s, addr);
+    case 2: return nam_readw(s, addr);
+    case 4: return nam_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void nam_write(void *opaque, target_phys_addr_t addr,
+                      uint64_t data, unsigned size)
+{
+    AC97LinkState *s = opaque;
+
+    switch (size) {
+    case 1: return nam_writeb(s, addr, data);
+    case 2: return nam_writew(s, addr, data);
+    case 4: return nam_writel(s, addr, data);
+    default: abort();
+    }
+}
+
+static MemoryRegionOps ac97_io_nam_ops = {
+    .read = nam_read,
+    .write = nam_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 /**
  * Native audio bus master
  * I/O Reads
@@ -714,7 +746,7 @@ static uint32_t nabm_readb (void *opaque, uint32_t addr)
 {
     AC97LinkState *s = opaque;
     AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
     uint32_t val = ~0U;
 
     switch (index) {
@@ -769,7 +801,7 @@ static uint32_t nabm_readw (void *opaque, uint32_t addr)
 {
     AC97LinkState *s = opaque;
     AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
     uint32_t val = ~0U;
 
     switch (index) {
@@ -798,7 +830,7 @@ static uint32_t nabm_readl (void *opaque, uint32_t addr)
 {
     AC97LinkState *s = opaque;
     AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
     uint32_t val = ~0U;
 
     switch (index) {
@@ -848,7 +880,7 @@ static void nabm_writeb (void *opaque, uint32_t addr, uint32_t val)
 {
     AC97LinkState *s = opaque;
     AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
     switch (index) {
     case PI_LVI:
     case PO_LVI:
@@ -904,7 +936,7 @@ static void nabm_writew (void *opaque, uint32_t addr, uint32_t val)
 {
     AC97LinkState *s = opaque;
     AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
     switch (index) {
     case PI_SR:
     case PO_SR:
@@ -924,7 +956,7 @@ static void nabm_writel (void *opaque, uint32_t addr, uint32_t val)
 {
     AC97LinkState *s = opaque;
     AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
     switch (index) {
     case PI_BDBAR:
     case PO_BDBAR:
@@ -954,6 +986,38 @@ static void nabm_writel (void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
+static uint64_t nabm_read(void *opaque, target_phys_addr_t addr,
+                         unsigned size)
+{
+    AC97LinkState *s = opaque;
+
+    switch (size) {
+    case 1: return nabm_readb(s, addr);
+    case 2: return nabm_readw(s, addr);
+    case 4: return nabm_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void nabm_write(void *opaque, target_phys_addr_t addr,
+                       uint64_t data, unsigned size)
+{
+    AC97LinkState *s = opaque;
+
+    switch (size) {
+    case 1: return nabm_writeb(s, addr, data);
+    case 2: return nabm_writew(s, addr, data);
+    case 4: return nabm_writel(s, addr, data);
+    default: abort();
+    }
+}
+
+static MemoryRegionOps ac97_io_nabm_ops = {
+    .read = nabm_read,
+    .write = nabm_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static int write_audio (AC97LinkState *s, AC97BusMasterRegs *r,
                         int max, int *stop)
 {
@@ -1230,32 +1294,6 @@ static const VMStateDescription vmstate_ac97 = {
     }
 };
 
-static void ac97_map (PCIDevice *pci_dev, int region_num,
-                      pcibus_t addr, pcibus_t size, int type)
-{
-    AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, pci_dev);
-    PCIDevice *d = &s->dev;
-
-    if (!region_num) {
-        s->base[0] = addr;
-        register_ioport_read (addr, 256 * 1, 1, nam_readb, d);
-        register_ioport_read (addr, 256 * 2, 2, nam_readw, d);
-        register_ioport_read (addr, 256 * 4, 4, nam_readl, d);
-        register_ioport_write (addr, 256 * 1, 1, nam_writeb, d);
-        register_ioport_write (addr, 256 * 2, 2, nam_writew, d);
-        register_ioport_write (addr, 256 * 4, 4, nam_writel, d);
-    }
-    else {
-        s->base[1] = addr;
-        register_ioport_read (addr, 64 * 1, 1, nabm_readb, d);
-        register_ioport_read (addr, 64 * 2, 2, nabm_readw, d);
-        register_ioport_read (addr, 64 * 4, 4, nabm_readl, d);
-        register_ioport_write (addr, 64 * 1, 1, nabm_writeb, d);
-        register_ioport_write (addr, 64 * 2, 2, nabm_writew, d);
-        register_ioport_write (addr, 64 * 4, 4, nabm_writel, d);
-    }
-}
-
 static void ac97_on_reset (void *opaque)
 {
     AC97LinkState *s = opaque;
@@ -1311,15 +1349,26 @@ static int ac97_initfn (PCIDevice *dev)
     /* TODO: RST# value should be 0. */
     c[PCI_INTERRUPT_PIN] = 0x01;      /* intr_pn interrupt pin ro */
 
-    pci_register_bar (&s->dev, 0, 256 * 4, PCI_BASE_ADDRESS_SPACE_IO,
-                      ac97_map);
-    pci_register_bar (&s->dev, 1, 64 * 4, PCI_BASE_ADDRESS_SPACE_IO, ac97_map);
+    memory_region_init_io(&s->io_nam, &ac97_io_nam_ops, s, "ac97-nam", 1024);
+    memory_region_init_io(&s->io_nabm, &ac97_io_nabm_ops, s, "ac97-nabm", 256);
+
+    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nam);
+    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nabm);
     qemu_register_reset (ac97_on_reset, s);
     AUD_register_card ("ac97", &s->card);
     ac97_on_reset (s);
     return 0;
 }
 
+static int ac97_exitfn(PCIDevice *dev)
+{
+    AC97LinkState *s = DO_UPCAST(AC97LinkState, dev, dev);
+
+    memory_region_destroy(&s->io_nam);
+    memory_region_destroy(&s->io_nabm);
+    return 0;
+}
+
 int ac97_init (PCIBus *bus)
 {
     pci_create_simple (bus, -1, "AC97");
@@ -1332,6 +1381,7 @@ static PCIDeviceInfo ac97_info = {
     .qdev.size    = sizeof (AC97LinkState),
     .qdev.vmsd    = &vmstate_ac97,
     .init         = ac97_initfn,
+    .exit         = ac97_exitfn,
     .vendor_id    = PCI_VENDOR_ID_INTEL,
     .device_id    = PCI_DEVICE_ID_INTEL_82801AA_5,
     .revision     = 0x01,
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 32/56] e1000: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/e1000.c |  114 +++++++++++++++++++++++++----------------------------------
 1 files changed, 48 insertions(+), 66 deletions(-)

diff --git a/hw/e1000.c b/hw/e1000.c
index 96d84f9..8e4830f 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -82,7 +82,8 @@ typedef struct E1000State_st {
     PCIDevice dev;
     NICState *nic;
     NICConf conf;
-    int mmio_index;
+    MemoryRegion mmio;
+    MemoryRegion io;
 
     uint32_t mac_reg[0x8000];
     uint16_t phy_reg[0x20];
@@ -151,14 +152,6 @@ static const char phy_regcap[0x20] = {
 };
 
 static void
-ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr,
-           pcibus_t size, int type)
-{
-    DBGOUT(IO, "e1000_ioport_map addr=0x%04"FMT_PCIBUS
-           " size=0x%08"FMT_PCIBUS"\n", addr, size);
-}
-
-static void
 set_interrupt_cause(E1000State *s, int index, uint32_t val)
 {
     if (val)
@@ -905,7 +898,8 @@ static void (*macreg_writeops[])(E1000State *, int, uint32_t) = {
 enum { NWRITEOPS = ARRAY_SIZE(macreg_writeops) };
 
 static void
-e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+e1000_mmio_write(void *opaque, target_phys_addr_t addr, uint64_t val,
+                 unsigned size)
 {
     E1000State *s = opaque;
     unsigned int index = (addr & 0x1ffff) >> 2;
@@ -913,31 +907,15 @@ e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
     if (index < NWRITEOPS && macreg_writeops[index]) {
         macreg_writeops[index](s, index, val);
     } else if (index < NREADOPS && macreg_readops[index]) {
-        DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04x\n", index<<2, val);
+        DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04"PRIx64"\n", index<<2, val);
     } else {
-        DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08x\n",
+        DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08"PRIx64"\n",
                index<<2, val);
     }
 }
 
-static void
-e1000_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    // emulate hw without byte enables: no RMW
-    e1000_mmio_writel(opaque, addr & ~3,
-                      (val & 0xffff) << (8*(addr & 3)));
-}
-
-static void
-e1000_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    // emulate hw without byte enables: no RMW
-    e1000_mmio_writel(opaque, addr & ~3,
-                      (val & 0xff) << (8*(addr & 3)));
-}
-
-static uint32_t
-e1000_mmio_readl(void *opaque, target_phys_addr_t addr)
+static uint64_t
+e1000_mmio_read(void *opaque, target_phys_addr_t addr, unsigned size)
 {
     E1000State *s = opaque;
     unsigned int index = (addr & 0x1ffff) >> 2;
@@ -950,20 +928,39 @@ e1000_mmio_readl(void *opaque, target_phys_addr_t addr)
     return 0;
 }
 
-static uint32_t
-e1000_mmio_readb(void *opaque, target_phys_addr_t addr)
+static MemoryRegionOps e1000_mmio_ops = {
+    .read = e1000_mmio_read,
+    .write = e1000_mmio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+};
+
+static uint64_t e1000_io_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
 {
-    return ((e1000_mmio_readl(opaque, addr & ~3)) >>
-            (8 * (addr & 3))) & 0xff;
+    E1000State *s = opaque;
+
+    (void)s;
+    return 0;
 }
 
-static uint32_t
-e1000_mmio_readw(void *opaque, target_phys_addr_t addr)
+static void e1000_io_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t val, unsigned size)
 {
-    return ((e1000_mmio_readl(opaque, addr & ~3)) >>
-            (8 * (addr & 3))) & 0xffff;
+    E1000State *s = opaque;
+
+    (void)s;
 }
 
+static MemoryRegionOps e1000_io_ops = {
+    .read = e1000_io_read,
+    .write = e1000_io_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static bool is_version_1(void *opaque, int version_id)
 {
     return version_id == 1;
@@ -1083,36 +1080,22 @@ static const uint32_t mac_reg_init[] = {
 
 /* PCI interface */
 
-static CPUWriteMemoryFunc * const e1000_mmio_write[] = {
-    e1000_mmio_writeb,	e1000_mmio_writew,	e1000_mmio_writel
-};
-
-static CPUReadMemoryFunc * const e1000_mmio_read[] = {
-    e1000_mmio_readb,	e1000_mmio_readw,	e1000_mmio_readl
-};
-
 static void
-e1000_mmio_map(PCIDevice *pci_dev, int region_num,
-                pcibus_t addr, pcibus_t size, int type)
+e1000_mmio_setup(E1000State *d)
 {
-    E1000State *d = DO_UPCAST(E1000State, dev, pci_dev);
     int i;
     const uint32_t excluded_regs[] = {
         E1000_MDIC, E1000_ICR, E1000_ICS, E1000_IMS,
         E1000_IMC, E1000_TCTL, E1000_TDT, PNPMMIO_SIZE
     };
 
-
-    DBGOUT(MMIO, "e1000_mmio_map addr=0x%08"FMT_PCIBUS" 0x%08"FMT_PCIBUS"\n",
-           addr, size);
-
-    cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
-    qemu_register_coalesced_mmio(addr, excluded_regs[0]);
-
+    memory_region_init_io(&d->mmio, &e1000_mmio_ops, d, "e1000-mmio",
+                          PNPMMIO_SIZE);
+    memory_region_add_coalescing(&d->mmio, 0, excluded_regs[0]);
     for (i = 0; excluded_regs[i] != PNPMMIO_SIZE; i++)
-        qemu_register_coalesced_mmio(addr + excluded_regs[i] + 4,
-                                     excluded_regs[i + 1] -
-                                     excluded_regs[i] - 4);
+        memory_region_add_coalescing(&d->mmio, excluded_regs[i] + 4,
+                                     excluded_regs[i+1] - excluded_regs[i] - 4);
+    memory_region_init_io(&d->io, &e1000_io_ops, d, "e1000-io", IOPORT_SIZE);
 }
 
 static void
@@ -1128,7 +1111,8 @@ pci_e1000_uninit(PCIDevice *dev)
 {
     E1000State *d = DO_UPCAST(E1000State, dev, dev);
 
-    cpu_unregister_io_memory(d->mmio_index);
+    memory_region_destroy(&d->mmio);
+    memory_region_destroy(&d->io);
     qemu_del_vlan_client(&d->nic->nc);
     return 0;
 }
@@ -1172,14 +1156,12 @@ static int pci_e1000_init(PCIDevice *pci_dev)
     /* TODO: RST# value should be 0 if programmable, PCI spec 6.2.4 */
     pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
 
-    d->mmio_index = cpu_register_io_memory(e1000_mmio_read,
-            e1000_mmio_write, d, DEVICE_LITTLE_ENDIAN);
+    e1000_mmio_setup(d);
 
-    pci_register_bar(&d->dev, 0, PNPMMIO_SIZE,
-                           PCI_BASE_ADDRESS_SPACE_MEMORY, e1000_mmio_map);
+    pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                            &d->mmio);
 
-    pci_register_bar(&d->dev, 1, IOPORT_SIZE,
-                           PCI_BASE_ADDRESS_SPACE_IO, ioport_map);
+    pci_register_bar_region(&d->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->io);
 
     memmove(d->eeprom_data, e1000_eeprom_template,
         sizeof e1000_eeprom_template);
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 32/56] e1000: convert to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/e1000.c |  114 +++++++++++++++++++++++++----------------------------------
 1 files changed, 48 insertions(+), 66 deletions(-)

diff --git a/hw/e1000.c b/hw/e1000.c
index 96d84f9..8e4830f 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -82,7 +82,8 @@ typedef struct E1000State_st {
     PCIDevice dev;
     NICState *nic;
     NICConf conf;
-    int mmio_index;
+    MemoryRegion mmio;
+    MemoryRegion io;
 
     uint32_t mac_reg[0x8000];
     uint16_t phy_reg[0x20];
@@ -151,14 +152,6 @@ static const char phy_regcap[0x20] = {
 };
 
 static void
-ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr,
-           pcibus_t size, int type)
-{
-    DBGOUT(IO, "e1000_ioport_map addr=0x%04"FMT_PCIBUS
-           " size=0x%08"FMT_PCIBUS"\n", addr, size);
-}
-
-static void
 set_interrupt_cause(E1000State *s, int index, uint32_t val)
 {
     if (val)
@@ -905,7 +898,8 @@ static void (*macreg_writeops[])(E1000State *, int, uint32_t) = {
 enum { NWRITEOPS = ARRAY_SIZE(macreg_writeops) };
 
 static void
-e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+e1000_mmio_write(void *opaque, target_phys_addr_t addr, uint64_t val,
+                 unsigned size)
 {
     E1000State *s = opaque;
     unsigned int index = (addr & 0x1ffff) >> 2;
@@ -913,31 +907,15 @@ e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
     if (index < NWRITEOPS && macreg_writeops[index]) {
         macreg_writeops[index](s, index, val);
     } else if (index < NREADOPS && macreg_readops[index]) {
-        DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04x\n", index<<2, val);
+        DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04"PRIx64"\n", index<<2, val);
     } else {
-        DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08x\n",
+        DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08"PRIx64"\n",
                index<<2, val);
     }
 }
 
-static void
-e1000_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    // emulate hw without byte enables: no RMW
-    e1000_mmio_writel(opaque, addr & ~3,
-                      (val & 0xffff) << (8*(addr & 3)));
-}
-
-static void
-e1000_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    // emulate hw without byte enables: no RMW
-    e1000_mmio_writel(opaque, addr & ~3,
-                      (val & 0xff) << (8*(addr & 3)));
-}
-
-static uint32_t
-e1000_mmio_readl(void *opaque, target_phys_addr_t addr)
+static uint64_t
+e1000_mmio_read(void *opaque, target_phys_addr_t addr, unsigned size)
 {
     E1000State *s = opaque;
     unsigned int index = (addr & 0x1ffff) >> 2;
@@ -950,20 +928,39 @@ e1000_mmio_readl(void *opaque, target_phys_addr_t addr)
     return 0;
 }
 
-static uint32_t
-e1000_mmio_readb(void *opaque, target_phys_addr_t addr)
+static MemoryRegionOps e1000_mmio_ops = {
+    .read = e1000_mmio_read,
+    .write = e1000_mmio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+};
+
+static uint64_t e1000_io_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
 {
-    return ((e1000_mmio_readl(opaque, addr & ~3)) >>
-            (8 * (addr & 3))) & 0xff;
+    E1000State *s = opaque;
+
+    (void)s;
+    return 0;
 }
 
-static uint32_t
-e1000_mmio_readw(void *opaque, target_phys_addr_t addr)
+static void e1000_io_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t val, unsigned size)
 {
-    return ((e1000_mmio_readl(opaque, addr & ~3)) >>
-            (8 * (addr & 3))) & 0xffff;
+    E1000State *s = opaque;
+
+    (void)s;
 }
 
+static MemoryRegionOps e1000_io_ops = {
+    .read = e1000_io_read,
+    .write = e1000_io_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static bool is_version_1(void *opaque, int version_id)
 {
     return version_id == 1;
@@ -1083,36 +1080,22 @@ static const uint32_t mac_reg_init[] = {
 
 /* PCI interface */
 
-static CPUWriteMemoryFunc * const e1000_mmio_write[] = {
-    e1000_mmio_writeb,	e1000_mmio_writew,	e1000_mmio_writel
-};
-
-static CPUReadMemoryFunc * const e1000_mmio_read[] = {
-    e1000_mmio_readb,	e1000_mmio_readw,	e1000_mmio_readl
-};
-
 static void
-e1000_mmio_map(PCIDevice *pci_dev, int region_num,
-                pcibus_t addr, pcibus_t size, int type)
+e1000_mmio_setup(E1000State *d)
 {
-    E1000State *d = DO_UPCAST(E1000State, dev, pci_dev);
     int i;
     const uint32_t excluded_regs[] = {
         E1000_MDIC, E1000_ICR, E1000_ICS, E1000_IMS,
         E1000_IMC, E1000_TCTL, E1000_TDT, PNPMMIO_SIZE
     };
 
-
-    DBGOUT(MMIO, "e1000_mmio_map addr=0x%08"FMT_PCIBUS" 0x%08"FMT_PCIBUS"\n",
-           addr, size);
-
-    cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
-    qemu_register_coalesced_mmio(addr, excluded_regs[0]);
-
+    memory_region_init_io(&d->mmio, &e1000_mmio_ops, d, "e1000-mmio",
+                          PNPMMIO_SIZE);
+    memory_region_add_coalescing(&d->mmio, 0, excluded_regs[0]);
     for (i = 0; excluded_regs[i] != PNPMMIO_SIZE; i++)
-        qemu_register_coalesced_mmio(addr + excluded_regs[i] + 4,
-                                     excluded_regs[i + 1] -
-                                     excluded_regs[i] - 4);
+        memory_region_add_coalescing(&d->mmio, excluded_regs[i] + 4,
+                                     excluded_regs[i+1] - excluded_regs[i] - 4);
+    memory_region_init_io(&d->io, &e1000_io_ops, d, "e1000-io", IOPORT_SIZE);
 }
 
 static void
@@ -1128,7 +1111,8 @@ pci_e1000_uninit(PCIDevice *dev)
 {
     E1000State *d = DO_UPCAST(E1000State, dev, dev);
 
-    cpu_unregister_io_memory(d->mmio_index);
+    memory_region_destroy(&d->mmio);
+    memory_region_destroy(&d->io);
     qemu_del_vlan_client(&d->nic->nc);
     return 0;
 }
@@ -1172,14 +1156,12 @@ static int pci_e1000_init(PCIDevice *pci_dev)
     /* TODO: RST# value should be 0 if programmable, PCI spec 6.2.4 */
     pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
 
-    d->mmio_index = cpu_register_io_memory(e1000_mmio_read,
-            e1000_mmio_write, d, DEVICE_LITTLE_ENDIAN);
+    e1000_mmio_setup(d);
 
-    pci_register_bar(&d->dev, 0, PNPMMIO_SIZE,
-                           PCI_BASE_ADDRESS_SPACE_MEMORY, e1000_mmio_map);
+    pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                            &d->mmio);
 
-    pci_register_bar(&d->dev, 1, IOPORT_SIZE,
-                           PCI_BASE_ADDRESS_SPACE_IO, ioport_map);
+    pci_register_bar_region(&d->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->io);
 
     memmove(d->eeprom_data, e1000_eeprom_template,
         sizeof e1000_eeprom_template);
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 33/56] eepro100: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Note: the existing code aliases the flash BAR into the MMIO bar.  This is
probably a bug.  This patch does not correct the problem.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/eepro100.c |  182 ++++++++++++---------------------------------------------
 1 files changed, 37 insertions(+), 145 deletions(-)

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 9b6f4a5..7b4171f 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -228,13 +228,14 @@ typedef struct {
     PCIDevice dev;
     /* Hash register (multicast mask array, multiple individual addresses). */
     uint8_t mult[8];
-    int mmio_index;
+    MemoryRegion mmio_bar;
+    MemoryRegion io_bar;
+    MemoryRegion flash_bar;
     NICState *nic;
     NICConf conf;
     uint8_t scb_stat;           /* SCB stat/ack byte */
     uint8_t int_stat;           /* PCI interrupt status */
     /* region must not be saved by nic_save. */
-    uint32_t region1;           /* PCI region 1 address */
     uint16_t mdimem[32];
     eeprom_t *eeprom;
     uint32_t device;            /* device variant */
@@ -1584,147 +1585,36 @@ static void eepro100_write4(EEPRO100State * s, uint32_t addr, uint32_t val)
     }
 }
 
-/*****************************************************************************
- *
- * Port mapped I/O.
- *
- ****************************************************************************/
-
-static uint32_t ioport_read1(void *opaque, uint32_t addr)
-{
-    EEPRO100State *s = opaque;
-#if 0
-    logout("addr=%s\n", regname(addr));
-#endif
-    return eepro100_read1(s, addr - s->region1);
-}
-
-static uint32_t ioport_read2(void *opaque, uint32_t addr)
-{
-    EEPRO100State *s = opaque;
-    return eepro100_read2(s, addr - s->region1);
-}
-
-static uint32_t ioport_read4(void *opaque, uint32_t addr)
-{
-    EEPRO100State *s = opaque;
-    return eepro100_read4(s, addr - s->region1);
-}
-
-static void ioport_write1(void *opaque, uint32_t addr, uint32_t val)
-{
-    EEPRO100State *s = opaque;
-#if 0
-    logout("addr=%s val=0x%02x\n", regname(addr), val);
-#endif
-    eepro100_write1(s, addr - s->region1, val);
-}
-
-static void ioport_write2(void *opaque, uint32_t addr, uint32_t val)
-{
-    EEPRO100State *s = opaque;
-    eepro100_write2(s, addr - s->region1, val);
-}
-
-static void ioport_write4(void *opaque, uint32_t addr, uint32_t val)
-{
-    EEPRO100State *s = opaque;
-    eepro100_write4(s, addr - s->region1, val);
-}
-
-/***********************************************************/
-/* PCI EEPRO100 definitions */
-
-static void pci_map(PCIDevice * pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
-{
-    EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
-
-    TRACE(OTHER, logout("region %d, addr=0x%08"FMT_PCIBUS", "
-          "size=0x%08"FMT_PCIBUS", type=%d\n",
-          region_num, addr, size, type));
-
-    assert(region_num == 1);
-    register_ioport_write(addr, size, 1, ioport_write1, s);
-    register_ioport_read(addr, size, 1, ioport_read1, s);
-    register_ioport_write(addr, size, 2, ioport_write2, s);
-    register_ioport_read(addr, size, 2, ioport_read2, s);
-    register_ioport_write(addr, size, 4, ioport_write4, s);
-    register_ioport_read(addr, size, 4, ioport_read4, s);
-
-    s->region1 = addr;
-}
-
-/*****************************************************************************
- *
- * Memory mapped I/O.
- *
- ****************************************************************************/
-
-static void pci_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    EEPRO100State *s = opaque;
-#if 0
-    logout("addr=%s val=0x%02x\n", regname(addr), val);
-#endif
-    eepro100_write1(s, addr, val);
-}
-
-static void pci_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
+static uint64_t eepro100_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
 {
     EEPRO100State *s = opaque;
-#if 0
-    logout("addr=%s val=0x%02x\n", regname(addr), val);
-#endif
-    eepro100_write2(s, addr, val);
-}
 
-static void pci_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    EEPRO100State *s = opaque;
-#if 0
-    logout("addr=%s val=0x%02x\n", regname(addr), val);
-#endif
-    eepro100_write4(s, addr, val);
-}
-
-static uint32_t pci_mmio_readb(void *opaque, target_phys_addr_t addr)
-{
-    EEPRO100State *s = opaque;
-#if 0
-    logout("addr=%s\n", regname(addr));
-#endif
-    return eepro100_read1(s, addr);
+    switch (size) {
+    case 1: return eepro100_read1(s, addr);
+    case 2: return eepro100_read2(s, addr);
+    case 4: return eepro100_read4(s, addr);
+    default: abort();
+    }
 }
 
-static uint32_t pci_mmio_readw(void *opaque, target_phys_addr_t addr)
+static void eepro100_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t data, unsigned size)
 {
     EEPRO100State *s = opaque;
-#if 0
-    logout("addr=%s\n", regname(addr));
-#endif
-    return eepro100_read2(s, addr);
-}
 
-static uint32_t pci_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
-    EEPRO100State *s = opaque;
-#if 0
-    logout("addr=%s\n", regname(addr));
-#endif
-    return eepro100_read4(s, addr);
+    switch (size) {
+    case 1: return eepro100_write1(s, addr, data);
+    case 2: return eepro100_write2(s, addr, data);
+    case 4: return eepro100_write4(s, addr, data);
+    default: abort();
+    }
 }
 
-static CPUWriteMemoryFunc * const pci_mmio_write[] = {
-    pci_mmio_writeb,
-    pci_mmio_writew,
-    pci_mmio_writel
-};
-
-static CPUReadMemoryFunc * const pci_mmio_read[] = {
-    pci_mmio_readb,
-    pci_mmio_readw,
-    pci_mmio_readl
+static MemoryRegionOps eepro100_ops = {
+    .read = eepro100_read,
+    .write = eepro100_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static int nic_can_receive(VLANClientState *nc)
@@ -1953,7 +1843,9 @@ static int pci_nic_uninit(PCIDevice *pci_dev)
 {
     EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
 
-    cpu_unregister_io_memory(s->mmio_index);
+    memory_region_destroy(&s->mmio_bar);
+    memory_region_destroy(&s->io_bar);
+    memory_region_destroy(&s->flash_bar);
     vmstate_unregister(&pci_dev->qdev, s->vmstate, s);
     eeprom93xx_free(&pci_dev->qdev, s->eeprom);
     qemu_del_vlan_client(&s->nic->nc);
@@ -1985,20 +1877,20 @@ static int e100_nic_init(PCIDevice *pci_dev)
     s->eeprom = eeprom93xx_new(&pci_dev->qdev, EEPROM_SIZE);
 
     /* Handler for memory-mapped I/O */
-    s->mmio_index =
-        cpu_register_io_memory(pci_mmio_read, pci_mmio_write, s,
-                               DEVICE_LITTLE_ENDIAN);
-
-    pci_register_bar_simple(&s->dev, 0, PCI_MEM_SIZE,
-                            PCI_BASE_ADDRESS_MEM_PREFETCH, s->mmio_index);
-
-    pci_register_bar(&s->dev, 1, PCI_IO_SIZE, PCI_BASE_ADDRESS_SPACE_IO,
-                           pci_map);
-    pci_register_bar_simple(&s->dev, 2, PCI_FLASH_SIZE, 0, s->mmio_index);
+    memory_region_init_io(&s->mmio_bar, &eepro100_ops, s, "eepro100-mmio",
+                          PCI_MEM_SIZE);
+    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH,
+                            &s->mmio_bar);
+    memory_region_init_io(&s->io_bar, &eepro100_ops, s, "eepro100-io",
+                          PCI_IO_SIZE);
+    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
+    /* FIXME: flash aliases to mmio?! */
+    memory_region_init_io(&s->flash_bar, &eepro100_ops, s, "eepro100-flash",
+                          PCI_FLASH_SIZE);
+    pci_register_bar_region(&s->dev, 2, 0, &s->flash_bar);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     logout("macaddr: %s\n", nic_dump(&s->conf.macaddr.a[0], 6));
-    assert(s->region1 == 0);
 
     nic_reset(s);
 
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 33/56] eepro100: convert to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Note: the existing code aliases the flash BAR into the MMIO bar.  This is
probably a bug.  This patch does not correct the problem.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/eepro100.c |  182 ++++++++++++---------------------------------------------
 1 files changed, 37 insertions(+), 145 deletions(-)

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 9b6f4a5..7b4171f 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -228,13 +228,14 @@ typedef struct {
     PCIDevice dev;
     /* Hash register (multicast mask array, multiple individual addresses). */
     uint8_t mult[8];
-    int mmio_index;
+    MemoryRegion mmio_bar;
+    MemoryRegion io_bar;
+    MemoryRegion flash_bar;
     NICState *nic;
     NICConf conf;
     uint8_t scb_stat;           /* SCB stat/ack byte */
     uint8_t int_stat;           /* PCI interrupt status */
     /* region must not be saved by nic_save. */
-    uint32_t region1;           /* PCI region 1 address */
     uint16_t mdimem[32];
     eeprom_t *eeprom;
     uint32_t device;            /* device variant */
@@ -1584,147 +1585,36 @@ static void eepro100_write4(EEPRO100State * s, uint32_t addr, uint32_t val)
     }
 }
 
-/*****************************************************************************
- *
- * Port mapped I/O.
- *
- ****************************************************************************/
-
-static uint32_t ioport_read1(void *opaque, uint32_t addr)
-{
-    EEPRO100State *s = opaque;
-#if 0
-    logout("addr=%s\n", regname(addr));
-#endif
-    return eepro100_read1(s, addr - s->region1);
-}
-
-static uint32_t ioport_read2(void *opaque, uint32_t addr)
-{
-    EEPRO100State *s = opaque;
-    return eepro100_read2(s, addr - s->region1);
-}
-
-static uint32_t ioport_read4(void *opaque, uint32_t addr)
-{
-    EEPRO100State *s = opaque;
-    return eepro100_read4(s, addr - s->region1);
-}
-
-static void ioport_write1(void *opaque, uint32_t addr, uint32_t val)
-{
-    EEPRO100State *s = opaque;
-#if 0
-    logout("addr=%s val=0x%02x\n", regname(addr), val);
-#endif
-    eepro100_write1(s, addr - s->region1, val);
-}
-
-static void ioport_write2(void *opaque, uint32_t addr, uint32_t val)
-{
-    EEPRO100State *s = opaque;
-    eepro100_write2(s, addr - s->region1, val);
-}
-
-static void ioport_write4(void *opaque, uint32_t addr, uint32_t val)
-{
-    EEPRO100State *s = opaque;
-    eepro100_write4(s, addr - s->region1, val);
-}
-
-/***********************************************************/
-/* PCI EEPRO100 definitions */
-
-static void pci_map(PCIDevice * pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
-{
-    EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
-
-    TRACE(OTHER, logout("region %d, addr=0x%08"FMT_PCIBUS", "
-          "size=0x%08"FMT_PCIBUS", type=%d\n",
-          region_num, addr, size, type));
-
-    assert(region_num == 1);
-    register_ioport_write(addr, size, 1, ioport_write1, s);
-    register_ioport_read(addr, size, 1, ioport_read1, s);
-    register_ioport_write(addr, size, 2, ioport_write2, s);
-    register_ioport_read(addr, size, 2, ioport_read2, s);
-    register_ioport_write(addr, size, 4, ioport_write4, s);
-    register_ioport_read(addr, size, 4, ioport_read4, s);
-
-    s->region1 = addr;
-}
-
-/*****************************************************************************
- *
- * Memory mapped I/O.
- *
- ****************************************************************************/
-
-static void pci_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    EEPRO100State *s = opaque;
-#if 0
-    logout("addr=%s val=0x%02x\n", regname(addr), val);
-#endif
-    eepro100_write1(s, addr, val);
-}
-
-static void pci_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
+static uint64_t eepro100_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
 {
     EEPRO100State *s = opaque;
-#if 0
-    logout("addr=%s val=0x%02x\n", regname(addr), val);
-#endif
-    eepro100_write2(s, addr, val);
-}
 
-static void pci_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    EEPRO100State *s = opaque;
-#if 0
-    logout("addr=%s val=0x%02x\n", regname(addr), val);
-#endif
-    eepro100_write4(s, addr, val);
-}
-
-static uint32_t pci_mmio_readb(void *opaque, target_phys_addr_t addr)
-{
-    EEPRO100State *s = opaque;
-#if 0
-    logout("addr=%s\n", regname(addr));
-#endif
-    return eepro100_read1(s, addr);
+    switch (size) {
+    case 1: return eepro100_read1(s, addr);
+    case 2: return eepro100_read2(s, addr);
+    case 4: return eepro100_read4(s, addr);
+    default: abort();
+    }
 }
 
-static uint32_t pci_mmio_readw(void *opaque, target_phys_addr_t addr)
+static void eepro100_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t data, unsigned size)
 {
     EEPRO100State *s = opaque;
-#if 0
-    logout("addr=%s\n", regname(addr));
-#endif
-    return eepro100_read2(s, addr);
-}
 
-static uint32_t pci_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
-    EEPRO100State *s = opaque;
-#if 0
-    logout("addr=%s\n", regname(addr));
-#endif
-    return eepro100_read4(s, addr);
+    switch (size) {
+    case 1: return eepro100_write1(s, addr, data);
+    case 2: return eepro100_write2(s, addr, data);
+    case 4: return eepro100_write4(s, addr, data);
+    default: abort();
+    }
 }
 
-static CPUWriteMemoryFunc * const pci_mmio_write[] = {
-    pci_mmio_writeb,
-    pci_mmio_writew,
-    pci_mmio_writel
-};
-
-static CPUReadMemoryFunc * const pci_mmio_read[] = {
-    pci_mmio_readb,
-    pci_mmio_readw,
-    pci_mmio_readl
+static MemoryRegionOps eepro100_ops = {
+    .read = eepro100_read,
+    .write = eepro100_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static int nic_can_receive(VLANClientState *nc)
@@ -1953,7 +1843,9 @@ static int pci_nic_uninit(PCIDevice *pci_dev)
 {
     EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
 
-    cpu_unregister_io_memory(s->mmio_index);
+    memory_region_destroy(&s->mmio_bar);
+    memory_region_destroy(&s->io_bar);
+    memory_region_destroy(&s->flash_bar);
     vmstate_unregister(&pci_dev->qdev, s->vmstate, s);
     eeprom93xx_free(&pci_dev->qdev, s->eeprom);
     qemu_del_vlan_client(&s->nic->nc);
@@ -1985,20 +1877,20 @@ static int e100_nic_init(PCIDevice *pci_dev)
     s->eeprom = eeprom93xx_new(&pci_dev->qdev, EEPROM_SIZE);
 
     /* Handler for memory-mapped I/O */
-    s->mmio_index =
-        cpu_register_io_memory(pci_mmio_read, pci_mmio_write, s,
-                               DEVICE_LITTLE_ENDIAN);
-
-    pci_register_bar_simple(&s->dev, 0, PCI_MEM_SIZE,
-                            PCI_BASE_ADDRESS_MEM_PREFETCH, s->mmio_index);
-
-    pci_register_bar(&s->dev, 1, PCI_IO_SIZE, PCI_BASE_ADDRESS_SPACE_IO,
-                           pci_map);
-    pci_register_bar_simple(&s->dev, 2, PCI_FLASH_SIZE, 0, s->mmio_index);
+    memory_region_init_io(&s->mmio_bar, &eepro100_ops, s, "eepro100-mmio",
+                          PCI_MEM_SIZE);
+    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH,
+                            &s->mmio_bar);
+    memory_region_init_io(&s->io_bar, &eepro100_ops, s, "eepro100-io",
+                          PCI_IO_SIZE);
+    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
+    /* FIXME: flash aliases to mmio?! */
+    memory_region_init_io(&s->flash_bar, &eepro100_ops, s, "eepro100-flash",
+                          PCI_FLASH_SIZE);
+    pci_register_bar_region(&s->dev, 2, 0, &s->flash_bar);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     logout("macaddr: %s\n", nic_dump(&s->conf.macaddr.a[0], 6));
-    assert(s->region1 == 0);
 
     nic_reset(s);
 
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 34/56] es1370: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/es1370.c |   62 ++++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 43 insertions(+), 19 deletions(-)

diff --git a/hw/es1370.c b/hw/es1370.c
index 1ed62b7..a696eb2 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -268,6 +268,7 @@ struct chan {
 typedef struct ES1370State {
     PCIDevice dev;
     QEMUSoundCard card;
+    MemoryRegion io;
     struct chan chan[NB_CHANNELS];
     SWVoiceOut *dac_voice[2];
     SWVoiceIn *adc_voice;
@@ -775,6 +776,37 @@ IO_READ_PROTO (es1370_readl)
     return val;
 }
 
+static uint64_t es1370_read(void *opaque, target_phys_addr_t addr,
+                            unsigned size)
+{
+    ES1370State *s = opaque;
+
+    switch (addr) {
+    case 1: return es1370_readb(s, addr);
+    case 2: return es1370_readw(s, addr);
+    case 4: return es1370_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void es1370_write(void *opaque, target_phys_addr_t addr,
+                         uint64_t data, unsigned size)
+{
+    ES1370State *s = opaque;
+
+    switch (addr) {
+    case 1: return es1370_writeb(s, addr, data);
+    case 2: return es1370_writew(s, addr, data);
+    case 4: return es1370_writel(s, addr, data);
+    default: abort();
+    }
+}
+
+static MemoryRegionOps es1370_io_ops = {
+    .read = es1370_read,
+    .write = es1370_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
 
 static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel,
                                    int max, int *irq)
@@ -906,24 +938,6 @@ static void es1370_adc_callback (void *opaque, int avail)
     es1370_run_channel (s, ADC_CHANNEL, avail);
 }
 
-static void es1370_map (PCIDevice *pci_dev, int region_num,
-                        pcibus_t addr, pcibus_t size, int type)
-{
-    ES1370State *s = DO_UPCAST (ES1370State, dev, pci_dev);
-
-    (void) region_num;
-    (void) size;
-    (void) type;
-
-    register_ioport_write (addr, 0x40 * 4, 1, es1370_writeb, s);
-    register_ioport_write (addr, 0x40 * 2, 2, es1370_writew, s);
-    register_ioport_write (addr, 0x40, 4, es1370_writel, s);
-
-    register_ioport_read (addr, 0x40 * 4, 1, es1370_readb, s);
-    register_ioport_read (addr, 0x40 * 2, 2, es1370_readw, s);
-    register_ioport_read (addr, 0x40, 4, es1370_readl, s);
-}
-
 static const VMStateDescription vmstate_es1370_channel = {
     .name = "es1370_channel",
     .version_id = 2,
@@ -1011,7 +1025,8 @@ static int es1370_initfn (PCIDevice *dev)
     c[PCI_MIN_GNT] = 0x0c;
     c[PCI_MAX_LAT] = 0x80;
 
-    pci_register_bar (&s->dev, 0, 256, PCI_BASE_ADDRESS_SPACE_IO, es1370_map);
+    memory_region_init_io(&s->io, &es1370_io_ops, s, "es1370", 256);
+    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
     qemu_register_reset (es1370_on_reset, s);
 
     AUD_register_card ("es1370", &s->card);
@@ -1019,6 +1034,14 @@ static int es1370_initfn (PCIDevice *dev)
     return 0;
 }
 
+static int es1370_exitfn(PCIDevice *dev)
+{
+    ES1370State *s = DO_UPCAST (ES1370State, dev, dev);
+
+    memory_region_destroy(&s->io);
+    return 0;
+}
+
 int es1370_init (PCIBus *bus)
 {
     pci_create_simple (bus, -1, "ES1370");
@@ -1031,6 +1054,7 @@ static PCIDeviceInfo es1370_info = {
     .qdev.size    = sizeof (ES1370State),
     .qdev.vmsd    = &vmstate_es1370,
     .init         = es1370_initfn,
+    .exit         = es1370_exitfn,
     .vendor_id    = PCI_VENDOR_ID_ENSONIQ,
     .device_id    = PCI_DEVICE_ID_ENSONIQ_ES1370,
     .class_id     = PCI_CLASS_MULTIMEDIA_AUDIO,
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 34/56] es1370: convert to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/es1370.c |   62 ++++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 43 insertions(+), 19 deletions(-)

diff --git a/hw/es1370.c b/hw/es1370.c
index 1ed62b7..a696eb2 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -268,6 +268,7 @@ struct chan {
 typedef struct ES1370State {
     PCIDevice dev;
     QEMUSoundCard card;
+    MemoryRegion io;
     struct chan chan[NB_CHANNELS];
     SWVoiceOut *dac_voice[2];
     SWVoiceIn *adc_voice;
@@ -775,6 +776,37 @@ IO_READ_PROTO (es1370_readl)
     return val;
 }
 
+static uint64_t es1370_read(void *opaque, target_phys_addr_t addr,
+                            unsigned size)
+{
+    ES1370State *s = opaque;
+
+    switch (addr) {
+    case 1: return es1370_readb(s, addr);
+    case 2: return es1370_readw(s, addr);
+    case 4: return es1370_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void es1370_write(void *opaque, target_phys_addr_t addr,
+                         uint64_t data, unsigned size)
+{
+    ES1370State *s = opaque;
+
+    switch (addr) {
+    case 1: return es1370_writeb(s, addr, data);
+    case 2: return es1370_writew(s, addr, data);
+    case 4: return es1370_writel(s, addr, data);
+    default: abort();
+    }
+}
+
+static MemoryRegionOps es1370_io_ops = {
+    .read = es1370_read,
+    .write = es1370_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
 
 static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel,
                                    int max, int *irq)
@@ -906,24 +938,6 @@ static void es1370_adc_callback (void *opaque, int avail)
     es1370_run_channel (s, ADC_CHANNEL, avail);
 }
 
-static void es1370_map (PCIDevice *pci_dev, int region_num,
-                        pcibus_t addr, pcibus_t size, int type)
-{
-    ES1370State *s = DO_UPCAST (ES1370State, dev, pci_dev);
-
-    (void) region_num;
-    (void) size;
-    (void) type;
-
-    register_ioport_write (addr, 0x40 * 4, 1, es1370_writeb, s);
-    register_ioport_write (addr, 0x40 * 2, 2, es1370_writew, s);
-    register_ioport_write (addr, 0x40, 4, es1370_writel, s);
-
-    register_ioport_read (addr, 0x40 * 4, 1, es1370_readb, s);
-    register_ioport_read (addr, 0x40 * 2, 2, es1370_readw, s);
-    register_ioport_read (addr, 0x40, 4, es1370_readl, s);
-}
-
 static const VMStateDescription vmstate_es1370_channel = {
     .name = "es1370_channel",
     .version_id = 2,
@@ -1011,7 +1025,8 @@ static int es1370_initfn (PCIDevice *dev)
     c[PCI_MIN_GNT] = 0x0c;
     c[PCI_MAX_LAT] = 0x80;
 
-    pci_register_bar (&s->dev, 0, 256, PCI_BASE_ADDRESS_SPACE_IO, es1370_map);
+    memory_region_init_io(&s->io, &es1370_io_ops, s, "es1370", 256);
+    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
     qemu_register_reset (es1370_on_reset, s);
 
     AUD_register_card ("es1370", &s->card);
@@ -1019,6 +1034,14 @@ static int es1370_initfn (PCIDevice *dev)
     return 0;
 }
 
+static int es1370_exitfn(PCIDevice *dev)
+{
+    ES1370State *s = DO_UPCAST (ES1370State, dev, dev);
+
+    memory_region_destroy(&s->io);
+    return 0;
+}
+
 int es1370_init (PCIBus *bus)
 {
     pci_create_simple (bus, -1, "ES1370");
@@ -1031,6 +1054,7 @@ static PCIDeviceInfo es1370_info = {
     .qdev.size    = sizeof (ES1370State),
     .qdev.vmsd    = &vmstate_es1370,
     .init         = es1370_initfn,
+    .exit         = es1370_exitfn,
     .vendor_id    = PCI_VENDOR_ID_ENSONIQ,
     .device_id    = PCI_DEVICE_ID_ENSONIQ_ES1370,
     .class_id     = PCI_CLASS_MULTIMEDIA_AUDIO,
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 35/56] ide: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/ide/cmd646.c |  208 +++++++++++++++++++++++++++++++++++--------------------
 hw/ide/pci.c    |   25 ++++---
 hw/ide/pci.h    |   19 ++++-
 hw/ide/piix.c   |   64 +++++++++++++----
 hw/ide/via.c    |   65 +++++++++++++----
 5 files changed, 261 insertions(+), 120 deletions(-)

diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 56302b5..699ad6b 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -44,35 +44,95 @@
 
 static void cmd646_update_irq(PCIIDEState *d);
 
-static void ide_map(PCIDevice *pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
+static uint64_t cmd646_cmd_read(void *opaque, target_phys_addr_t addr,
+                                unsigned size)
 {
-    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
-    IDEBus *bus;
-
-    if (region_num <= 3) {
-        bus = &d->bus[(region_num >> 1)];
-        if (region_num & 1) {
-            register_ioport_read(addr + 2, 1, 1, ide_status_read, bus);
-            register_ioport_write(addr + 2, 1, 1, ide_cmd_write, bus);
+    CMD646BAR *cmd646bar = opaque;
+
+    if (addr != 2 || size != 1) {
+        return ((uint64_t)1 << (size * 8)) - 1;
+    }
+    return ide_status_read(cmd646bar->bus, addr + 2);
+}
+
+static void cmd646_cmd_write(void *opaque, target_phys_addr_t addr,
+                             uint64_t data, unsigned size)
+{
+    CMD646BAR *cmd646bar = opaque;
+
+    if (addr != 2 || size != 1) {
+        return;
+    }
+    ide_cmd_write(cmd646bar->bus, addr + 2, data);
+}
+
+static MemoryRegionOps cmd646_cmd_ops = {
+    .read = cmd646_cmd_read,
+    .write = cmd646_cmd_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static uint64_t cmd646_data_read(void *opaque, target_phys_addr_t addr,
+                                 unsigned size)
+{
+    CMD646BAR *cmd646bar = opaque;
+
+    if (size == 1) {
+        return ide_ioport_read(cmd646bar->bus, addr);
+    } else if (addr == 0) {
+        if (size == 2) {
+            return ide_data_readw(cmd646bar->bus, addr);
         } else {
-            register_ioport_write(addr, 8, 1, ide_ioport_write, bus);
-            register_ioport_read(addr, 8, 1, ide_ioport_read, bus);
-
-            /* data ports */
-            register_ioport_write(addr, 2, 2, ide_data_writew, bus);
-            register_ioport_read(addr, 2, 2, ide_data_readw, bus);
-            register_ioport_write(addr, 4, 4, ide_data_writel, bus);
-            register_ioport_read(addr, 4, 4, ide_data_readl, bus);
+            return ide_data_readl(cmd646bar->bus, addr);
         }
     }
+    return ((uint64_t)1 << (size * 8)) - 1;
 }
 
-static uint32_t bmdma_readb_common(PCIIDEState *pci_dev, BMDMAState *bm,
-                                   uint32_t addr)
+static void cmd646_data_write(void *opaque, target_phys_addr_t addr,
+                             uint64_t data, unsigned size)
 {
+    CMD646BAR *cmd646bar = opaque;
+
+    if (size == 1) {
+        return ide_ioport_write(cmd646bar->bus, addr, data);
+    } else if (addr == 0) {
+        if (size == 2) {
+            return ide_data_writew(cmd646bar->bus, addr, data);
+        } else {
+            return ide_data_writel(cmd646bar->bus, addr, data);
+        }
+    }
+}
+
+static MemoryRegionOps cmd646_data_ops = {
+    .read = cmd646_data_read,
+    .write = cmd646_data_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void setup_cmd646_bar(PCIIDEState *d, int bus_num)
+{
+    IDEBus *bus = &d->bus[bus_num];
+    CMD646BAR *bar = &d->cmd646_bar[bus_num];
+
+    bar->bus = bus;
+    bar->pci_dev = d;
+    memory_region_init_io(&bar->cmd, &cmd646_cmd_ops, bar, "cmd646-cmd", 4);
+    memory_region_init_io(&bar->data, &cmd646_data_ops, bar, "cmd646-data", 8);
+}
+
+static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr,
+                           unsigned size)
+{
+    BMDMAState *bm = opaque;
+    PCIIDEState *pci_dev = bm->pci_dev;
     uint32_t val;
 
+    if (size != 1) {
+        return ((uint64_t)1 << (size * 8)) - 1;
+    }
+
     switch(addr & 3) {
     case 0:
         val = bm->cmd;
@@ -100,31 +160,22 @@ static uint32_t bmdma_readb_common(PCIIDEState *pci_dev, BMDMAState *bm,
     return val;
 }
 
-static uint32_t bmdma_readb_0(void *opaque, uint32_t addr)
+static void bmdma_write(void *opaque, target_phys_addr_t addr,
+                        uint64_t val, unsigned size)
 {
-    PCIIDEState *pci_dev = opaque;
-    BMDMAState *bm = &pci_dev->bmdma[0];
-
-    return bmdma_readb_common(pci_dev, bm, addr);
-}
+    BMDMAState *bm = opaque;
+    PCIIDEState *pci_dev = bm->pci_dev;
 
-static uint32_t bmdma_readb_1(void *opaque, uint32_t addr)
-{
-    PCIIDEState *pci_dev = opaque;
-    BMDMAState *bm = &pci_dev->bmdma[1];
-
-    return bmdma_readb_common(pci_dev, bm, addr);
-}
+    if (size != 1) {
+        return;
+    }
 
-static void bmdma_writeb_common(PCIIDEState *pci_dev, BMDMAState *bm,
-                                uint32_t addr, uint32_t val)
-{
 #ifdef DEBUG_IDE
     printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
 #endif
     switch(addr & 3) {
     case 0:
-        bmdma_cmd_writeb(bm, addr, val);
+        bmdma_cmd_writeb(bm, val);
         break;
     case 1:
         pci_dev->dev.config[MRDMODE] =
@@ -143,42 +194,25 @@ static void bmdma_writeb_common(PCIIDEState *pci_dev, BMDMAState *bm,
     }
 }
 
-static void bmdma_writeb_0(void *opaque, uint32_t addr, uint32_t val)
-{
-    PCIIDEState *pci_dev = opaque;
-    BMDMAState *bm = &pci_dev->bmdma[0];
-
-    bmdma_writeb_common(pci_dev, bm, addr, val);
-}
-
-static void bmdma_writeb_1(void *opaque, uint32_t addr, uint32_t val)
-{
-    PCIIDEState *pci_dev = opaque;
-    BMDMAState *bm = &pci_dev->bmdma[1];
-
-    bmdma_writeb_common(pci_dev, bm, addr, val);
-}
+static MemoryRegionOps cmd646_bmdma_ops = {
+    .read = bmdma_read,
+    .write = bmdma_write,
+};
 
-static void bmdma_map(PCIDevice *pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
+static void bmdma_setup_bar(PCIIDEState *d)
 {
-    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
+    BMDMAState *bm;
     int i;
 
+    memory_region_init(&d->bmdma_bar, "cmd646-bmdma", 16);
     for(i = 0;i < 2; i++) {
-        BMDMAState *bm = &d->bmdma[i];
-
-        if (i == 0) {
-            register_ioport_write(addr, 4, 1, bmdma_writeb_0, d);
-            register_ioport_read(addr, 4, 1, bmdma_readb_0, d);
-        } else {
-            register_ioport_write(addr, 4, 1, bmdma_writeb_1, d);
-            register_ioport_read(addr, 4, 1, bmdma_readb_1, d);
-        }
-
-        iorange_init(&bm->addr_ioport, &bmdma_addr_ioport_ops, addr + 4, 4);
-        ioport_register(&bm->addr_ioport);
-        addr += 8;
+        bm = &d->bmdma[i];
+        memory_region_init_io(&bm->extra_io, &cmd646_bmdma_ops, bm,
+                              "cmd646-bmdma-bus", 4);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
+        memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm,
+                              "cmd646-bmdma-ioport", 4);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
     }
 }
 
@@ -234,11 +268,18 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
         pci_conf[0x51] |= 0x08; /* enable IDE1 */
     }
 
-    pci_register_bar(dev, 0, 0x8, PCI_BASE_ADDRESS_SPACE_IO, ide_map);
-    pci_register_bar(dev, 1, 0x4, PCI_BASE_ADDRESS_SPACE_IO, ide_map);
-    pci_register_bar(dev, 2, 0x8, PCI_BASE_ADDRESS_SPACE_IO, ide_map);
-    pci_register_bar(dev, 3, 0x4, PCI_BASE_ADDRESS_SPACE_IO, ide_map);
-    pci_register_bar(dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO, bmdma_map);
+    setup_cmd646_bar(d, 0);
+    setup_cmd646_bar(d, 1);
+    pci_register_bar_region(dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
+                            &d->cmd646_bar[0].data);
+    pci_register_bar_region(dev, 1, PCI_BASE_ADDRESS_SPACE_IO,
+                            &d->cmd646_bar[0].cmd);
+    pci_register_bar_region(dev, 2, PCI_BASE_ADDRESS_SPACE_IO,
+                            &d->cmd646_bar[1].data);
+    pci_register_bar_region(dev, 3, PCI_BASE_ADDRESS_SPACE_IO,
+                            &d->cmd646_bar[2].cmd);
+    bmdma_setup_bar(d);
+    pci_register_bar_region(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
 
     /* TODO: RST# value should be 0 */
     pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
@@ -248,7 +289,7 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
         ide_bus_new(&d->bus[i], &d->dev.qdev, i);
         ide_init2(&d->bus[i], irq[i]);
 
-        bmdma_init(&d->bus[i], &d->bmdma[i]);
+        bmdma_init(&d->bus[i], &d->bmdma[i], d);
         d->bmdma[i].bus = &d->bus[i];
         qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
                                          &d->bmdma[i].dma);
@@ -259,6 +300,24 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
     return 0;
 }
 
+static int pci_cmd646_ide_exitfn(PCIDevice *dev)
+{
+    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
+    unsigned i;
+
+    for (i = 0; i < 2; ++i) {
+        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
+        memory_region_destroy(&d->bmdma[i].extra_io);
+        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
+        memory_region_destroy(&d->bmdma[i].addr_ioport);
+        memory_region_destroy(&d->cmd646_bar[i].cmd);
+        memory_region_destroy(&d->cmd646_bar[i].data);
+    }
+    memory_region_destroy(&d->bmdma_bar);
+
+    return 0;
+}
+
 void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
                          int secondary_ide_enabled)
 {
@@ -276,6 +335,7 @@ static PCIDeviceInfo cmd646_ide_info[] = {
         .qdev.name    = "cmd646-ide",
         .qdev.size    = sizeof(PCIIDEState),
         .init         = pci_cmd646_ide_initfn,
+        .exit         = pci_cmd646_ide_exitfn,
         .vendor_id    = PCI_VENDOR_ID_CMD,
         .device_id    = PCI_DEVICE_ID_CMD_646,
         .revision     = 0x07, // IDE controller revision
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 9f3050a..d1a14d7 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -287,9 +287,8 @@ static void bmdma_irq(void *opaque, int n, int level)
     qemu_set_irq(bm->irq, level);
 }
 
-void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
+void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
 {
-    BMDMAState *bm = opaque;
 #ifdef DEBUG_IDE
     printf("%s: 0x%08x\n", __func__, val);
 #endif
@@ -328,22 +327,24 @@ void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
     bm->cmd = val & 0x09;
 }
 
-static void bmdma_addr_read(IORange *ioport, uint64_t addr,
-                            unsigned width, uint64_t *data)
+static uint64_t bmdma_addr_read(void *opaque, target_phys_addr_t addr,
+                                unsigned width)
 {
-    BMDMAState *bm = container_of(ioport, BMDMAState, addr_ioport);
+    BMDMAState *bm = opaque;
     uint32_t mask = (1ULL << (width * 8)) - 1;
+    uint64_t data;
 
-    *data = (bm->addr >> (addr * 8)) & mask;
+    data = (bm->addr >> (addr * 8)) & mask;
 #ifdef DEBUG_IDE
     printf("%s: 0x%08x\n", __func__, (unsigned)*data);
 #endif
+    return data;
 }
 
-static void bmdma_addr_write(IORange *ioport, uint64_t addr,
-                             unsigned width, uint64_t data)
+static void bmdma_addr_write(void *opaque, target_phys_addr_t addr,
+                             uint64_t data, unsigned width)
 {
-    BMDMAState *bm = container_of(ioport, BMDMAState, addr_ioport);
+    BMDMAState *bm = opaque;
     int shift = addr * 8;
     uint32_t mask = (1ULL << (width * 8)) - 1;
 
@@ -354,9 +355,10 @@ static void bmdma_addr_write(IORange *ioport, uint64_t addr,
     bm->addr |= ((data & mask) << shift) & ~3;
 }
 
-const IORangeOps bmdma_addr_ioport_ops = {
+MemoryRegionOps bmdma_addr_ioport_ops = {
     .read = bmdma_addr_read,
     .write = bmdma_addr_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static bool ide_bmdma_current_needed(void *opaque)
@@ -514,7 +516,7 @@ static const struct IDEDMAOps bmdma_ops = {
     .reset = bmdma_reset,
 };
 
-void bmdma_init(IDEBus *bus, BMDMAState *bm)
+void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d)
 {
     qemu_irq *irq;
 
@@ -527,4 +529,5 @@ void bmdma_init(IDEBus *bus, BMDMAState *bm)
     bm->irq = bus->irq;
     irq = qemu_allocate_irqs(bmdma_irq, bm, 1);
     bus->irq = *irq;
+    bm->pci_dev = d;
 }
diff --git a/hw/ide/pci.h b/hw/ide/pci.h
index b4f3691..a694e54 100644
--- a/hw/ide/pci.h
+++ b/hw/ide/pci.h
@@ -19,20 +19,31 @@ typedef struct BMDMAState {
     BlockDriverCompletionFunc *dma_cb;
     int64_t sector_num;
     uint32_t nsector;
-    IORange addr_ioport;
+    MemoryRegion addr_ioport;
+    MemoryRegion extra_io;
     QEMUBH *bh;
     qemu_irq irq;
 
     /* Bit 0-2 and 7:   BM status register
      * Bit 3-6:         bus->error_status */
     uint8_t migration_compat_status;
+    struct PCIIDEState *pci_dev;
 } BMDMAState;
 
+typedef struct CMD646BAR {
+    MemoryRegion cmd;
+    MemoryRegion data;
+    IDEBus *bus;
+    struct PCIIDEState *pci_dev;
+} CMD646BAR;
+
 typedef struct PCIIDEState {
     PCIDevice dev;
     IDEBus bus[2];
     BMDMAState bmdma[2];
     uint32_t secondary; /* used only for cmd646 */
+    MemoryRegion bmdma_bar;
+    CMD646BAR cmd646_bar[2]; /* used only for cmd646 */
 } PCIIDEState;
 
 
@@ -43,9 +54,9 @@ static inline IDEState *bmdma_active_if(BMDMAState *bmdma)
 }
 
 
-void bmdma_init(IDEBus *bus, BMDMAState *bm);
-void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val);
-extern const IORangeOps bmdma_addr_ioport_ops;
+void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
+void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
+extern MemoryRegionOps bmdma_addr_ioport_ops;
 void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table);
 
 extern const VMStateDescription vmstate_ide_pci;
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 84f72b0..c11b960 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -33,11 +33,15 @@
 
 #include <hw/ide/pci.h>
 
-static uint32_t bmdma_readb(void *opaque, uint32_t addr)
+static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, unsigned size)
 {
     BMDMAState *bm = opaque;
     uint32_t val;
 
+    if (size != 1) {
+        return ((uint64_t)1 << (size * 8)) - 1;
+    }
+
     switch(addr & 3) {
     case 0:
         val = bm->cmd;
@@ -55,36 +59,46 @@ static uint32_t bmdma_readb(void *opaque, uint32_t addr)
     return val;
 }
 
-static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
+static void bmdma_write(void *opaque, target_phys_addr_t addr,
+                        uint64_t val, unsigned size)
 {
     BMDMAState *bm = opaque;
+
+    if (size != 1) {
+        return;
+    }
+
 #ifdef DEBUG_IDE
     printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
 #endif
     switch(addr & 3) {
+    case 0:
+        return bmdma_cmd_writeb(bm, val);
     case 2:
         bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
         break;
     }
 }
 
-static void bmdma_map(PCIDevice *pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
+static MemoryRegionOps piix_bmdma_ops = {
+    .read = bmdma_read,
+    .write = bmdma_write,
+};
+
+static void bmdma_setup_bar(PCIIDEState *d)
 {
-    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
     int i;
 
+    memory_region_init(&d->bmdma_bar, "piix-bmdma-container", 16);
     for(i = 0;i < 2; i++) {
         BMDMAState *bm = &d->bmdma[i];
 
-        register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
-
-        register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
-        register_ioport_read(addr, 4, 1, bmdma_readb, bm);
-
-        iorange_init(&bm->addr_ioport, &bmdma_addr_ioport_ops, addr + 4, 4);
-        ioport_register(&bm->addr_ioport);
-        addr += 8;
+        memory_region_init_io(&bm->extra_io, &piix_bmdma_ops, bm,
+                              "piix-bmdma", 4);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
+        memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm,
+                              "bmdma", 4);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
     }
 }
 
@@ -124,7 +138,7 @@ static void pci_piix_init_ports(PCIIDEState *d) {
         ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2);
         ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq));
 
-        bmdma_init(&d->bus[i], &d->bmdma[i]);
+        bmdma_init(&d->bus[i], &d->bmdma[i], d);
         d->bmdma[i].bus = &d->bus[i];
         qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
                                          &d->bmdma[i].dma);
@@ -140,7 +154,9 @@ static int pci_piix_ide_initfn(PCIDevice *dev)
 
     qemu_register_reset(piix3_reset, d);
 
-    pci_register_bar(&d->dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO, bmdma_map);
+    bmdma_setup_bar(d);
+    pci_register_bar_region(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO,
+                            &d->bmdma_bar);
 
     vmstate_register(&d->dev.qdev, 0, &vmstate_ide_pci, d);
 
@@ -149,6 +165,22 @@ static int pci_piix_ide_initfn(PCIDevice *dev)
     return 0;
 }
 
+static int pci_piix_ide_exitfn(PCIDevice *dev)
+{
+    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
+    unsigned i;
+
+    for (i = 0; i < 2; ++i) {
+        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
+        memory_region_destroy(&d->bmdma[i].extra_io);
+        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
+        memory_region_destroy(&d->bmdma[i].addr_ioport);
+    }
+    memory_region_destroy(&d->bmdma_bar);
+
+    return 0;
+}
+
 /* hd_table must contain 4 block drivers */
 /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
 PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
@@ -178,6 +210,7 @@ static PCIDeviceInfo piix_ide_info[] = {
         .qdev.no_user = 1,
         .no_hotplug   = 1,
         .init         = pci_piix_ide_initfn,
+        .exit         = pci_piix_ide_exitfn,
         .vendor_id    = PCI_VENDOR_ID_INTEL,
         .device_id    = PCI_DEVICE_ID_INTEL_82371SB_1,
         .class_id     = PCI_CLASS_STORAGE_IDE,
@@ -187,6 +220,7 @@ static PCIDeviceInfo piix_ide_info[] = {
         .qdev.no_user = 1,
         .no_hotplug   = 1,
         .init         = pci_piix_ide_initfn,
+        .exit         = pci_piix_ide_exitfn,
         .vendor_id    = PCI_VENDOR_ID_INTEL,
         .device_id    = PCI_DEVICE_ID_INTEL_82371AB,
         .class_id     = PCI_CLASS_STORAGE_IDE,
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 3474c37..eb6a409 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -34,11 +34,16 @@
 
 #include <hw/ide/pci.h>
 
-static uint32_t bmdma_readb(void *opaque, uint32_t addr)
+static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr,
+                           unsigned size)
 {
     BMDMAState *bm = opaque;
     uint32_t val;
 
+    if (size != 1) {
+        return ((uint64_t)1 << (size * 8)) - 1;
+    }
+
     switch (addr & 3) {
     case 0:
         val = bm->cmd;
@@ -56,13 +61,21 @@ static uint32_t bmdma_readb(void *opaque, uint32_t addr)
     return val;
 }
 
-static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
+static void bmdma_write(void *opaque, target_phys_addr_t addr,
+                        uint64_t val, unsigned size)
 {
     BMDMAState *bm = opaque;
+
+    if (size != 1) {
+        return;
+    }
+
 #ifdef DEBUG_IDE
     printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
 #endif
     switch (addr & 3) {
+    case 0:
+        return bmdma_cmd_writeb(bm, val);
     case 2:
         bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
         break;
@@ -70,23 +83,25 @@ static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
-static void bmdma_map(PCIDevice *pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
+static MemoryRegionOps via_bmdma_ops = {
+    .read = bmdma_read,
+    .write = bmdma_write,
+};
+
+static void bmdma_setup_bar(PCIIDEState *d)
 {
-    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
     int i;
 
+    memory_region_init(&d->bmdma_bar, "via-bmdma-container", 16);
     for(i = 0;i < 2; i++) {
         BMDMAState *bm = &d->bmdma[i];
 
-        register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
-
-        register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
-        register_ioport_read(addr, 4, 1, bmdma_readb, bm);
-
-        iorange_init(&bm->addr_ioport, &bmdma_addr_ioport_ops, addr + 4, 4);
-        ioport_register(&bm->addr_ioport);
-        addr += 8;
+        memory_region_init_io(&bm->extra_io, &via_bmdma_ops, bm,
+                              "via-bmdma", 4);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
+        memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm,
+                              "bmdma", 4);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
     }
 }
 
@@ -147,7 +162,7 @@ static void vt82c686b_init_ports(PCIIDEState *d) {
         ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2);
         ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq));
 
-        bmdma_init(&d->bus[i], &d->bmdma[i]);
+        bmdma_init(&d->bus[i], &d->bmdma[i], d);
         d->bmdma[i].bus = &d->bus[i];
         qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
                                          &d->bmdma[i].dma);
@@ -164,8 +179,9 @@ static int vt82c686b_ide_initfn(PCIDevice *dev)
     pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0);
 
     qemu_register_reset(via_reset, d);
-    pci_register_bar(&d->dev, 4, 0x10,
-                           PCI_BASE_ADDRESS_SPACE_IO, bmdma_map);
+    bmdma_setup_bar(d);
+    pci_register_bar_region(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO,
+                            &d->bmdma_bar);
 
     vmstate_register(&dev->qdev, 0, &vmstate_ide_pci, d);
 
@@ -174,6 +190,22 @@ static int vt82c686b_ide_initfn(PCIDevice *dev)
     return 0;
 }
 
+static int vt82c686b_ide_exitfn(PCIDevice *dev)
+{
+    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
+    unsigned i;
+
+    for (i = 0; i < 2; ++i) {
+        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
+        memory_region_destroy(&d->bmdma[i].extra_io);
+        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
+        memory_region_destroy(&d->bmdma[i].addr_ioport);
+    }
+    memory_region_destroy(&d->bmdma_bar);
+
+    return 0;
+}
+
 void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
 {
     PCIDevice *dev;
@@ -187,6 +219,7 @@ static PCIDeviceInfo via_ide_info = {
     .qdev.size    = sizeof(PCIIDEState),
     .qdev.no_user = 1,
     .init         = vt82c686b_ide_initfn,
+    .exit         = vt82c686b_ide_exitfn,
     .vendor_id    = PCI_VENDOR_ID_VIA,
     .device_id    = PCI_DEVICE_ID_VIA_IDE,
     .revision     = 0x06,
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 35/56] ide: convert to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/ide/cmd646.c |  208 +++++++++++++++++++++++++++++++++++--------------------
 hw/ide/pci.c    |   25 ++++---
 hw/ide/pci.h    |   19 ++++-
 hw/ide/piix.c   |   64 +++++++++++++----
 hw/ide/via.c    |   65 +++++++++++++----
 5 files changed, 261 insertions(+), 120 deletions(-)

diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 56302b5..699ad6b 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -44,35 +44,95 @@
 
 static void cmd646_update_irq(PCIIDEState *d);
 
-static void ide_map(PCIDevice *pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
+static uint64_t cmd646_cmd_read(void *opaque, target_phys_addr_t addr,
+                                unsigned size)
 {
-    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
-    IDEBus *bus;
-
-    if (region_num <= 3) {
-        bus = &d->bus[(region_num >> 1)];
-        if (region_num & 1) {
-            register_ioport_read(addr + 2, 1, 1, ide_status_read, bus);
-            register_ioport_write(addr + 2, 1, 1, ide_cmd_write, bus);
+    CMD646BAR *cmd646bar = opaque;
+
+    if (addr != 2 || size != 1) {
+        return ((uint64_t)1 << (size * 8)) - 1;
+    }
+    return ide_status_read(cmd646bar->bus, addr + 2);
+}
+
+static void cmd646_cmd_write(void *opaque, target_phys_addr_t addr,
+                             uint64_t data, unsigned size)
+{
+    CMD646BAR *cmd646bar = opaque;
+
+    if (addr != 2 || size != 1) {
+        return;
+    }
+    ide_cmd_write(cmd646bar->bus, addr + 2, data);
+}
+
+static MemoryRegionOps cmd646_cmd_ops = {
+    .read = cmd646_cmd_read,
+    .write = cmd646_cmd_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static uint64_t cmd646_data_read(void *opaque, target_phys_addr_t addr,
+                                 unsigned size)
+{
+    CMD646BAR *cmd646bar = opaque;
+
+    if (size == 1) {
+        return ide_ioport_read(cmd646bar->bus, addr);
+    } else if (addr == 0) {
+        if (size == 2) {
+            return ide_data_readw(cmd646bar->bus, addr);
         } else {
-            register_ioport_write(addr, 8, 1, ide_ioport_write, bus);
-            register_ioport_read(addr, 8, 1, ide_ioport_read, bus);
-
-            /* data ports */
-            register_ioport_write(addr, 2, 2, ide_data_writew, bus);
-            register_ioport_read(addr, 2, 2, ide_data_readw, bus);
-            register_ioport_write(addr, 4, 4, ide_data_writel, bus);
-            register_ioport_read(addr, 4, 4, ide_data_readl, bus);
+            return ide_data_readl(cmd646bar->bus, addr);
         }
     }
+    return ((uint64_t)1 << (size * 8)) - 1;
 }
 
-static uint32_t bmdma_readb_common(PCIIDEState *pci_dev, BMDMAState *bm,
-                                   uint32_t addr)
+static void cmd646_data_write(void *opaque, target_phys_addr_t addr,
+                             uint64_t data, unsigned size)
 {
+    CMD646BAR *cmd646bar = opaque;
+
+    if (size == 1) {
+        return ide_ioport_write(cmd646bar->bus, addr, data);
+    } else if (addr == 0) {
+        if (size == 2) {
+            return ide_data_writew(cmd646bar->bus, addr, data);
+        } else {
+            return ide_data_writel(cmd646bar->bus, addr, data);
+        }
+    }
+}
+
+static MemoryRegionOps cmd646_data_ops = {
+    .read = cmd646_data_read,
+    .write = cmd646_data_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void setup_cmd646_bar(PCIIDEState *d, int bus_num)
+{
+    IDEBus *bus = &d->bus[bus_num];
+    CMD646BAR *bar = &d->cmd646_bar[bus_num];
+
+    bar->bus = bus;
+    bar->pci_dev = d;
+    memory_region_init_io(&bar->cmd, &cmd646_cmd_ops, bar, "cmd646-cmd", 4);
+    memory_region_init_io(&bar->data, &cmd646_data_ops, bar, "cmd646-data", 8);
+}
+
+static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr,
+                           unsigned size)
+{
+    BMDMAState *bm = opaque;
+    PCIIDEState *pci_dev = bm->pci_dev;
     uint32_t val;
 
+    if (size != 1) {
+        return ((uint64_t)1 << (size * 8)) - 1;
+    }
+
     switch(addr & 3) {
     case 0:
         val = bm->cmd;
@@ -100,31 +160,22 @@ static uint32_t bmdma_readb_common(PCIIDEState *pci_dev, BMDMAState *bm,
     return val;
 }
 
-static uint32_t bmdma_readb_0(void *opaque, uint32_t addr)
+static void bmdma_write(void *opaque, target_phys_addr_t addr,
+                        uint64_t val, unsigned size)
 {
-    PCIIDEState *pci_dev = opaque;
-    BMDMAState *bm = &pci_dev->bmdma[0];
-
-    return bmdma_readb_common(pci_dev, bm, addr);
-}
+    BMDMAState *bm = opaque;
+    PCIIDEState *pci_dev = bm->pci_dev;
 
-static uint32_t bmdma_readb_1(void *opaque, uint32_t addr)
-{
-    PCIIDEState *pci_dev = opaque;
-    BMDMAState *bm = &pci_dev->bmdma[1];
-
-    return bmdma_readb_common(pci_dev, bm, addr);
-}
+    if (size != 1) {
+        return;
+    }
 
-static void bmdma_writeb_common(PCIIDEState *pci_dev, BMDMAState *bm,
-                                uint32_t addr, uint32_t val)
-{
 #ifdef DEBUG_IDE
     printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
 #endif
     switch(addr & 3) {
     case 0:
-        bmdma_cmd_writeb(bm, addr, val);
+        bmdma_cmd_writeb(bm, val);
         break;
     case 1:
         pci_dev->dev.config[MRDMODE] =
@@ -143,42 +194,25 @@ static void bmdma_writeb_common(PCIIDEState *pci_dev, BMDMAState *bm,
     }
 }
 
-static void bmdma_writeb_0(void *opaque, uint32_t addr, uint32_t val)
-{
-    PCIIDEState *pci_dev = opaque;
-    BMDMAState *bm = &pci_dev->bmdma[0];
-
-    bmdma_writeb_common(pci_dev, bm, addr, val);
-}
-
-static void bmdma_writeb_1(void *opaque, uint32_t addr, uint32_t val)
-{
-    PCIIDEState *pci_dev = opaque;
-    BMDMAState *bm = &pci_dev->bmdma[1];
-
-    bmdma_writeb_common(pci_dev, bm, addr, val);
-}
+static MemoryRegionOps cmd646_bmdma_ops = {
+    .read = bmdma_read,
+    .write = bmdma_write,
+};
 
-static void bmdma_map(PCIDevice *pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
+static void bmdma_setup_bar(PCIIDEState *d)
 {
-    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
+    BMDMAState *bm;
     int i;
 
+    memory_region_init(&d->bmdma_bar, "cmd646-bmdma", 16);
     for(i = 0;i < 2; i++) {
-        BMDMAState *bm = &d->bmdma[i];
-
-        if (i == 0) {
-            register_ioport_write(addr, 4, 1, bmdma_writeb_0, d);
-            register_ioport_read(addr, 4, 1, bmdma_readb_0, d);
-        } else {
-            register_ioport_write(addr, 4, 1, bmdma_writeb_1, d);
-            register_ioport_read(addr, 4, 1, bmdma_readb_1, d);
-        }
-
-        iorange_init(&bm->addr_ioport, &bmdma_addr_ioport_ops, addr + 4, 4);
-        ioport_register(&bm->addr_ioport);
-        addr += 8;
+        bm = &d->bmdma[i];
+        memory_region_init_io(&bm->extra_io, &cmd646_bmdma_ops, bm,
+                              "cmd646-bmdma-bus", 4);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
+        memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm,
+                              "cmd646-bmdma-ioport", 4);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
     }
 }
 
@@ -234,11 +268,18 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
         pci_conf[0x51] |= 0x08; /* enable IDE1 */
     }
 
-    pci_register_bar(dev, 0, 0x8, PCI_BASE_ADDRESS_SPACE_IO, ide_map);
-    pci_register_bar(dev, 1, 0x4, PCI_BASE_ADDRESS_SPACE_IO, ide_map);
-    pci_register_bar(dev, 2, 0x8, PCI_BASE_ADDRESS_SPACE_IO, ide_map);
-    pci_register_bar(dev, 3, 0x4, PCI_BASE_ADDRESS_SPACE_IO, ide_map);
-    pci_register_bar(dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO, bmdma_map);
+    setup_cmd646_bar(d, 0);
+    setup_cmd646_bar(d, 1);
+    pci_register_bar_region(dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
+                            &d->cmd646_bar[0].data);
+    pci_register_bar_region(dev, 1, PCI_BASE_ADDRESS_SPACE_IO,
+                            &d->cmd646_bar[0].cmd);
+    pci_register_bar_region(dev, 2, PCI_BASE_ADDRESS_SPACE_IO,
+                            &d->cmd646_bar[1].data);
+    pci_register_bar_region(dev, 3, PCI_BASE_ADDRESS_SPACE_IO,
+                            &d->cmd646_bar[2].cmd);
+    bmdma_setup_bar(d);
+    pci_register_bar_region(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
 
     /* TODO: RST# value should be 0 */
     pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
@@ -248,7 +289,7 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
         ide_bus_new(&d->bus[i], &d->dev.qdev, i);
         ide_init2(&d->bus[i], irq[i]);
 
-        bmdma_init(&d->bus[i], &d->bmdma[i]);
+        bmdma_init(&d->bus[i], &d->bmdma[i], d);
         d->bmdma[i].bus = &d->bus[i];
         qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
                                          &d->bmdma[i].dma);
@@ -259,6 +300,24 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
     return 0;
 }
 
+static int pci_cmd646_ide_exitfn(PCIDevice *dev)
+{
+    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
+    unsigned i;
+
+    for (i = 0; i < 2; ++i) {
+        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
+        memory_region_destroy(&d->bmdma[i].extra_io);
+        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
+        memory_region_destroy(&d->bmdma[i].addr_ioport);
+        memory_region_destroy(&d->cmd646_bar[i].cmd);
+        memory_region_destroy(&d->cmd646_bar[i].data);
+    }
+    memory_region_destroy(&d->bmdma_bar);
+
+    return 0;
+}
+
 void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
                          int secondary_ide_enabled)
 {
@@ -276,6 +335,7 @@ static PCIDeviceInfo cmd646_ide_info[] = {
         .qdev.name    = "cmd646-ide",
         .qdev.size    = sizeof(PCIIDEState),
         .init         = pci_cmd646_ide_initfn,
+        .exit         = pci_cmd646_ide_exitfn,
         .vendor_id    = PCI_VENDOR_ID_CMD,
         .device_id    = PCI_DEVICE_ID_CMD_646,
         .revision     = 0x07, // IDE controller revision
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 9f3050a..d1a14d7 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -287,9 +287,8 @@ static void bmdma_irq(void *opaque, int n, int level)
     qemu_set_irq(bm->irq, level);
 }
 
-void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
+void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
 {
-    BMDMAState *bm = opaque;
 #ifdef DEBUG_IDE
     printf("%s: 0x%08x\n", __func__, val);
 #endif
@@ -328,22 +327,24 @@ void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
     bm->cmd = val & 0x09;
 }
 
-static void bmdma_addr_read(IORange *ioport, uint64_t addr,
-                            unsigned width, uint64_t *data)
+static uint64_t bmdma_addr_read(void *opaque, target_phys_addr_t addr,
+                                unsigned width)
 {
-    BMDMAState *bm = container_of(ioport, BMDMAState, addr_ioport);
+    BMDMAState *bm = opaque;
     uint32_t mask = (1ULL << (width * 8)) - 1;
+    uint64_t data;
 
-    *data = (bm->addr >> (addr * 8)) & mask;
+    data = (bm->addr >> (addr * 8)) & mask;
 #ifdef DEBUG_IDE
     printf("%s: 0x%08x\n", __func__, (unsigned)*data);
 #endif
+    return data;
 }
 
-static void bmdma_addr_write(IORange *ioport, uint64_t addr,
-                             unsigned width, uint64_t data)
+static void bmdma_addr_write(void *opaque, target_phys_addr_t addr,
+                             uint64_t data, unsigned width)
 {
-    BMDMAState *bm = container_of(ioport, BMDMAState, addr_ioport);
+    BMDMAState *bm = opaque;
     int shift = addr * 8;
     uint32_t mask = (1ULL << (width * 8)) - 1;
 
@@ -354,9 +355,10 @@ static void bmdma_addr_write(IORange *ioport, uint64_t addr,
     bm->addr |= ((data & mask) << shift) & ~3;
 }
 
-const IORangeOps bmdma_addr_ioport_ops = {
+MemoryRegionOps bmdma_addr_ioport_ops = {
     .read = bmdma_addr_read,
     .write = bmdma_addr_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static bool ide_bmdma_current_needed(void *opaque)
@@ -514,7 +516,7 @@ static const struct IDEDMAOps bmdma_ops = {
     .reset = bmdma_reset,
 };
 
-void bmdma_init(IDEBus *bus, BMDMAState *bm)
+void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d)
 {
     qemu_irq *irq;
 
@@ -527,4 +529,5 @@ void bmdma_init(IDEBus *bus, BMDMAState *bm)
     bm->irq = bus->irq;
     irq = qemu_allocate_irqs(bmdma_irq, bm, 1);
     bus->irq = *irq;
+    bm->pci_dev = d;
 }
diff --git a/hw/ide/pci.h b/hw/ide/pci.h
index b4f3691..a694e54 100644
--- a/hw/ide/pci.h
+++ b/hw/ide/pci.h
@@ -19,20 +19,31 @@ typedef struct BMDMAState {
     BlockDriverCompletionFunc *dma_cb;
     int64_t sector_num;
     uint32_t nsector;
-    IORange addr_ioport;
+    MemoryRegion addr_ioport;
+    MemoryRegion extra_io;
     QEMUBH *bh;
     qemu_irq irq;
 
     /* Bit 0-2 and 7:   BM status register
      * Bit 3-6:         bus->error_status */
     uint8_t migration_compat_status;
+    struct PCIIDEState *pci_dev;
 } BMDMAState;
 
+typedef struct CMD646BAR {
+    MemoryRegion cmd;
+    MemoryRegion data;
+    IDEBus *bus;
+    struct PCIIDEState *pci_dev;
+} CMD646BAR;
+
 typedef struct PCIIDEState {
     PCIDevice dev;
     IDEBus bus[2];
     BMDMAState bmdma[2];
     uint32_t secondary; /* used only for cmd646 */
+    MemoryRegion bmdma_bar;
+    CMD646BAR cmd646_bar[2]; /* used only for cmd646 */
 } PCIIDEState;
 
 
@@ -43,9 +54,9 @@ static inline IDEState *bmdma_active_if(BMDMAState *bmdma)
 }
 
 
-void bmdma_init(IDEBus *bus, BMDMAState *bm);
-void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val);
-extern const IORangeOps bmdma_addr_ioport_ops;
+void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
+void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
+extern MemoryRegionOps bmdma_addr_ioport_ops;
 void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table);
 
 extern const VMStateDescription vmstate_ide_pci;
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 84f72b0..c11b960 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -33,11 +33,15 @@
 
 #include <hw/ide/pci.h>
 
-static uint32_t bmdma_readb(void *opaque, uint32_t addr)
+static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, unsigned size)
 {
     BMDMAState *bm = opaque;
     uint32_t val;
 
+    if (size != 1) {
+        return ((uint64_t)1 << (size * 8)) - 1;
+    }
+
     switch(addr & 3) {
     case 0:
         val = bm->cmd;
@@ -55,36 +59,46 @@ static uint32_t bmdma_readb(void *opaque, uint32_t addr)
     return val;
 }
 
-static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
+static void bmdma_write(void *opaque, target_phys_addr_t addr,
+                        uint64_t val, unsigned size)
 {
     BMDMAState *bm = opaque;
+
+    if (size != 1) {
+        return;
+    }
+
 #ifdef DEBUG_IDE
     printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
 #endif
     switch(addr & 3) {
+    case 0:
+        return bmdma_cmd_writeb(bm, val);
     case 2:
         bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
         break;
     }
 }
 
-static void bmdma_map(PCIDevice *pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
+static MemoryRegionOps piix_bmdma_ops = {
+    .read = bmdma_read,
+    .write = bmdma_write,
+};
+
+static void bmdma_setup_bar(PCIIDEState *d)
 {
-    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
     int i;
 
+    memory_region_init(&d->bmdma_bar, "piix-bmdma-container", 16);
     for(i = 0;i < 2; i++) {
         BMDMAState *bm = &d->bmdma[i];
 
-        register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
-
-        register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
-        register_ioport_read(addr, 4, 1, bmdma_readb, bm);
-
-        iorange_init(&bm->addr_ioport, &bmdma_addr_ioport_ops, addr + 4, 4);
-        ioport_register(&bm->addr_ioport);
-        addr += 8;
+        memory_region_init_io(&bm->extra_io, &piix_bmdma_ops, bm,
+                              "piix-bmdma", 4);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
+        memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm,
+                              "bmdma", 4);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
     }
 }
 
@@ -124,7 +138,7 @@ static void pci_piix_init_ports(PCIIDEState *d) {
         ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2);
         ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq));
 
-        bmdma_init(&d->bus[i], &d->bmdma[i]);
+        bmdma_init(&d->bus[i], &d->bmdma[i], d);
         d->bmdma[i].bus = &d->bus[i];
         qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
                                          &d->bmdma[i].dma);
@@ -140,7 +154,9 @@ static int pci_piix_ide_initfn(PCIDevice *dev)
 
     qemu_register_reset(piix3_reset, d);
 
-    pci_register_bar(&d->dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO, bmdma_map);
+    bmdma_setup_bar(d);
+    pci_register_bar_region(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO,
+                            &d->bmdma_bar);
 
     vmstate_register(&d->dev.qdev, 0, &vmstate_ide_pci, d);
 
@@ -149,6 +165,22 @@ static int pci_piix_ide_initfn(PCIDevice *dev)
     return 0;
 }
 
+static int pci_piix_ide_exitfn(PCIDevice *dev)
+{
+    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
+    unsigned i;
+
+    for (i = 0; i < 2; ++i) {
+        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
+        memory_region_destroy(&d->bmdma[i].extra_io);
+        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
+        memory_region_destroy(&d->bmdma[i].addr_ioport);
+    }
+    memory_region_destroy(&d->bmdma_bar);
+
+    return 0;
+}
+
 /* hd_table must contain 4 block drivers */
 /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
 PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
@@ -178,6 +210,7 @@ static PCIDeviceInfo piix_ide_info[] = {
         .qdev.no_user = 1,
         .no_hotplug   = 1,
         .init         = pci_piix_ide_initfn,
+        .exit         = pci_piix_ide_exitfn,
         .vendor_id    = PCI_VENDOR_ID_INTEL,
         .device_id    = PCI_DEVICE_ID_INTEL_82371SB_1,
         .class_id     = PCI_CLASS_STORAGE_IDE,
@@ -187,6 +220,7 @@ static PCIDeviceInfo piix_ide_info[] = {
         .qdev.no_user = 1,
         .no_hotplug   = 1,
         .init         = pci_piix_ide_initfn,
+        .exit         = pci_piix_ide_exitfn,
         .vendor_id    = PCI_VENDOR_ID_INTEL,
         .device_id    = PCI_DEVICE_ID_INTEL_82371AB,
         .class_id     = PCI_CLASS_STORAGE_IDE,
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 3474c37..eb6a409 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -34,11 +34,16 @@
 
 #include <hw/ide/pci.h>
 
-static uint32_t bmdma_readb(void *opaque, uint32_t addr)
+static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr,
+                           unsigned size)
 {
     BMDMAState *bm = opaque;
     uint32_t val;
 
+    if (size != 1) {
+        return ((uint64_t)1 << (size * 8)) - 1;
+    }
+
     switch (addr & 3) {
     case 0:
         val = bm->cmd;
@@ -56,13 +61,21 @@ static uint32_t bmdma_readb(void *opaque, uint32_t addr)
     return val;
 }
 
-static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
+static void bmdma_write(void *opaque, target_phys_addr_t addr,
+                        uint64_t val, unsigned size)
 {
     BMDMAState *bm = opaque;
+
+    if (size != 1) {
+        return;
+    }
+
 #ifdef DEBUG_IDE
     printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
 #endif
     switch (addr & 3) {
+    case 0:
+        return bmdma_cmd_writeb(bm, val);
     case 2:
         bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
         break;
@@ -70,23 +83,25 @@ static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
-static void bmdma_map(PCIDevice *pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
+static MemoryRegionOps via_bmdma_ops = {
+    .read = bmdma_read,
+    .write = bmdma_write,
+};
+
+static void bmdma_setup_bar(PCIIDEState *d)
 {
-    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
     int i;
 
+    memory_region_init(&d->bmdma_bar, "via-bmdma-container", 16);
     for(i = 0;i < 2; i++) {
         BMDMAState *bm = &d->bmdma[i];
 
-        register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
-
-        register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
-        register_ioport_read(addr, 4, 1, bmdma_readb, bm);
-
-        iorange_init(&bm->addr_ioport, &bmdma_addr_ioport_ops, addr + 4, 4);
-        ioport_register(&bm->addr_ioport);
-        addr += 8;
+        memory_region_init_io(&bm->extra_io, &via_bmdma_ops, bm,
+                              "via-bmdma", 4);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
+        memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm,
+                              "bmdma", 4);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
     }
 }
 
@@ -147,7 +162,7 @@ static void vt82c686b_init_ports(PCIIDEState *d) {
         ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2);
         ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq));
 
-        bmdma_init(&d->bus[i], &d->bmdma[i]);
+        bmdma_init(&d->bus[i], &d->bmdma[i], d);
         d->bmdma[i].bus = &d->bus[i];
         qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
                                          &d->bmdma[i].dma);
@@ -164,8 +179,9 @@ static int vt82c686b_ide_initfn(PCIDevice *dev)
     pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0);
 
     qemu_register_reset(via_reset, d);
-    pci_register_bar(&d->dev, 4, 0x10,
-                           PCI_BASE_ADDRESS_SPACE_IO, bmdma_map);
+    bmdma_setup_bar(d);
+    pci_register_bar_region(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO,
+                            &d->bmdma_bar);
 
     vmstate_register(&dev->qdev, 0, &vmstate_ide_pci, d);
 
@@ -174,6 +190,22 @@ static int vt82c686b_ide_initfn(PCIDevice *dev)
     return 0;
 }
 
+static int vt82c686b_ide_exitfn(PCIDevice *dev)
+{
+    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
+    unsigned i;
+
+    for (i = 0; i < 2; ++i) {
+        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
+        memory_region_destroy(&d->bmdma[i].extra_io);
+        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
+        memory_region_destroy(&d->bmdma[i].addr_ioport);
+    }
+    memory_region_destroy(&d->bmdma_bar);
+
+    return 0;
+}
+
 void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
 {
     PCIDevice *dev;
@@ -187,6 +219,7 @@ static PCIDeviceInfo via_ide_info = {
     .qdev.size    = sizeof(PCIIDEState),
     .qdev.no_user = 1,
     .init         = vt82c686b_ide_initfn,
+    .exit         = vt82c686b_ide_exitfn,
     .vendor_id    = PCI_VENDOR_ID_VIA,
     .device_id    = PCI_DEVICE_ID_VIA_IDE,
     .revision     = 0x06,
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 36/56] memory: add ioeventfd support
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

As with the rest of the memory API, the caller associates an eventfd
with an address, and the memory API takes care of registering or
unregistering when the address is made visible or invisible to the
guest.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |  218 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 memory.h |   20 ++++++
 2 files changed, 238 insertions(+), 0 deletions(-)

diff --git a/memory.c b/memory.c
index 62bd60b..0d2ecf1 100644
--- a/memory.c
+++ b/memory.c
@@ -14,6 +14,7 @@
 #include "memory.h"
 #include "exec-memory.h"
 #include "ioport.h"
+#include "kvm.h"
 #include <assert.h>
 
 typedef struct AddrRange AddrRange;
@@ -63,6 +64,38 @@ struct CoalescedMemoryRange {
     QTAILQ_ENTRY(CoalescedMemoryRange) link;
 };
 
+struct MemoryRegionIoeventfd {
+    AddrRange addr;
+    bool match_data;
+    uint64_t data;
+    int fd;
+};
+
+static bool memory_region_ioeventfd_before(MemoryRegionIoeventfd a,
+                                           MemoryRegionIoeventfd b)
+{
+    if (a.addr.start < b.addr.start) return true;
+    if (a.addr.start > b.addr.start) return false;
+    if (a.addr.size < b.addr.size) return true;
+    if (a.addr.size > b.addr.size) return false;
+    if (a.match_data < b.match_data) return true;
+    if (a.match_data > b.match_data) return false;
+    if (a.match_data) {
+        if (a.data < b.data) return true;
+        if (a.data > b.data) return false;
+    }
+    if (a.fd < b.fd) return true;
+    if (a.fd > b.fd) return false;
+    return false;
+}
+
+static bool memory_region_ioeventfd_equal(MemoryRegionIoeventfd a,
+                                          MemoryRegionIoeventfd b)
+{
+    return !memory_region_ioeventfd_before(a, b)
+        && !memory_region_ioeventfd_before(b, a);
+}
+
 typedef struct FlatRange FlatRange;
 typedef struct FlatView FlatView;
 
@@ -91,6 +124,8 @@ struct AddressSpace {
     const AddressSpaceOps *ops;
     MemoryRegion *root;
     FlatView current_map;
+    int ioeventfd_nb;
+    MemoryRegionIoeventfd *ioeventfds;
 };
 
 struct AddressSpaceOps {
@@ -98,6 +133,8 @@ struct AddressSpaceOps {
     void (*range_del)(AddressSpace *as, FlatRange *fr);
     void (*log_start)(AddressSpace *as, FlatRange *fr);
     void (*log_stop)(AddressSpace *as, FlatRange *fr);
+    void (*ioeventfd_add)(AddressSpace *as, MemoryRegionIoeventfd *fd);
+    void (*ioeventfd_del)(AddressSpace *as, MemoryRegionIoeventfd *fd);
 };
 
 #define FOR_EACH_FLAT_RANGE(var, view)          \
@@ -200,11 +237,37 @@ static void as_memory_log_stop(AddressSpace *as, FlatRange *fr)
     cpu_physical_log_stop(fr->addr.start, fr->addr.size);
 }
 
+static void as_memory_ioeventfd_add(AddressSpace *as, MemoryRegionIoeventfd *fd)
+{
+    int r;
+
+    if (!fd->match_data || fd->addr.size != 4) {
+        abort();
+    }
+
+    r = kvm_set_ioeventfd_mmio_long(fd->fd, fd->addr.start, fd->data, true);
+    if (r < 0) {
+        abort();
+    }
+}
+
+static void as_memory_ioeventfd_del(AddressSpace *as, MemoryRegionIoeventfd *fd)
+{
+    int r;
+
+    r = kvm_set_ioeventfd_mmio_long(fd->fd, fd->addr.start, fd->data, false);
+    if (r < 0) {
+        abort();
+    }
+}
+
 static const AddressSpaceOps address_space_ops_memory = {
     .range_add = as_memory_range_add,
     .range_del = as_memory_range_del,
     .log_start = as_memory_log_start,
     .log_stop = as_memory_log_stop,
+    .ioeventfd_add = as_memory_ioeventfd_add,
+    .ioeventfd_del = as_memory_ioeventfd_del,
 };
 
 static AddressSpace address_space_memory = {
@@ -248,9 +311,35 @@ static void as_io_range_del(AddressSpace *as, FlatRange *fr)
     isa_unassign_ioport(fr->addr.start, fr->addr.size);
 }
 
+static void as_io_ioeventfd_add(AddressSpace *as, MemoryRegionIoeventfd *fd)
+{
+    int r;
+
+    if (!fd->match_data || fd->addr.size != 2) {
+        abort();
+    }
+
+    r = kvm_set_ioeventfd_pio_word(fd->fd, fd->addr.start, fd->data, true);
+    if (r < 0) {
+        abort();
+    }
+}
+
+static void as_io_ioeventfd_del(AddressSpace *as, MemoryRegionIoeventfd *fd)
+{
+    int r;
+
+    r = kvm_set_ioeventfd_pio_word(fd->fd, fd->addr.start, fd->data, false);
+    if (r < 0) {
+        abort();
+    }
+}
+
 static const AddressSpaceOps address_space_ops_io = {
     .range_add = as_io_range_add,
     .range_del = as_io_range_del,
+    .ioeventfd_add = as_io_ioeventfd_add,
+    .ioeventfd_del = as_io_ioeventfd_del,
 };
 
 static AddressSpace address_space_io = {
@@ -349,6 +438,69 @@ static FlatView generate_memory_topology(MemoryRegion *mr)
     return view;
 }
 
+static void address_space_add_del_ioeventfds(AddressSpace *as,
+                                             MemoryRegionIoeventfd *fds_new,
+                                             unsigned fds_new_nb,
+                                             MemoryRegionIoeventfd *fds_old,
+                                             unsigned fds_old_nb)
+{
+    unsigned iold, inew;
+
+    /* Generate a symmetric difference of the old and new fd sets, adding
+     * and deleting as necessary.
+     */
+
+    iold = inew = 0;
+    while (iold < fds_old_nb || inew < fds_new_nb) {
+        if (iold < fds_old_nb
+            && (inew == fds_new_nb
+                || memory_region_ioeventfd_before(fds_old[iold],
+                                                  fds_new[inew]))) {
+            as->ops->ioeventfd_del(as, &fds_old[iold]);
+            ++iold;
+        } else if (inew < fds_new_nb
+                   && (iold == fds_old_nb
+                       || memory_region_ioeventfd_before(fds_new[inew],
+                                                         fds_old[iold]))) {
+            as->ops->ioeventfd_add(as, &fds_new[inew]);
+            ++inew;
+        } else {
+            ++iold;
+            ++inew;
+        }
+    }
+}
+
+static void address_space_update_ioeventfds(AddressSpace *as)
+{
+    FlatRange *fr;
+    unsigned ioeventfd_nb = 0;
+    MemoryRegionIoeventfd *ioeventfds = NULL;
+    AddrRange tmp;
+    unsigned i;
+
+    FOR_EACH_FLAT_RANGE(fr, &as->current_map) {
+        for (i = 0; i < fr->mr->ioeventfd_nb; ++i) {
+            tmp = addrrange_shift(fr->mr->ioeventfds[i].addr,
+                                  fr->addr.start - fr->offset_in_region);
+            if (addrrange_intersects(fr->addr, tmp)) {
+                ++ioeventfd_nb;
+                ioeventfds = qemu_realloc(ioeventfds,
+                                          ioeventfd_nb * sizeof(*ioeventfds));
+                ioeventfds[ioeventfd_nb-1] = fr->mr->ioeventfds[i];
+                ioeventfds[ioeventfd_nb-1].addr = tmp;
+            }
+        }
+    }
+
+    address_space_add_del_ioeventfds(as, ioeventfds, ioeventfd_nb,
+                                     as->ioeventfds, as->ioeventfd_nb);
+
+    qemu_free(as->ioeventfds);
+    as->ioeventfds = ioeventfds;
+    as->ioeventfd_nb = ioeventfd_nb;
+}
+
 static void address_space_update_topology(AddressSpace *as)
 {
     FlatView old_view = as->current_map;
@@ -401,6 +553,7 @@ static void address_space_update_topology(AddressSpace *as)
     }
     as->current_map = new_view;
     flatview_destroy(&old_view);
+    address_space_update_ioeventfds(as);
 }
 
 static void memory_region_update_topology(void)
@@ -431,6 +584,8 @@ void memory_region_init(MemoryRegion *mr,
     QTAILQ_INIT(&mr->coalesced);
     mr->name = qemu_strdup(name);
     mr->dirty_log_mask = 0;
+    mr->ioeventfd_nb = 0;
+    mr->ioeventfds = NULL;
 }
 
 static bool memory_region_access_valid(MemoryRegion *mr,
@@ -633,6 +788,7 @@ void memory_region_destroy(MemoryRegion *mr)
     assert(QTAILQ_EMPTY(&mr->subregions));
     memory_region_clear_coalescing(mr);
     qemu_free((char *)mr->name);
+    qemu_free(mr->ioeventfds);
 }
 
 target_phys_addr_t memory_region_size(MemoryRegion *mr)
@@ -756,6 +912,68 @@ void memory_region_clear_coalescing(MemoryRegion *mr)
     memory_region_update_coalesced_range(mr);
 }
 
+void memory_region_add_eventfd(MemoryRegion *mr,
+                               target_phys_addr_t addr,
+                               unsigned size,
+                               bool match_data,
+                               uint64_t data,
+                               int fd)
+{
+    MemoryRegionIoeventfd mrfd = {
+        .addr.start = addr,
+        .addr.size = size,
+        .match_data = match_data,
+        .data = data,
+        .fd = fd,
+    };
+    unsigned i;
+
+    for (i = 0; i < mr->ioeventfd_nb; ++i) {
+        if (memory_region_ioeventfd_before(mrfd, mr->ioeventfds[i])) {
+            break;
+        }
+    }
+    ++mr->ioeventfd_nb;
+    mr->ioeventfds = qemu_realloc(mr->ioeventfds,
+                                  sizeof(*mr->ioeventfds) * mr->ioeventfd_nb);
+    memmove(&mr->ioeventfds[i+1], &mr->ioeventfds[i],
+            sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb-1 - i));
+    mr->ioeventfds[i] = mrfd;
+    memory_region_update_topology();
+}
+
+void memory_region_del_eventfd(MemoryRegion *mr,
+                               target_phys_addr_t addr,
+                               unsigned size,
+                               bool match_data,
+                               uint64_t data,
+                               int fd)
+{
+    MemoryRegionIoeventfd mrfd = {
+        .addr.start = addr,
+        .addr.size = size,
+        .match_data = match_data,
+        .data = data,
+        .fd = fd,
+    };
+    unsigned i;
+
+    for (i = 0; i < mr->ioeventfd_nb; ++i) {
+        if (memory_region_ioeventfd_equal(mrfd, mr->ioeventfds[i])) {
+            break;
+        }
+    }
+    if (i == mr->ioeventfd_nb) {
+        abort();
+    }
+    memmove(&mr->ioeventfds[i], &mr->ioeventfds[i+1],
+            sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb - (i+1)));
+    --mr->ioeventfd_nb;
+    mr->ioeventfds = qemu_realloc(mr->ioeventfds,
+                                  sizeof(*mr->ioeventfds)*mr->ioeventfd_nb + 1);
+    memory_region_update_topology();
+}
+
 static void memory_region_add_subregion_common(MemoryRegion *mr,
                                                target_phys_addr_t offset,
                                                MemoryRegion *subregion)
diff --git a/memory.h b/memory.h
index 2afbf13..34e0acd 100644
--- a/memory.h
+++ b/memory.h
@@ -68,6 +68,7 @@ struct MemoryRegionOps {
 };
 
 typedef struct CoalescedMemoryRange CoalescedMemoryRange;
+typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
 
 struct MemoryRegion {
     /* All fields are private - violators will be prosecuted */
@@ -90,6 +91,8 @@ struct MemoryRegion {
     QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
     const char *name;
     uint8_t dirty_log_mask;
+    unsigned ioeventfd_nb;
+    MemoryRegionIoeventfd *ioeventfds;
 };
 
 /* Initialize a memory region
@@ -181,6 +184,23 @@ void memory_region_add_coalescing(MemoryRegion *mr,
 /* Disable MMIO coalescing for the region. */
 void memory_region_clear_coalescing(MemoryRegion *mr);
 
+
+/* Request an eventfd to be triggered when a word is written to a location */
+void memory_region_add_eventfd(MemoryRegion *mr,
+                               target_phys_addr_t addr,
+                               unsigned size,
+                               bool match_data,
+                               uint64_t data,
+                               int fd);
+
+/* Cancel an existing eventfd  */
+void memory_region_del_eventfd(MemoryRegion *mr,
+                               target_phys_addr_t addr,
+                               unsigned size,
+                               bool match_data,
+                               uint64_t data,
+                               int fd);
+
 /* Add a sub-region at @offset.  The sub-region may not overlap with other
  * subregions (except for those explicitly marked as overlapping)
  */
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 36/56] memory: add ioeventfd support
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

As with the rest of the memory API, the caller associates an eventfd
with an address, and the memory API takes care of registering or
unregistering when the address is made visible or invisible to the
guest.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 memory.c |  218 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 memory.h |   20 ++++++
 2 files changed, 238 insertions(+), 0 deletions(-)

diff --git a/memory.c b/memory.c
index 62bd60b..0d2ecf1 100644
--- a/memory.c
+++ b/memory.c
@@ -14,6 +14,7 @@
 #include "memory.h"
 #include "exec-memory.h"
 #include "ioport.h"
+#include "kvm.h"
 #include <assert.h>
 
 typedef struct AddrRange AddrRange;
@@ -63,6 +64,38 @@ struct CoalescedMemoryRange {
     QTAILQ_ENTRY(CoalescedMemoryRange) link;
 };
 
+struct MemoryRegionIoeventfd {
+    AddrRange addr;
+    bool match_data;
+    uint64_t data;
+    int fd;
+};
+
+static bool memory_region_ioeventfd_before(MemoryRegionIoeventfd a,
+                                           MemoryRegionIoeventfd b)
+{
+    if (a.addr.start < b.addr.start) return true;
+    if (a.addr.start > b.addr.start) return false;
+    if (a.addr.size < b.addr.size) return true;
+    if (a.addr.size > b.addr.size) return false;
+    if (a.match_data < b.match_data) return true;
+    if (a.match_data > b.match_data) return false;
+    if (a.match_data) {
+        if (a.data < b.data) return true;
+        if (a.data > b.data) return false;
+    }
+    if (a.fd < b.fd) return true;
+    if (a.fd > b.fd) return false;
+    return false;
+}
+
+static bool memory_region_ioeventfd_equal(MemoryRegionIoeventfd a,
+                                          MemoryRegionIoeventfd b)
+{
+    return !memory_region_ioeventfd_before(a, b)
+        && !memory_region_ioeventfd_before(b, a);
+}
+
 typedef struct FlatRange FlatRange;
 typedef struct FlatView FlatView;
 
@@ -91,6 +124,8 @@ struct AddressSpace {
     const AddressSpaceOps *ops;
     MemoryRegion *root;
     FlatView current_map;
+    int ioeventfd_nb;
+    MemoryRegionIoeventfd *ioeventfds;
 };
 
 struct AddressSpaceOps {
@@ -98,6 +133,8 @@ struct AddressSpaceOps {
     void (*range_del)(AddressSpace *as, FlatRange *fr);
     void (*log_start)(AddressSpace *as, FlatRange *fr);
     void (*log_stop)(AddressSpace *as, FlatRange *fr);
+    void (*ioeventfd_add)(AddressSpace *as, MemoryRegionIoeventfd *fd);
+    void (*ioeventfd_del)(AddressSpace *as, MemoryRegionIoeventfd *fd);
 };
 
 #define FOR_EACH_FLAT_RANGE(var, view)          \
@@ -200,11 +237,37 @@ static void as_memory_log_stop(AddressSpace *as, FlatRange *fr)
     cpu_physical_log_stop(fr->addr.start, fr->addr.size);
 }
 
+static void as_memory_ioeventfd_add(AddressSpace *as, MemoryRegionIoeventfd *fd)
+{
+    int r;
+
+    if (!fd->match_data || fd->addr.size != 4) {
+        abort();
+    }
+
+    r = kvm_set_ioeventfd_mmio_long(fd->fd, fd->addr.start, fd->data, true);
+    if (r < 0) {
+        abort();
+    }
+}
+
+static void as_memory_ioeventfd_del(AddressSpace *as, MemoryRegionIoeventfd *fd)
+{
+    int r;
+
+    r = kvm_set_ioeventfd_mmio_long(fd->fd, fd->addr.start, fd->data, false);
+    if (r < 0) {
+        abort();
+    }
+}
+
 static const AddressSpaceOps address_space_ops_memory = {
     .range_add = as_memory_range_add,
     .range_del = as_memory_range_del,
     .log_start = as_memory_log_start,
     .log_stop = as_memory_log_stop,
+    .ioeventfd_add = as_memory_ioeventfd_add,
+    .ioeventfd_del = as_memory_ioeventfd_del,
 };
 
 static AddressSpace address_space_memory = {
@@ -248,9 +311,35 @@ static void as_io_range_del(AddressSpace *as, FlatRange *fr)
     isa_unassign_ioport(fr->addr.start, fr->addr.size);
 }
 
+static void as_io_ioeventfd_add(AddressSpace *as, MemoryRegionIoeventfd *fd)
+{
+    int r;
+
+    if (!fd->match_data || fd->addr.size != 2) {
+        abort();
+    }
+
+    r = kvm_set_ioeventfd_pio_word(fd->fd, fd->addr.start, fd->data, true);
+    if (r < 0) {
+        abort();
+    }
+}
+
+static void as_io_ioeventfd_del(AddressSpace *as, MemoryRegionIoeventfd *fd)
+{
+    int r;
+
+    r = kvm_set_ioeventfd_pio_word(fd->fd, fd->addr.start, fd->data, false);
+    if (r < 0) {
+        abort();
+    }
+}
+
 static const AddressSpaceOps address_space_ops_io = {
     .range_add = as_io_range_add,
     .range_del = as_io_range_del,
+    .ioeventfd_add = as_io_ioeventfd_add,
+    .ioeventfd_del = as_io_ioeventfd_del,
 };
 
 static AddressSpace address_space_io = {
@@ -349,6 +438,69 @@ static FlatView generate_memory_topology(MemoryRegion *mr)
     return view;
 }
 
+static void address_space_add_del_ioeventfds(AddressSpace *as,
+                                             MemoryRegionIoeventfd *fds_new,
+                                             unsigned fds_new_nb,
+                                             MemoryRegionIoeventfd *fds_old,
+                                             unsigned fds_old_nb)
+{
+    unsigned iold, inew;
+
+    /* Generate a symmetric difference of the old and new fd sets, adding
+     * and deleting as necessary.
+     */
+
+    iold = inew = 0;
+    while (iold < fds_old_nb || inew < fds_new_nb) {
+        if (iold < fds_old_nb
+            && (inew == fds_new_nb
+                || memory_region_ioeventfd_before(fds_old[iold],
+                                                  fds_new[inew]))) {
+            as->ops->ioeventfd_del(as, &fds_old[iold]);
+            ++iold;
+        } else if (inew < fds_new_nb
+                   && (iold == fds_old_nb
+                       || memory_region_ioeventfd_before(fds_new[inew],
+                                                         fds_old[iold]))) {
+            as->ops->ioeventfd_add(as, &fds_new[inew]);
+            ++inew;
+        } else {
+            ++iold;
+            ++inew;
+        }
+    }
+}
+
+static void address_space_update_ioeventfds(AddressSpace *as)
+{
+    FlatRange *fr;
+    unsigned ioeventfd_nb = 0;
+    MemoryRegionIoeventfd *ioeventfds = NULL;
+    AddrRange tmp;
+    unsigned i;
+
+    FOR_EACH_FLAT_RANGE(fr, &as->current_map) {
+        for (i = 0; i < fr->mr->ioeventfd_nb; ++i) {
+            tmp = addrrange_shift(fr->mr->ioeventfds[i].addr,
+                                  fr->addr.start - fr->offset_in_region);
+            if (addrrange_intersects(fr->addr, tmp)) {
+                ++ioeventfd_nb;
+                ioeventfds = qemu_realloc(ioeventfds,
+                                          ioeventfd_nb * sizeof(*ioeventfds));
+                ioeventfds[ioeventfd_nb-1] = fr->mr->ioeventfds[i];
+                ioeventfds[ioeventfd_nb-1].addr = tmp;
+            }
+        }
+    }
+
+    address_space_add_del_ioeventfds(as, ioeventfds, ioeventfd_nb,
+                                     as->ioeventfds, as->ioeventfd_nb);
+
+    qemu_free(as->ioeventfds);
+    as->ioeventfds = ioeventfds;
+    as->ioeventfd_nb = ioeventfd_nb;
+}
+
 static void address_space_update_topology(AddressSpace *as)
 {
     FlatView old_view = as->current_map;
@@ -401,6 +553,7 @@ static void address_space_update_topology(AddressSpace *as)
     }
     as->current_map = new_view;
     flatview_destroy(&old_view);
+    address_space_update_ioeventfds(as);
 }
 
 static void memory_region_update_topology(void)
@@ -431,6 +584,8 @@ void memory_region_init(MemoryRegion *mr,
     QTAILQ_INIT(&mr->coalesced);
     mr->name = qemu_strdup(name);
     mr->dirty_log_mask = 0;
+    mr->ioeventfd_nb = 0;
+    mr->ioeventfds = NULL;
 }
 
 static bool memory_region_access_valid(MemoryRegion *mr,
@@ -633,6 +788,7 @@ void memory_region_destroy(MemoryRegion *mr)
     assert(QTAILQ_EMPTY(&mr->subregions));
     memory_region_clear_coalescing(mr);
     qemu_free((char *)mr->name);
+    qemu_free(mr->ioeventfds);
 }
 
 target_phys_addr_t memory_region_size(MemoryRegion *mr)
@@ -756,6 +912,68 @@ void memory_region_clear_coalescing(MemoryRegion *mr)
     memory_region_update_coalesced_range(mr);
 }
 
+void memory_region_add_eventfd(MemoryRegion *mr,
+                               target_phys_addr_t addr,
+                               unsigned size,
+                               bool match_data,
+                               uint64_t data,
+                               int fd)
+{
+    MemoryRegionIoeventfd mrfd = {
+        .addr.start = addr,
+        .addr.size = size,
+        .match_data = match_data,
+        .data = data,
+        .fd = fd,
+    };
+    unsigned i;
+
+    for (i = 0; i < mr->ioeventfd_nb; ++i) {
+        if (memory_region_ioeventfd_before(mrfd, mr->ioeventfds[i])) {
+            break;
+        }
+    }
+    ++mr->ioeventfd_nb;
+    mr->ioeventfds = qemu_realloc(mr->ioeventfds,
+                                  sizeof(*mr->ioeventfds) * mr->ioeventfd_nb);
+    memmove(&mr->ioeventfds[i+1], &mr->ioeventfds[i],
+            sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb-1 - i));
+    mr->ioeventfds[i] = mrfd;
+    memory_region_update_topology();
+}
+
+void memory_region_del_eventfd(MemoryRegion *mr,
+                               target_phys_addr_t addr,
+                               unsigned size,
+                               bool match_data,
+                               uint64_t data,
+                               int fd)
+{
+    MemoryRegionIoeventfd mrfd = {
+        .addr.start = addr,
+        .addr.size = size,
+        .match_data = match_data,
+        .data = data,
+        .fd = fd,
+    };
+    unsigned i;
+
+    for (i = 0; i < mr->ioeventfd_nb; ++i) {
+        if (memory_region_ioeventfd_equal(mrfd, mr->ioeventfds[i])) {
+            break;
+        }
+    }
+    if (i == mr->ioeventfd_nb) {
+        abort();
+    }
+    memmove(&mr->ioeventfds[i], &mr->ioeventfds[i+1],
+            sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb - (i+1)));
+    --mr->ioeventfd_nb;
+    mr->ioeventfds = qemu_realloc(mr->ioeventfds,
+                                  sizeof(*mr->ioeventfds)*mr->ioeventfd_nb + 1);
+    memory_region_update_topology();
+}
+
 static void memory_region_add_subregion_common(MemoryRegion *mr,
                                                target_phys_addr_t offset,
                                                MemoryRegion *subregion)
diff --git a/memory.h b/memory.h
index 2afbf13..34e0acd 100644
--- a/memory.h
+++ b/memory.h
@@ -68,6 +68,7 @@ struct MemoryRegionOps {
 };
 
 typedef struct CoalescedMemoryRange CoalescedMemoryRange;
+typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
 
 struct MemoryRegion {
     /* All fields are private - violators will be prosecuted */
@@ -90,6 +91,8 @@ struct MemoryRegion {
     QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
     const char *name;
     uint8_t dirty_log_mask;
+    unsigned ioeventfd_nb;
+    MemoryRegionIoeventfd *ioeventfds;
 };
 
 /* Initialize a memory region
@@ -181,6 +184,23 @@ void memory_region_add_coalescing(MemoryRegion *mr,
 /* Disable MMIO coalescing for the region. */
 void memory_region_clear_coalescing(MemoryRegion *mr);
 
+
+/* Request an eventfd to be triggered when a word is written to a location */
+void memory_region_add_eventfd(MemoryRegion *mr,
+                               target_phys_addr_t addr,
+                               unsigned size,
+                               bool match_data,
+                               uint64_t data,
+                               int fd);
+
+/* Cancel an existing eventfd  */
+void memory_region_del_eventfd(MemoryRegion *mr,
+                               target_phys_addr_t addr,
+                               unsigned size,
+                               bool match_data,
+                               uint64_t data,
+                               int fd);
+
 /* Add a sub-region at @offset.  The sub-region may not overlap with other
  * subregions (except for those explicitly marked as overlapping)
  */
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 37/56] ivshmem: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

excluding msix.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/ivshmem.c |  148 ++++++++++++++++++++--------------------------------------
 1 files changed, 50 insertions(+), 98 deletions(-)

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 3055dd2..e028b19 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -56,11 +56,15 @@ typedef struct IVShmemState {
 
     CharDriverState **eventfd_chr;
     CharDriverState *server_chr;
-    int ivshmem_mmio_io_addr;
+    MemoryRegion ivshmem_mmio;
 
     pcibus_t mmio_addr;
-    pcibus_t shm_pci_addr;
-    uint64_t ivshmem_offset;
+    /* We might need to register the BAR before we actually have the memory.
+     * So prepare a container MemoryRegion for the BAR immediately and
+     * add a subregion when we have the memory.
+     */
+    MemoryRegion bar;
+    MemoryRegion ivshmem;
     uint64_t ivshmem_size; /* size of shared memory region */
     int shm_fd; /* shared memory file descriptor */
 
@@ -96,23 +100,6 @@ static inline bool is_power_of_two(uint64_t x) {
     return (x & (x - 1)) == 0;
 }
 
-static void ivshmem_map(PCIDevice *pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
-{
-    IVShmemState *s = DO_UPCAST(IVShmemState, dev, pci_dev);
-
-    s->shm_pci_addr = addr;
-
-    if (s->ivshmem_offset > 0) {
-        cpu_register_physical_memory(s->shm_pci_addr, s->ivshmem_size,
-                                                            s->ivshmem_offset);
-    }
-
-    IVSHMEM_DPRINTF("guest pci addr = %" FMT_PCIBUS ", guest h/w addr = %"
-        PRIu64 ", size = %" FMT_PCIBUS "\n", addr, s->ivshmem_offset, size);
-
-}
-
 /* accessing registers - based on rtl8139 */
 static void ivshmem_update_irq(IVShmemState *s, int val)
 {
@@ -168,15 +155,8 @@ static uint32_t ivshmem_IntrStatus_read(IVShmemState *s)
     return ret;
 }
 
-static void ivshmem_io_writew(void *opaque, target_phys_addr_t addr,
-                                                            uint32_t val)
-{
-
-    IVSHMEM_DPRINTF("We shouldn't be writing words\n");
-}
-
-static void ivshmem_io_writel(void *opaque, target_phys_addr_t addr,
-                                                            uint32_t val)
+static void ivshmem_io_write(void *opaque, target_phys_addr_t addr,
+                             uint64_t val, unsigned size)
 {
     IVShmemState *s = opaque;
 
@@ -219,20 +199,8 @@ static void ivshmem_io_writel(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static void ivshmem_io_writeb(void *opaque, target_phys_addr_t addr,
-                                                                uint32_t val)
-{
-    IVSHMEM_DPRINTF("We shouldn't be writing bytes\n");
-}
-
-static uint32_t ivshmem_io_readw(void *opaque, target_phys_addr_t addr)
-{
-
-    IVSHMEM_DPRINTF("We shouldn't be reading words\n");
-    return 0;
-}
-
-static uint32_t ivshmem_io_readl(void *opaque, target_phys_addr_t addr)
+static uint64_t ivshmem_io_read(void *opaque, target_phys_addr_t addr,
+                                unsigned size)
 {
 
     IVShmemState *s = opaque;
@@ -265,23 +233,14 @@ static uint32_t ivshmem_io_readl(void *opaque, target_phys_addr_t addr)
     return ret;
 }
 
-static uint32_t ivshmem_io_readb(void *opaque, target_phys_addr_t addr)
-{
-    IVSHMEM_DPRINTF("We shouldn't be reading bytes\n");
-
-    return 0;
-}
-
-static CPUReadMemoryFunc * const ivshmem_mmio_read[3] = {
-    ivshmem_io_readb,
-    ivshmem_io_readw,
-    ivshmem_io_readl,
-};
-
-static CPUWriteMemoryFunc * const ivshmem_mmio_write[3] = {
-    ivshmem_io_writeb,
-    ivshmem_io_writew,
-    ivshmem_io_writel,
+static MemoryRegionOps ivshmem_mmio_ops = {
+    .read = ivshmem_io_read,
+    .write = ivshmem_io_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
 };
 
 static void ivshmem_receive(void *opaque, const uint8_t *buf, int size)
@@ -371,12 +330,12 @@ static void create_shared_memory_BAR(IVShmemState *s, int fd) {
 
     ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
 
-    s->ivshmem_offset = qemu_ram_alloc_from_ptr(&s->dev.qdev, "ivshmem.bar2",
-                                                        s->ivshmem_size, ptr);
+    memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev, "ivshmem.bar2",
+                               s->ivshmem_size, ptr);
+    memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
 
     /* region for shared memory */
-    pci_register_bar(&s->dev, 2, s->ivshmem_size,
-                                PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map);
+    pci_register_bar_region(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
 }
 
 static void close_guest_eventfds(IVShmemState *s, int posn)
@@ -401,8 +360,12 @@ static void setup_ioeventfds(IVShmemState *s) {
 
     for (i = 0; i <= s->max_peer; i++) {
         for (j = 0; j < s->peers[i].nb_eventfds; j++) {
-            kvm_set_ioeventfd_mmio_long(s->peers[i].eventfds[j],
-                    s->mmio_addr + DOORBELL, (i << 16) | j, 1);
+            memory_region_add_eventfd(&s->ivshmem_mmio,
+                                      DOORBELL,
+                                      4,
+                                      true,
+                                      (i << 16) | j,
+                                      s->peers[i].eventfds[j]);
         }
     }
 }
@@ -483,18 +446,13 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
         /* mmap the region and map into the BAR2 */
         map_ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED,
                                                             incoming_fd, 0);
-        s->ivshmem_offset = qemu_ram_alloc_from_ptr(&s->dev.qdev,
-                                    "ivshmem.bar2", s->ivshmem_size, map_ptr);
+        memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev,
+                                   "ivshmem.bar2", s->ivshmem_size, map_ptr);
 
-        IVSHMEM_DPRINTF("guest pci addr = %" FMT_PCIBUS ", guest h/w addr = %"
-                         PRIu64 ", size = %" PRIu64 "\n", s->shm_pci_addr,
+        IVSHMEM_DPRINTF("guest h/w addr = %" PRIu64 ", size = %" PRIu64 "\n",
                          s->ivshmem_offset, s->ivshmem_size);
 
-        if (s->shm_pci_addr > 0) {
-            /* map memory into BAR2 */
-            cpu_register_physical_memory(s->shm_pci_addr, s->ivshmem_size,
-                                                            s->ivshmem_offset);
-        }
+        memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
 
         /* only store the fd if it is successfully mapped */
         s->shm_fd = incoming_fd;
@@ -549,20 +507,6 @@ static void ivshmem_reset(DeviceState *d)
     return;
 }
 
-static void ivshmem_mmio_map(PCIDevice *pci_dev, int region_num,
-                       pcibus_t addr, pcibus_t size, int type)
-{
-    IVShmemState *s = DO_UPCAST(IVShmemState, dev, pci_dev);
-
-    s->mmio_addr = addr;
-    cpu_register_physical_memory(addr + 0, IVSHMEM_REG_BAR_SIZE,
-                                                s->ivshmem_mmio_io_addr);
-
-    if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
-        setup_ioeventfds(s);
-    }
-}
-
 static uint64_t ivshmem_get_size(IVShmemState * s) {
 
     uint64_t value;
@@ -710,15 +654,20 @@ static int pci_ivshmem_init(PCIDevice *dev)
 
     pci_config_set_interrupt_pin(pci_conf, 1);
 
-    s->shm_pci_addr = 0;
-    s->ivshmem_offset = 0;
     s->shm_fd = 0;
 
-    s->ivshmem_mmio_io_addr = cpu_register_io_memory(ivshmem_mmio_read,
-                                    ivshmem_mmio_write, s, DEVICE_NATIVE_ENDIAN);
+    memory_region_init_io(&s->ivshmem_mmio, &ivshmem_mmio_ops, s,
+                          "ivshmem-mmio", IVSHMEM_REG_BAR_SIZE);
+
+    if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
+        setup_ioeventfds(s);
+    }
+
     /* region for registers*/
-    pci_register_bar(&s->dev, 0, IVSHMEM_REG_BAR_SIZE,
-                           PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_mmio_map);
+    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                            &s->ivshmem_mmio);
+
+    memory_region_init(&s->bar, "ivshmem-bar2-container", s->ivshmem_size);
 
     if ((s->server_chr != NULL) &&
                         (strncmp(s->server_chr->filename, "unix:", 5) == 0)) {
@@ -744,8 +693,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
         /* allocate/initialize space for interrupt handling */
         s->peers = qemu_mallocz(s->nb_peers * sizeof(Peer));
 
-        pci_register_bar(&s->dev, 2, s->ivshmem_size,
-                                PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map);
+        pci_register_bar_region(&s->dev, 2,
+                                PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ivshmem);
 
         s->eventfd_chr = qemu_mallocz(s->vectors * sizeof(CharDriverState *));
 
@@ -792,7 +741,10 @@ static int pci_ivshmem_uninit(PCIDevice *dev)
 {
     IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
 
-    cpu_unregister_io_memory(s->ivshmem_mmio_io_addr);
+    memory_region_destroy(&s->ivshmem_mmio);
+    memory_region_del_subregion(&s->bar, &s->ivshmem);
+    memory_region_destroy(&s->ivshmem);
+    memory_region_destroy(&s->bar);
     unregister_savevm(&dev->qdev, "ivshmem", s);
 
     return 0;
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 37/56] ivshmem: convert to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

excluding msix.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/ivshmem.c |  148 ++++++++++++++++++++--------------------------------------
 1 files changed, 50 insertions(+), 98 deletions(-)

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 3055dd2..e028b19 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -56,11 +56,15 @@ typedef struct IVShmemState {
 
     CharDriverState **eventfd_chr;
     CharDriverState *server_chr;
-    int ivshmem_mmio_io_addr;
+    MemoryRegion ivshmem_mmio;
 
     pcibus_t mmio_addr;
-    pcibus_t shm_pci_addr;
-    uint64_t ivshmem_offset;
+    /* We might need to register the BAR before we actually have the memory.
+     * So prepare a container MemoryRegion for the BAR immediately and
+     * add a subregion when we have the memory.
+     */
+    MemoryRegion bar;
+    MemoryRegion ivshmem;
     uint64_t ivshmem_size; /* size of shared memory region */
     int shm_fd; /* shared memory file descriptor */
 
@@ -96,23 +100,6 @@ static inline bool is_power_of_two(uint64_t x) {
     return (x & (x - 1)) == 0;
 }
 
-static void ivshmem_map(PCIDevice *pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
-{
-    IVShmemState *s = DO_UPCAST(IVShmemState, dev, pci_dev);
-
-    s->shm_pci_addr = addr;
-
-    if (s->ivshmem_offset > 0) {
-        cpu_register_physical_memory(s->shm_pci_addr, s->ivshmem_size,
-                                                            s->ivshmem_offset);
-    }
-
-    IVSHMEM_DPRINTF("guest pci addr = %" FMT_PCIBUS ", guest h/w addr = %"
-        PRIu64 ", size = %" FMT_PCIBUS "\n", addr, s->ivshmem_offset, size);
-
-}
-
 /* accessing registers - based on rtl8139 */
 static void ivshmem_update_irq(IVShmemState *s, int val)
 {
@@ -168,15 +155,8 @@ static uint32_t ivshmem_IntrStatus_read(IVShmemState *s)
     return ret;
 }
 
-static void ivshmem_io_writew(void *opaque, target_phys_addr_t addr,
-                                                            uint32_t val)
-{
-
-    IVSHMEM_DPRINTF("We shouldn't be writing words\n");
-}
-
-static void ivshmem_io_writel(void *opaque, target_phys_addr_t addr,
-                                                            uint32_t val)
+static void ivshmem_io_write(void *opaque, target_phys_addr_t addr,
+                             uint64_t val, unsigned size)
 {
     IVShmemState *s = opaque;
 
@@ -219,20 +199,8 @@ static void ivshmem_io_writel(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static void ivshmem_io_writeb(void *opaque, target_phys_addr_t addr,
-                                                                uint32_t val)
-{
-    IVSHMEM_DPRINTF("We shouldn't be writing bytes\n");
-}
-
-static uint32_t ivshmem_io_readw(void *opaque, target_phys_addr_t addr)
-{
-
-    IVSHMEM_DPRINTF("We shouldn't be reading words\n");
-    return 0;
-}
-
-static uint32_t ivshmem_io_readl(void *opaque, target_phys_addr_t addr)
+static uint64_t ivshmem_io_read(void *opaque, target_phys_addr_t addr,
+                                unsigned size)
 {
 
     IVShmemState *s = opaque;
@@ -265,23 +233,14 @@ static uint32_t ivshmem_io_readl(void *opaque, target_phys_addr_t addr)
     return ret;
 }
 
-static uint32_t ivshmem_io_readb(void *opaque, target_phys_addr_t addr)
-{
-    IVSHMEM_DPRINTF("We shouldn't be reading bytes\n");
-
-    return 0;
-}
-
-static CPUReadMemoryFunc * const ivshmem_mmio_read[3] = {
-    ivshmem_io_readb,
-    ivshmem_io_readw,
-    ivshmem_io_readl,
-};
-
-static CPUWriteMemoryFunc * const ivshmem_mmio_write[3] = {
-    ivshmem_io_writeb,
-    ivshmem_io_writew,
-    ivshmem_io_writel,
+static MemoryRegionOps ivshmem_mmio_ops = {
+    .read = ivshmem_io_read,
+    .write = ivshmem_io_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
 };
 
 static void ivshmem_receive(void *opaque, const uint8_t *buf, int size)
@@ -371,12 +330,12 @@ static void create_shared_memory_BAR(IVShmemState *s, int fd) {
 
     ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
 
-    s->ivshmem_offset = qemu_ram_alloc_from_ptr(&s->dev.qdev, "ivshmem.bar2",
-                                                        s->ivshmem_size, ptr);
+    memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev, "ivshmem.bar2",
+                               s->ivshmem_size, ptr);
+    memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
 
     /* region for shared memory */
-    pci_register_bar(&s->dev, 2, s->ivshmem_size,
-                                PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map);
+    pci_register_bar_region(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
 }
 
 static void close_guest_eventfds(IVShmemState *s, int posn)
@@ -401,8 +360,12 @@ static void setup_ioeventfds(IVShmemState *s) {
 
     for (i = 0; i <= s->max_peer; i++) {
         for (j = 0; j < s->peers[i].nb_eventfds; j++) {
-            kvm_set_ioeventfd_mmio_long(s->peers[i].eventfds[j],
-                    s->mmio_addr + DOORBELL, (i << 16) | j, 1);
+            memory_region_add_eventfd(&s->ivshmem_mmio,
+                                      DOORBELL,
+                                      4,
+                                      true,
+                                      (i << 16) | j,
+                                      s->peers[i].eventfds[j]);
         }
     }
 }
@@ -483,18 +446,13 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
         /* mmap the region and map into the BAR2 */
         map_ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED,
                                                             incoming_fd, 0);
-        s->ivshmem_offset = qemu_ram_alloc_from_ptr(&s->dev.qdev,
-                                    "ivshmem.bar2", s->ivshmem_size, map_ptr);
+        memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev,
+                                   "ivshmem.bar2", s->ivshmem_size, map_ptr);
 
-        IVSHMEM_DPRINTF("guest pci addr = %" FMT_PCIBUS ", guest h/w addr = %"
-                         PRIu64 ", size = %" PRIu64 "\n", s->shm_pci_addr,
+        IVSHMEM_DPRINTF("guest h/w addr = %" PRIu64 ", size = %" PRIu64 "\n",
                          s->ivshmem_offset, s->ivshmem_size);
 
-        if (s->shm_pci_addr > 0) {
-            /* map memory into BAR2 */
-            cpu_register_physical_memory(s->shm_pci_addr, s->ivshmem_size,
-                                                            s->ivshmem_offset);
-        }
+        memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
 
         /* only store the fd if it is successfully mapped */
         s->shm_fd = incoming_fd;
@@ -549,20 +507,6 @@ static void ivshmem_reset(DeviceState *d)
     return;
 }
 
-static void ivshmem_mmio_map(PCIDevice *pci_dev, int region_num,
-                       pcibus_t addr, pcibus_t size, int type)
-{
-    IVShmemState *s = DO_UPCAST(IVShmemState, dev, pci_dev);
-
-    s->mmio_addr = addr;
-    cpu_register_physical_memory(addr + 0, IVSHMEM_REG_BAR_SIZE,
-                                                s->ivshmem_mmio_io_addr);
-
-    if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
-        setup_ioeventfds(s);
-    }
-}
-
 static uint64_t ivshmem_get_size(IVShmemState * s) {
 
     uint64_t value;
@@ -710,15 +654,20 @@ static int pci_ivshmem_init(PCIDevice *dev)
 
     pci_config_set_interrupt_pin(pci_conf, 1);
 
-    s->shm_pci_addr = 0;
-    s->ivshmem_offset = 0;
     s->shm_fd = 0;
 
-    s->ivshmem_mmio_io_addr = cpu_register_io_memory(ivshmem_mmio_read,
-                                    ivshmem_mmio_write, s, DEVICE_NATIVE_ENDIAN);
+    memory_region_init_io(&s->ivshmem_mmio, &ivshmem_mmio_ops, s,
+                          "ivshmem-mmio", IVSHMEM_REG_BAR_SIZE);
+
+    if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
+        setup_ioeventfds(s);
+    }
+
     /* region for registers*/
-    pci_register_bar(&s->dev, 0, IVSHMEM_REG_BAR_SIZE,
-                           PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_mmio_map);
+    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                            &s->ivshmem_mmio);
+
+    memory_region_init(&s->bar, "ivshmem-bar2-container", s->ivshmem_size);
 
     if ((s->server_chr != NULL) &&
                         (strncmp(s->server_chr->filename, "unix:", 5) == 0)) {
@@ -744,8 +693,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
         /* allocate/initialize space for interrupt handling */
         s->peers = qemu_mallocz(s->nb_peers * sizeof(Peer));
 
-        pci_register_bar(&s->dev, 2, s->ivshmem_size,
-                                PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map);
+        pci_register_bar_region(&s->dev, 2,
+                                PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ivshmem);
 
         s->eventfd_chr = qemu_mallocz(s->vectors * sizeof(CharDriverState *));
 
@@ -792,7 +741,10 @@ static int pci_ivshmem_uninit(PCIDevice *dev)
 {
     IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
 
-    cpu_unregister_io_memory(s->ivshmem_mmio_io_addr);
+    memory_region_destroy(&s->ivshmem_mmio);
+    memory_region_del_subregion(&s->bar, &s->ivshmem);
+    memory_region_destroy(&s->ivshmem);
+    memory_region_destroy(&s->bar);
     unregister_savevm(&dev->qdev, "ivshmem", s);
 
     return 0;
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 38/56] virtio-pci: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

except msix.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/virtio-pci.c |   84 +++++++++++++++++++++++++++++-------------------------
 hw/virtio-pci.h |    2 +-
 2 files changed, 46 insertions(+), 40 deletions(-)

diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index b3e7ba5..20e6c5b 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -162,6 +162,7 @@ static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
     VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
     EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
     int r;
+
     if (assign) {
         r = event_notifier_init(notifier, 1);
         if (r < 0) {
@@ -169,24 +170,11 @@ static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
                          __func__, r);
             return r;
         }
-        r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier),
-                                       proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
-                                       n, assign);
-        if (r < 0) {
-            error_report("%s: unable to map ioeventfd: %d",
-                         __func__, r);
-            event_notifier_cleanup(notifier);
-        }
+        memory_region_add_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
+                                  true, n, event_notifier_get_fd(notifier));
     } else {
-        r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier),
-                                       proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
-                                       n, assign);
-        if (r < 0) {
-            error_report("%s: unable to unmap ioeventfd: %d",
-                         __func__, r);
-            return r;
-        }
-
+        memory_region_del_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
+                                  true, n, event_notifier_get_fd(notifier));
         /* Handle the race condition where the guest kicked and we deassigned
          * before we got around to handling the kick.
          */
@@ -423,7 +411,6 @@ static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config)
         return virtio_ioport_read(proxy, addr);
     addr -= config;
@@ -434,7 +421,6 @@ static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config)
         return virtio_ioport_read(proxy, addr);
     addr -= config;
@@ -445,7 +431,6 @@ static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config)
         return virtio_ioport_read(proxy, addr);
     addr -= config;
@@ -456,7 +441,6 @@ static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config) {
         virtio_ioport_write(proxy, addr, val);
         return;
@@ -469,7 +453,6 @@ static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config) {
         virtio_ioport_write(proxy, addr, val);
         return;
@@ -482,7 +465,6 @@ static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config) {
         virtio_ioport_write(proxy, addr, val);
         return;
@@ -491,30 +473,46 @@ static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val)
     virtio_config_writel(proxy->vdev, addr, val);
 }
 
-static void virtio_map(PCIDevice *pci_dev, int region_num,
-                       pcibus_t addr, pcibus_t size, int type)
+static uint64_t virtio_pci_config_read(void *opaque,
+                                       target_phys_addr_t addr,
+                                       unsigned size)
 {
-    VirtIOPCIProxy *proxy = container_of(pci_dev, VirtIOPCIProxy, pci_dev);
-    VirtIODevice *vdev = proxy->vdev;
-    unsigned config_len = VIRTIO_PCI_REGION_SIZE(pci_dev) + vdev->config_len;
+    VirtIOPCIProxy *proxy = opaque;
 
-    proxy->addr = addr;
+    switch (size) {
+    case 1: return virtio_pci_config_readb(proxy, addr);
+    case 2: return virtio_pci_config_readw(proxy, addr);
+    case 4: return virtio_pci_config_readl(proxy, addr);
+    default: abort();
+    }
+}
 
-    register_ioport_write(addr, config_len, 1, virtio_pci_config_writeb, proxy);
-    register_ioport_write(addr, config_len, 2, virtio_pci_config_writew, proxy);
-    register_ioport_write(addr, config_len, 4, virtio_pci_config_writel, proxy);
-    register_ioport_read(addr, config_len, 1, virtio_pci_config_readb, proxy);
-    register_ioport_read(addr, config_len, 2, virtio_pci_config_readw, proxy);
-    register_ioport_read(addr, config_len, 4, virtio_pci_config_readl, proxy);
+static void virtio_pci_config_write(void *opaque,
+                                    target_phys_addr_t addr,
+                                    uint64_t data,
+                                    unsigned size)
+{
+    VirtIOPCIProxy *proxy = opaque;
 
-    if (vdev->config_len)
-        vdev->get_config(vdev, vdev->config);
+    switch (size) {
+    case 1: return virtio_pci_config_writeb(proxy, addr, data);
+    case 2: return virtio_pci_config_writew(proxy, addr, data);
+    case 4: return virtio_pci_config_writel(proxy, addr, data);
+    default: abort();
+    }
 }
 
+static MemoryRegionOps virtio_pci_config_ops = {
+    .read = virtio_pci_config_read,
+    .write = virtio_pci_config_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
                                 uint32_t val, int len)
 {
     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+    VirtIODevice *vdev = proxy->vdev;
 
     if (PCI_COMMAND == address) {
         if (!(val & PCI_COMMAND_MASTER)) {
@@ -525,6 +523,9 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
             }
         }
     }
+    if (address == PCI_BASE_ADDRESS_0 && vdev->config_len) {
+        vdev->get_config(vdev, vdev->config);
+    }
 
     pci_default_write_config(pci_dev, address, val, len);
     msix_write_config(pci_dev, address, val, len);
@@ -678,8 +679,10 @@ void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
     if (size & (size-1))
         size = 1 << qemu_fls(size);
 
-    pci_register_bar(&proxy->pci_dev, 0, size, PCI_BASE_ADDRESS_SPACE_IO,
-                           virtio_map);
+    memory_region_init_io(&proxy->bar, &virtio_pci_config_ops, proxy,
+                          "virtio-pci", size);
+    pci_register_bar_region(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
+                            &proxy->bar);
 
     if (!kvm_has_many_ioeventfds()) {
         proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
@@ -713,6 +716,9 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev)
 
 static int virtio_exit_pci(PCIDevice *pci_dev)
 {
+    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+
+    memory_region_destroy(&proxy->bar);
     return msix_uninit(pci_dev);
 }
 
diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
index b518917..d17e5fc 100644
--- a/hw/virtio-pci.h
+++ b/hw/virtio-pci.h
@@ -21,8 +21,8 @@
 typedef struct {
     PCIDevice pci_dev;
     VirtIODevice *vdev;
+    MemoryRegion bar;
     uint32_t flags;
-    uint32_t addr;
     uint32_t class_code;
     uint32_t nvectors;
     BlockConf block;
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 38/56] virtio-pci: convert to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

except msix.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/virtio-pci.c |   84 +++++++++++++++++++++++++++++-------------------------
 hw/virtio-pci.h |    2 +-
 2 files changed, 46 insertions(+), 40 deletions(-)

diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index b3e7ba5..20e6c5b 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -162,6 +162,7 @@ static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
     VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
     EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
     int r;
+
     if (assign) {
         r = event_notifier_init(notifier, 1);
         if (r < 0) {
@@ -169,24 +170,11 @@ static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
                          __func__, r);
             return r;
         }
-        r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier),
-                                       proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
-                                       n, assign);
-        if (r < 0) {
-            error_report("%s: unable to map ioeventfd: %d",
-                         __func__, r);
-            event_notifier_cleanup(notifier);
-        }
+        memory_region_add_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
+                                  true, n, event_notifier_get_fd(notifier));
     } else {
-        r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier),
-                                       proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
-                                       n, assign);
-        if (r < 0) {
-            error_report("%s: unable to unmap ioeventfd: %d",
-                         __func__, r);
-            return r;
-        }
-
+        memory_region_del_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
+                                  true, n, event_notifier_get_fd(notifier));
         /* Handle the race condition where the guest kicked and we deassigned
          * before we got around to handling the kick.
          */
@@ -423,7 +411,6 @@ static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config)
         return virtio_ioport_read(proxy, addr);
     addr -= config;
@@ -434,7 +421,6 @@ static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config)
         return virtio_ioport_read(proxy, addr);
     addr -= config;
@@ -445,7 +431,6 @@ static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config)
         return virtio_ioport_read(proxy, addr);
     addr -= config;
@@ -456,7 +441,6 @@ static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config) {
         virtio_ioport_write(proxy, addr, val);
         return;
@@ -469,7 +453,6 @@ static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config) {
         virtio_ioport_write(proxy, addr, val);
         return;
@@ -482,7 +465,6 @@ static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config) {
         virtio_ioport_write(proxy, addr, val);
         return;
@@ -491,30 +473,46 @@ static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val)
     virtio_config_writel(proxy->vdev, addr, val);
 }
 
-static void virtio_map(PCIDevice *pci_dev, int region_num,
-                       pcibus_t addr, pcibus_t size, int type)
+static uint64_t virtio_pci_config_read(void *opaque,
+                                       target_phys_addr_t addr,
+                                       unsigned size)
 {
-    VirtIOPCIProxy *proxy = container_of(pci_dev, VirtIOPCIProxy, pci_dev);
-    VirtIODevice *vdev = proxy->vdev;
-    unsigned config_len = VIRTIO_PCI_REGION_SIZE(pci_dev) + vdev->config_len;
+    VirtIOPCIProxy *proxy = opaque;
 
-    proxy->addr = addr;
+    switch (size) {
+    case 1: return virtio_pci_config_readb(proxy, addr);
+    case 2: return virtio_pci_config_readw(proxy, addr);
+    case 4: return virtio_pci_config_readl(proxy, addr);
+    default: abort();
+    }
+}
 
-    register_ioport_write(addr, config_len, 1, virtio_pci_config_writeb, proxy);
-    register_ioport_write(addr, config_len, 2, virtio_pci_config_writew, proxy);
-    register_ioport_write(addr, config_len, 4, virtio_pci_config_writel, proxy);
-    register_ioport_read(addr, config_len, 1, virtio_pci_config_readb, proxy);
-    register_ioport_read(addr, config_len, 2, virtio_pci_config_readw, proxy);
-    register_ioport_read(addr, config_len, 4, virtio_pci_config_readl, proxy);
+static void virtio_pci_config_write(void *opaque,
+                                    target_phys_addr_t addr,
+                                    uint64_t data,
+                                    unsigned size)
+{
+    VirtIOPCIProxy *proxy = opaque;
 
-    if (vdev->config_len)
-        vdev->get_config(vdev, vdev->config);
+    switch (size) {
+    case 1: return virtio_pci_config_writeb(proxy, addr, data);
+    case 2: return virtio_pci_config_writew(proxy, addr, data);
+    case 4: return virtio_pci_config_writel(proxy, addr, data);
+    default: abort();
+    }
 }
 
+static MemoryRegionOps virtio_pci_config_ops = {
+    .read = virtio_pci_config_read,
+    .write = virtio_pci_config_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
                                 uint32_t val, int len)
 {
     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+    VirtIODevice *vdev = proxy->vdev;
 
     if (PCI_COMMAND == address) {
         if (!(val & PCI_COMMAND_MASTER)) {
@@ -525,6 +523,9 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
             }
         }
     }
+    if (address == PCI_BASE_ADDRESS_0 && vdev->config_len) {
+        vdev->get_config(vdev, vdev->config);
+    }
 
     pci_default_write_config(pci_dev, address, val, len);
     msix_write_config(pci_dev, address, val, len);
@@ -678,8 +679,10 @@ void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
     if (size & (size-1))
         size = 1 << qemu_fls(size);
 
-    pci_register_bar(&proxy->pci_dev, 0, size, PCI_BASE_ADDRESS_SPACE_IO,
-                           virtio_map);
+    memory_region_init_io(&proxy->bar, &virtio_pci_config_ops, proxy,
+                          "virtio-pci", size);
+    pci_register_bar_region(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
+                            &proxy->bar);
 
     if (!kvm_has_many_ioeventfds()) {
         proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
@@ -713,6 +716,9 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev)
 
 static int virtio_exit_pci(PCIDevice *pci_dev)
 {
+    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+
+    memory_region_destroy(&proxy->bar);
     return msix_uninit(pci_dev);
 }
 
diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
index b518917..d17e5fc 100644
--- a/hw/virtio-pci.h
+++ b/hw/virtio-pci.h
@@ -21,8 +21,8 @@
 typedef struct {
     PCIDevice pci_dev;
     VirtIODevice *vdev;
+    MemoryRegion bar;
     uint32_t flags;
-    uint32_t addr;
     uint32_t class_code;
     uint32_t nvectors;
     BlockConf block;
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 39/56] ahci: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/ide/ahci.c |   31 +++++++++++++------------------
 hw/ide/ahci.h |    2 +-
 hw/ide/ich.c  |    3 +--
 3 files changed, 15 insertions(+), 21 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 1f008a3..e207ca0 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -276,12 +276,12 @@ static void  ahci_port_write(AHCIState *s, int port, int offset, uint32_t val)
     }
 }
 
-static uint32_t ahci_mem_readl(void *ptr, target_phys_addr_t addr)
+static uint64_t ahci_mem_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
 {
-    AHCIState *s = ptr;
+    AHCIState *s = opaque;
     uint32_t val = 0;
 
-    addr = addr & 0xfff;
     if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) {
         switch (addr) {
         case HOST_CAP:
@@ -314,10 +314,10 @@ static uint32_t ahci_mem_readl(void *ptr, target_phys_addr_t addr)
 
 
 
-static void ahci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
+static void ahci_mem_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t val, unsigned size)
 {
-    AHCIState *s = ptr;
-    addr = addr & 0xfff;
+    AHCIState *s = opaque;
 
     /* Only aligned reads are allowed on AHCI */
     if (addr & 3) {
@@ -364,16 +364,10 @@ static void ahci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
 
 }
 
-static CPUReadMemoryFunc * const ahci_readfn[3]={
-    ahci_mem_readl,
-    ahci_mem_readl,
-    ahci_mem_readl
-};
-
-static CPUWriteMemoryFunc * const ahci_writefn[3]={
-    ahci_mem_writel,
-    ahci_mem_writel,
-    ahci_mem_writel
+static MemoryRegionOps ahci_mem_ops = {
+    .read = ahci_mem_read,
+    .write = ahci_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void ahci_reg_init(AHCIState *s)
@@ -1131,8 +1125,8 @@ void ahci_init(AHCIState *s, DeviceState *qdev, int ports)
     s->ports = ports;
     s->dev = qemu_mallocz(sizeof(AHCIDevice) * ports);
     ahci_reg_init(s);
-    s->mem = cpu_register_io_memory(ahci_readfn, ahci_writefn, s,
-                                    DEVICE_LITTLE_ENDIAN);
+    /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
+    memory_region_init_io(&s->mem, &ahci_mem_ops, s, "ahci", 0x1000);
     irqs = qemu_allocate_irqs(ahci_irq_set, s, s->ports);
 
     for (i = 0; i < s->ports; i++) {
@@ -1151,6 +1145,7 @@ void ahci_init(AHCIState *s, DeviceState *qdev, int ports)
 
 void ahci_uninit(AHCIState *s)
 {
+    memory_region_destroy(&s->mem);
     qemu_free(s->dev);
 }
 
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index dc86951..e456193 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -289,7 +289,7 @@ struct AHCIDevice {
 typedef struct AHCIState {
     AHCIDevice *dev;
     AHCIControlRegs control_regs;
-    int mem;
+    MemoryRegion mem;
     int ports;
     qemu_irq irq;
 } AHCIState;
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 054e073..7e497c3 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -93,8 +93,7 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
     msi_init(dev, 0x50, 1, true, false);
     d->ahci.irq = d->card.irq[0];
 
-    /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
-    pci_register_bar_simple(&d->card, 5, 0x1000, 0, d->ahci.mem);
+    pci_register_bar_region(&d->card, 5, 0, &d->ahci.mem);
 
     return 0;
 }
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 39/56] ahci: convert to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/ide/ahci.c |   31 +++++++++++++------------------
 hw/ide/ahci.h |    2 +-
 hw/ide/ich.c  |    3 +--
 3 files changed, 15 insertions(+), 21 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 1f008a3..e207ca0 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -276,12 +276,12 @@ static void  ahci_port_write(AHCIState *s, int port, int offset, uint32_t val)
     }
 }
 
-static uint32_t ahci_mem_readl(void *ptr, target_phys_addr_t addr)
+static uint64_t ahci_mem_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
 {
-    AHCIState *s = ptr;
+    AHCIState *s = opaque;
     uint32_t val = 0;
 
-    addr = addr & 0xfff;
     if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) {
         switch (addr) {
         case HOST_CAP:
@@ -314,10 +314,10 @@ static uint32_t ahci_mem_readl(void *ptr, target_phys_addr_t addr)
 
 
 
-static void ahci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
+static void ahci_mem_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t val, unsigned size)
 {
-    AHCIState *s = ptr;
-    addr = addr & 0xfff;
+    AHCIState *s = opaque;
 
     /* Only aligned reads are allowed on AHCI */
     if (addr & 3) {
@@ -364,16 +364,10 @@ static void ahci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
 
 }
 
-static CPUReadMemoryFunc * const ahci_readfn[3]={
-    ahci_mem_readl,
-    ahci_mem_readl,
-    ahci_mem_readl
-};
-
-static CPUWriteMemoryFunc * const ahci_writefn[3]={
-    ahci_mem_writel,
-    ahci_mem_writel,
-    ahci_mem_writel
+static MemoryRegionOps ahci_mem_ops = {
+    .read = ahci_mem_read,
+    .write = ahci_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void ahci_reg_init(AHCIState *s)
@@ -1131,8 +1125,8 @@ void ahci_init(AHCIState *s, DeviceState *qdev, int ports)
     s->ports = ports;
     s->dev = qemu_mallocz(sizeof(AHCIDevice) * ports);
     ahci_reg_init(s);
-    s->mem = cpu_register_io_memory(ahci_readfn, ahci_writefn, s,
-                                    DEVICE_LITTLE_ENDIAN);
+    /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
+    memory_region_init_io(&s->mem, &ahci_mem_ops, s, "ahci", 0x1000);
     irqs = qemu_allocate_irqs(ahci_irq_set, s, s->ports);
 
     for (i = 0; i < s->ports; i++) {
@@ -1151,6 +1145,7 @@ void ahci_init(AHCIState *s, DeviceState *qdev, int ports)
 
 void ahci_uninit(AHCIState *s)
 {
+    memory_region_destroy(&s->mem);
     qemu_free(s->dev);
 }
 
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index dc86951..e456193 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -289,7 +289,7 @@ struct AHCIDevice {
 typedef struct AHCIState {
     AHCIDevice *dev;
     AHCIControlRegs control_regs;
-    int mem;
+    MemoryRegion mem;
     int ports;
     qemu_irq irq;
 } AHCIState;
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 054e073..7e497c3 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -93,8 +93,7 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
     msi_init(dev, 0x50, 1, true, false);
     d->ahci.irq = d->card.irq[0];
 
-    /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
-    pci_register_bar_simple(&d->card, 5, 0x1000, 0, d->ahci.mem);
+    pci_register_bar_region(&d->card, 5, 0, &d->ahci.mem);
 
     return 0;
 }
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 40/56] intel-hda: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/intel-hda.c |   49 ++++++++++++++++++++++++++++++++++---------------
 1 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 0ffffce..0f5c6c4 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -177,7 +177,7 @@ struct IntelHDAState {
     IntelHDAStream st[8];
 
     /* state */
-    int mmio_addr;
+    MemoryRegion mmio;
     uint32_t rirb_count;
     int64_t wall_base_ns;
 
@@ -1097,16 +1097,36 @@ static uint32_t intel_hda_mmio_readl(void *opaque, target_phys_addr_t addr)
     return intel_hda_reg_read(d, reg, 0xffffffff);
 }
 
-static CPUReadMemoryFunc * const intel_hda_mmio_read[3] = {
-    intel_hda_mmio_readb,
-    intel_hda_mmio_readw,
-    intel_hda_mmio_readl,
-};
+static uint64_t intel_hda_mmio_read(void *opaque, target_phys_addr_t addr,
+                                    unsigned size)
+{
+    IntelHDAState *d = opaque;
+
+    switch (size) {
+    case 1: return intel_hda_mmio_readb(d, addr);
+    case 2: return intel_hda_mmio_readw(d, addr);
+    case 4: return intel_hda_mmio_readl(d, addr);
+    default: abort();
+    }
+}
+
+static void intel_hda_mmio_write(void *opaque, target_phys_addr_t addr,
+                                 uint64_t data, unsigned size)
+{
+    IntelHDAState *d = opaque;
+
+    switch (size) {
+    case 1: return intel_hda_mmio_writeb(d, addr, data);
+    case 2: return intel_hda_mmio_writew(d, addr, data);
+    case 4: return intel_hda_mmio_writel(d, addr, data);
+    default: abort();
+    }
+}
 
-static CPUWriteMemoryFunc * const intel_hda_mmio_write[3] = {
-    intel_hda_mmio_writeb,
-    intel_hda_mmio_writew,
-    intel_hda_mmio_writel,
+static MemoryRegionOps intel_hda_mmio_ops = {
+    .read = intel_hda_mmio_read,
+    .write = intel_hda_mmio_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 /* --------------------------------------------------------------------- */
@@ -1143,10 +1163,9 @@ static int intel_hda_init(PCIDevice *pci)
     /* HDCTL off 0x40 bit 0 selects signaling mode (1-HDA, 0 - Ac97) 18.1.19 */
     conf[0x40] = 0x01;
 
-    d->mmio_addr = cpu_register_io_memory(intel_hda_mmio_read,
-                                          intel_hda_mmio_write, d,
-                                          DEVICE_NATIVE_ENDIAN);
-    pci_register_bar_simple(&d->pci, 0, 0x4000, 0, d->mmio_addr);
+    memory_region_init_io(&d->mmio, &intel_hda_mmio_ops, d,
+                          "intel-hda", 0x4000);
+    pci_register_bar_region(&d->pci, 0, 0, &d->mmio);
     if (d->msi) {
         msi_init(&d->pci, 0x50, 1, true, false);
     }
@@ -1162,7 +1181,7 @@ static int intel_hda_exit(PCIDevice *pci)
     IntelHDAState *d = DO_UPCAST(IntelHDAState, pci, pci);
 
     msi_uninit(&d->pci);
-    cpu_unregister_io_memory(d->mmio_addr);
+    memory_region_destroy(&d->mmio);
     return 0;
 }
 
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 40/56] intel-hda: convert to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/intel-hda.c |   49 ++++++++++++++++++++++++++++++++++---------------
 1 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 0ffffce..0f5c6c4 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -177,7 +177,7 @@ struct IntelHDAState {
     IntelHDAStream st[8];
 
     /* state */
-    int mmio_addr;
+    MemoryRegion mmio;
     uint32_t rirb_count;
     int64_t wall_base_ns;
 
@@ -1097,16 +1097,36 @@ static uint32_t intel_hda_mmio_readl(void *opaque, target_phys_addr_t addr)
     return intel_hda_reg_read(d, reg, 0xffffffff);
 }
 
-static CPUReadMemoryFunc * const intel_hda_mmio_read[3] = {
-    intel_hda_mmio_readb,
-    intel_hda_mmio_readw,
-    intel_hda_mmio_readl,
-};
+static uint64_t intel_hda_mmio_read(void *opaque, target_phys_addr_t addr,
+                                    unsigned size)
+{
+    IntelHDAState *d = opaque;
+
+    switch (size) {
+    case 1: return intel_hda_mmio_readb(d, addr);
+    case 2: return intel_hda_mmio_readw(d, addr);
+    case 4: return intel_hda_mmio_readl(d, addr);
+    default: abort();
+    }
+}
+
+static void intel_hda_mmio_write(void *opaque, target_phys_addr_t addr,
+                                 uint64_t data, unsigned size)
+{
+    IntelHDAState *d = opaque;
+
+    switch (size) {
+    case 1: return intel_hda_mmio_writeb(d, addr, data);
+    case 2: return intel_hda_mmio_writew(d, addr, data);
+    case 4: return intel_hda_mmio_writel(d, addr, data);
+    default: abort();
+    }
+}
 
-static CPUWriteMemoryFunc * const intel_hda_mmio_write[3] = {
-    intel_hda_mmio_writeb,
-    intel_hda_mmio_writew,
-    intel_hda_mmio_writel,
+static MemoryRegionOps intel_hda_mmio_ops = {
+    .read = intel_hda_mmio_read,
+    .write = intel_hda_mmio_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 /* --------------------------------------------------------------------- */
@@ -1143,10 +1163,9 @@ static int intel_hda_init(PCIDevice *pci)
     /* HDCTL off 0x40 bit 0 selects signaling mode (1-HDA, 0 - Ac97) 18.1.19 */
     conf[0x40] = 0x01;
 
-    d->mmio_addr = cpu_register_io_memory(intel_hda_mmio_read,
-                                          intel_hda_mmio_write, d,
-                                          DEVICE_NATIVE_ENDIAN);
-    pci_register_bar_simple(&d->pci, 0, 0x4000, 0, d->mmio_addr);
+    memory_region_init_io(&d->mmio, &intel_hda_mmio_ops, d,
+                          "intel-hda", 0x4000);
+    pci_register_bar_region(&d->pci, 0, 0, &d->mmio);
     if (d->msi) {
         msi_init(&d->pci, 0x50, 1, true, false);
     }
@@ -1162,7 +1181,7 @@ static int intel_hda_exit(PCIDevice *pci)
     IntelHDAState *d = DO_UPCAST(IntelHDAState, pci, pci);
 
     msi_uninit(&d->pci);
-    cpu_unregister_io_memory(d->mmio_addr);
+    memory_region_destroy(&d->mmio);
     return 0;
 }
 
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 41/56] lsi53c895a: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

An optimization that fast-pathed DMA reads from the SCRIPTS memory
was removed int the process.  Likely it breaks with iommus anyway.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/lsi53c895a.c |  258 ++++++++++++-------------------------------------------
 1 files changed, 56 insertions(+), 202 deletions(-)

diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 940b43a..a433920 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -185,9 +185,9 @@ typedef struct lsi_request {
 
 typedef struct {
     PCIDevice dev;
-    int mmio_io_addr;
-    int ram_io_addr;
-    uint32_t script_ram_base;
+    MemoryRegion mmio_io;
+    MemoryRegion ram_io;
+    MemoryRegion io_io;
 
     int carry; /* ??? Should this be an a visible register somewhere?  */
     int status;
@@ -391,10 +391,9 @@ static inline uint32_t read_dword(LSIState *s, uint32_t addr)
 {
     uint32_t buf;
 
-    /* Optimize reading from SCRIPTS RAM.  */
-    if ((addr & 0xffffe000) == s->script_ram_base) {
-        return s->script_ram[(addr & 0x1fff) >> 2];
-    }
+    /* XXX: an optimization here used to fast-path the read from scripts
+     * memory.  But that bypasses any iommu.
+     */
     cpu_physical_memory_read(addr, (uint8_t *)&buf, 4);
     return cpu_to_le32(buf);
 }
@@ -1905,232 +1904,90 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
 #undef CASE_SET_REG32
 }
 
-static void lsi_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void lsi_mmio_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t val, unsigned size)
 {
     LSIState *s = opaque;
 
     lsi_reg_writeb(s, addr & 0xff, val);
 }
 
-static void lsi_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    LSIState *s = opaque;
-
-    addr &= 0xff;
-    lsi_reg_writeb(s, addr, val & 0xff);
-    lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
-}
-
-static void lsi_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    LSIState *s = opaque;
-
-    addr &= 0xff;
-    lsi_reg_writeb(s, addr, val & 0xff);
-    lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
-    lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff);
-    lsi_reg_writeb(s, addr + 3, (val >> 24) & 0xff);
-}
-
-static uint32_t lsi_mmio_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t lsi_mmio_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
 {
     LSIState *s = opaque;
 
     return lsi_reg_readb(s, addr & 0xff);
 }
 
-static uint32_t lsi_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
-    LSIState *s = opaque;
-    uint32_t val;
-
-    addr &= 0xff;
-    val = lsi_reg_readb(s, addr);
-    val |= lsi_reg_readb(s, addr + 1) << 8;
-    return val;
-}
-
-static uint32_t lsi_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
-    LSIState *s = opaque;
-    uint32_t val;
-    addr &= 0xff;
-    val = lsi_reg_readb(s, addr);
-    val |= lsi_reg_readb(s, addr + 1) << 8;
-    val |= lsi_reg_readb(s, addr + 2) << 16;
-    val |= lsi_reg_readb(s, addr + 3) << 24;
-    return val;
-}
-
-static CPUReadMemoryFunc * const lsi_mmio_readfn[3] = {
-    lsi_mmio_readb,
-    lsi_mmio_readw,
-    lsi_mmio_readl,
-};
-
-static CPUWriteMemoryFunc * const lsi_mmio_writefn[3] = {
-    lsi_mmio_writeb,
-    lsi_mmio_writew,
-    lsi_mmio_writel,
+static MemoryRegionOps lsi_mmio_ops = {
+    .read = lsi_mmio_read,
+    .write = lsi_mmio_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
 };
 
-static void lsi_ram_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void lsi_ram_write(void *opaque, target_phys_addr_t addr,
+                          uint64_t val, unsigned size)
 {
     LSIState *s = opaque;
     uint32_t newval;
+    uint32_t mask;
     int shift;
 
-    addr &= 0x1fff;
     newval = s->script_ram[addr >> 2];
     shift = (addr & 3) * 8;
-    newval &= ~(0xff << shift);
+    mask = ((uint64_t)1 << (size * 8)) - 1;
+    newval &= ~(mask << shift);
     newval |= val << shift;
     s->script_ram[addr >> 2] = newval;
 }
 
-static void lsi_ram_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    LSIState *s = opaque;
-    uint32_t newval;
-
-    addr &= 0x1fff;
-    newval = s->script_ram[addr >> 2];
-    if (addr & 2) {
-        newval = (newval & 0xffff) | (val << 16);
-    } else {
-        newval = (newval & 0xffff0000) | val;
-    }
-    s->script_ram[addr >> 2] = newval;
-}
-
-
-static void lsi_ram_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    LSIState *s = opaque;
-
-    addr &= 0x1fff;
-    s->script_ram[addr >> 2] = val;
-}
-
-static uint32_t lsi_ram_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t lsi_ram_read(void *opaque, target_phys_addr_t addr,
+                             unsigned size)
 {
     LSIState *s = opaque;
     uint32_t val;
+    uint32_t mask;
 
-    addr &= 0x1fff;
     val = s->script_ram[addr >> 2];
+    mask = ((uint64_t)1 << (size * 8)) - 1;
     val >>= (addr & 3) * 8;
-    return val & 0xff;
-}
-
-static uint32_t lsi_ram_readw(void *opaque, target_phys_addr_t addr)
-{
-    LSIState *s = opaque;
-    uint32_t val;
-
-    addr &= 0x1fff;
-    val = s->script_ram[addr >> 2];
-    if (addr & 2)
-        val >>= 16;
-    return val;
-}
-
-static uint32_t lsi_ram_readl(void *opaque, target_phys_addr_t addr)
-{
-    LSIState *s = opaque;
-
-    addr &= 0x1fff;
-    return s->script_ram[addr >> 2];
+    return val & mask;
 }
 
-static CPUReadMemoryFunc * const lsi_ram_readfn[3] = {
-    lsi_ram_readb,
-    lsi_ram_readw,
-    lsi_ram_readl,
+static MemoryRegionOps lsi_ram_ops = {
+    .read = lsi_ram_read,
+    .write = lsi_ram_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUWriteMemoryFunc * const lsi_ram_writefn[3] = {
-    lsi_ram_writeb,
-    lsi_ram_writew,
-    lsi_ram_writel,
-};
-
-static uint32_t lsi_io_readb(void *opaque, uint32_t addr)
+static uint64_t lsi_io_read(void *opaque, target_phys_addr_t addr,
+                            unsigned size)
 {
     LSIState *s = opaque;
     return lsi_reg_readb(s, addr & 0xff);
 }
 
-static uint32_t lsi_io_readw(void *opaque, uint32_t addr)
-{
-    LSIState *s = opaque;
-    uint32_t val;
-    addr &= 0xff;
-    val = lsi_reg_readb(s, addr);
-    val |= lsi_reg_readb(s, addr + 1) << 8;
-    return val;
-}
-
-static uint32_t lsi_io_readl(void *opaque, uint32_t addr)
-{
-    LSIState *s = opaque;
-    uint32_t val;
-    addr &= 0xff;
-    val = lsi_reg_readb(s, addr);
-    val |= lsi_reg_readb(s, addr + 1) << 8;
-    val |= lsi_reg_readb(s, addr + 2) << 16;
-    val |= lsi_reg_readb(s, addr + 3) << 24;
-    return val;
-}
-
-static void lsi_io_writeb(void *opaque, uint32_t addr, uint32_t val)
+static void lsi_io_write(void *opaque, target_phys_addr_t addr,
+                         uint64_t val, unsigned size)
 {
     LSIState *s = opaque;
     lsi_reg_writeb(s, addr & 0xff, val);
 }
 
-static void lsi_io_writew(void *opaque, uint32_t addr, uint32_t val)
-{
-    LSIState *s = opaque;
-    addr &= 0xff;
-    lsi_reg_writeb(s, addr, val & 0xff);
-    lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
-}
-
-static void lsi_io_writel(void *opaque, uint32_t addr, uint32_t val)
-{
-    LSIState *s = opaque;
-    addr &= 0xff;
-    lsi_reg_writeb(s, addr, val & 0xff);
-    lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
-    lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff);
-    lsi_reg_writeb(s, addr + 3, (val >> 24) & 0xff);
-}
-
-static void lsi_io_mapfunc(PCIDevice *pci_dev, int region_num,
-                           pcibus_t addr, pcibus_t size, int type)
-{
-    LSIState *s = DO_UPCAST(LSIState, dev, pci_dev);
-
-    DPRINTF("Mapping IO at %08"FMT_PCIBUS"\n", addr);
-
-    register_ioport_write(addr, 256, 1, lsi_io_writeb, s);
-    register_ioport_read(addr, 256, 1, lsi_io_readb, s);
-    register_ioport_write(addr, 256, 2, lsi_io_writew, s);
-    register_ioport_read(addr, 256, 2, lsi_io_readw, s);
-    register_ioport_write(addr, 256, 4, lsi_io_writel, s);
-    register_ioport_read(addr, 256, 4, lsi_io_readl, s);
-}
-
-static void lsi_ram_mapfunc(PCIDevice *pci_dev, int region_num,
-                            pcibus_t addr, pcibus_t size, int type)
-{
-    LSIState *s = DO_UPCAST(LSIState, dev, pci_dev);
-
-    DPRINTF("Mapping ram at %08"FMT_PCIBUS"\n", addr);
-    s->script_ram_base = addr;
-    cpu_register_physical_memory(addr + 0, 0x2000, s->ram_io_addr);
-}
+static MemoryRegionOps lsi_io_ops = {
+    .read = lsi_io_read,
+    .write = lsi_io_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
 
 static void lsi_scsi_reset(DeviceState *dev)
 {
@@ -2237,8 +2094,9 @@ static int lsi_scsi_uninit(PCIDevice *d)
 {
     LSIState *s = DO_UPCAST(LSIState, dev, d);
 
-    cpu_unregister_io_memory(s->mmio_io_addr);
-    cpu_unregister_io_memory(s->ram_io_addr);
+    memory_region_destroy(&s->mmio_io);
+    memory_region_destroy(&s->ram_io);
+    memory_region_destroy(&s->io_io);
 
     return 0;
 }
@@ -2262,18 +2120,14 @@ static int lsi_scsi_init(PCIDevice *dev)
     /* Interrupt pin 1 */
     pci_conf[PCI_INTERRUPT_PIN] = 0x01;
 
-    s->mmio_io_addr = cpu_register_io_memory(lsi_mmio_readfn,
-                                             lsi_mmio_writefn, s,
-                                             DEVICE_NATIVE_ENDIAN);
-    s->ram_io_addr = cpu_register_io_memory(lsi_ram_readfn,
-                                            lsi_ram_writefn, s,
-                                            DEVICE_NATIVE_ENDIAN);
-
-    pci_register_bar(&s->dev, 0, 256,
-                           PCI_BASE_ADDRESS_SPACE_IO, lsi_io_mapfunc);
-    pci_register_bar_simple(&s->dev, 1, 0x400, 0, s->mmio_io_addr);
-    pci_register_bar(&s->dev, 2, 0x2000,
-                           PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_ram_mapfunc);
+    memory_region_init_io(&s->mmio_io, &lsi_mmio_ops, s, "lsi-mmio", 0x400);
+    memory_region_init_io(&s->ram_io, &lsi_ram_ops, s, "lsi-ram", 0x2000);
+    memory_region_init_io(&s->io_io, &lsi_io_ops, s, "lsi-io", 256);
+
+    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_io);
+    pci_register_bar_region(&s->dev, 1, 0, &s->mmio_io);
+    pci_register_bar_region(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                            &s->ram_io);
     QTAILQ_INIT(&s->queue);
 
     scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, &lsi_scsi_ops);
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 41/56] lsi53c895a: convert to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

An optimization that fast-pathed DMA reads from the SCRIPTS memory
was removed int the process.  Likely it breaks with iommus anyway.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/lsi53c895a.c |  258 ++++++++++++-------------------------------------------
 1 files changed, 56 insertions(+), 202 deletions(-)

diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 940b43a..a433920 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -185,9 +185,9 @@ typedef struct lsi_request {
 
 typedef struct {
     PCIDevice dev;
-    int mmio_io_addr;
-    int ram_io_addr;
-    uint32_t script_ram_base;
+    MemoryRegion mmio_io;
+    MemoryRegion ram_io;
+    MemoryRegion io_io;
 
     int carry; /* ??? Should this be an a visible register somewhere?  */
     int status;
@@ -391,10 +391,9 @@ static inline uint32_t read_dword(LSIState *s, uint32_t addr)
 {
     uint32_t buf;
 
-    /* Optimize reading from SCRIPTS RAM.  */
-    if ((addr & 0xffffe000) == s->script_ram_base) {
-        return s->script_ram[(addr & 0x1fff) >> 2];
-    }
+    /* XXX: an optimization here used to fast-path the read from scripts
+     * memory.  But that bypasses any iommu.
+     */
     cpu_physical_memory_read(addr, (uint8_t *)&buf, 4);
     return cpu_to_le32(buf);
 }
@@ -1905,232 +1904,90 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
 #undef CASE_SET_REG32
 }
 
-static void lsi_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void lsi_mmio_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t val, unsigned size)
 {
     LSIState *s = opaque;
 
     lsi_reg_writeb(s, addr & 0xff, val);
 }
 
-static void lsi_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    LSIState *s = opaque;
-
-    addr &= 0xff;
-    lsi_reg_writeb(s, addr, val & 0xff);
-    lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
-}
-
-static void lsi_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    LSIState *s = opaque;
-
-    addr &= 0xff;
-    lsi_reg_writeb(s, addr, val & 0xff);
-    lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
-    lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff);
-    lsi_reg_writeb(s, addr + 3, (val >> 24) & 0xff);
-}
-
-static uint32_t lsi_mmio_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t lsi_mmio_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
 {
     LSIState *s = opaque;
 
     return lsi_reg_readb(s, addr & 0xff);
 }
 
-static uint32_t lsi_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
-    LSIState *s = opaque;
-    uint32_t val;
-
-    addr &= 0xff;
-    val = lsi_reg_readb(s, addr);
-    val |= lsi_reg_readb(s, addr + 1) << 8;
-    return val;
-}
-
-static uint32_t lsi_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
-    LSIState *s = opaque;
-    uint32_t val;
-    addr &= 0xff;
-    val = lsi_reg_readb(s, addr);
-    val |= lsi_reg_readb(s, addr + 1) << 8;
-    val |= lsi_reg_readb(s, addr + 2) << 16;
-    val |= lsi_reg_readb(s, addr + 3) << 24;
-    return val;
-}
-
-static CPUReadMemoryFunc * const lsi_mmio_readfn[3] = {
-    lsi_mmio_readb,
-    lsi_mmio_readw,
-    lsi_mmio_readl,
-};
-
-static CPUWriteMemoryFunc * const lsi_mmio_writefn[3] = {
-    lsi_mmio_writeb,
-    lsi_mmio_writew,
-    lsi_mmio_writel,
+static MemoryRegionOps lsi_mmio_ops = {
+    .read = lsi_mmio_read,
+    .write = lsi_mmio_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
 };
 
-static void lsi_ram_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void lsi_ram_write(void *opaque, target_phys_addr_t addr,
+                          uint64_t val, unsigned size)
 {
     LSIState *s = opaque;
     uint32_t newval;
+    uint32_t mask;
     int shift;
 
-    addr &= 0x1fff;
     newval = s->script_ram[addr >> 2];
     shift = (addr & 3) * 8;
-    newval &= ~(0xff << shift);
+    mask = ((uint64_t)1 << (size * 8)) - 1;
+    newval &= ~(mask << shift);
     newval |= val << shift;
     s->script_ram[addr >> 2] = newval;
 }
 
-static void lsi_ram_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    LSIState *s = opaque;
-    uint32_t newval;
-
-    addr &= 0x1fff;
-    newval = s->script_ram[addr >> 2];
-    if (addr & 2) {
-        newval = (newval & 0xffff) | (val << 16);
-    } else {
-        newval = (newval & 0xffff0000) | val;
-    }
-    s->script_ram[addr >> 2] = newval;
-}
-
-
-static void lsi_ram_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    LSIState *s = opaque;
-
-    addr &= 0x1fff;
-    s->script_ram[addr >> 2] = val;
-}
-
-static uint32_t lsi_ram_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t lsi_ram_read(void *opaque, target_phys_addr_t addr,
+                             unsigned size)
 {
     LSIState *s = opaque;
     uint32_t val;
+    uint32_t mask;
 
-    addr &= 0x1fff;
     val = s->script_ram[addr >> 2];
+    mask = ((uint64_t)1 << (size * 8)) - 1;
     val >>= (addr & 3) * 8;
-    return val & 0xff;
-}
-
-static uint32_t lsi_ram_readw(void *opaque, target_phys_addr_t addr)
-{
-    LSIState *s = opaque;
-    uint32_t val;
-
-    addr &= 0x1fff;
-    val = s->script_ram[addr >> 2];
-    if (addr & 2)
-        val >>= 16;
-    return val;
-}
-
-static uint32_t lsi_ram_readl(void *opaque, target_phys_addr_t addr)
-{
-    LSIState *s = opaque;
-
-    addr &= 0x1fff;
-    return s->script_ram[addr >> 2];
+    return val & mask;
 }
 
-static CPUReadMemoryFunc * const lsi_ram_readfn[3] = {
-    lsi_ram_readb,
-    lsi_ram_readw,
-    lsi_ram_readl,
+static MemoryRegionOps lsi_ram_ops = {
+    .read = lsi_ram_read,
+    .write = lsi_ram_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUWriteMemoryFunc * const lsi_ram_writefn[3] = {
-    lsi_ram_writeb,
-    lsi_ram_writew,
-    lsi_ram_writel,
-};
-
-static uint32_t lsi_io_readb(void *opaque, uint32_t addr)
+static uint64_t lsi_io_read(void *opaque, target_phys_addr_t addr,
+                            unsigned size)
 {
     LSIState *s = opaque;
     return lsi_reg_readb(s, addr & 0xff);
 }
 
-static uint32_t lsi_io_readw(void *opaque, uint32_t addr)
-{
-    LSIState *s = opaque;
-    uint32_t val;
-    addr &= 0xff;
-    val = lsi_reg_readb(s, addr);
-    val |= lsi_reg_readb(s, addr + 1) << 8;
-    return val;
-}
-
-static uint32_t lsi_io_readl(void *opaque, uint32_t addr)
-{
-    LSIState *s = opaque;
-    uint32_t val;
-    addr &= 0xff;
-    val = lsi_reg_readb(s, addr);
-    val |= lsi_reg_readb(s, addr + 1) << 8;
-    val |= lsi_reg_readb(s, addr + 2) << 16;
-    val |= lsi_reg_readb(s, addr + 3) << 24;
-    return val;
-}
-
-static void lsi_io_writeb(void *opaque, uint32_t addr, uint32_t val)
+static void lsi_io_write(void *opaque, target_phys_addr_t addr,
+                         uint64_t val, unsigned size)
 {
     LSIState *s = opaque;
     lsi_reg_writeb(s, addr & 0xff, val);
 }
 
-static void lsi_io_writew(void *opaque, uint32_t addr, uint32_t val)
-{
-    LSIState *s = opaque;
-    addr &= 0xff;
-    lsi_reg_writeb(s, addr, val & 0xff);
-    lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
-}
-
-static void lsi_io_writel(void *opaque, uint32_t addr, uint32_t val)
-{
-    LSIState *s = opaque;
-    addr &= 0xff;
-    lsi_reg_writeb(s, addr, val & 0xff);
-    lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
-    lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff);
-    lsi_reg_writeb(s, addr + 3, (val >> 24) & 0xff);
-}
-
-static void lsi_io_mapfunc(PCIDevice *pci_dev, int region_num,
-                           pcibus_t addr, pcibus_t size, int type)
-{
-    LSIState *s = DO_UPCAST(LSIState, dev, pci_dev);
-
-    DPRINTF("Mapping IO at %08"FMT_PCIBUS"\n", addr);
-
-    register_ioport_write(addr, 256, 1, lsi_io_writeb, s);
-    register_ioport_read(addr, 256, 1, lsi_io_readb, s);
-    register_ioport_write(addr, 256, 2, lsi_io_writew, s);
-    register_ioport_read(addr, 256, 2, lsi_io_readw, s);
-    register_ioport_write(addr, 256, 4, lsi_io_writel, s);
-    register_ioport_read(addr, 256, 4, lsi_io_readl, s);
-}
-
-static void lsi_ram_mapfunc(PCIDevice *pci_dev, int region_num,
-                            pcibus_t addr, pcibus_t size, int type)
-{
-    LSIState *s = DO_UPCAST(LSIState, dev, pci_dev);
-
-    DPRINTF("Mapping ram at %08"FMT_PCIBUS"\n", addr);
-    s->script_ram_base = addr;
-    cpu_register_physical_memory(addr + 0, 0x2000, s->ram_io_addr);
-}
+static MemoryRegionOps lsi_io_ops = {
+    .read = lsi_io_read,
+    .write = lsi_io_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
 
 static void lsi_scsi_reset(DeviceState *dev)
 {
@@ -2237,8 +2094,9 @@ static int lsi_scsi_uninit(PCIDevice *d)
 {
     LSIState *s = DO_UPCAST(LSIState, dev, d);
 
-    cpu_unregister_io_memory(s->mmio_io_addr);
-    cpu_unregister_io_memory(s->ram_io_addr);
+    memory_region_destroy(&s->mmio_io);
+    memory_region_destroy(&s->ram_io);
+    memory_region_destroy(&s->io_io);
 
     return 0;
 }
@@ -2262,18 +2120,14 @@ static int lsi_scsi_init(PCIDevice *dev)
     /* Interrupt pin 1 */
     pci_conf[PCI_INTERRUPT_PIN] = 0x01;
 
-    s->mmio_io_addr = cpu_register_io_memory(lsi_mmio_readfn,
-                                             lsi_mmio_writefn, s,
-                                             DEVICE_NATIVE_ENDIAN);
-    s->ram_io_addr = cpu_register_io_memory(lsi_ram_readfn,
-                                            lsi_ram_writefn, s,
-                                            DEVICE_NATIVE_ENDIAN);
-
-    pci_register_bar(&s->dev, 0, 256,
-                           PCI_BASE_ADDRESS_SPACE_IO, lsi_io_mapfunc);
-    pci_register_bar_simple(&s->dev, 1, 0x400, 0, s->mmio_io_addr);
-    pci_register_bar(&s->dev, 2, 0x2000,
-                           PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_ram_mapfunc);
+    memory_region_init_io(&s->mmio_io, &lsi_mmio_ops, s, "lsi-mmio", 0x400);
+    memory_region_init_io(&s->ram_io, &lsi_ram_ops, s, "lsi-ram", 0x2000);
+    memory_region_init_io(&s->io_io, &lsi_io_ops, s, "lsi-io", 256);
+
+    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_io);
+    pci_register_bar_region(&s->dev, 1, 0, &s->mmio_io);
+    pci_register_bar_region(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                            &s->ram_io);
     QTAILQ_INIT(&s->queue);
 
     scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, &lsi_scsi_ops);
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 42/56] ppc: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/cuda.c         |    6 ++-
 hw/escc.c         |   42 +++++++++++++--------------
 hw/escc.h         |    2 +-
 hw/heathrow_pic.c |   29 ++++++++----------
 hw/ide.h          |    2 +-
 hw/ide/macio.c    |   50 ++++++++++++++++++++++----------
 hw/mac_dbdma.c    |   32 ++++++++++----------
 hw/mac_dbdma.h    |    4 ++-
 hw/mac_nvram.c    |   39 ++++++++++---------------
 hw/macio.c        |   74 +++++++++++++++++++++++-------------------------
 hw/openpic.c      |   81 +++++++++++++++++++++++++----------------------------
 hw/openpic.h      |    2 +-
 hw/ppc_mac.h      |   16 ++++++----
 hw/ppc_newworld.c |   30 +++++++++----------
 hw/ppc_oldworld.c |   23 +++++++--------
 15 files changed, 216 insertions(+), 216 deletions(-)

diff --git a/hw/cuda.c b/hw/cuda.c
index 065c362..5c92d81 100644
--- a/hw/cuda.c
+++ b/hw/cuda.c
@@ -117,6 +117,7 @@ typedef struct CUDATimer {
 } CUDATimer;
 
 typedef struct CUDAState {
+    MemoryRegion mem;
     /* cuda registers */
     uint8_t b;      /* B-side data */
     uint8_t a;      /* A-side data */
@@ -722,7 +723,7 @@ static void cuda_reset(void *opaque)
     set_counter(s, &s->timers[1], 0xffff);
 }
 
-void cuda_init (int *cuda_mem_index, qemu_irq irq)
+void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq)
 {
     struct tm tm;
     CUDAState *s = &cuda_state;
@@ -738,8 +739,9 @@ void cuda_init (int *cuda_mem_index, qemu_irq irq)
     s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
 
     s->adb_poll_timer = qemu_new_timer_ns(vm_clock, cuda_adb_poll, s);
-    *cuda_mem_index = cpu_register_io_memory(cuda_read, cuda_write, s,
+    cpu_register_io_memory(cuda_read, cuda_write, s,
                                              DEVICE_NATIVE_ENDIAN);
+    *cuda_mem = &s->mem;
     vmstate_register(NULL, -1, &vmstate_cuda, s);
     qemu_register_reset(cuda_reset, s);
 }
diff --git a/hw/escc.c b/hw/escc.c
index f6fd919..3b48620 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -126,7 +126,7 @@ struct SerialState {
     SysBusDevice busdev;
     struct ChannelState chn[2];
     uint32_t it_shift;
-    int mmio_index;
+    MemoryRegion mmio;
     uint32_t disabled;
     uint32_t frequency;
 };
@@ -490,7 +490,8 @@ static void escc_update_parameters(ChannelState *s)
     qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
 }
 
-static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void escc_mem_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t val, unsigned size)
 {
     SerialState *serial = opaque;
     ChannelState *s;
@@ -592,7 +593,8 @@ static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
     }
 }
 
-static uint32_t escc_mem_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t escc_mem_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
 {
     SerialState *serial = opaque;
     ChannelState *s;
@@ -627,6 +629,16 @@ static uint32_t escc_mem_readb(void *opaque, target_phys_addr_t addr)
     return 0;
 }
 
+static MemoryRegionOps escc_mem_ops = {
+    .read = escc_mem_read,
+    .write = escc_mem_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
 static int serial_can_receive(void *opaque)
 {
     ChannelState *s = opaque;
@@ -668,18 +680,6 @@ static void serial_event(void *opaque, int event)
         serial_receive_break(s);
 }
 
-static CPUReadMemoryFunc * const escc_mem_read[3] = {
-    escc_mem_readb,
-    NULL,
-    NULL,
-};
-
-static CPUWriteMemoryFunc * const escc_mem_write[3] = {
-    escc_mem_writeb,
-    NULL,
-    NULL,
-};
-
 static const VMStateDescription vmstate_escc_chn = {
     .name ="escc_chn",
     .version_id = 2,
@@ -712,7 +712,7 @@ static const VMStateDescription vmstate_escc = {
     }
 };
 
-int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
+MemoryRegion *escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
               CharDriverState *chrA, CharDriverState *chrB,
               int clock, int it_shift)
 {
@@ -737,7 +737,7 @@ int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
     }
 
     d = FROM_SYSBUS(SerialState, s);
-    return d->mmio_index;
+    return &d->mmio;
 }
 
 static const uint8_t keycodes[128] = {
@@ -901,7 +901,6 @@ void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
 static int escc_init1(SysBusDevice *dev)
 {
     SerialState *s = FROM_SYSBUS(SerialState, dev);
-    int io;
     unsigned int i;
 
     s->chn[0].disabled = s->disabled;
@@ -918,10 +917,9 @@ static int escc_init1(SysBusDevice *dev)
     s->chn[0].otherchn = &s->chn[1];
     s->chn[1].otherchn = &s->chn[0];
 
-    io = cpu_register_io_memory(escc_mem_read, escc_mem_write, s,
-                                DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, ESCC_SIZE << s->it_shift, io);
-    s->mmio_index = io;
+    memory_region_init_io(&s->mmio, &escc_mem_ops, s, "escc",
+                          ESCC_SIZE << s->it_shift);
+    sysbus_init_mmio_region(dev, &s->mmio);
 
     if (s->chn[0].type == mouse) {
         qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
diff --git a/hw/escc.h b/hw/escc.h
index 015b9d0..d1da46f 100644
--- a/hw/escc.h
+++ b/hw/escc.h
@@ -1,6 +1,6 @@
 /* escc.c */
 #define ESCC_SIZE 4
-int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
+MemoryRegion *escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
               CharDriverState *chrA, CharDriverState *chrB,
               int clock, int it_shift);
 
diff --git a/hw/heathrow_pic.c b/hw/heathrow_pic.c
index 5fd71a0..4e4597c 100644
--- a/hw/heathrow_pic.c
+++ b/hw/heathrow_pic.c
@@ -43,6 +43,7 @@ typedef struct HeathrowPIC {
 } HeathrowPIC;
 
 typedef struct HeathrowPICS {
+    MemoryRegion mem;
     HeathrowPIC pics[2];
     qemu_irq *irqs;
 } HeathrowPICS;
@@ -62,7 +63,8 @@ static void heathrow_pic_update(HeathrowPICS *s)
     }
 }
 
-static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+static void pic_write(void *opaque, target_phys_addr_t addr,
+                      uint64_t value, unsigned size)
 {
     HeathrowPICS *s = opaque;
     HeathrowPIC *pic;
@@ -89,7 +91,8 @@ static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     }
 }
 
-static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t pic_read(void *opaque, target_phys_addr_t addr,
+                         unsigned size)
 {
     HeathrowPICS *s = opaque;
     HeathrowPIC *pic;
@@ -120,19 +123,12 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
     return value;
 }
 
-static CPUWriteMemoryFunc * const pic_write[] = {
-    &pic_writel,
-    &pic_writel,
-    &pic_writel,
+static MemoryRegionOps heathrow_pic_ops = {
+    .read = pic_read,
+    .write = pic_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUReadMemoryFunc * const pic_read[] = {
-    &pic_readl,
-    &pic_readl,
-    &pic_readl,
-};
-
-
 static void heathrow_pic_set_irq(void *opaque, int num, int level)
 {
     HeathrowPICS *s = opaque;
@@ -201,7 +197,7 @@ static void heathrow_pic_reset(void *opaque)
     s->pics[1].level_triggered = 0x1ff00000;
 }
 
-qemu_irq *heathrow_pic_init(int *pmem_index,
+qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
                             int nb_cpus, qemu_irq **irqs)
 {
     HeathrowPICS *s;
@@ -209,8 +205,9 @@ qemu_irq *heathrow_pic_init(int *pmem_index,
     s = qemu_mallocz(sizeof(HeathrowPICS));
     /* only 1 CPU */
     s->irqs = irqs[0];
-    *pmem_index = cpu_register_io_memory(pic_read, pic_write, s,
-                                         DEVICE_LITTLE_ENDIAN);
+    memory_region_init_io(&s->mem, &heathrow_pic_ops, s,
+                          "heathrow-pic", 0x1000);
+    *pmem = &s->mem;
 
     vmstate_register(NULL, -1, &vmstate_heathrow_pic, s);
     qemu_register_reset(heathrow_pic_reset, s);
diff --git a/hw/ide.h b/hw/ide.h
index 34d9394..63a9912 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -18,7 +18,7 @@ PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 
 /* ide-macio.c */
-int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
+MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
 		   void *dbdma, int channel, qemu_irq dma_irq);
 
 /* ide-mmio.c */
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 7daeb31..7e5db16 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -35,6 +35,7 @@
 /* MacIO based PowerPC IDE */
 
 typedef struct MACIOIDEState {
+    MemoryRegion mem;
     IDEBus bus;
     BlockDriverAIOCB *aiocb;
 } MACIOIDEState;
@@ -281,16 +282,36 @@ static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr)
     return retval;
 }
 
-static CPUWriteMemoryFunc * const pmac_ide_write[] = {
-    pmac_ide_writeb,
-    pmac_ide_writew,
-    pmac_ide_writel,
-};
+static uint64_t pmac_ide_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
+{
+    MACIOIDEState *d = opaque;
+
+    switch (size) {
+    case 1: return pmac_ide_readb(d, addr);
+    case 2: return pmac_ide_readw(d, addr);
+    case 4: return pmac_ide_readl(d, addr);
+    default: abort();
+    }
+}
+
+static void pmac_ide_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t data, unsigned size)
+{
+    MACIOIDEState *d = opaque;
+
+    switch (size) {
+    case 1: return pmac_ide_writeb(d, addr, data);
+    case 2: return pmac_ide_writew(d, addr, data);
+    case 4: return pmac_ide_writel(d, addr, data);
+    default: abort();
+    }
+}
 
-static CPUReadMemoryFunc * const pmac_ide_read[] = {
-    pmac_ide_readb,
-    pmac_ide_readw,
-    pmac_ide_readl,
+static MemoryRegionOps pmac_ide_ops = {
+    .read = pmac_ide_read,
+    .write = pmac_ide_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static const VMStateDescription vmstate_pmac = {
@@ -315,11 +336,10 @@ static void pmac_ide_reset(void *opaque)
 /* hd_table must contain 4 block drivers */
 /* PowerMac uses memory mapped registers, not I/O. Return the memory
    I/O index to access the ide. */
-int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
-		   void *dbdma, int channel, qemu_irq dma_irq)
+MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
+                             void *dbdma, int channel, qemu_irq dma_irq)
 {
     MACIOIDEState *d;
-    int pmac_ide_memory;
 
     d = qemu_mallocz(sizeof(MACIOIDEState));
     ide_init2_with_non_qdev_drives(&d->bus, hd_table[0], hd_table[1], irq);
@@ -327,11 +347,9 @@ int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
     if (dbdma)
         DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, pmac_ide_flush, d);
 
-    pmac_ide_memory = cpu_register_io_memory(pmac_ide_read,
-                                             pmac_ide_write, d,
-                                             DEVICE_NATIVE_ENDIAN);
+    memory_region_init_io(&d->mem, &pmac_ide_ops, d, "pmac-ide", 0x1000);
     vmstate_register(NULL, 0, &vmstate_pmac, d);
     qemu_register_reset(pmac_ide_reset, d);
 
-    return pmac_ide_memory;
+    return &d->mem;
 }
diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c
index ed4458e..d977802 100644
--- a/hw/mac_dbdma.c
+++ b/hw/mac_dbdma.c
@@ -166,6 +166,7 @@ typedef struct DBDMA_channel {
 } DBDMA_channel;
 
 typedef struct {
+    MemoryRegion mem;
     DBDMA_channel channels[DBDMA_CHANNELS];
 } DBDMAState;
 
@@ -703,8 +704,8 @@ dbdma_control_write(DBDMA_channel *ch)
         ch->flush(&ch->io);
 }
 
-static void dbdma_writel (void *opaque,
-                          target_phys_addr_t addr, uint32_t value)
+static void dbdma_write(void *opaque, target_phys_addr_t addr,
+                        uint64_t value, unsigned size)
 {
     int channel = addr >> DBDMA_CHANNEL_SHIFT;
     DBDMAState *s = opaque;
@@ -753,7 +754,8 @@ static void dbdma_writel (void *opaque,
     }
 }
 
-static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t dbdma_read(void *opaque, target_phys_addr_t addr,
+                           unsigned size)
 {
     uint32_t value;
     int channel = addr >> DBDMA_CHANNEL_SHIFT;
@@ -798,16 +800,14 @@ static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)
     return value;
 }
 
-static CPUWriteMemoryFunc * const dbdma_write[] = {
-    NULL,
-    NULL,
-    dbdma_writel,
-};
-
-static CPUReadMemoryFunc * const dbdma_read[] = {
-    NULL,
-    NULL,
-    dbdma_readl,
+static MemoryRegionOps dbdma_ops = {
+    .read = dbdma_read,
+    .write = dbdma_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
 };
 
 static const VMStateDescription vmstate_dbdma_channel = {
@@ -842,14 +842,14 @@ static void dbdma_reset(void *opaque)
         memset(s->channels[i].regs, 0, DBDMA_SIZE);
 }
 
-void* DBDMA_init (int *dbdma_mem_index)
+void* DBDMA_init (MemoryRegion **dbdma_mem)
 {
     DBDMAState *s;
 
     s = qemu_mallocz(sizeof(DBDMAState));
 
-    *dbdma_mem_index = cpu_register_io_memory(dbdma_read, dbdma_write, s,
-                                              DEVICE_LITTLE_ENDIAN);
+    memory_region_init_io(&s->mem, &dbdma_ops, s, "dbdma", 0x1000);
+    *dbdma_mem = &s->mem;
     vmstate_register(NULL, -1, &vmstate_dbdma, s);
     qemu_register_reset(dbdma_reset, s);
 
diff --git a/hw/mac_dbdma.h b/hw/mac_dbdma.h
index d236c5b..933e17c 100644
--- a/hw/mac_dbdma.h
+++ b/hw/mac_dbdma.h
@@ -20,6 +20,8 @@
  * THE SOFTWARE.
  */
 
+#include "memory.h"
+
 typedef struct DBDMA_io DBDMA_io;
 
 typedef void (*DBDMA_flush)(DBDMA_io *io);
@@ -40,4 +42,4 @@ void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
                             DBDMA_rw rw, DBDMA_flush flush,
                             void *opaque);
 void DBDMA_schedule(void);
-void* DBDMA_init (int *dbdma_mem_index);
+void* DBDMA_init (MemoryRegion **dbdma_mem);
diff --git a/hw/mac_nvram.c b/hw/mac_nvram.c
index 61e53d2..5b9764e 100644
--- a/hw/mac_nvram.c
+++ b/hw/mac_nvram.c
@@ -39,7 +39,7 @@
 
 struct MacIONVRAMState {
     uint32_t size;
-    int mem_index;
+    MemoryRegion mem;
     unsigned int it_shift;
     uint8_t *data;
 };
@@ -71,8 +71,8 @@ void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val)
 }
 
 /* macio style NVRAM device */
-static void macio_nvram_writeb (void *opaque,
-                                target_phys_addr_t addr, uint32_t value)
+static void macio_nvram_writeb(void *opaque, target_phys_addr_t addr,
+                               uint64_t value, unsigned size)
 {
     MacIONVRAMState *s = opaque;
 
@@ -81,7 +81,8 @@ static void macio_nvram_writeb (void *opaque,
     NVR_DPRINTF("writeb addr %04x val %x\n", (int)addr, value);
 }
 
-static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr)
+static uint64_t macio_nvram_readb(void *opaque, target_phys_addr_t addr,
+                                  unsigned size)
 {
     MacIONVRAMState *s = opaque;
     uint32_t value;
@@ -93,16 +94,10 @@ static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr)
     return value;
 }
 
-static CPUWriteMemoryFunc * const nvram_write[] = {
-    &macio_nvram_writeb,
-    &macio_nvram_writeb,
-    &macio_nvram_writeb,
-};
-
-static CPUReadMemoryFunc * const nvram_read[] = {
-    &macio_nvram_readb,
-    &macio_nvram_readb,
-    &macio_nvram_readb,
+static MemoryRegionOps macio_nvram_ops = {
+    .read = macio_nvram_readb,
+    .write = macio_nvram_writeb,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static const VMStateDescription vmstate_macio_nvram = {
@@ -121,7 +116,7 @@ static void macio_nvram_reset(void *opaque)
 {
 }
 
-MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size,
+MacIONVRAMState *macio_nvram_init (target_phys_addr_t size,
                                    unsigned int it_shift)
 {
     MacIONVRAMState *s;
@@ -131,22 +126,18 @@ MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size,
     s->size = size;
     s->it_shift = it_shift;
 
-    s->mem_index = cpu_register_io_memory(nvram_read, nvram_write, s,
-                                          DEVICE_NATIVE_ENDIAN);
-    *mem_index = s->mem_index;
+    memory_region_init_io(&s->mem, &macio_nvram_ops, s, "macio-nvram",
+                          size << it_shift);
     vmstate_register(NULL, -1, &vmstate_macio_nvram, s);
     qemu_register_reset(macio_nvram_reset, s);
 
     return s;
 }
 
-void macio_nvram_map (void *opaque, target_phys_addr_t mem_base)
+void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar,
+                           target_phys_addr_t mem_base)
 {
-    MacIONVRAMState *s;
-
-    s = opaque;
-    cpu_register_physical_memory(mem_base, s->size << s->it_shift,
-                                 s->mem_index);
+    memory_region_add_subregion(bar, mem_base, &s->mem);
 }
 
 /* Set up a system OpenBIOS NVRAM partition */
diff --git a/hw/macio.c b/hw/macio.c
index 789ca55..71fa2a8 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -30,58 +30,55 @@
 typedef struct macio_state_t macio_state_t;
 struct macio_state_t {
     int is_oldworld;
-    int pic_mem_index;
-    int dbdma_mem_index;
-    int cuda_mem_index;
-    int escc_mem_index;
+    MemoryRegion bar;
+    MemoryRegion *pic_mem;
+    MemoryRegion *dbdma_mem;
+    MemoryRegion *cuda_mem;
+    MemoryRegion *escc_mem;
     void *nvram;
     int nb_ide;
-    int ide_mem_index[4];
+    MemoryRegion *ide_mem[4];
 };
 
-static void macio_map (PCIDevice *pci_dev, int region_num,
-                       pcibus_t addr, pcibus_t size, int type)
+static void macio_bar_setup(macio_state_t *macio_state)
 {
-    macio_state_t *macio_state;
     int i;
+    MemoryRegion *bar = &macio_state->bar;
 
-    macio_state = (macio_state_t *)(pci_dev + 1);
-    if (macio_state->pic_mem_index >= 0) {
+    memory_region_init(bar, "macio", 0x80000);
+    if (macio_state->pic_mem) {
         if (macio_state->is_oldworld) {
             /* Heathrow PIC */
-            cpu_register_physical_memory(addr + 0x00000, 0x1000,
-                                         macio_state->pic_mem_index);
+            memory_region_add_subregion(bar, 0x00000, macio_state->pic_mem);
         } else {
             /* OpenPIC */
-            cpu_register_physical_memory(addr + 0x40000, 0x40000,
-                                         macio_state->pic_mem_index);
+            memory_region_add_subregion(bar, 0x40000, macio_state->pic_mem);
         }
     }
-    if (macio_state->dbdma_mem_index >= 0) {
-        cpu_register_physical_memory(addr + 0x08000, 0x1000,
-                                     macio_state->dbdma_mem_index);
+    if (macio_state->dbdma_mem) {
+        memory_region_add_subregion(bar, 0x08000, macio_state->dbdma_mem);
     }
-    if (macio_state->escc_mem_index >= 0) {
-        cpu_register_physical_memory(addr + 0x13000, ESCC_SIZE << 4,
-                                     macio_state->escc_mem_index);
+    if (macio_state->escc_mem) {
+        memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem);
     }
-    if (macio_state->cuda_mem_index >= 0) {
-        cpu_register_physical_memory(addr + 0x16000, 0x2000,
-                                     macio_state->cuda_mem_index);
+    if (macio_state->cuda_mem) {
+        memory_region_add_subregion(bar, 0x16000, macio_state->cuda_mem);
     }
     for (i = 0; i < macio_state->nb_ide; i++) {
-        if (macio_state->ide_mem_index[i] >= 0) {
-            cpu_register_physical_memory(addr + 0x1f000 + (i * 0x1000), 0x1000,
-                                         macio_state->ide_mem_index[i]);
+        if (macio_state->ide_mem[i]) {
+            memory_region_add_subregion(bar, 0x1f000 + (i * 0x1000),
+                                        macio_state->ide_mem[i]);
         }
     }
     if (macio_state->nvram != NULL)
-        macio_nvram_map(macio_state->nvram, addr + 0x60000);
+        macio_nvram_setup_bar(macio_state->nvram, bar, 0x60000);
 }
 
-void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
-                 int dbdma_mem_index, int cuda_mem_index, void *nvram,
-                 int nb_ide, int *ide_mem_index, int escc_mem_index)
+void macio_init (PCIBus *bus, int device_id, int is_oldworld,
+                 MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
+                 MemoryRegion *cuda_mem, void *nvram,
+                 int nb_ide, MemoryRegion **ide_mem,
+                 MemoryRegion *escc_mem)
 {
     PCIDevice *d;
     macio_state_t *macio_state;
@@ -92,18 +89,18 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
                             -1, NULL, NULL);
     macio_state = (macio_state_t *)(d + 1);
     macio_state->is_oldworld = is_oldworld;
-    macio_state->pic_mem_index = pic_mem_index;
-    macio_state->dbdma_mem_index = dbdma_mem_index;
-    macio_state->cuda_mem_index = cuda_mem_index;
-    macio_state->escc_mem_index = escc_mem_index;
+    macio_state->pic_mem = pic_mem;
+    macio_state->dbdma_mem = dbdma_mem;
+    macio_state->cuda_mem = cuda_mem;
+    macio_state->escc_mem = escc_mem;
     macio_state->nvram = nvram;
     if (nb_ide > 4)
         nb_ide = 4;
     macio_state->nb_ide = nb_ide;
     for (i = 0; i < nb_ide; i++)
-        macio_state->ide_mem_index[i] = ide_mem_index[i];
+        macio_state->ide_mem[i] = ide_mem[i];
     for (; i < 4; i++)
-        macio_state->ide_mem_index[i] = -1;
+        macio_state->ide_mem[i] = NULL;
     /* Note: this code is strongly inspirated from the corresponding code
        in PearPC */
 
@@ -113,6 +110,7 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
 
     d->config[0x3d] = 0x01; // interrupt on pin 1
 
-    pci_register_bar(d, 0, 0x80000,
-                           PCI_BASE_ADDRESS_SPACE_MEMORY, macio_map);
+    macio_bar_setup(macio_state);
+    pci_register_bar_region(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                            &macio_state->bar);
 }
diff --git a/hw/openpic.c b/hw/openpic.c
index 6d2cf99..fd1ffba 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -205,7 +205,7 @@ typedef struct IRQ_dst_t {
 
 typedef struct openpic_t {
     PCIDevice pci_dev;
-    int mem_index;
+    MemoryRegion mem;
     /* Global registers */
     uint32_t frep; /* Feature reporting register */
     uint32_t glbc; /* Global configuration register  */
@@ -984,47 +984,34 @@ static uint32_t openpic_readl (void *opaque,target_phys_addr_t addr)
     return retval;
 }
 
-static CPUWriteMemoryFunc * const openpic_write[] = {
-    &openpic_buggy_write,
-    &openpic_buggy_write,
-    &openpic_writel,
-};
+static uint64_t openpic_read(void *opaque, target_phys_addr_t addr,
+                             unsigned size)
+{
+    openpic_t *opp = opaque;
 
-static CPUReadMemoryFunc * const openpic_read[] = {
-    &openpic_buggy_read,
-    &openpic_buggy_read,
-    &openpic_readl,
-};
+    switch (size) {
+    case 4: return openpic_readl(opp, addr);
+    default: return openpic_buggy_read(opp, addr);
+    }
+}
 
-static void openpic_map(PCIDevice *pci_dev, int region_num,
-                        pcibus_t addr, pcibus_t size, int type)
+static void openpic_write(void *opaque, target_phys_addr_t addr,
+                          uint64_t data, unsigned size)
 {
-    openpic_t *opp;
+    openpic_t *opp = opaque;
 
-    DPRINTF("Map OpenPIC\n");
-    opp = (openpic_t *)pci_dev;
-    /* Global registers */
-    DPRINTF("Register OPENPIC gbl   %08x => %08x\n",
-            addr + 0x1000, addr + 0x1000 + 0x100);
-    /* Timer registers */
-    DPRINTF("Register OPENPIC timer %08x => %08x\n",
-            addr + 0x1100, addr + 0x1100 + 0x40 * MAX_TMR);
-    /* Interrupt source registers */
-    DPRINTF("Register OPENPIC src   %08x => %08x\n",
-            addr + 0x10000, addr + 0x10000 + 0x20 * (OPENPIC_EXT_IRQ + 2));
-    /* Per CPU registers */
-    DPRINTF("Register OPENPIC dst   %08x => %08x\n",
-            addr + 0x20000, addr + 0x20000 + 0x1000 * MAX_CPU);
-    cpu_register_physical_memory(addr, 0x40000, opp->mem_index);
-#if 0 // Don't implement ISU for now
-    opp_io_memory = cpu_register_io_memory(openpic_src_read,
-                                           openpic_src_write, NULL
-                                           DEVICE_NATIVE_ENDIAN);
-    cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2),
-                                 opp_io_memory);
-#endif
+    switch (size) {
+    case 4: return openpic_writel(opp, addr, data);
+    default: return openpic_buggy_write(opp, addr, data);
+    }
 }
 
+static MemoryRegionOps openpic_ops = {
+    .read = openpic_read,
+    .write = openpic_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static void openpic_save_IRQ_queue(QEMUFile* f, IRQ_queue_t *q)
 {
     unsigned int i;
@@ -1161,7 +1148,7 @@ static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src)
     qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
 }
 
-qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
+qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus,
                         qemu_irq **irqs, qemu_irq irq_out)
 {
     openpic_t *opp;
@@ -1180,14 +1167,22 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
         pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER); // FIXME?
         pci_conf[0x3d] = 0x00; // no interrupt pin
 
+        memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000);
+#if 0 // Don't implement ISU for now
+        opp_io_memory = cpu_register_io_memory(openpic_src_read,
+                                               openpic_src_write, NULL
+                                               DEVICE_NATIVE_ENDIAN);
+        cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2),
+                                     opp_io_memory);
+#endif
+
         /* Register I/O spaces */
-        pci_register_bar(&opp->pci_dev, 0, 0x40000,
-                               PCI_BASE_ADDRESS_SPACE_MEMORY, &openpic_map);
+        pci_register_bar_region(&opp->pci_dev, 0,
+                                PCI_BASE_ADDRESS_SPACE_MEMORY, &opp->mem);
     } else {
         opp = qemu_mallocz(sizeof(openpic_t));
+        memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000);
     }
-    opp->mem_index = cpu_register_io_memory(openpic_read, openpic_write, opp,
-                                            DEVICE_LITTLE_ENDIAN);
 
     //    isu_base &= 0xFFFC0000;
     opp->nb_cpus = nb_cpus;
@@ -1223,8 +1218,8 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
     opp->irq_raise = openpic_irq_raise;
     opp->reset = openpic_reset;
 
-    if (pmem_index)
-        *pmem_index = opp->mem_index;
+    if (pmem)
+        *pmem = &opp->mem;
 
     return qemu_allocate_irqs(openpic_set_irq, opp, opp->max_irq);
 }
diff --git a/hw/openpic.h b/hw/openpic.h
index 0957c1f..75de361 100644
--- a/hw/openpic.h
+++ b/hw/openpic.h
@@ -11,7 +11,7 @@ enum {
     OPENPIC_OUTPUT_NB,
 };
 
-qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
+qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus,
                         qemu_irq **irqs, qemu_irq irq_out);
 qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
                         qemu_irq **irqs, qemu_irq irq_out);
diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h
index 25a2274..7351bb6 100644
--- a/hw/ppc_mac.h
+++ b/hw/ppc_mac.h
@@ -42,15 +42,16 @@
 #define ESCC_CLOCK 3686400
 
 /* Cuda */
-void cuda_init (int *cuda_mem_index, qemu_irq irq);
+void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq);
 
 /* MacIO */
-void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
-                 int dbdma_mem_index, int cuda_mem_index, void *nvram,
-                 int nb_ide, int *ide_mem_index, int escc_mem_index);
+void macio_init (PCIBus *bus, int device_id, int is_oldworld,
+                 MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
+                 MemoryRegion *cuda_mem, void *nvram,
+                 int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem);
 
 /* Heathrow PIC */
-qemu_irq *heathrow_pic_init(int *pmem_index,
+qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
                             int nb_cpus, qemu_irq **irqs);
 
 /* Grackle PCI */
@@ -69,9 +70,10 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
 /* Mac NVRAM */
 typedef struct MacIONVRAMState MacIONVRAMState;
 
-MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size,
+MacIONVRAMState *macio_nvram_init (target_phys_addr_t size,
                                    unsigned int it_shift);
-void macio_nvram_map (void *opaque, target_phys_addr_t mem_base);
+void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar,
+                           target_phys_addr_t mem_base);
 void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len);
 uint32_t macio_nvram_read (void *opaque, uint32_t addr);
 void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val);
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 94a21f9..3039022 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -144,10 +144,9 @@ static void ppc_core99_init (ram_addr_t ram_size,
     long kernel_size, initrd_size;
     PCIBus *pci_bus;
     MacIONVRAMState *nvr;
-    int nvram_mem_index;
     int bios_size;
-    int pic_mem_index, dbdma_mem_index, cuda_mem_index, escc_mem_index;
-    int ide_mem_index[3];
+    MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem, *escc_mem;
+    MemoryRegion *ide_mem[3];
     int ppc_boot_device;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     void *fw_cfg;
@@ -315,7 +314,7 @@ static void ppc_core99_init (ram_addr_t ram_size,
             exit(1);
         }
     }
-    pic = openpic_init(NULL, &pic_mem_index, smp_cpus, openpic_irqs, NULL);
+    pic = openpic_init(NULL, &pic_mem, smp_cpus, openpic_irqs, NULL);
     if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
         /* 970 gets a U3 bus */
         pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io());
@@ -327,32 +326,31 @@ static void ppc_core99_init (ram_addr_t ram_size,
     /* init basic PC hardware */
     pci_vga_init(pci_bus);
 
-    escc_mem_index = escc_init(0x80013000, pic[0x25], pic[0x24],
-                               serial_hds[0], serial_hds[1], ESCC_CLOCK, 4);
+    escc_mem = escc_init(0x80013000, pic[0x25], pic[0x24],
+                         serial_hds[0], serial_hds[1], ESCC_CLOCK, 4);
 
     for(i = 0; i < nb_nics; i++)
         pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
 
     ide_drive_get(hd, MAX_IDE_BUS);
-    dbdma = DBDMA_init(&dbdma_mem_index);
+    dbdma = DBDMA_init(&dbdma_mem);
 
     /* We only emulate 2 out of 3 IDE controllers for now */
-    ide_mem_index[0] = -1;
-    ide_mem_index[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]);
-    ide_mem_index[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]);
+    ide_mem[0] = NULL;
+    ide_mem[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]);
+    ide_mem[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]);
 
     /* cuda also initialize ADB */
     if (machine_arch == ARCH_MAC99_U3) {
         usb_enabled = 1;
     }
-    cuda_init(&cuda_mem_index, pic[0x19]);
+    cuda_init(&cuda_mem, pic[0x19]);
 
     adb_kbd_init(&adb_bus);
     adb_mouse_init(&adb_bus);
 
-    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem_index,
-               dbdma_mem_index, cuda_mem_index, NULL, 3, ide_mem_index,
-               escc_mem_index);
+    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem,
+               dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_mem);
 
     if (usb_enabled) {
         usb_ohci_init_pci(pci_bus, -1);
@@ -369,9 +367,9 @@ static void ppc_core99_init (ram_addr_t ram_size,
         graphic_depth = 15;
 
     /* The NewWorld NVRAM is not located in the MacIO device */
-    nvr = macio_nvram_init(&nvram_mem_index, 0x2000, 1);
+    nvr = macio_nvram_init(0x2000, 1);
     pmac_format_nvram_partition(nvr, 0x2000);
-    macio_nvram_map(nvr, 0xFFF04000);
+    macio_nvram_setup_bar(nvr, get_system_memory(), 0xFFF04000);
     /* No PCI init: the BIOS will do it */
 
     fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 0f99eef..41703a7 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -82,8 +82,8 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
     PCIBus *pci_bus;
     MacIONVRAMState *nvr;
     int bios_size;
-    int pic_mem_index, nvram_mem_index, dbdma_mem_index, cuda_mem_index;
-    int escc_mem_index, ide_mem_index[2];
+    MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem;
+    MemoryRegion *escc_mem, *ide_mem[2];
     uint16_t ppc_boot_device;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     void *fw_cfg;
@@ -233,13 +233,13 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
     if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
         hw_error("Only 6xx bus is supported on heathrow machine\n");
     }
-    pic = heathrow_pic_init(&pic_mem_index, 1, heathrow_irqs);
+    pic = heathrow_pic_init(&pic_mem, 1, heathrow_irqs);
     pci_bus = pci_grackle_init(0xfec00000, pic,
                                get_system_memory(),
                                get_system_io());
     pci_vga_init(pci_bus);
 
-    escc_mem_index = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0],
+    escc_mem = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0],
                                serial_hds[1], ESCC_CLOCK, 4);
 
     for(i = 0; i < nb_nics; i++)
@@ -249,9 +249,9 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
     ide_drive_get(hd, MAX_IDE_BUS);
 
     /* First IDE channel is a MAC IDE on the MacIO bus */
-    dbdma = DBDMA_init(&dbdma_mem_index);
-    ide_mem_index[0] = -1;
-    ide_mem_index[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]);
+    dbdma = DBDMA_init(&dbdma_mem);
+    ide_mem[0] = NULL;
+    ide_mem[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]);
 
     /* Second IDE channel is a CMD646 on the PCI bus */
     hd[0] = hd[MAX_IDE_DEVS];
@@ -260,17 +260,16 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
     pci_cmd646_ide_init(pci_bus, hd, 0);
 
     /* cuda also initialize ADB */
-    cuda_init(&cuda_mem_index, pic[0x12]);
+    cuda_init(&cuda_mem, pic[0x12]);
 
     adb_kbd_init(&adb_bus);
     adb_mouse_init(&adb_bus);
 
-    nvr = macio_nvram_init(&nvram_mem_index, 0x2000, 4);
+    nvr = macio_nvram_init(0x2000, 4);
     pmac_format_nvram_partition(nvr, 0x2000);
 
-    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem_index,
-               dbdma_mem_index, cuda_mem_index, nvr, 2, ide_mem_index,
-               escc_mem_index);
+    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem,
+               dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_mem);
 
     if (usb_enabled) {
         usb_ohci_init_pci(pci_bus, -1);
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 42/56] ppc: convert to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/cuda.c         |    6 ++-
 hw/escc.c         |   42 +++++++++++++--------------
 hw/escc.h         |    2 +-
 hw/heathrow_pic.c |   29 ++++++++----------
 hw/ide.h          |    2 +-
 hw/ide/macio.c    |   50 ++++++++++++++++++++++----------
 hw/mac_dbdma.c    |   32 ++++++++++----------
 hw/mac_dbdma.h    |    4 ++-
 hw/mac_nvram.c    |   39 ++++++++++---------------
 hw/macio.c        |   74 +++++++++++++++++++++++-------------------------
 hw/openpic.c      |   81 +++++++++++++++++++++++++----------------------------
 hw/openpic.h      |    2 +-
 hw/ppc_mac.h      |   16 ++++++----
 hw/ppc_newworld.c |   30 +++++++++----------
 hw/ppc_oldworld.c |   23 +++++++--------
 15 files changed, 216 insertions(+), 216 deletions(-)

diff --git a/hw/cuda.c b/hw/cuda.c
index 065c362..5c92d81 100644
--- a/hw/cuda.c
+++ b/hw/cuda.c
@@ -117,6 +117,7 @@ typedef struct CUDATimer {
 } CUDATimer;
 
 typedef struct CUDAState {
+    MemoryRegion mem;
     /* cuda registers */
     uint8_t b;      /* B-side data */
     uint8_t a;      /* A-side data */
@@ -722,7 +723,7 @@ static void cuda_reset(void *opaque)
     set_counter(s, &s->timers[1], 0xffff);
 }
 
-void cuda_init (int *cuda_mem_index, qemu_irq irq)
+void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq)
 {
     struct tm tm;
     CUDAState *s = &cuda_state;
@@ -738,8 +739,9 @@ void cuda_init (int *cuda_mem_index, qemu_irq irq)
     s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
 
     s->adb_poll_timer = qemu_new_timer_ns(vm_clock, cuda_adb_poll, s);
-    *cuda_mem_index = cpu_register_io_memory(cuda_read, cuda_write, s,
+    cpu_register_io_memory(cuda_read, cuda_write, s,
                                              DEVICE_NATIVE_ENDIAN);
+    *cuda_mem = &s->mem;
     vmstate_register(NULL, -1, &vmstate_cuda, s);
     qemu_register_reset(cuda_reset, s);
 }
diff --git a/hw/escc.c b/hw/escc.c
index f6fd919..3b48620 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -126,7 +126,7 @@ struct SerialState {
     SysBusDevice busdev;
     struct ChannelState chn[2];
     uint32_t it_shift;
-    int mmio_index;
+    MemoryRegion mmio;
     uint32_t disabled;
     uint32_t frequency;
 };
@@ -490,7 +490,8 @@ static void escc_update_parameters(ChannelState *s)
     qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
 }
 
-static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void escc_mem_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t val, unsigned size)
 {
     SerialState *serial = opaque;
     ChannelState *s;
@@ -592,7 +593,8 @@ static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
     }
 }
 
-static uint32_t escc_mem_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t escc_mem_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
 {
     SerialState *serial = opaque;
     ChannelState *s;
@@ -627,6 +629,16 @@ static uint32_t escc_mem_readb(void *opaque, target_phys_addr_t addr)
     return 0;
 }
 
+static MemoryRegionOps escc_mem_ops = {
+    .read = escc_mem_read,
+    .write = escc_mem_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
 static int serial_can_receive(void *opaque)
 {
     ChannelState *s = opaque;
@@ -668,18 +680,6 @@ static void serial_event(void *opaque, int event)
         serial_receive_break(s);
 }
 
-static CPUReadMemoryFunc * const escc_mem_read[3] = {
-    escc_mem_readb,
-    NULL,
-    NULL,
-};
-
-static CPUWriteMemoryFunc * const escc_mem_write[3] = {
-    escc_mem_writeb,
-    NULL,
-    NULL,
-};
-
 static const VMStateDescription vmstate_escc_chn = {
     .name ="escc_chn",
     .version_id = 2,
@@ -712,7 +712,7 @@ static const VMStateDescription vmstate_escc = {
     }
 };
 
-int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
+MemoryRegion *escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
               CharDriverState *chrA, CharDriverState *chrB,
               int clock, int it_shift)
 {
@@ -737,7 +737,7 @@ int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
     }
 
     d = FROM_SYSBUS(SerialState, s);
-    return d->mmio_index;
+    return &d->mmio;
 }
 
 static const uint8_t keycodes[128] = {
@@ -901,7 +901,6 @@ void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
 static int escc_init1(SysBusDevice *dev)
 {
     SerialState *s = FROM_SYSBUS(SerialState, dev);
-    int io;
     unsigned int i;
 
     s->chn[0].disabled = s->disabled;
@@ -918,10 +917,9 @@ static int escc_init1(SysBusDevice *dev)
     s->chn[0].otherchn = &s->chn[1];
     s->chn[1].otherchn = &s->chn[0];
 
-    io = cpu_register_io_memory(escc_mem_read, escc_mem_write, s,
-                                DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, ESCC_SIZE << s->it_shift, io);
-    s->mmio_index = io;
+    memory_region_init_io(&s->mmio, &escc_mem_ops, s, "escc",
+                          ESCC_SIZE << s->it_shift);
+    sysbus_init_mmio_region(dev, &s->mmio);
 
     if (s->chn[0].type == mouse) {
         qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
diff --git a/hw/escc.h b/hw/escc.h
index 015b9d0..d1da46f 100644
--- a/hw/escc.h
+++ b/hw/escc.h
@@ -1,6 +1,6 @@
 /* escc.c */
 #define ESCC_SIZE 4
-int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
+MemoryRegion *escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
               CharDriverState *chrA, CharDriverState *chrB,
               int clock, int it_shift);
 
diff --git a/hw/heathrow_pic.c b/hw/heathrow_pic.c
index 5fd71a0..4e4597c 100644
--- a/hw/heathrow_pic.c
+++ b/hw/heathrow_pic.c
@@ -43,6 +43,7 @@ typedef struct HeathrowPIC {
 } HeathrowPIC;
 
 typedef struct HeathrowPICS {
+    MemoryRegion mem;
     HeathrowPIC pics[2];
     qemu_irq *irqs;
 } HeathrowPICS;
@@ -62,7 +63,8 @@ static void heathrow_pic_update(HeathrowPICS *s)
     }
 }
 
-static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+static void pic_write(void *opaque, target_phys_addr_t addr,
+                      uint64_t value, unsigned size)
 {
     HeathrowPICS *s = opaque;
     HeathrowPIC *pic;
@@ -89,7 +91,8 @@ static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     }
 }
 
-static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t pic_read(void *opaque, target_phys_addr_t addr,
+                         unsigned size)
 {
     HeathrowPICS *s = opaque;
     HeathrowPIC *pic;
@@ -120,19 +123,12 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
     return value;
 }
 
-static CPUWriteMemoryFunc * const pic_write[] = {
-    &pic_writel,
-    &pic_writel,
-    &pic_writel,
+static MemoryRegionOps heathrow_pic_ops = {
+    .read = pic_read,
+    .write = pic_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUReadMemoryFunc * const pic_read[] = {
-    &pic_readl,
-    &pic_readl,
-    &pic_readl,
-};
-
-
 static void heathrow_pic_set_irq(void *opaque, int num, int level)
 {
     HeathrowPICS *s = opaque;
@@ -201,7 +197,7 @@ static void heathrow_pic_reset(void *opaque)
     s->pics[1].level_triggered = 0x1ff00000;
 }
 
-qemu_irq *heathrow_pic_init(int *pmem_index,
+qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
                             int nb_cpus, qemu_irq **irqs)
 {
     HeathrowPICS *s;
@@ -209,8 +205,9 @@ qemu_irq *heathrow_pic_init(int *pmem_index,
     s = qemu_mallocz(sizeof(HeathrowPICS));
     /* only 1 CPU */
     s->irqs = irqs[0];
-    *pmem_index = cpu_register_io_memory(pic_read, pic_write, s,
-                                         DEVICE_LITTLE_ENDIAN);
+    memory_region_init_io(&s->mem, &heathrow_pic_ops, s,
+                          "heathrow-pic", 0x1000);
+    *pmem = &s->mem;
 
     vmstate_register(NULL, -1, &vmstate_heathrow_pic, s);
     qemu_register_reset(heathrow_pic_reset, s);
diff --git a/hw/ide.h b/hw/ide.h
index 34d9394..63a9912 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -18,7 +18,7 @@ PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 
 /* ide-macio.c */
-int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
+MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
 		   void *dbdma, int channel, qemu_irq dma_irq);
 
 /* ide-mmio.c */
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 7daeb31..7e5db16 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -35,6 +35,7 @@
 /* MacIO based PowerPC IDE */
 
 typedef struct MACIOIDEState {
+    MemoryRegion mem;
     IDEBus bus;
     BlockDriverAIOCB *aiocb;
 } MACIOIDEState;
@@ -281,16 +282,36 @@ static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr)
     return retval;
 }
 
-static CPUWriteMemoryFunc * const pmac_ide_write[] = {
-    pmac_ide_writeb,
-    pmac_ide_writew,
-    pmac_ide_writel,
-};
+static uint64_t pmac_ide_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
+{
+    MACIOIDEState *d = opaque;
+
+    switch (size) {
+    case 1: return pmac_ide_readb(d, addr);
+    case 2: return pmac_ide_readw(d, addr);
+    case 4: return pmac_ide_readl(d, addr);
+    default: abort();
+    }
+}
+
+static void pmac_ide_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t data, unsigned size)
+{
+    MACIOIDEState *d = opaque;
+
+    switch (size) {
+    case 1: return pmac_ide_writeb(d, addr, data);
+    case 2: return pmac_ide_writew(d, addr, data);
+    case 4: return pmac_ide_writel(d, addr, data);
+    default: abort();
+    }
+}
 
-static CPUReadMemoryFunc * const pmac_ide_read[] = {
-    pmac_ide_readb,
-    pmac_ide_readw,
-    pmac_ide_readl,
+static MemoryRegionOps pmac_ide_ops = {
+    .read = pmac_ide_read,
+    .write = pmac_ide_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static const VMStateDescription vmstate_pmac = {
@@ -315,11 +336,10 @@ static void pmac_ide_reset(void *opaque)
 /* hd_table must contain 4 block drivers */
 /* PowerMac uses memory mapped registers, not I/O. Return the memory
    I/O index to access the ide. */
-int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
-		   void *dbdma, int channel, qemu_irq dma_irq)
+MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
+                             void *dbdma, int channel, qemu_irq dma_irq)
 {
     MACIOIDEState *d;
-    int pmac_ide_memory;
 
     d = qemu_mallocz(sizeof(MACIOIDEState));
     ide_init2_with_non_qdev_drives(&d->bus, hd_table[0], hd_table[1], irq);
@@ -327,11 +347,9 @@ int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
     if (dbdma)
         DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, pmac_ide_flush, d);
 
-    pmac_ide_memory = cpu_register_io_memory(pmac_ide_read,
-                                             pmac_ide_write, d,
-                                             DEVICE_NATIVE_ENDIAN);
+    memory_region_init_io(&d->mem, &pmac_ide_ops, d, "pmac-ide", 0x1000);
     vmstate_register(NULL, 0, &vmstate_pmac, d);
     qemu_register_reset(pmac_ide_reset, d);
 
-    return pmac_ide_memory;
+    return &d->mem;
 }
diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c
index ed4458e..d977802 100644
--- a/hw/mac_dbdma.c
+++ b/hw/mac_dbdma.c
@@ -166,6 +166,7 @@ typedef struct DBDMA_channel {
 } DBDMA_channel;
 
 typedef struct {
+    MemoryRegion mem;
     DBDMA_channel channels[DBDMA_CHANNELS];
 } DBDMAState;
 
@@ -703,8 +704,8 @@ dbdma_control_write(DBDMA_channel *ch)
         ch->flush(&ch->io);
 }
 
-static void dbdma_writel (void *opaque,
-                          target_phys_addr_t addr, uint32_t value)
+static void dbdma_write(void *opaque, target_phys_addr_t addr,
+                        uint64_t value, unsigned size)
 {
     int channel = addr >> DBDMA_CHANNEL_SHIFT;
     DBDMAState *s = opaque;
@@ -753,7 +754,8 @@ static void dbdma_writel (void *opaque,
     }
 }
 
-static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t dbdma_read(void *opaque, target_phys_addr_t addr,
+                           unsigned size)
 {
     uint32_t value;
     int channel = addr >> DBDMA_CHANNEL_SHIFT;
@@ -798,16 +800,14 @@ static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)
     return value;
 }
 
-static CPUWriteMemoryFunc * const dbdma_write[] = {
-    NULL,
-    NULL,
-    dbdma_writel,
-};
-
-static CPUReadMemoryFunc * const dbdma_read[] = {
-    NULL,
-    NULL,
-    dbdma_readl,
+static MemoryRegionOps dbdma_ops = {
+    .read = dbdma_read,
+    .write = dbdma_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
 };
 
 static const VMStateDescription vmstate_dbdma_channel = {
@@ -842,14 +842,14 @@ static void dbdma_reset(void *opaque)
         memset(s->channels[i].regs, 0, DBDMA_SIZE);
 }
 
-void* DBDMA_init (int *dbdma_mem_index)
+void* DBDMA_init (MemoryRegion **dbdma_mem)
 {
     DBDMAState *s;
 
     s = qemu_mallocz(sizeof(DBDMAState));
 
-    *dbdma_mem_index = cpu_register_io_memory(dbdma_read, dbdma_write, s,
-                                              DEVICE_LITTLE_ENDIAN);
+    memory_region_init_io(&s->mem, &dbdma_ops, s, "dbdma", 0x1000);
+    *dbdma_mem = &s->mem;
     vmstate_register(NULL, -1, &vmstate_dbdma, s);
     qemu_register_reset(dbdma_reset, s);
 
diff --git a/hw/mac_dbdma.h b/hw/mac_dbdma.h
index d236c5b..933e17c 100644
--- a/hw/mac_dbdma.h
+++ b/hw/mac_dbdma.h
@@ -20,6 +20,8 @@
  * THE SOFTWARE.
  */
 
+#include "memory.h"
+
 typedef struct DBDMA_io DBDMA_io;
 
 typedef void (*DBDMA_flush)(DBDMA_io *io);
@@ -40,4 +42,4 @@ void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
                             DBDMA_rw rw, DBDMA_flush flush,
                             void *opaque);
 void DBDMA_schedule(void);
-void* DBDMA_init (int *dbdma_mem_index);
+void* DBDMA_init (MemoryRegion **dbdma_mem);
diff --git a/hw/mac_nvram.c b/hw/mac_nvram.c
index 61e53d2..5b9764e 100644
--- a/hw/mac_nvram.c
+++ b/hw/mac_nvram.c
@@ -39,7 +39,7 @@
 
 struct MacIONVRAMState {
     uint32_t size;
-    int mem_index;
+    MemoryRegion mem;
     unsigned int it_shift;
     uint8_t *data;
 };
@@ -71,8 +71,8 @@ void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val)
 }
 
 /* macio style NVRAM device */
-static void macio_nvram_writeb (void *opaque,
-                                target_phys_addr_t addr, uint32_t value)
+static void macio_nvram_writeb(void *opaque, target_phys_addr_t addr,
+                               uint64_t value, unsigned size)
 {
     MacIONVRAMState *s = opaque;
 
@@ -81,7 +81,8 @@ static void macio_nvram_writeb (void *opaque,
     NVR_DPRINTF("writeb addr %04x val %x\n", (int)addr, value);
 }
 
-static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr)
+static uint64_t macio_nvram_readb(void *opaque, target_phys_addr_t addr,
+                                  unsigned size)
 {
     MacIONVRAMState *s = opaque;
     uint32_t value;
@@ -93,16 +94,10 @@ static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr)
     return value;
 }
 
-static CPUWriteMemoryFunc * const nvram_write[] = {
-    &macio_nvram_writeb,
-    &macio_nvram_writeb,
-    &macio_nvram_writeb,
-};
-
-static CPUReadMemoryFunc * const nvram_read[] = {
-    &macio_nvram_readb,
-    &macio_nvram_readb,
-    &macio_nvram_readb,
+static MemoryRegionOps macio_nvram_ops = {
+    .read = macio_nvram_readb,
+    .write = macio_nvram_writeb,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static const VMStateDescription vmstate_macio_nvram = {
@@ -121,7 +116,7 @@ static void macio_nvram_reset(void *opaque)
 {
 }
 
-MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size,
+MacIONVRAMState *macio_nvram_init (target_phys_addr_t size,
                                    unsigned int it_shift)
 {
     MacIONVRAMState *s;
@@ -131,22 +126,18 @@ MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size,
     s->size = size;
     s->it_shift = it_shift;
 
-    s->mem_index = cpu_register_io_memory(nvram_read, nvram_write, s,
-                                          DEVICE_NATIVE_ENDIAN);
-    *mem_index = s->mem_index;
+    memory_region_init_io(&s->mem, &macio_nvram_ops, s, "macio-nvram",
+                          size << it_shift);
     vmstate_register(NULL, -1, &vmstate_macio_nvram, s);
     qemu_register_reset(macio_nvram_reset, s);
 
     return s;
 }
 
-void macio_nvram_map (void *opaque, target_phys_addr_t mem_base)
+void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar,
+                           target_phys_addr_t mem_base)
 {
-    MacIONVRAMState *s;
-
-    s = opaque;
-    cpu_register_physical_memory(mem_base, s->size << s->it_shift,
-                                 s->mem_index);
+    memory_region_add_subregion(bar, mem_base, &s->mem);
 }
 
 /* Set up a system OpenBIOS NVRAM partition */
diff --git a/hw/macio.c b/hw/macio.c
index 789ca55..71fa2a8 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -30,58 +30,55 @@
 typedef struct macio_state_t macio_state_t;
 struct macio_state_t {
     int is_oldworld;
-    int pic_mem_index;
-    int dbdma_mem_index;
-    int cuda_mem_index;
-    int escc_mem_index;
+    MemoryRegion bar;
+    MemoryRegion *pic_mem;
+    MemoryRegion *dbdma_mem;
+    MemoryRegion *cuda_mem;
+    MemoryRegion *escc_mem;
     void *nvram;
     int nb_ide;
-    int ide_mem_index[4];
+    MemoryRegion *ide_mem[4];
 };
 
-static void macio_map (PCIDevice *pci_dev, int region_num,
-                       pcibus_t addr, pcibus_t size, int type)
+static void macio_bar_setup(macio_state_t *macio_state)
 {
-    macio_state_t *macio_state;
     int i;
+    MemoryRegion *bar = &macio_state->bar;
 
-    macio_state = (macio_state_t *)(pci_dev + 1);
-    if (macio_state->pic_mem_index >= 0) {
+    memory_region_init(bar, "macio", 0x80000);
+    if (macio_state->pic_mem) {
         if (macio_state->is_oldworld) {
             /* Heathrow PIC */
-            cpu_register_physical_memory(addr + 0x00000, 0x1000,
-                                         macio_state->pic_mem_index);
+            memory_region_add_subregion(bar, 0x00000, macio_state->pic_mem);
         } else {
             /* OpenPIC */
-            cpu_register_physical_memory(addr + 0x40000, 0x40000,
-                                         macio_state->pic_mem_index);
+            memory_region_add_subregion(bar, 0x40000, macio_state->pic_mem);
         }
     }
-    if (macio_state->dbdma_mem_index >= 0) {
-        cpu_register_physical_memory(addr + 0x08000, 0x1000,
-                                     macio_state->dbdma_mem_index);
+    if (macio_state->dbdma_mem) {
+        memory_region_add_subregion(bar, 0x08000, macio_state->dbdma_mem);
     }
-    if (macio_state->escc_mem_index >= 0) {
-        cpu_register_physical_memory(addr + 0x13000, ESCC_SIZE << 4,
-                                     macio_state->escc_mem_index);
+    if (macio_state->escc_mem) {
+        memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem);
     }
-    if (macio_state->cuda_mem_index >= 0) {
-        cpu_register_physical_memory(addr + 0x16000, 0x2000,
-                                     macio_state->cuda_mem_index);
+    if (macio_state->cuda_mem) {
+        memory_region_add_subregion(bar, 0x16000, macio_state->cuda_mem);
     }
     for (i = 0; i < macio_state->nb_ide; i++) {
-        if (macio_state->ide_mem_index[i] >= 0) {
-            cpu_register_physical_memory(addr + 0x1f000 + (i * 0x1000), 0x1000,
-                                         macio_state->ide_mem_index[i]);
+        if (macio_state->ide_mem[i]) {
+            memory_region_add_subregion(bar, 0x1f000 + (i * 0x1000),
+                                        macio_state->ide_mem[i]);
         }
     }
     if (macio_state->nvram != NULL)
-        macio_nvram_map(macio_state->nvram, addr + 0x60000);
+        macio_nvram_setup_bar(macio_state->nvram, bar, 0x60000);
 }
 
-void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
-                 int dbdma_mem_index, int cuda_mem_index, void *nvram,
-                 int nb_ide, int *ide_mem_index, int escc_mem_index)
+void macio_init (PCIBus *bus, int device_id, int is_oldworld,
+                 MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
+                 MemoryRegion *cuda_mem, void *nvram,
+                 int nb_ide, MemoryRegion **ide_mem,
+                 MemoryRegion *escc_mem)
 {
     PCIDevice *d;
     macio_state_t *macio_state;
@@ -92,18 +89,18 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
                             -1, NULL, NULL);
     macio_state = (macio_state_t *)(d + 1);
     macio_state->is_oldworld = is_oldworld;
-    macio_state->pic_mem_index = pic_mem_index;
-    macio_state->dbdma_mem_index = dbdma_mem_index;
-    macio_state->cuda_mem_index = cuda_mem_index;
-    macio_state->escc_mem_index = escc_mem_index;
+    macio_state->pic_mem = pic_mem;
+    macio_state->dbdma_mem = dbdma_mem;
+    macio_state->cuda_mem = cuda_mem;
+    macio_state->escc_mem = escc_mem;
     macio_state->nvram = nvram;
     if (nb_ide > 4)
         nb_ide = 4;
     macio_state->nb_ide = nb_ide;
     for (i = 0; i < nb_ide; i++)
-        macio_state->ide_mem_index[i] = ide_mem_index[i];
+        macio_state->ide_mem[i] = ide_mem[i];
     for (; i < 4; i++)
-        macio_state->ide_mem_index[i] = -1;
+        macio_state->ide_mem[i] = NULL;
     /* Note: this code is strongly inspirated from the corresponding code
        in PearPC */
 
@@ -113,6 +110,7 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
 
     d->config[0x3d] = 0x01; // interrupt on pin 1
 
-    pci_register_bar(d, 0, 0x80000,
-                           PCI_BASE_ADDRESS_SPACE_MEMORY, macio_map);
+    macio_bar_setup(macio_state);
+    pci_register_bar_region(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                            &macio_state->bar);
 }
diff --git a/hw/openpic.c b/hw/openpic.c
index 6d2cf99..fd1ffba 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -205,7 +205,7 @@ typedef struct IRQ_dst_t {
 
 typedef struct openpic_t {
     PCIDevice pci_dev;
-    int mem_index;
+    MemoryRegion mem;
     /* Global registers */
     uint32_t frep; /* Feature reporting register */
     uint32_t glbc; /* Global configuration register  */
@@ -984,47 +984,34 @@ static uint32_t openpic_readl (void *opaque,target_phys_addr_t addr)
     return retval;
 }
 
-static CPUWriteMemoryFunc * const openpic_write[] = {
-    &openpic_buggy_write,
-    &openpic_buggy_write,
-    &openpic_writel,
-};
+static uint64_t openpic_read(void *opaque, target_phys_addr_t addr,
+                             unsigned size)
+{
+    openpic_t *opp = opaque;
 
-static CPUReadMemoryFunc * const openpic_read[] = {
-    &openpic_buggy_read,
-    &openpic_buggy_read,
-    &openpic_readl,
-};
+    switch (size) {
+    case 4: return openpic_readl(opp, addr);
+    default: return openpic_buggy_read(opp, addr);
+    }
+}
 
-static void openpic_map(PCIDevice *pci_dev, int region_num,
-                        pcibus_t addr, pcibus_t size, int type)
+static void openpic_write(void *opaque, target_phys_addr_t addr,
+                          uint64_t data, unsigned size)
 {
-    openpic_t *opp;
+    openpic_t *opp = opaque;
 
-    DPRINTF("Map OpenPIC\n");
-    opp = (openpic_t *)pci_dev;
-    /* Global registers */
-    DPRINTF("Register OPENPIC gbl   %08x => %08x\n",
-            addr + 0x1000, addr + 0x1000 + 0x100);
-    /* Timer registers */
-    DPRINTF("Register OPENPIC timer %08x => %08x\n",
-            addr + 0x1100, addr + 0x1100 + 0x40 * MAX_TMR);
-    /* Interrupt source registers */
-    DPRINTF("Register OPENPIC src   %08x => %08x\n",
-            addr + 0x10000, addr + 0x10000 + 0x20 * (OPENPIC_EXT_IRQ + 2));
-    /* Per CPU registers */
-    DPRINTF("Register OPENPIC dst   %08x => %08x\n",
-            addr + 0x20000, addr + 0x20000 + 0x1000 * MAX_CPU);
-    cpu_register_physical_memory(addr, 0x40000, opp->mem_index);
-#if 0 // Don't implement ISU for now
-    opp_io_memory = cpu_register_io_memory(openpic_src_read,
-                                           openpic_src_write, NULL
-                                           DEVICE_NATIVE_ENDIAN);
-    cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2),
-                                 opp_io_memory);
-#endif
+    switch (size) {
+    case 4: return openpic_writel(opp, addr, data);
+    default: return openpic_buggy_write(opp, addr, data);
+    }
 }
 
+static MemoryRegionOps openpic_ops = {
+    .read = openpic_read,
+    .write = openpic_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static void openpic_save_IRQ_queue(QEMUFile* f, IRQ_queue_t *q)
 {
     unsigned int i;
@@ -1161,7 +1148,7 @@ static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src)
     qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
 }
 
-qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
+qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus,
                         qemu_irq **irqs, qemu_irq irq_out)
 {
     openpic_t *opp;
@@ -1180,14 +1167,22 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
         pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER); // FIXME?
         pci_conf[0x3d] = 0x00; // no interrupt pin
 
+        memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000);
+#if 0 // Don't implement ISU for now
+        opp_io_memory = cpu_register_io_memory(openpic_src_read,
+                                               openpic_src_write, NULL
+                                               DEVICE_NATIVE_ENDIAN);
+        cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2),
+                                     opp_io_memory);
+#endif
+
         /* Register I/O spaces */
-        pci_register_bar(&opp->pci_dev, 0, 0x40000,
-                               PCI_BASE_ADDRESS_SPACE_MEMORY, &openpic_map);
+        pci_register_bar_region(&opp->pci_dev, 0,
+                                PCI_BASE_ADDRESS_SPACE_MEMORY, &opp->mem);
     } else {
         opp = qemu_mallocz(sizeof(openpic_t));
+        memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000);
     }
-    opp->mem_index = cpu_register_io_memory(openpic_read, openpic_write, opp,
-                                            DEVICE_LITTLE_ENDIAN);
 
     //    isu_base &= 0xFFFC0000;
     opp->nb_cpus = nb_cpus;
@@ -1223,8 +1218,8 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
     opp->irq_raise = openpic_irq_raise;
     opp->reset = openpic_reset;
 
-    if (pmem_index)
-        *pmem_index = opp->mem_index;
+    if (pmem)
+        *pmem = &opp->mem;
 
     return qemu_allocate_irqs(openpic_set_irq, opp, opp->max_irq);
 }
diff --git a/hw/openpic.h b/hw/openpic.h
index 0957c1f..75de361 100644
--- a/hw/openpic.h
+++ b/hw/openpic.h
@@ -11,7 +11,7 @@ enum {
     OPENPIC_OUTPUT_NB,
 };
 
-qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
+qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus,
                         qemu_irq **irqs, qemu_irq irq_out);
 qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
                         qemu_irq **irqs, qemu_irq irq_out);
diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h
index 25a2274..7351bb6 100644
--- a/hw/ppc_mac.h
+++ b/hw/ppc_mac.h
@@ -42,15 +42,16 @@
 #define ESCC_CLOCK 3686400
 
 /* Cuda */
-void cuda_init (int *cuda_mem_index, qemu_irq irq);
+void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq);
 
 /* MacIO */
-void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
-                 int dbdma_mem_index, int cuda_mem_index, void *nvram,
-                 int nb_ide, int *ide_mem_index, int escc_mem_index);
+void macio_init (PCIBus *bus, int device_id, int is_oldworld,
+                 MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
+                 MemoryRegion *cuda_mem, void *nvram,
+                 int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem);
 
 /* Heathrow PIC */
-qemu_irq *heathrow_pic_init(int *pmem_index,
+qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
                             int nb_cpus, qemu_irq **irqs);
 
 /* Grackle PCI */
@@ -69,9 +70,10 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
 /* Mac NVRAM */
 typedef struct MacIONVRAMState MacIONVRAMState;
 
-MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size,
+MacIONVRAMState *macio_nvram_init (target_phys_addr_t size,
                                    unsigned int it_shift);
-void macio_nvram_map (void *opaque, target_phys_addr_t mem_base);
+void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar,
+                           target_phys_addr_t mem_base);
 void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len);
 uint32_t macio_nvram_read (void *opaque, uint32_t addr);
 void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val);
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 94a21f9..3039022 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -144,10 +144,9 @@ static void ppc_core99_init (ram_addr_t ram_size,
     long kernel_size, initrd_size;
     PCIBus *pci_bus;
     MacIONVRAMState *nvr;
-    int nvram_mem_index;
     int bios_size;
-    int pic_mem_index, dbdma_mem_index, cuda_mem_index, escc_mem_index;
-    int ide_mem_index[3];
+    MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem, *escc_mem;
+    MemoryRegion *ide_mem[3];
     int ppc_boot_device;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     void *fw_cfg;
@@ -315,7 +314,7 @@ static void ppc_core99_init (ram_addr_t ram_size,
             exit(1);
         }
     }
-    pic = openpic_init(NULL, &pic_mem_index, smp_cpus, openpic_irqs, NULL);
+    pic = openpic_init(NULL, &pic_mem, smp_cpus, openpic_irqs, NULL);
     if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
         /* 970 gets a U3 bus */
         pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io());
@@ -327,32 +326,31 @@ static void ppc_core99_init (ram_addr_t ram_size,
     /* init basic PC hardware */
     pci_vga_init(pci_bus);
 
-    escc_mem_index = escc_init(0x80013000, pic[0x25], pic[0x24],
-                               serial_hds[0], serial_hds[1], ESCC_CLOCK, 4);
+    escc_mem = escc_init(0x80013000, pic[0x25], pic[0x24],
+                         serial_hds[0], serial_hds[1], ESCC_CLOCK, 4);
 
     for(i = 0; i < nb_nics; i++)
         pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
 
     ide_drive_get(hd, MAX_IDE_BUS);
-    dbdma = DBDMA_init(&dbdma_mem_index);
+    dbdma = DBDMA_init(&dbdma_mem);
 
     /* We only emulate 2 out of 3 IDE controllers for now */
-    ide_mem_index[0] = -1;
-    ide_mem_index[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]);
-    ide_mem_index[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]);
+    ide_mem[0] = NULL;
+    ide_mem[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]);
+    ide_mem[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]);
 
     /* cuda also initialize ADB */
     if (machine_arch == ARCH_MAC99_U3) {
         usb_enabled = 1;
     }
-    cuda_init(&cuda_mem_index, pic[0x19]);
+    cuda_init(&cuda_mem, pic[0x19]);
 
     adb_kbd_init(&adb_bus);
     adb_mouse_init(&adb_bus);
 
-    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem_index,
-               dbdma_mem_index, cuda_mem_index, NULL, 3, ide_mem_index,
-               escc_mem_index);
+    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem,
+               dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_mem);
 
     if (usb_enabled) {
         usb_ohci_init_pci(pci_bus, -1);
@@ -369,9 +367,9 @@ static void ppc_core99_init (ram_addr_t ram_size,
         graphic_depth = 15;
 
     /* The NewWorld NVRAM is not located in the MacIO device */
-    nvr = macio_nvram_init(&nvram_mem_index, 0x2000, 1);
+    nvr = macio_nvram_init(0x2000, 1);
     pmac_format_nvram_partition(nvr, 0x2000);
-    macio_nvram_map(nvr, 0xFFF04000);
+    macio_nvram_setup_bar(nvr, get_system_memory(), 0xFFF04000);
     /* No PCI init: the BIOS will do it */
 
     fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 0f99eef..41703a7 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -82,8 +82,8 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
     PCIBus *pci_bus;
     MacIONVRAMState *nvr;
     int bios_size;
-    int pic_mem_index, nvram_mem_index, dbdma_mem_index, cuda_mem_index;
-    int escc_mem_index, ide_mem_index[2];
+    MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem;
+    MemoryRegion *escc_mem, *ide_mem[2];
     uint16_t ppc_boot_device;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     void *fw_cfg;
@@ -233,13 +233,13 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
     if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
         hw_error("Only 6xx bus is supported on heathrow machine\n");
     }
-    pic = heathrow_pic_init(&pic_mem_index, 1, heathrow_irqs);
+    pic = heathrow_pic_init(&pic_mem, 1, heathrow_irqs);
     pci_bus = pci_grackle_init(0xfec00000, pic,
                                get_system_memory(),
                                get_system_io());
     pci_vga_init(pci_bus);
 
-    escc_mem_index = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0],
+    escc_mem = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0],
                                serial_hds[1], ESCC_CLOCK, 4);
 
     for(i = 0; i < nb_nics; i++)
@@ -249,9 +249,9 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
     ide_drive_get(hd, MAX_IDE_BUS);
 
     /* First IDE channel is a MAC IDE on the MacIO bus */
-    dbdma = DBDMA_init(&dbdma_mem_index);
-    ide_mem_index[0] = -1;
-    ide_mem_index[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]);
+    dbdma = DBDMA_init(&dbdma_mem);
+    ide_mem[0] = NULL;
+    ide_mem[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]);
 
     /* Second IDE channel is a CMD646 on the PCI bus */
     hd[0] = hd[MAX_IDE_DEVS];
@@ -260,17 +260,16 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
     pci_cmd646_ide_init(pci_bus, hd, 0);
 
     /* cuda also initialize ADB */
-    cuda_init(&cuda_mem_index, pic[0x12]);
+    cuda_init(&cuda_mem, pic[0x12]);
 
     adb_kbd_init(&adb_bus);
     adb_mouse_init(&adb_bus);
 
-    nvr = macio_nvram_init(&nvram_mem_index, 0x2000, 4);
+    nvr = macio_nvram_init(0x2000, 4);
     pmac_format_nvram_partition(nvr, 0x2000);
 
-    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem_index,
-               dbdma_mem_index, cuda_mem_index, nvr, 2, ide_mem_index,
-               escc_mem_index);
+    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem,
+               dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_mem);
 
     if (usb_enabled) {
         usb_ohci_init_pci(pci_bus, -1);
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 43/56] ne2000: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/ne2000-isa.c |   14 +++-------
 hw/ne2000.c     |   77 +++++++++++++++++++++++++++++++++++++-----------------
 hw/ne2000.h     |    8 +----
 3 files changed, 59 insertions(+), 40 deletions(-)

diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c
index e41dbba..ce7b365 100644
--- a/hw/ne2000-isa.c
+++ b/hw/ne2000-isa.c
@@ -61,24 +61,18 @@ static const VMStateDescription vmstate_isa_ne2000 = {
     }
 };
 
+#include "exec-memory.h"
+
 static int isa_ne2000_initfn(ISADevice *dev)
 {
     ISANE2000State *isa = DO_UPCAST(ISANE2000State, dev, dev);
     NE2000State *s = &isa->ne2000;
 
-    register_ioport_write(isa->iobase, 16, 1, ne2000_ioport_write, s);
-    register_ioport_read(isa->iobase, 16, 1, ne2000_ioport_read, s);
+    ne2000_setup_io(s, 0x20);
     isa_init_ioport_range(dev, isa->iobase, 16);
-
-    register_ioport_write(isa->iobase + 0x10, 1, 1, ne2000_asic_ioport_write, s);
-    register_ioport_read(isa->iobase + 0x10, 1, 1, ne2000_asic_ioport_read, s);
-    register_ioport_write(isa->iobase + 0x10, 2, 2, ne2000_asic_ioport_write, s);
-    register_ioport_read(isa->iobase + 0x10, 2, 2, ne2000_asic_ioport_read, s);
     isa_init_ioport_range(dev, isa->iobase + 0x10, 2);
-
-    register_ioport_write(isa->iobase + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
-    register_ioport_read(isa->iobase + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
     isa_init_ioport(dev, isa->iobase + 0x1f);
+    memory_region_add_subregion(get_system_io(), isa->iobase, &s->io);
 
     isa_init_irq(dev, &s->irq, isa->isairq);
 
diff --git a/hw/ne2000.c b/hw/ne2000.c
index f8acaae..ba20dc2 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -297,7 +297,7 @@ ssize_t ne2000_receive(VLANClientState *nc, const uint8_t *buf, size_t size_)
     return size_;
 }
 
-void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 {
     NE2000State *s = opaque;
     int offset, page, index;
@@ -394,7 +394,7 @@ void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
-uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
+static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
 {
     NE2000State *s = opaque;
     int offset, page, ret;
@@ -544,7 +544,7 @@ static inline void ne2000_dma_update(NE2000State *s, int len)
     }
 }
 
-void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 {
     NE2000State *s = opaque;
 
@@ -564,7 +564,7 @@ void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
-uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr)
+static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr)
 {
     NE2000State *s = opaque;
     int ret;
@@ -612,12 +612,12 @@ static uint32_t ne2000_asic_ioport_readl(void *opaque, uint32_t addr)
     return ret;
 }
 
-void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 {
     /* nothing to do (end of reset pulse) */
 }
 
-uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr)
+static uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr)
 {
     NE2000State *s = opaque;
     ne2000_reset(s);
@@ -676,27 +676,55 @@ static const VMStateDescription vmstate_pci_ne2000 = {
     }
 };
 
-/***********************************************************/
-/* PCI NE2000 definitions */
+static uint64_t ne2000_read(void *opaque, target_phys_addr_t addr,
+                            unsigned size)
+{
+    NE2000State *s = opaque;
 
-static void ne2000_map(PCIDevice *pci_dev, int region_num,
-                       pcibus_t addr, pcibus_t size, int type)
+    if (addr < 0x10 && size == 1) {
+        return ne2000_ioport_read(s, addr);
+    } else if (addr == 0x10) {
+        if (size <= 2) {
+            return ne2000_asic_ioport_read(s, addr);
+        } else {
+            return ne2000_asic_ioport_readl(s, addr);
+        }
+    } else if (addr == 0x1f && size == 1) {
+        return ne2000_reset_ioport_read(s, addr);
+    }
+    return ((uint64_t)1 << (size * 8)) - 1;
+}
+
+static void ne2000_write(void *opaque, target_phys_addr_t addr,
+                         uint64_t data, unsigned size)
 {
-    PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
-    NE2000State *s = &d->ne2000;
+    NE2000State *s = opaque;
+
+    if (addr < 0x10 && size == 1) {
+        return ne2000_ioport_write(s, addr, data);
+    } else if (addr == 0x10) {
+        if (size <= 2) {
+            return ne2000_asic_ioport_write(s, addr, data);
+        } else {
+            return ne2000_asic_ioport_writel(s, addr, data);
+        }
+    } else if (addr == 0x1f && size == 1) {
+        return ne2000_reset_ioport_write(s, addr, data);
+    }
+}
 
-    register_ioport_write(addr, 16, 1, ne2000_ioport_write, s);
-    register_ioport_read(addr, 16, 1, ne2000_ioport_read, s);
+static MemoryRegionOps ne2000_ops = {
+    .read = ne2000_read,
+    .write = ne2000_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
 
-    register_ioport_write(addr + 0x10, 1, 1, ne2000_asic_ioport_write, s);
-    register_ioport_read(addr + 0x10, 1, 1, ne2000_asic_ioport_read, s);
-    register_ioport_write(addr + 0x10, 2, 2, ne2000_asic_ioport_write, s);
-    register_ioport_read(addr + 0x10, 2, 2, ne2000_asic_ioport_read, s);
-    register_ioport_write(addr + 0x10, 4, 4, ne2000_asic_ioport_writel, s);
-    register_ioport_read(addr + 0x10, 4, 4, ne2000_asic_ioport_readl, s);
+/***********************************************************/
+/* PCI NE2000 definitions */
 
-    register_ioport_write(addr + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
-    register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
+void ne2000_setup_io(NE2000State *s, unsigned size)
+{
+    memory_region_init_io(&s->io, &ne2000_ops, s, "ne2000", size);
 }
 
 static void ne2000_cleanup(VLANClientState *nc)
@@ -724,9 +752,9 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
     /* TODO: RST# value should be 0. PCI spec 6.2.4 */
     pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
 
-    pci_register_bar(&d->dev, 0, 0x100,
-                           PCI_BASE_ADDRESS_SPACE_IO, ne2000_map);
     s = &d->ne2000;
+    ne2000_setup_io(s, 0x100);
+    pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
     s->irq = d->dev.irq[0];
 
     qemu_macaddr_default_if_unset(&s->c.macaddr);
@@ -754,6 +782,7 @@ static int pci_ne2000_exit(PCIDevice *pci_dev)
     PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
     NE2000State *s = &d->ne2000;
 
+    memory_region_destroy(&s->io);
     qemu_del_vlan_client(&s->nic->nc);
     return 0;
 }
diff --git a/hw/ne2000.h b/hw/ne2000.h
index 54fdfca..5fee052 100644
--- a/hw/ne2000.h
+++ b/hw/ne2000.h
@@ -4,6 +4,7 @@
 #define NE2000_MEM_SIZE     NE2000_PMEM_END
 
 typedef struct NE2000State {
+    MemoryRegion io;
     uint8_t cmd;
     uint32_t start;
     uint32_t stop;
@@ -27,12 +28,7 @@ typedef struct NE2000State {
     uint8_t mem[NE2000_MEM_SIZE];
 } NE2000State;
 
-void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val);
-uint32_t ne2000_ioport_read(void *opaque, uint32_t addr);
-void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val);
-uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr);
-void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val);
-uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr);
+void ne2000_setup_io(NE2000State *s, unsigned size);
 extern const VMStateDescription vmstate_ne2000;
 void ne2000_reset(NE2000State *s);
 int ne2000_can_receive(VLANClientState *vc);
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 43/56] ne2000: convert to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/ne2000-isa.c |   14 +++-------
 hw/ne2000.c     |   77 +++++++++++++++++++++++++++++++++++++-----------------
 hw/ne2000.h     |    8 +----
 3 files changed, 59 insertions(+), 40 deletions(-)

diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c
index e41dbba..ce7b365 100644
--- a/hw/ne2000-isa.c
+++ b/hw/ne2000-isa.c
@@ -61,24 +61,18 @@ static const VMStateDescription vmstate_isa_ne2000 = {
     }
 };
 
+#include "exec-memory.h"
+
 static int isa_ne2000_initfn(ISADevice *dev)
 {
     ISANE2000State *isa = DO_UPCAST(ISANE2000State, dev, dev);
     NE2000State *s = &isa->ne2000;
 
-    register_ioport_write(isa->iobase, 16, 1, ne2000_ioport_write, s);
-    register_ioport_read(isa->iobase, 16, 1, ne2000_ioport_read, s);
+    ne2000_setup_io(s, 0x20);
     isa_init_ioport_range(dev, isa->iobase, 16);
-
-    register_ioport_write(isa->iobase + 0x10, 1, 1, ne2000_asic_ioport_write, s);
-    register_ioport_read(isa->iobase + 0x10, 1, 1, ne2000_asic_ioport_read, s);
-    register_ioport_write(isa->iobase + 0x10, 2, 2, ne2000_asic_ioport_write, s);
-    register_ioport_read(isa->iobase + 0x10, 2, 2, ne2000_asic_ioport_read, s);
     isa_init_ioport_range(dev, isa->iobase + 0x10, 2);
-
-    register_ioport_write(isa->iobase + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
-    register_ioport_read(isa->iobase + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
     isa_init_ioport(dev, isa->iobase + 0x1f);
+    memory_region_add_subregion(get_system_io(), isa->iobase, &s->io);
 
     isa_init_irq(dev, &s->irq, isa->isairq);
 
diff --git a/hw/ne2000.c b/hw/ne2000.c
index f8acaae..ba20dc2 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -297,7 +297,7 @@ ssize_t ne2000_receive(VLANClientState *nc, const uint8_t *buf, size_t size_)
     return size_;
 }
 
-void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 {
     NE2000State *s = opaque;
     int offset, page, index;
@@ -394,7 +394,7 @@ void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
-uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
+static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
 {
     NE2000State *s = opaque;
     int offset, page, ret;
@@ -544,7 +544,7 @@ static inline void ne2000_dma_update(NE2000State *s, int len)
     }
 }
 
-void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 {
     NE2000State *s = opaque;
 
@@ -564,7 +564,7 @@ void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
-uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr)
+static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr)
 {
     NE2000State *s = opaque;
     int ret;
@@ -612,12 +612,12 @@ static uint32_t ne2000_asic_ioport_readl(void *opaque, uint32_t addr)
     return ret;
 }
 
-void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 {
     /* nothing to do (end of reset pulse) */
 }
 
-uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr)
+static uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr)
 {
     NE2000State *s = opaque;
     ne2000_reset(s);
@@ -676,27 +676,55 @@ static const VMStateDescription vmstate_pci_ne2000 = {
     }
 };
 
-/***********************************************************/
-/* PCI NE2000 definitions */
+static uint64_t ne2000_read(void *opaque, target_phys_addr_t addr,
+                            unsigned size)
+{
+    NE2000State *s = opaque;
 
-static void ne2000_map(PCIDevice *pci_dev, int region_num,
-                       pcibus_t addr, pcibus_t size, int type)
+    if (addr < 0x10 && size == 1) {
+        return ne2000_ioport_read(s, addr);
+    } else if (addr == 0x10) {
+        if (size <= 2) {
+            return ne2000_asic_ioport_read(s, addr);
+        } else {
+            return ne2000_asic_ioport_readl(s, addr);
+        }
+    } else if (addr == 0x1f && size == 1) {
+        return ne2000_reset_ioport_read(s, addr);
+    }
+    return ((uint64_t)1 << (size * 8)) - 1;
+}
+
+static void ne2000_write(void *opaque, target_phys_addr_t addr,
+                         uint64_t data, unsigned size)
 {
-    PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
-    NE2000State *s = &d->ne2000;
+    NE2000State *s = opaque;
+
+    if (addr < 0x10 && size == 1) {
+        return ne2000_ioport_write(s, addr, data);
+    } else if (addr == 0x10) {
+        if (size <= 2) {
+            return ne2000_asic_ioport_write(s, addr, data);
+        } else {
+            return ne2000_asic_ioport_writel(s, addr, data);
+        }
+    } else if (addr == 0x1f && size == 1) {
+        return ne2000_reset_ioport_write(s, addr, data);
+    }
+}
 
-    register_ioport_write(addr, 16, 1, ne2000_ioport_write, s);
-    register_ioport_read(addr, 16, 1, ne2000_ioport_read, s);
+static MemoryRegionOps ne2000_ops = {
+    .read = ne2000_read,
+    .write = ne2000_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
 
-    register_ioport_write(addr + 0x10, 1, 1, ne2000_asic_ioport_write, s);
-    register_ioport_read(addr + 0x10, 1, 1, ne2000_asic_ioport_read, s);
-    register_ioport_write(addr + 0x10, 2, 2, ne2000_asic_ioport_write, s);
-    register_ioport_read(addr + 0x10, 2, 2, ne2000_asic_ioport_read, s);
-    register_ioport_write(addr + 0x10, 4, 4, ne2000_asic_ioport_writel, s);
-    register_ioport_read(addr + 0x10, 4, 4, ne2000_asic_ioport_readl, s);
+/***********************************************************/
+/* PCI NE2000 definitions */
 
-    register_ioport_write(addr + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
-    register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
+void ne2000_setup_io(NE2000State *s, unsigned size)
+{
+    memory_region_init_io(&s->io, &ne2000_ops, s, "ne2000", size);
 }
 
 static void ne2000_cleanup(VLANClientState *nc)
@@ -724,9 +752,9 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
     /* TODO: RST# value should be 0. PCI spec 6.2.4 */
     pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
 
-    pci_register_bar(&d->dev, 0, 0x100,
-                           PCI_BASE_ADDRESS_SPACE_IO, ne2000_map);
     s = &d->ne2000;
+    ne2000_setup_io(s, 0x100);
+    pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
     s->irq = d->dev.irq[0];
 
     qemu_macaddr_default_if_unset(&s->c.macaddr);
@@ -754,6 +782,7 @@ static int pci_ne2000_exit(PCIDevice *pci_dev)
     PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
     NE2000State *s = &d->ne2000;
 
+    memory_region_destroy(&s->io);
     qemu_del_vlan_client(&s->nic->nc);
     return 0;
 }
diff --git a/hw/ne2000.h b/hw/ne2000.h
index 54fdfca..5fee052 100644
--- a/hw/ne2000.h
+++ b/hw/ne2000.h
@@ -4,6 +4,7 @@
 #define NE2000_MEM_SIZE     NE2000_PMEM_END
 
 typedef struct NE2000State {
+    MemoryRegion io;
     uint8_t cmd;
     uint32_t start;
     uint32_t stop;
@@ -27,12 +28,7 @@ typedef struct NE2000State {
     uint8_t mem[NE2000_MEM_SIZE];
 } NE2000State;
 
-void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val);
-uint32_t ne2000_ioport_read(void *opaque, uint32_t addr);
-void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val);
-uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr);
-void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val);
-uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr);
+void ne2000_setup_io(NE2000State *s, unsigned size);
 extern const VMStateDescription vmstate_ne2000;
 void ne2000_reset(NE2000State *s);
 int ne2000_can_receive(VLANClientState *vc);
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 44/56] pcnet: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Also related chips.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/lance.c     |   31 ++++++++----------
 hw/pcnet-pci.c |   98 ++++++++++++++++++++++++++++++++++++++-----------------
 hw/pcnet.h     |    4 ++-
 3 files changed, 85 insertions(+), 48 deletions(-)

diff --git a/hw/lance.c b/hw/lance.c
index ddb1cbb..1c81cd3 100644
--- a/hw/lance.c
+++ b/hw/lance.c
@@ -55,8 +55,8 @@ static void parent_lance_reset(void *opaque, int irq, int level)
         pcnet_h_reset(&d->state);
 }
 
-static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
-                             uint32_t val)
+static void lance_mem_write(void *opaque, target_phys_addr_t addr,
+                            uint64_t val, unsigned size)
 {
     SysBusPCNetState *d = opaque;
 
@@ -64,7 +64,8 @@ static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
     pcnet_ioport_writew(&d->state, addr, val & 0xffff);
 }
 
-static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
+static uint64_t lance_mem_read(void *opaque, target_phys_addr_t addr,
+                               unsigned size)
 {
     SysBusPCNetState *d = opaque;
     uint32_t val;
@@ -74,16 +75,14 @@ static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
     return val & 0xffff;
 }
 
-static CPUReadMemoryFunc * const lance_mem_read[3] = {
-    NULL,
-    lance_mem_readw,
-    NULL,
-};
-
-static CPUWriteMemoryFunc * const lance_mem_write[3] = {
-    NULL,
-    lance_mem_writew,
-    NULL,
+static MemoryRegionOps lance_mem_ops = {
+    .read = lance_mem_read,
+    .write = lance_mem_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 2,
+        .max_access_size = 2,
+    },
 };
 
 static void lance_cleanup(VLANClientState *nc)
@@ -117,13 +116,11 @@ static int lance_init(SysBusDevice *dev)
     SysBusPCNetState *d = FROM_SYSBUS(SysBusPCNetState, dev);
     PCNetState *s = &d->state;
 
-    s->mmio_index =
-        cpu_register_io_memory(lance_mem_read, lance_mem_write, d,
-                               DEVICE_NATIVE_ENDIAN);
+    memory_region_init_io(&s->mmio, &lance_mem_ops, s, "lance-mmio", 4);
 
     qdev_init_gpio_in(&dev->qdev, parent_lance_reset, 1);
 
-    sysbus_init_mmio(dev, 4, s->mmio_index);
+    sysbus_init_mmio_region(dev, &s->mmio);
 
     sysbus_init_irq(dev, &s->irq);
 
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 216cf81..fad0722 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -46,6 +46,7 @@
 typedef struct {
     PCIDevice pci_dev;
     PCNetState state;
+    MemoryRegion io_bar;
 } PCIPCNetState;
 
 static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
@@ -69,25 +70,41 @@ static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
     return val;
 }
 
-static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
-                             pcibus_t addr, pcibus_t size, int type)
+static uint64_t pcnet_ioport_read(void *opaque, target_phys_addr_t addr,
+                                  unsigned size)
 {
-    PCNetState *d = &DO_UPCAST(PCIPCNetState, pci_dev, pci_dev)->state;
+    PCNetState *d = opaque;
 
-#ifdef PCNET_DEBUG_IO
-    printf("pcnet_ioport_map addr=0x%04"FMT_PCIBUS" size=0x%04"FMT_PCIBUS"\n",
-           addr, size);
-#endif
+    if (addr < 16 && size == 1) {
+        return pcnet_aprom_readb(d, addr);
+    } else if (addr >= 0x10 && addr < 0x20 && size == 2) {
+        return pcnet_ioport_readw(d, addr);
+    } else if (addr >= 0x10 && addr < 0x20 && size == 4) {
+        return pcnet_ioport_readl(d, addr);
+    }
+    return ((uint64_t)1 << (size * 8)) - 1;
+}
 
-    register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
-    register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
+static void pcnet_ioport_write(void *opaque, target_phys_addr_t addr,
+                               uint64_t data, unsigned size)
+{
+    PCNetState *d = opaque;
 
-    register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
-    register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
-    register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
-    register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
+    if (addr < 16 && size == 1) {
+        return pcnet_aprom_writeb(d, addr, data);
+    } else if (addr >= 0x10 && addr < 0x20 && size == 2) {
+        return pcnet_ioport_writew(d, addr, data);
+    } else if (addr >= 0x10 && addr < 0x20 && size == 4) {
+        return pcnet_ioport_writel(d, addr, data);
+    }
 }
 
+static MemoryRegionOps pcnet_io_ops = {
+    .read = pcnet_ioport_read,
+    .write = pcnet_ioport_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
 static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
     PCNetState *d = opaque;
@@ -188,6 +205,32 @@ static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr)
     return val;
 }
 
+static uint64_t pcnet_mmio_read(void *opaque, target_phys_addr_t addr,
+                                unsigned size)
+{
+    PCNetState *d = opaque;
+
+    switch (size) {
+    case 1: return pcnet_mmio_readb(d, addr);
+    case 2: return pcnet_mmio_readw(d, addr);
+    case 4: return pcnet_mmio_readl(d, addr);
+    default: abort();
+    };
+}
+
+static void pcnet_mmio_write(void *opaque, target_phys_addr_t addr,
+                             uint64_t data, unsigned size)
+{
+    PCNetState *d = opaque;
+
+    switch (size) {
+    case 1: return pcnet_mmio_writeb(d, addr, data);
+    case 2: return pcnet_mmio_writew(d, addr, data);
+    case 4: return pcnet_mmio_writel(d, addr, data);
+    default: abort();
+    };
+}
+
 static const VMStateDescription vmstate_pci_pcnet = {
     .name = "pcnet",
     .version_id = 3,
@@ -202,16 +245,10 @@ static const VMStateDescription vmstate_pci_pcnet = {
 
 /* PCI interface */
 
-static CPUWriteMemoryFunc * const pcnet_mmio_write[] = {
-    &pcnet_mmio_writeb,
-    &pcnet_mmio_writew,
-    &pcnet_mmio_writel
-};
-
-static CPUReadMemoryFunc * const pcnet_mmio_read[] = {
-    &pcnet_mmio_readb,
-    &pcnet_mmio_readw,
-    &pcnet_mmio_readl
+static MemoryRegionOps pcnet_mmio_ops = {
+    .read = pcnet_mmio_read,
+    .write = pcnet_mmio_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
@@ -237,7 +274,8 @@ static int pci_pcnet_uninit(PCIDevice *dev)
 {
     PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, dev);
 
-    cpu_unregister_io_memory(d->state.mmio_index);
+    memory_region_destroy(&d->state.mmio);
+    memory_region_destroy(&d->io_bar);
     qemu_del_timer(d->state.poll_timer);
     qemu_free_timer(d->state.poll_timer);
     qemu_del_vlan_client(&d->state.nic->nc);
@@ -276,14 +314,14 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
     pci_conf[PCI_MAX_LAT] = 0xff;
 
     /* Handler for memory-mapped I/O */
-    s->mmio_index =
-      cpu_register_io_memory(pcnet_mmio_read, pcnet_mmio_write, &d->state,
-                             DEVICE_NATIVE_ENDIAN);
+    memory_region_init_io(&d->state.mmio, &pcnet_mmio_ops, d, "pcnet-mmio",
+                          PCNET_PNPMMIO_SIZE);
 
-    pci_register_bar(pci_dev, 0, PCNET_IOPORT_SIZE,
-                           PCI_BASE_ADDRESS_SPACE_IO, pcnet_ioport_map);
+    memory_region_init_io(&d->io_bar, &pcnet_io_ops, d, "pcnet-io",
+                          PCNET_IOPORT_SIZE);
+    pci_register_bar_region(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->io_bar);
 
-    pci_register_bar_simple(pci_dev, 1, PCNET_PNPMMIO_SIZE, 0, s->mmio_index);
+    pci_register_bar_region(pci_dev, 1, 0, &s->mmio);
 
     s->irq = pci_dev->irq[0];
     s->phys_mem_read = pci_physical_memory_read;
diff --git a/hw/pcnet.h b/hw/pcnet.h
index 534bdf9..7e1c685 100644
--- a/hw/pcnet.h
+++ b/hw/pcnet.h
@@ -4,6 +4,7 @@
 #define PCNET_LOOPTEST_CRC	1
 #define PCNET_LOOPTEST_NOCRC	2
 
+#include "memory.h"
 
 typedef struct PCNetState_st PCNetState;
 
@@ -17,7 +18,8 @@ struct PCNetState_st {
     uint16_t csr[128];
     uint16_t bcr[32];
     uint64_t timer;
-    int mmio_index, xmit_pos;
+    MemoryRegion mmio;
+    int xmit_pos;
     uint8_t buffer[4096];
     int tx_busy;
     qemu_irq irq;
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 44/56] pcnet: convert to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Also related chips.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/lance.c     |   31 ++++++++----------
 hw/pcnet-pci.c |   98 ++++++++++++++++++++++++++++++++++++++-----------------
 hw/pcnet.h     |    4 ++-
 3 files changed, 85 insertions(+), 48 deletions(-)

diff --git a/hw/lance.c b/hw/lance.c
index ddb1cbb..1c81cd3 100644
--- a/hw/lance.c
+++ b/hw/lance.c
@@ -55,8 +55,8 @@ static void parent_lance_reset(void *opaque, int irq, int level)
         pcnet_h_reset(&d->state);
 }
 
-static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
-                             uint32_t val)
+static void lance_mem_write(void *opaque, target_phys_addr_t addr,
+                            uint64_t val, unsigned size)
 {
     SysBusPCNetState *d = opaque;
 
@@ -64,7 +64,8 @@ static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
     pcnet_ioport_writew(&d->state, addr, val & 0xffff);
 }
 
-static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
+static uint64_t lance_mem_read(void *opaque, target_phys_addr_t addr,
+                               unsigned size)
 {
     SysBusPCNetState *d = opaque;
     uint32_t val;
@@ -74,16 +75,14 @@ static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
     return val & 0xffff;
 }
 
-static CPUReadMemoryFunc * const lance_mem_read[3] = {
-    NULL,
-    lance_mem_readw,
-    NULL,
-};
-
-static CPUWriteMemoryFunc * const lance_mem_write[3] = {
-    NULL,
-    lance_mem_writew,
-    NULL,
+static MemoryRegionOps lance_mem_ops = {
+    .read = lance_mem_read,
+    .write = lance_mem_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 2,
+        .max_access_size = 2,
+    },
 };
 
 static void lance_cleanup(VLANClientState *nc)
@@ -117,13 +116,11 @@ static int lance_init(SysBusDevice *dev)
     SysBusPCNetState *d = FROM_SYSBUS(SysBusPCNetState, dev);
     PCNetState *s = &d->state;
 
-    s->mmio_index =
-        cpu_register_io_memory(lance_mem_read, lance_mem_write, d,
-                               DEVICE_NATIVE_ENDIAN);
+    memory_region_init_io(&s->mmio, &lance_mem_ops, s, "lance-mmio", 4);
 
     qdev_init_gpio_in(&dev->qdev, parent_lance_reset, 1);
 
-    sysbus_init_mmio(dev, 4, s->mmio_index);
+    sysbus_init_mmio_region(dev, &s->mmio);
 
     sysbus_init_irq(dev, &s->irq);
 
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 216cf81..fad0722 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -46,6 +46,7 @@
 typedef struct {
     PCIDevice pci_dev;
     PCNetState state;
+    MemoryRegion io_bar;
 } PCIPCNetState;
 
 static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
@@ -69,25 +70,41 @@ static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
     return val;
 }
 
-static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
-                             pcibus_t addr, pcibus_t size, int type)
+static uint64_t pcnet_ioport_read(void *opaque, target_phys_addr_t addr,
+                                  unsigned size)
 {
-    PCNetState *d = &DO_UPCAST(PCIPCNetState, pci_dev, pci_dev)->state;
+    PCNetState *d = opaque;
 
-#ifdef PCNET_DEBUG_IO
-    printf("pcnet_ioport_map addr=0x%04"FMT_PCIBUS" size=0x%04"FMT_PCIBUS"\n",
-           addr, size);
-#endif
+    if (addr < 16 && size == 1) {
+        return pcnet_aprom_readb(d, addr);
+    } else if (addr >= 0x10 && addr < 0x20 && size == 2) {
+        return pcnet_ioport_readw(d, addr);
+    } else if (addr >= 0x10 && addr < 0x20 && size == 4) {
+        return pcnet_ioport_readl(d, addr);
+    }
+    return ((uint64_t)1 << (size * 8)) - 1;
+}
 
-    register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
-    register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
+static void pcnet_ioport_write(void *opaque, target_phys_addr_t addr,
+                               uint64_t data, unsigned size)
+{
+    PCNetState *d = opaque;
 
-    register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
-    register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
-    register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
-    register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
+    if (addr < 16 && size == 1) {
+        return pcnet_aprom_writeb(d, addr, data);
+    } else if (addr >= 0x10 && addr < 0x20 && size == 2) {
+        return pcnet_ioport_writew(d, addr, data);
+    } else if (addr >= 0x10 && addr < 0x20 && size == 4) {
+        return pcnet_ioport_writel(d, addr, data);
+    }
 }
 
+static MemoryRegionOps pcnet_io_ops = {
+    .read = pcnet_ioport_read,
+    .write = pcnet_ioport_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
 static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
     PCNetState *d = opaque;
@@ -188,6 +205,32 @@ static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr)
     return val;
 }
 
+static uint64_t pcnet_mmio_read(void *opaque, target_phys_addr_t addr,
+                                unsigned size)
+{
+    PCNetState *d = opaque;
+
+    switch (size) {
+    case 1: return pcnet_mmio_readb(d, addr);
+    case 2: return pcnet_mmio_readw(d, addr);
+    case 4: return pcnet_mmio_readl(d, addr);
+    default: abort();
+    };
+}
+
+static void pcnet_mmio_write(void *opaque, target_phys_addr_t addr,
+                             uint64_t data, unsigned size)
+{
+    PCNetState *d = opaque;
+
+    switch (size) {
+    case 1: return pcnet_mmio_writeb(d, addr, data);
+    case 2: return pcnet_mmio_writew(d, addr, data);
+    case 4: return pcnet_mmio_writel(d, addr, data);
+    default: abort();
+    };
+}
+
 static const VMStateDescription vmstate_pci_pcnet = {
     .name = "pcnet",
     .version_id = 3,
@@ -202,16 +245,10 @@ static const VMStateDescription vmstate_pci_pcnet = {
 
 /* PCI interface */
 
-static CPUWriteMemoryFunc * const pcnet_mmio_write[] = {
-    &pcnet_mmio_writeb,
-    &pcnet_mmio_writew,
-    &pcnet_mmio_writel
-};
-
-static CPUReadMemoryFunc * const pcnet_mmio_read[] = {
-    &pcnet_mmio_readb,
-    &pcnet_mmio_readw,
-    &pcnet_mmio_readl
+static MemoryRegionOps pcnet_mmio_ops = {
+    .read = pcnet_mmio_read,
+    .write = pcnet_mmio_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
@@ -237,7 +274,8 @@ static int pci_pcnet_uninit(PCIDevice *dev)
 {
     PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, dev);
 
-    cpu_unregister_io_memory(d->state.mmio_index);
+    memory_region_destroy(&d->state.mmio);
+    memory_region_destroy(&d->io_bar);
     qemu_del_timer(d->state.poll_timer);
     qemu_free_timer(d->state.poll_timer);
     qemu_del_vlan_client(&d->state.nic->nc);
@@ -276,14 +314,14 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
     pci_conf[PCI_MAX_LAT] = 0xff;
 
     /* Handler for memory-mapped I/O */
-    s->mmio_index =
-      cpu_register_io_memory(pcnet_mmio_read, pcnet_mmio_write, &d->state,
-                             DEVICE_NATIVE_ENDIAN);
+    memory_region_init_io(&d->state.mmio, &pcnet_mmio_ops, d, "pcnet-mmio",
+                          PCNET_PNPMMIO_SIZE);
 
-    pci_register_bar(pci_dev, 0, PCNET_IOPORT_SIZE,
-                           PCI_BASE_ADDRESS_SPACE_IO, pcnet_ioport_map);
+    memory_region_init_io(&d->io_bar, &pcnet_io_ops, d, "pcnet-io",
+                          PCNET_IOPORT_SIZE);
+    pci_register_bar_region(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->io_bar);
 
-    pci_register_bar_simple(pci_dev, 1, PCNET_PNPMMIO_SIZE, 0, s->mmio_index);
+    pci_register_bar_region(pci_dev, 1, 0, &s->mmio);
 
     s->irq = pci_dev->irq[0];
     s->phys_mem_read = pci_physical_memory_read;
diff --git a/hw/pcnet.h b/hw/pcnet.h
index 534bdf9..7e1c685 100644
--- a/hw/pcnet.h
+++ b/hw/pcnet.h
@@ -4,6 +4,7 @@
 #define PCNET_LOOPTEST_CRC	1
 #define PCNET_LOOPTEST_NOCRC	2
 
+#include "memory.h"
 
 typedef struct PCNetState_st PCNetState;
 
@@ -17,7 +18,8 @@ struct PCNetState_st {
     uint16_t csr[128];
     uint16_t bcr[32];
     uint64_t timer;
-    int mmio_index, xmit_pos;
+    MemoryRegion mmio;
+    int xmit_pos;
     uint8_t buffer[4096];
     int tx_busy;
     qemu_irq irq;
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 45/56] i6300esb: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Also add missing destructor.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/wdt_i6300esb.c |   59 ++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c
index 53786ce..242a8fa 100644
--- a/hw/wdt_i6300esb.c
+++ b/hw/wdt_i6300esb.c
@@ -66,6 +66,7 @@
 /* Device state. */
 struct I6300State {
     PCIDevice dev;
+    MemoryRegion io_mem;
 
     int reboot_enabled;         /* "Reboot" on timer expiry.  The real action
                                  * performed depends on the -watchdog-action
@@ -355,6 +356,38 @@ static void i6300esb_mem_writel(void *vp, target_phys_addr_t addr, uint32_t val)
     }
 }
 
+static uint64_t i6300esb_mem_read(void *opaque, target_phys_addr_t addr,
+                                  unsigned size)
+{
+    I6300State *s = opaque;
+
+    switch (size) {
+    case 1: return i6300esb_mem_readb(s, addr);
+    case 2: return i6300esb_mem_readw(s, addr);
+    case 4: return i6300esb_mem_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void i6300esb_mem_write(void *opaque, target_phys_addr_t addr,
+                               uint64_t data, unsigned size)
+{
+    I6300State *s = opaque;
+
+    switch (size) {
+    case 1: return i6300esb_mem_writeb(s, addr, data);
+    case 2: return i6300esb_mem_writew(s, addr, data);
+    case 4: return i6300esb_mem_writel(s, addr, data);
+    default: abort();
+    }
+}
+
+static MemoryRegionOps i6300esb_ops = {
+    .read = i6300esb_mem_read,
+    .write = i6300esb_mem_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
 static const VMStateDescription vmstate_i6300esb = {
     .name = "i6300esb_wdt",
     .version_id = sizeof(I6300State),
@@ -381,31 +414,28 @@ static const VMStateDescription vmstate_i6300esb = {
 static int i6300esb_init(PCIDevice *dev)
 {
     I6300State *d = DO_UPCAST(I6300State, dev, dev);
-    int io_mem;
-    static CPUReadMemoryFunc * const mem_read[3] = {
-        i6300esb_mem_readb,
-        i6300esb_mem_readw,
-        i6300esb_mem_readl,
-    };
-    static CPUWriteMemoryFunc * const mem_write[3] = {
-        i6300esb_mem_writeb,
-        i6300esb_mem_writew,
-        i6300esb_mem_writel,
-    };
 
     i6300esb_debug("I6300State = %p\n", d);
 
     d->timer = qemu_new_timer_ns(vm_clock, i6300esb_timer_expired, d);
     d->previous_reboot_flag = 0;
 
-    io_mem = cpu_register_io_memory(mem_read, mem_write, d,
-                                    DEVICE_NATIVE_ENDIAN);
-    pci_register_bar_simple(&d->dev, 0, 0x10, 0, io_mem);
+    memory_region_init_io(&d->io_mem, &i6300esb_ops, d, "i6300esb", 0x10);
+    pci_register_bar_region(&d->dev, 0, 0, &d->io_mem);
     /* qemu_register_coalesced_mmio (addr, 0x10); ? */
 
     return 0;
 }
 
+static int i6300esb_exit(PCIDevice *dev)
+{
+    I6300State *d = DO_UPCAST(I6300State, dev, dev);
+
+    memory_region_destroy(&d->io_mem);
+
+    return 0;
+}
+
 static WatchdogTimerModel model = {
     .wdt_name = "i6300esb",
     .wdt_description = "Intel 6300ESB",
@@ -419,6 +449,7 @@ static PCIDeviceInfo i6300esb_info = {
     .config_read  = i6300esb_config_read,
     .config_write = i6300esb_config_write,
     .init         = i6300esb_init,
+    .exit         = i6300esb_exit,
     .vendor_id    = PCI_VENDOR_ID_INTEL,
     .device_id    = PCI_DEVICE_ID_INTEL_ESB_9,
     .class_id     = PCI_CLASS_SYSTEM_OTHER,
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 45/56] i6300esb: convert to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Also add missing destructor.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/wdt_i6300esb.c |   59 ++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c
index 53786ce..242a8fa 100644
--- a/hw/wdt_i6300esb.c
+++ b/hw/wdt_i6300esb.c
@@ -66,6 +66,7 @@
 /* Device state. */
 struct I6300State {
     PCIDevice dev;
+    MemoryRegion io_mem;
 
     int reboot_enabled;         /* "Reboot" on timer expiry.  The real action
                                  * performed depends on the -watchdog-action
@@ -355,6 +356,38 @@ static void i6300esb_mem_writel(void *vp, target_phys_addr_t addr, uint32_t val)
     }
 }
 
+static uint64_t i6300esb_mem_read(void *opaque, target_phys_addr_t addr,
+                                  unsigned size)
+{
+    I6300State *s = opaque;
+
+    switch (size) {
+    case 1: return i6300esb_mem_readb(s, addr);
+    case 2: return i6300esb_mem_readw(s, addr);
+    case 4: return i6300esb_mem_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void i6300esb_mem_write(void *opaque, target_phys_addr_t addr,
+                               uint64_t data, unsigned size)
+{
+    I6300State *s = opaque;
+
+    switch (size) {
+    case 1: return i6300esb_mem_writeb(s, addr, data);
+    case 2: return i6300esb_mem_writew(s, addr, data);
+    case 4: return i6300esb_mem_writel(s, addr, data);
+    default: abort();
+    }
+}
+
+static MemoryRegionOps i6300esb_ops = {
+    .read = i6300esb_mem_read,
+    .write = i6300esb_mem_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
 static const VMStateDescription vmstate_i6300esb = {
     .name = "i6300esb_wdt",
     .version_id = sizeof(I6300State),
@@ -381,31 +414,28 @@ static const VMStateDescription vmstate_i6300esb = {
 static int i6300esb_init(PCIDevice *dev)
 {
     I6300State *d = DO_UPCAST(I6300State, dev, dev);
-    int io_mem;
-    static CPUReadMemoryFunc * const mem_read[3] = {
-        i6300esb_mem_readb,
-        i6300esb_mem_readw,
-        i6300esb_mem_readl,
-    };
-    static CPUWriteMemoryFunc * const mem_write[3] = {
-        i6300esb_mem_writeb,
-        i6300esb_mem_writew,
-        i6300esb_mem_writel,
-    };
 
     i6300esb_debug("I6300State = %p\n", d);
 
     d->timer = qemu_new_timer_ns(vm_clock, i6300esb_timer_expired, d);
     d->previous_reboot_flag = 0;
 
-    io_mem = cpu_register_io_memory(mem_read, mem_write, d,
-                                    DEVICE_NATIVE_ENDIAN);
-    pci_register_bar_simple(&d->dev, 0, 0x10, 0, io_mem);
+    memory_region_init_io(&d->io_mem, &i6300esb_ops, d, "i6300esb", 0x10);
+    pci_register_bar_region(&d->dev, 0, 0, &d->io_mem);
     /* qemu_register_coalesced_mmio (addr, 0x10); ? */
 
     return 0;
 }
 
+static int i6300esb_exit(PCIDevice *dev)
+{
+    I6300State *d = DO_UPCAST(I6300State, dev, dev);
+
+    memory_region_destroy(&d->io_mem);
+
+    return 0;
+}
+
 static WatchdogTimerModel model = {
     .wdt_name = "i6300esb",
     .wdt_description = "Intel 6300ESB",
@@ -419,6 +449,7 @@ static PCIDeviceInfo i6300esb_info = {
     .config_read  = i6300esb_config_read,
     .config_write = i6300esb_config_write,
     .init         = i6300esb_init,
+    .exit         = i6300esb_exit,
     .vendor_id    = PCI_VENDOR_ID_INTEL,
     .device_id    = PCI_DEVICE_ID_INTEL_ESB_9,
     .class_id     = PCI_CLASS_SYSTEM_OTHER,
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 46/56] isa-mmio: concert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:14   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/isa.h      |    2 +
 hw/isa_mmio.c |   67 +++++++++++++++++++++++----------------------------------
 2 files changed, 29 insertions(+), 40 deletions(-)

diff --git a/hw/isa.h b/hw/isa.h
index d2b6126..f1f2181 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -4,6 +4,7 @@
 /* ISA bus */
 
 #include "ioport.h"
+#include "memory.h"
 #include "qdev.h"
 
 typedef struct ISABus ISABus;
@@ -37,6 +38,7 @@ ISADevice *isa_create_simple(const char *name);
 
 extern target_phys_addr_t isa_mem_base;
 
+void isa_mmio_setup(MemoryRegion *mr, target_phys_addr_t size);
 void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size);
 
 /* dma.c */
diff --git a/hw/isa_mmio.c b/hw/isa_mmio.c
index ca957fb..09f0598 100644
--- a/hw/isa_mmio.c
+++ b/hw/isa_mmio.c
@@ -25,58 +25,45 @@
 #include "hw.h"
 #include "isa.h"
 
-static void isa_mmio_writeb (void *opaque, target_phys_addr_t addr,
-                                  uint32_t val)
+static void isa_mmio_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t val, unsigned size)
 {
-    cpu_outb(addr & IOPORTS_MASK, val);
+    switch (size) {
+    case 1: return cpu_outb(addr & IOPORTS_MASK, val);
+    case 2: return cpu_outw(addr & IOPORTS_MASK, val);
+    case 4: return cpu_outl(addr & IOPORTS_MASK, val);
+    default: abort();
+    }
 }
 
-static void isa_mmio_writew(void *opaque, target_phys_addr_t addr,
-                               uint32_t val)
+static uint64_t isa_mmio_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
 {
-    cpu_outw(addr & IOPORTS_MASK, val);
+    switch (size) {
+    case 1: cpu_inb(addr & IOPORTS_MASK);
+    case 2: cpu_inw(addr & IOPORTS_MASK);
+    case 4: cpu_inl(addr & IOPORTS_MASK);
+    default: abort();
+    }
 }
 
-static void isa_mmio_writel(void *opaque, target_phys_addr_t addr,
-                               uint32_t val)
-{
-    cpu_outl(addr & IOPORTS_MASK, val);
-}
-
-static uint32_t isa_mmio_readb (void *opaque, target_phys_addr_t addr)
-{
-    return cpu_inb(addr & IOPORTS_MASK);
-}
-
-static uint32_t isa_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
-    return cpu_inw(addr & IOPORTS_MASK);
-}
+static MemoryRegionOps isa_mmio_ops = {
+    .read = isa_mmio_read,
+    .write = isa_mmio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
 
-static uint32_t isa_mmio_readl(void *opaque, target_phys_addr_t addr)
+void isa_mmio_setup(MemoryRegion *mr, target_phys_addr_t size)
 {
-    return cpu_inl(addr & IOPORTS_MASK);
+    memory_region_init_io(mr, &isa_mmio_ops, NULL, "isa-mmio", size);
 }
 
-static CPUWriteMemoryFunc * const isa_mmio_write[] = {
-    &isa_mmio_writeb,
-    &isa_mmio_writew,
-    &isa_mmio_writel,
-};
-
-static CPUReadMemoryFunc * const isa_mmio_read[] = {
-    &isa_mmio_readb,
-    &isa_mmio_readw,
-    &isa_mmio_readl,
-};
+#include "exec-memory.h"
 
 void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size)
 {
-    int isa_mmio_iomemtype;
+    MemoryRegion *mr = qemu_malloc(sizeof(*mr));
 
-    isa_mmio_iomemtype = cpu_register_io_memory(isa_mmio_read,
-                                                isa_mmio_write,
-                                                NULL,
-                                                DEVICE_LITTLE_ENDIAN);
-    cpu_register_physical_memory(base, size, isa_mmio_iomemtype);
+    isa_mmio_setup(mr, size);
+    memory_region_add_subregion(get_system_memory(), base, mr);
 }
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 46/56] isa-mmio: concert to memory API
@ 2011-07-10 18:14   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/isa.h      |    2 +
 hw/isa_mmio.c |   67 +++++++++++++++++++++++----------------------------------
 2 files changed, 29 insertions(+), 40 deletions(-)

diff --git a/hw/isa.h b/hw/isa.h
index d2b6126..f1f2181 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -4,6 +4,7 @@
 /* ISA bus */
 
 #include "ioport.h"
+#include "memory.h"
 #include "qdev.h"
 
 typedef struct ISABus ISABus;
@@ -37,6 +38,7 @@ ISADevice *isa_create_simple(const char *name);
 
 extern target_phys_addr_t isa_mem_base;
 
+void isa_mmio_setup(MemoryRegion *mr, target_phys_addr_t size);
 void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size);
 
 /* dma.c */
diff --git a/hw/isa_mmio.c b/hw/isa_mmio.c
index ca957fb..09f0598 100644
--- a/hw/isa_mmio.c
+++ b/hw/isa_mmio.c
@@ -25,58 +25,45 @@
 #include "hw.h"
 #include "isa.h"
 
-static void isa_mmio_writeb (void *opaque, target_phys_addr_t addr,
-                                  uint32_t val)
+static void isa_mmio_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t val, unsigned size)
 {
-    cpu_outb(addr & IOPORTS_MASK, val);
+    switch (size) {
+    case 1: return cpu_outb(addr & IOPORTS_MASK, val);
+    case 2: return cpu_outw(addr & IOPORTS_MASK, val);
+    case 4: return cpu_outl(addr & IOPORTS_MASK, val);
+    default: abort();
+    }
 }
 
-static void isa_mmio_writew(void *opaque, target_phys_addr_t addr,
-                               uint32_t val)
+static uint64_t isa_mmio_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
 {
-    cpu_outw(addr & IOPORTS_MASK, val);
+    switch (size) {
+    case 1: cpu_inb(addr & IOPORTS_MASK);
+    case 2: cpu_inw(addr & IOPORTS_MASK);
+    case 4: cpu_inl(addr & IOPORTS_MASK);
+    default: abort();
+    }
 }
 
-static void isa_mmio_writel(void *opaque, target_phys_addr_t addr,
-                               uint32_t val)
-{
-    cpu_outl(addr & IOPORTS_MASK, val);
-}
-
-static uint32_t isa_mmio_readb (void *opaque, target_phys_addr_t addr)
-{
-    return cpu_inb(addr & IOPORTS_MASK);
-}
-
-static uint32_t isa_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
-    return cpu_inw(addr & IOPORTS_MASK);
-}
+static MemoryRegionOps isa_mmio_ops = {
+    .read = isa_mmio_read,
+    .write = isa_mmio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
 
-static uint32_t isa_mmio_readl(void *opaque, target_phys_addr_t addr)
+void isa_mmio_setup(MemoryRegion *mr, target_phys_addr_t size)
 {
-    return cpu_inl(addr & IOPORTS_MASK);
+    memory_region_init_io(mr, &isa_mmio_ops, NULL, "isa-mmio", size);
 }
 
-static CPUWriteMemoryFunc * const isa_mmio_write[] = {
-    &isa_mmio_writeb,
-    &isa_mmio_writew,
-    &isa_mmio_writel,
-};
-
-static CPUReadMemoryFunc * const isa_mmio_read[] = {
-    &isa_mmio_readb,
-    &isa_mmio_readw,
-    &isa_mmio_readl,
-};
+#include "exec-memory.h"
 
 void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size)
 {
-    int isa_mmio_iomemtype;
+    MemoryRegion *mr = qemu_malloc(sizeof(*mr));
 
-    isa_mmio_iomemtype = cpu_register_io_memory(isa_mmio_read,
-                                                isa_mmio_write,
-                                                NULL,
-                                                DEVICE_LITTLE_ENDIAN);
-    cpu_register_physical_memory(base, size, isa_mmio_iomemtype);
+    isa_mmio_setup(mr, size);
+    memory_region_add_subregion(get_system_memory(), base, mr);
 }
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 47/56] sun4u: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:15   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

fixes memory leak on repeated BAR map/unmap

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/sun4u.c |   55 +++++++++++++++++++++++++------------------------------
 1 files changed, 25 insertions(+), 30 deletions(-)

diff --git a/hw/sun4u.c b/hw/sun4u.c
index d7dcaf0..74a06a8 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -91,6 +91,12 @@ struct hwdef {
     uint64_t console_serial_base;
 };
 
+typedef struct EbusState {
+    PCIDevice pci_dev;
+    MemoryRegion bar0;
+    MemoryRegion bar1;
+} EbusState;
+
 int DMA_get_channel_mode (int nchan)
 {
     return 0;
@@ -518,21 +524,6 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit)
     }
 }
 
-static void ebus_mmio_mapfunc(PCIDevice *pci_dev, int region_num,
-                              pcibus_t addr, pcibus_t size, int type)
-{
-    EBUS_DPRINTF("Mapping region %d registers at %" FMT_PCIBUS "\n",
-                 region_num, addr);
-    switch (region_num) {
-    case 0:
-        isa_mmio_init(addr, 0x1000000);
-        break;
-    case 1:
-        isa_mmio_init(addr, 0x800000);
-        break;
-    }
-}
-
 static void dummy_isa_irq_handler(void *opaque, int n, int level)
 {
 }
@@ -549,27 +540,31 @@ pci_ebus_init(PCIBus *bus, int devfn)
 }
 
 static int
-pci_ebus_init1(PCIDevice *s)
+pci_ebus_init1(PCIDevice *pci_dev)
 {
-    isa_bus_new(&s->qdev);
+    EbusState *s = container_of(pci_dev, EbusState, pci_dev);
+
+    isa_bus_new(&pci_dev->qdev);
 
-    s->config[0x04] = 0x06; // command = bus master, pci mem
-    s->config[0x05] = 0x00;
-    s->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
-    s->config[0x07] = 0x03; // status = medium devsel
-    s->config[0x09] = 0x00; // programming i/f
-    s->config[0x0D] = 0x0a; // latency_timer
+    pci_dev->config[0x04] = 0x06; // command = bus master, pci mem
+    pci_dev->config[0x05] = 0x00;
+    pci_dev->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
+    pci_dev->config[0x07] = 0x03; // status = medium devsel
+    pci_dev->config[0x09] = 0x00; // programming i/f
+    pci_dev->config[0x0D] = 0x0a; // latency_timer
 
-    pci_register_bar(s, 0, 0x1000000, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                           ebus_mmio_mapfunc);
-    pci_register_bar(s, 1, 0x800000,  PCI_BASE_ADDRESS_SPACE_MEMORY,
-                           ebus_mmio_mapfunc);
+    isa_mmio_setup(&s->bar0, 0x1000000);
+    pci_register_bar_region(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                            &s->bar0);
+    isa_mmio_setup(&s->bar1, 0x800000);
+    pci_register_bar_region(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                            &s->bar1);
     return 0;
 }
 
 static PCIDeviceInfo ebus_info = {
     .qdev.name = "ebus",
-    .qdev.size = sizeof(PCIDevice),
+    .qdev.size = sizeof(EbusState),
     .init = pci_ebus_init1,
     .vendor_id = PCI_VENDOR_ID_SUN,
     .device_id = PCI_DEVICE_ID_SUN_EBUS,
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 47/56] sun4u: convert to memory API
@ 2011-07-10 18:15   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

fixes memory leak on repeated BAR map/unmap

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/sun4u.c |   55 +++++++++++++++++++++++++------------------------------
 1 files changed, 25 insertions(+), 30 deletions(-)

diff --git a/hw/sun4u.c b/hw/sun4u.c
index d7dcaf0..74a06a8 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -91,6 +91,12 @@ struct hwdef {
     uint64_t console_serial_base;
 };
 
+typedef struct EbusState {
+    PCIDevice pci_dev;
+    MemoryRegion bar0;
+    MemoryRegion bar1;
+} EbusState;
+
 int DMA_get_channel_mode (int nchan)
 {
     return 0;
@@ -518,21 +524,6 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit)
     }
 }
 
-static void ebus_mmio_mapfunc(PCIDevice *pci_dev, int region_num,
-                              pcibus_t addr, pcibus_t size, int type)
-{
-    EBUS_DPRINTF("Mapping region %d registers at %" FMT_PCIBUS "\n",
-                 region_num, addr);
-    switch (region_num) {
-    case 0:
-        isa_mmio_init(addr, 0x1000000);
-        break;
-    case 1:
-        isa_mmio_init(addr, 0x800000);
-        break;
-    }
-}
-
 static void dummy_isa_irq_handler(void *opaque, int n, int level)
 {
 }
@@ -549,27 +540,31 @@ pci_ebus_init(PCIBus *bus, int devfn)
 }
 
 static int
-pci_ebus_init1(PCIDevice *s)
+pci_ebus_init1(PCIDevice *pci_dev)
 {
-    isa_bus_new(&s->qdev);
+    EbusState *s = container_of(pci_dev, EbusState, pci_dev);
+
+    isa_bus_new(&pci_dev->qdev);
 
-    s->config[0x04] = 0x06; // command = bus master, pci mem
-    s->config[0x05] = 0x00;
-    s->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
-    s->config[0x07] = 0x03; // status = medium devsel
-    s->config[0x09] = 0x00; // programming i/f
-    s->config[0x0D] = 0x0a; // latency_timer
+    pci_dev->config[0x04] = 0x06; // command = bus master, pci mem
+    pci_dev->config[0x05] = 0x00;
+    pci_dev->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
+    pci_dev->config[0x07] = 0x03; // status = medium devsel
+    pci_dev->config[0x09] = 0x00; // programming i/f
+    pci_dev->config[0x0D] = 0x0a; // latency_timer
 
-    pci_register_bar(s, 0, 0x1000000, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                           ebus_mmio_mapfunc);
-    pci_register_bar(s, 1, 0x800000,  PCI_BASE_ADDRESS_SPACE_MEMORY,
-                           ebus_mmio_mapfunc);
+    isa_mmio_setup(&s->bar0, 0x1000000);
+    pci_register_bar_region(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                            &s->bar0);
+    isa_mmio_setup(&s->bar1, 0x800000);
+    pci_register_bar_region(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                            &s->bar1);
     return 0;
 }
 
 static PCIDeviceInfo ebus_info = {
     .qdev.name = "ebus",
-    .qdev.size = sizeof(PCIDevice),
+    .qdev.size = sizeof(EbusState),
     .init = pci_ebus_init1,
     .vendor_id = PCI_VENDOR_ID_SUN,
     .device_id = PCI_DEVICE_ID_SUN_EBUS,
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 48/56] ehci: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:15   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/usb-ehci.c |   53 +++++++++++++++++++++++++++++------------------------
 1 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index 91fb7de..bd7fdcb 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -371,8 +371,7 @@ struct EHCIState {
     PCIDevice dev;
     USBBus bus;
     qemu_irq irq;
-    target_phys_addr_t mem_base;
-    int mem;
+    MemoryRegion mem;
     int num_ports;
 
     /* properties */
@@ -2094,29 +2093,38 @@ static void ehci_frame_timer(void *opaque)
     qemu_mod_timer(ehci->frame_timer, expire_time);
 }
 
-static CPUReadMemoryFunc *ehci_readfn[3]={
-    ehci_mem_readb,
-    ehci_mem_readw,
-    ehci_mem_readl
-};
+static uint64_t ehci_mem_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
+{
+    EHCIState *s = opaque;
 
-static CPUWriteMemoryFunc *ehci_writefn[3]={
-    ehci_mem_writeb,
-    ehci_mem_writew,
-    ehci_mem_writel
-};
+    switch (size) {
+    case 1: return ehci_mem_readb(s, addr);
+    case 2: return ehci_mem_readw(s, addr);
+    case 4: return ehci_mem_readl(s, addr);
+    default: abort();
+    }
+}
 
-static void ehci_map(PCIDevice *pci_dev, int region_num,
-                     pcibus_t addr, pcibus_t size, int type)
+static void ehci_mem_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t data, unsigned size)
 {
-    EHCIState *s =(EHCIState *)pci_dev;
+    EHCIState *s = opaque;
 
-    DPRINTF("ehci_map: region %d, addr %08" PRIx64 ", size %" PRId64 ", s->mem %08X\n",
-            region_num, addr, size, s->mem);
-    s->mem_base = addr;
-    cpu_register_physical_memory(addr, size, s->mem);
+    switch (size) {
+    case 1: return ehci_mem_writeb(s, addr, data);
+    case 2: return ehci_mem_writew(s, addr, data);
+    case 4: return ehci_mem_writel(s, addr, data);
+    default: abort();
+    }
 }
 
+static MemoryRegionOps ehci_mem_ops = {
+    .read = ehci_mem_read,
+    .write = ehci_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static void ehci_device_destroy(USBBus *bus, USBDevice *dev)
 {
     EHCIState *s = container_of(bus, EHCIState, bus);
@@ -2215,11 +2223,8 @@ static int usb_ehci_initfn(PCIDevice *dev)
 
     qemu_register_reset(ehci_reset, s);
 
-    s->mem = cpu_register_io_memory(ehci_readfn, ehci_writefn, s,
-                                    DEVICE_LITTLE_ENDIAN);
-
-    pci_register_bar(&s->dev, 0, MMIO_SIZE, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                                                            ehci_map);
+    memory_region_init_io(&s->mem, &ehci_mem_ops, s, "ehci", MMIO_SIZE);
+    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);
 
     fprintf(stderr, "*** EHCI support is under development ***\n");
 
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 48/56] ehci: convert to memory API
@ 2011-07-10 18:15   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/usb-ehci.c |   53 +++++++++++++++++++++++++++++------------------------
 1 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index 91fb7de..bd7fdcb 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -371,8 +371,7 @@ struct EHCIState {
     PCIDevice dev;
     USBBus bus;
     qemu_irq irq;
-    target_phys_addr_t mem_base;
-    int mem;
+    MemoryRegion mem;
     int num_ports;
 
     /* properties */
@@ -2094,29 +2093,38 @@ static void ehci_frame_timer(void *opaque)
     qemu_mod_timer(ehci->frame_timer, expire_time);
 }
 
-static CPUReadMemoryFunc *ehci_readfn[3]={
-    ehci_mem_readb,
-    ehci_mem_readw,
-    ehci_mem_readl
-};
+static uint64_t ehci_mem_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
+{
+    EHCIState *s = opaque;
 
-static CPUWriteMemoryFunc *ehci_writefn[3]={
-    ehci_mem_writeb,
-    ehci_mem_writew,
-    ehci_mem_writel
-};
+    switch (size) {
+    case 1: return ehci_mem_readb(s, addr);
+    case 2: return ehci_mem_readw(s, addr);
+    case 4: return ehci_mem_readl(s, addr);
+    default: abort();
+    }
+}
 
-static void ehci_map(PCIDevice *pci_dev, int region_num,
-                     pcibus_t addr, pcibus_t size, int type)
+static void ehci_mem_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t data, unsigned size)
 {
-    EHCIState *s =(EHCIState *)pci_dev;
+    EHCIState *s = opaque;
 
-    DPRINTF("ehci_map: region %d, addr %08" PRIx64 ", size %" PRId64 ", s->mem %08X\n",
-            region_num, addr, size, s->mem);
-    s->mem_base = addr;
-    cpu_register_physical_memory(addr, size, s->mem);
+    switch (size) {
+    case 1: return ehci_mem_writeb(s, addr, data);
+    case 2: return ehci_mem_writew(s, addr, data);
+    case 4: return ehci_mem_writel(s, addr, data);
+    default: abort();
+    }
 }
 
+static MemoryRegionOps ehci_mem_ops = {
+    .read = ehci_mem_read,
+    .write = ehci_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static void ehci_device_destroy(USBBus *bus, USBDevice *dev)
 {
     EHCIState *s = container_of(bus, EHCIState, bus);
@@ -2215,11 +2223,8 @@ static int usb_ehci_initfn(PCIDevice *dev)
 
     qemu_register_reset(ehci_reset, s);
 
-    s->mem = cpu_register_io_memory(ehci_readfn, ehci_writefn, s,
-                                    DEVICE_LITTLE_ENDIAN);
-
-    pci_register_bar(&s->dev, 0, MMIO_SIZE, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                                                            ehci_map);
+    memory_region_init_io(&s->mem, &ehci_mem_ops, s, "ehci", MMIO_SIZE);
+    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);
 
     fprintf(stderr, "*** EHCI support is under development ***\n");
 
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 49/56] uhci: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:15   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/usb-uhci.c |   57 +++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 405fa7b..95ef260 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -132,6 +132,7 @@ typedef struct UHCIPort {
 
 struct UHCIState {
     PCIDevice dev;
+    MemoryRegion io_bar;
     USBBus bus;
     uint16_t cmd; /* cmd register */
     uint16_t status;
@@ -1083,19 +1084,38 @@ static void uhci_frame_timer(void *opaque)
     qemu_mod_timer(s->frame_timer, s->expire_time);
 }
 
-static void uhci_map(PCIDevice *pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
+static uint64_t uhci_ioport_read(void *opaque, target_phys_addr_t addr,
+                                 unsigned size)
 {
-    UHCIState *s = (UHCIState *)pci_dev;
-
-    register_ioport_write(addr, 32, 2, uhci_ioport_writew, s);
-    register_ioport_read(addr, 32, 2, uhci_ioport_readw, s);
-    register_ioport_write(addr, 32, 4, uhci_ioport_writel, s);
-    register_ioport_read(addr, 32, 4, uhci_ioport_readl, s);
-    register_ioport_write(addr, 32, 1, uhci_ioport_writeb, s);
-    register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
+    UHCIState *s = opaque;
+
+    switch (size) {
+    case 1: return uhci_ioport_readb(s, addr);
+    case 2: return uhci_ioport_readw(s, addr);
+    case 4: return uhci_ioport_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void uhci_ioport_write(void *opaque, target_phys_addr_t addr,
+                              uint64_t data, unsigned size)
+{
+    UHCIState *s = opaque;
+
+    switch (size) {
+    case 1: return uhci_ioport_writeb(s, addr, data);
+    case 2: return uhci_ioport_writew(s, addr, data);
+    case 4: return uhci_ioport_writel(s, addr, data);
+    default: abort();
+    }
 }
 
+static MemoryRegionOps uhci_ioport_ops = {
+    .read = uhci_ioport_read,
+    .write = uhci_ioport_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static void uhci_device_destroy(USBBus *bus, USBDevice *dev)
 {
     UHCIState *s = container_of(bus, UHCIState, bus);
@@ -1137,10 +1157,11 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
 
     qemu_register_reset(uhci_reset, s);
 
+    memory_region_init_io(&s->io_bar, &uhci_ioport_ops, s, "uhci", 0x20);
     /* Use region 4 for consistency with real hardware.  BSD guests seem
        to rely on this.  */
-    pci_register_bar(&s->dev, 4, 0x20,
-                           PCI_BASE_ADDRESS_SPACE_IO, uhci_map);
+    pci_register_bar_region(&s->dev, 4,
+                            PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
 
     return 0;
 }
@@ -1160,12 +1181,22 @@ static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
     return usb_uhci_common_initfn(dev);
 }
 
+static int usb_uhci_exit(PCIDevice *dev)
+{
+    UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
+
+    memory_region_destroy(&s->io_bar);
+    return 0;
+}
+
+
 static PCIDeviceInfo uhci_info[] = {
     {
         .qdev.name    = "piix3-usb-uhci",
         .qdev.size    = sizeof(UHCIState),
         .qdev.vmsd    = &vmstate_uhci,
         .init         = usb_uhci_common_initfn,
+        .exit         = usb_uhci_exit,
         .vendor_id    = PCI_VENDOR_ID_INTEL,
         .device_id    = PCI_DEVICE_ID_INTEL_82371SB_2,
         .revision     = 0x01,
@@ -1175,6 +1206,7 @@ static PCIDeviceInfo uhci_info[] = {
         .qdev.size    = sizeof(UHCIState),
         .qdev.vmsd    = &vmstate_uhci,
         .init         = usb_uhci_common_initfn,
+        .exit         = usb_uhci_exit,
         .vendor_id    = PCI_VENDOR_ID_INTEL,
         .device_id    = PCI_DEVICE_ID_INTEL_82371AB_2,
         .revision     = 0x01,
@@ -1184,6 +1216,7 @@ static PCIDeviceInfo uhci_info[] = {
         .qdev.size    = sizeof(UHCIState),
         .qdev.vmsd    = &vmstate_uhci,
         .init         = usb_uhci_vt82c686b_initfn,
+        .exit         = usb_uhci_exit,
         .vendor_id    = PCI_VENDOR_ID_VIA,
         .device_id    = PCI_DEVICE_ID_VIA_UHCI,
         .revision     = 0x01,
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 49/56] uhci: convert to memory API
@ 2011-07-10 18:15   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/usb-uhci.c |   57 +++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 405fa7b..95ef260 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -132,6 +132,7 @@ typedef struct UHCIPort {
 
 struct UHCIState {
     PCIDevice dev;
+    MemoryRegion io_bar;
     USBBus bus;
     uint16_t cmd; /* cmd register */
     uint16_t status;
@@ -1083,19 +1084,38 @@ static void uhci_frame_timer(void *opaque)
     qemu_mod_timer(s->frame_timer, s->expire_time);
 }
 
-static void uhci_map(PCIDevice *pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
+static uint64_t uhci_ioport_read(void *opaque, target_phys_addr_t addr,
+                                 unsigned size)
 {
-    UHCIState *s = (UHCIState *)pci_dev;
-
-    register_ioport_write(addr, 32, 2, uhci_ioport_writew, s);
-    register_ioport_read(addr, 32, 2, uhci_ioport_readw, s);
-    register_ioport_write(addr, 32, 4, uhci_ioport_writel, s);
-    register_ioport_read(addr, 32, 4, uhci_ioport_readl, s);
-    register_ioport_write(addr, 32, 1, uhci_ioport_writeb, s);
-    register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
+    UHCIState *s = opaque;
+
+    switch (size) {
+    case 1: return uhci_ioport_readb(s, addr);
+    case 2: return uhci_ioport_readw(s, addr);
+    case 4: return uhci_ioport_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void uhci_ioport_write(void *opaque, target_phys_addr_t addr,
+                              uint64_t data, unsigned size)
+{
+    UHCIState *s = opaque;
+
+    switch (size) {
+    case 1: return uhci_ioport_writeb(s, addr, data);
+    case 2: return uhci_ioport_writew(s, addr, data);
+    case 4: return uhci_ioport_writel(s, addr, data);
+    default: abort();
+    }
 }
 
+static MemoryRegionOps uhci_ioport_ops = {
+    .read = uhci_ioport_read,
+    .write = uhci_ioport_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static void uhci_device_destroy(USBBus *bus, USBDevice *dev)
 {
     UHCIState *s = container_of(bus, UHCIState, bus);
@@ -1137,10 +1157,11 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
 
     qemu_register_reset(uhci_reset, s);
 
+    memory_region_init_io(&s->io_bar, &uhci_ioport_ops, s, "uhci", 0x20);
     /* Use region 4 for consistency with real hardware.  BSD guests seem
        to rely on this.  */
-    pci_register_bar(&s->dev, 4, 0x20,
-                           PCI_BASE_ADDRESS_SPACE_IO, uhci_map);
+    pci_register_bar_region(&s->dev, 4,
+                            PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
 
     return 0;
 }
@@ -1160,12 +1181,22 @@ static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
     return usb_uhci_common_initfn(dev);
 }
 
+static int usb_uhci_exit(PCIDevice *dev)
+{
+    UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
+
+    memory_region_destroy(&s->io_bar);
+    return 0;
+}
+
+
 static PCIDeviceInfo uhci_info[] = {
     {
         .qdev.name    = "piix3-usb-uhci",
         .qdev.size    = sizeof(UHCIState),
         .qdev.vmsd    = &vmstate_uhci,
         .init         = usb_uhci_common_initfn,
+        .exit         = usb_uhci_exit,
         .vendor_id    = PCI_VENDOR_ID_INTEL,
         .device_id    = PCI_DEVICE_ID_INTEL_82371SB_2,
         .revision     = 0x01,
@@ -1175,6 +1206,7 @@ static PCIDeviceInfo uhci_info[] = {
         .qdev.size    = sizeof(UHCIState),
         .qdev.vmsd    = &vmstate_uhci,
         .init         = usb_uhci_common_initfn,
+        .exit         = usb_uhci_exit,
         .vendor_id    = PCI_VENDOR_ID_INTEL,
         .device_id    = PCI_DEVICE_ID_INTEL_82371AB_2,
         .revision     = 0x01,
@@ -1184,6 +1216,7 @@ static PCIDeviceInfo uhci_info[] = {
         .qdev.size    = sizeof(UHCIState),
         .qdev.vmsd    = &vmstate_uhci,
         .init         = usb_uhci_vt82c686b_initfn,
+        .exit         = usb_uhci_exit,
         .vendor_id    = PCI_VENDOR_ID_VIA,
         .device_id    = PCI_DEVICE_ID_VIA_UHCI,
         .revision     = 0x01,
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 50/56] xen-platform: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:15   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Since this device bypasses PCI and registers I/O ports directly with
the system bus, it needs further attention.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/xen_platform.c |  110 ++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 76 insertions(+), 34 deletions(-)

diff --git a/hw/xen_platform.c b/hw/xen_platform.c
index b167eee..b5da08f 100644
--- a/hw/xen_platform.c
+++ b/hw/xen_platform.c
@@ -51,6 +51,9 @@
 
 typedef struct PCIXenPlatformState {
     PCIDevice  pci_dev;
+    MemoryRegion fixed_io;
+    MemoryRegion bar;
+    MemoryRegion mmio_bar;
     uint8_t flags; /* used only for version_id == 2 */
     int drivers_blacklisted;
     uint16_t driver_product_version;
@@ -173,6 +176,35 @@ static uint32_t platform_fixed_ioport_readb(void *opaque, uint32_t addr)
     }
 }
 
+static uint64_t platform_fixed_ioport_read(void *opaque,
+                                           target_phys_addr_t addr,
+                                           unsigned size)
+{
+    addr += XEN_PLATFORM_IOPORT;
+
+    switch (size) {
+    case 1: return platform_fixed_ioport_readb(opaque, addr);
+    case 2: return platform_fixed_ioport_readw(opaque, addr);
+    case 4: return -1u;
+    default: abort();
+    }
+}
+
+static void platform_fixed_ioport_write(void *opaque,
+                                        target_phys_addr_t addr,
+                                        uint64_t data,
+                                        unsigned size)
+{
+    addr += XEN_PLATFORM_IOPORT;
+
+    switch (size) {
+    case 1: return platform_fixed_ioport_writeb(opaque, addr, data);
+    case 2: return platform_fixed_ioport_writew(opaque, addr, data);
+    case 4: return platform_fixed_ioport_writel(opaque, addr, data);
+    default: abort();
+    }
+}
+
 static void platform_fixed_ioport_reset(void *opaque)
 {
     PCIXenPlatformState *s = opaque;
@@ -180,21 +212,27 @@ static void platform_fixed_ioport_reset(void *opaque)
     platform_fixed_ioport_writeb(s, XEN_PLATFORM_IOPORT, 0);
 }
 
+static MemoryRegionOps platform_fixed_io_ops = {
+    .read = platform_fixed_ioport_read,
+    .write = platform_fixed_ioport_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+#include "exec-memory.h"
+
 static void platform_fixed_ioport_init(PCIXenPlatformState* s)
 {
-    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 4, platform_fixed_ioport_writel, s);
-    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_writew, s);
-    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_writeb, s);
-    register_ioport_read(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_readw, s);
-    register_ioport_read(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_readb, s);
+    memory_region_init_io(&s->fixed_io, &platform_fixed_io_ops, s,
+                          "xen-fixed", 16);
+    memory_region_add_subregion(get_system_io(), XEN_PLATFORM_IOPORT,
+                                &s->fixed_io);
 }
 
 /* Xen Platform PCI Device */
 
-static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
+static uint64_t xen_platform_ioport_read(void *opaque, target_phys_addr_t addr,
+                                         unsigned size)
 {
-    addr &= 0xff;
-
     if (addr == 0) {
         return platform_fixed_ioport_readb(opaque, XEN_PLATFORM_IOPORT);
     } else {
@@ -202,13 +240,11 @@ static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
     }
 }
 
-static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+static void xen_platform_ioport_write(void *opaque, target_phys_addr_t addr,
+                                      uint64_t val, unsigned size)
 {
     PCIXenPlatformState *s = opaque;
 
-    addr &= 0xff;
-    val  &= 0xff;
-
     switch (addr) {
     case 0: /* Platform flags */
         platform_fixed_ioport_writeb(opaque, XEN_PLATFORM_IOPORT, val);
@@ -221,15 +257,23 @@ static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val
     }
 }
 
-static void platform_ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, pcibus_t size, int type)
-{
-    PCIXenPlatformState *d = DO_UPCAST(PCIXenPlatformState, pci_dev, pci_dev);
+static MemoryRegionOps xen_pci_io_ops = {
+    .read = xen_platform_ioport_read,
+    .write = xen_platform_ioport_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
 
-    register_ioport_write(addr, size, 1, xen_platform_ioport_writeb, d);
-    register_ioport_read(addr, size, 1, xen_platform_ioport_readb, d);
+static void platform_ioport_bar_setup(PCIXenPlatformState *d)
+{
+    memory_region_init_io(&d->bar, &xen_pci_io_ops, d, "xen-pci", 0x100);
 }
 
-static uint32_t platform_mmio_read(ReadWriteHandler *handler, pcibus_t addr, int len)
+static uint64_t platform_mmio_read(void *opaque, target_phys_addr_t addr,
+                                   unsigned size)
 {
     DPRINTF("Warning: attempted read from physical address "
             "0x" TARGET_FMT_plx " in xen platform mmio space\n", addr);
@@ -237,28 +281,24 @@ static uint32_t platform_mmio_read(ReadWriteHandler *handler, pcibus_t addr, int
     return 0;
 }
 
-static void platform_mmio_write(ReadWriteHandler *handler, pcibus_t addr,
-                                uint32_t val, int len)
+static void platform_mmio_write(void *opaque, target_phys_addr_t addr,
+                                uint64_t val, unsigned size)
 {
-    DPRINTF("Warning: attempted write of 0x%x to physical "
+    DPRINTF("Warning: attempted write of 0x%"PRIx64" to physical "
             "address 0x" TARGET_FMT_plx " in xen platform mmio space\n",
             val, addr);
 }
 
-static ReadWriteHandler platform_mmio_handler = {
+static MemoryRegionOps platform_mmio_handler = {
     .read = &platform_mmio_read,
     .write = &platform_mmio_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void platform_mmio_map(PCIDevice *d, int region_num,
-                              pcibus_t addr, pcibus_t size, int type)
+static void platform_mmio_setup(PCIXenPlatformState *d)
 {
-    int mmio_io_addr;
-
-    mmio_io_addr = cpu_register_io_memory_simple(&platform_mmio_handler,
-                                                 DEVICE_NATIVE_ENDIAN);
-
-    cpu_register_physical_memory(addr, size, mmio_io_addr);
+    memory_region_init_io(&d->mmio_bar, &platform_mmio_handler, d,
+                          "xen-mmio", 0x1000000);
 }
 
 static int xen_platform_post_load(void *opaque, int version_id)
@@ -304,12 +344,14 @@ static int xen_platform_initfn(PCIDevice *dev)
 
     pci_conf[PCI_INTERRUPT_PIN] = 1;
 
-    pci_register_bar(&d->pci_dev, 0, 0x100,
-            PCI_BASE_ADDRESS_SPACE_IO, platform_ioport_map);
+    platform_ioport_bar_setup(d);
+    pci_register_bar_region(&d->pci_dev, 0,
+                            PCI_BASE_ADDRESS_SPACE_IO, &d->bar);
 
     /* reserve 16MB mmio address for share memory*/
-    pci_register_bar(&d->pci_dev, 1, 0x1000000,
-            PCI_BASE_ADDRESS_MEM_PREFETCH, platform_mmio_map);
+    platform_mmio_setup(d);
+    pci_register_bar_region(&d->pci_dev, 1,
+                            PCI_BASE_ADDRESS_MEM_PREFETCH, &d->mmio_bar);
 
     platform_fixed_ioport_init(d);
 
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 50/56] xen-platform: convert to memory API
@ 2011-07-10 18:15   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Since this device bypasses PCI and registers I/O ports directly with
the system bus, it needs further attention.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/xen_platform.c |  110 ++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 76 insertions(+), 34 deletions(-)

diff --git a/hw/xen_platform.c b/hw/xen_platform.c
index b167eee..b5da08f 100644
--- a/hw/xen_platform.c
+++ b/hw/xen_platform.c
@@ -51,6 +51,9 @@
 
 typedef struct PCIXenPlatformState {
     PCIDevice  pci_dev;
+    MemoryRegion fixed_io;
+    MemoryRegion bar;
+    MemoryRegion mmio_bar;
     uint8_t flags; /* used only for version_id == 2 */
     int drivers_blacklisted;
     uint16_t driver_product_version;
@@ -173,6 +176,35 @@ static uint32_t platform_fixed_ioport_readb(void *opaque, uint32_t addr)
     }
 }
 
+static uint64_t platform_fixed_ioport_read(void *opaque,
+                                           target_phys_addr_t addr,
+                                           unsigned size)
+{
+    addr += XEN_PLATFORM_IOPORT;
+
+    switch (size) {
+    case 1: return platform_fixed_ioport_readb(opaque, addr);
+    case 2: return platform_fixed_ioport_readw(opaque, addr);
+    case 4: return -1u;
+    default: abort();
+    }
+}
+
+static void platform_fixed_ioport_write(void *opaque,
+                                        target_phys_addr_t addr,
+                                        uint64_t data,
+                                        unsigned size)
+{
+    addr += XEN_PLATFORM_IOPORT;
+
+    switch (size) {
+    case 1: return platform_fixed_ioport_writeb(opaque, addr, data);
+    case 2: return platform_fixed_ioport_writew(opaque, addr, data);
+    case 4: return platform_fixed_ioport_writel(opaque, addr, data);
+    default: abort();
+    }
+}
+
 static void platform_fixed_ioport_reset(void *opaque)
 {
     PCIXenPlatformState *s = opaque;
@@ -180,21 +212,27 @@ static void platform_fixed_ioport_reset(void *opaque)
     platform_fixed_ioport_writeb(s, XEN_PLATFORM_IOPORT, 0);
 }
 
+static MemoryRegionOps platform_fixed_io_ops = {
+    .read = platform_fixed_ioport_read,
+    .write = platform_fixed_ioport_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+#include "exec-memory.h"
+
 static void platform_fixed_ioport_init(PCIXenPlatformState* s)
 {
-    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 4, platform_fixed_ioport_writel, s);
-    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_writew, s);
-    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_writeb, s);
-    register_ioport_read(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_readw, s);
-    register_ioport_read(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_readb, s);
+    memory_region_init_io(&s->fixed_io, &platform_fixed_io_ops, s,
+                          "xen-fixed", 16);
+    memory_region_add_subregion(get_system_io(), XEN_PLATFORM_IOPORT,
+                                &s->fixed_io);
 }
 
 /* Xen Platform PCI Device */
 
-static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
+static uint64_t xen_platform_ioport_read(void *opaque, target_phys_addr_t addr,
+                                         unsigned size)
 {
-    addr &= 0xff;
-
     if (addr == 0) {
         return platform_fixed_ioport_readb(opaque, XEN_PLATFORM_IOPORT);
     } else {
@@ -202,13 +240,11 @@ static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
     }
 }
 
-static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+static void xen_platform_ioport_write(void *opaque, target_phys_addr_t addr,
+                                      uint64_t val, unsigned size)
 {
     PCIXenPlatformState *s = opaque;
 
-    addr &= 0xff;
-    val  &= 0xff;
-
     switch (addr) {
     case 0: /* Platform flags */
         platform_fixed_ioport_writeb(opaque, XEN_PLATFORM_IOPORT, val);
@@ -221,15 +257,23 @@ static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val
     }
 }
 
-static void platform_ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, pcibus_t size, int type)
-{
-    PCIXenPlatformState *d = DO_UPCAST(PCIXenPlatformState, pci_dev, pci_dev);
+static MemoryRegionOps xen_pci_io_ops = {
+    .read = xen_platform_ioport_read,
+    .write = xen_platform_ioport_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
 
-    register_ioport_write(addr, size, 1, xen_platform_ioport_writeb, d);
-    register_ioport_read(addr, size, 1, xen_platform_ioport_readb, d);
+static void platform_ioport_bar_setup(PCIXenPlatformState *d)
+{
+    memory_region_init_io(&d->bar, &xen_pci_io_ops, d, "xen-pci", 0x100);
 }
 
-static uint32_t platform_mmio_read(ReadWriteHandler *handler, pcibus_t addr, int len)
+static uint64_t platform_mmio_read(void *opaque, target_phys_addr_t addr,
+                                   unsigned size)
 {
     DPRINTF("Warning: attempted read from physical address "
             "0x" TARGET_FMT_plx " in xen platform mmio space\n", addr);
@@ -237,28 +281,24 @@ static uint32_t platform_mmio_read(ReadWriteHandler *handler, pcibus_t addr, int
     return 0;
 }
 
-static void platform_mmio_write(ReadWriteHandler *handler, pcibus_t addr,
-                                uint32_t val, int len)
+static void platform_mmio_write(void *opaque, target_phys_addr_t addr,
+                                uint64_t val, unsigned size)
 {
-    DPRINTF("Warning: attempted write of 0x%x to physical "
+    DPRINTF("Warning: attempted write of 0x%"PRIx64" to physical "
             "address 0x" TARGET_FMT_plx " in xen platform mmio space\n",
             val, addr);
 }
 
-static ReadWriteHandler platform_mmio_handler = {
+static MemoryRegionOps platform_mmio_handler = {
     .read = &platform_mmio_read,
     .write = &platform_mmio_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void platform_mmio_map(PCIDevice *d, int region_num,
-                              pcibus_t addr, pcibus_t size, int type)
+static void platform_mmio_setup(PCIXenPlatformState *d)
 {
-    int mmio_io_addr;
-
-    mmio_io_addr = cpu_register_io_memory_simple(&platform_mmio_handler,
-                                                 DEVICE_NATIVE_ENDIAN);
-
-    cpu_register_physical_memory(addr, size, mmio_io_addr);
+    memory_region_init_io(&d->mmio_bar, &platform_mmio_handler, d,
+                          "xen-mmio", 0x1000000);
 }
 
 static int xen_platform_post_load(void *opaque, int version_id)
@@ -304,12 +344,14 @@ static int xen_platform_initfn(PCIDevice *dev)
 
     pci_conf[PCI_INTERRUPT_PIN] = 1;
 
-    pci_register_bar(&d->pci_dev, 0, 0x100,
-            PCI_BASE_ADDRESS_SPACE_IO, platform_ioport_map);
+    platform_ioport_bar_setup(d);
+    pci_register_bar_region(&d->pci_dev, 0,
+                            PCI_BASE_ADDRESS_SPACE_IO, &d->bar);
 
     /* reserve 16MB mmio address for share memory*/
-    pci_register_bar(&d->pci_dev, 1, 0x1000000,
-            PCI_BASE_ADDRESS_MEM_PREFETCH, platform_mmio_map);
+    platform_mmio_setup(d);
+    pci_register_bar_region(&d->pci_dev, 1,
+                            PCI_BASE_ADDRESS_MEM_PREFETCH, &d->mmio_bar);
 
     platform_fixed_ioport_init(d);
 
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 51/56] msix: convert to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:15   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

The msix table is defined as a subregion, to allow for a BAR that
mixes device specific regions with the msix table.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/ivshmem.c    |   11 +++++----
 hw/msix.c       |   64 +++++++++++++++++++------------------------------------
 hw/msix.h       |    6 +---
 hw/pci.h        |    2 +-
 hw/virtio-pci.c |   16 ++++++++-----
 hw/virtio-pci.h |    1 +
 6 files changed, 42 insertions(+), 58 deletions(-)

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index e028b19..77695a8 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -65,6 +65,7 @@ typedef struct IVShmemState {
      */
     MemoryRegion bar;
     MemoryRegion ivshmem;
+    MemoryRegion msix_bar;
     uint64_t ivshmem_size; /* size of shared memory region */
     int shm_fd; /* shared memory file descriptor */
 
@@ -540,11 +541,11 @@ static void ivshmem_setup_msi(IVShmemState * s) {
 
     /* allocate the MSI-X vectors */
 
-    if (!msix_init(&s->dev, s->vectors, 1, 0)) {
-        pci_register_bar(&s->dev, 1,
-                         msix_bar_size(&s->dev),
-                         PCI_BASE_ADDRESS_SPACE_MEMORY,
-                         msix_mmio_map);
+    memory_region_init(&s->msix_bar, "ivshmem-msix", 4096);
+    if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) {
+        pci_register_bar_region(&s->dev, 1,
+                                PCI_BASE_ADDRESS_SPACE_MEMORY,
+                                &s->msix_bar);
         IVSHMEM_DPRINTF("msix initialized (%d vectors)\n", s->vectors);
     } else {
         IVSHMEM_DPRINTF("msix initialization failed\n");
diff --git a/hw/msix.c b/hw/msix.c
index 03d7bec..c69f6d1 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -82,7 +82,8 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,
     return 0;
 }
 
-static uint32_t msix_mmio_readl(void *opaque, target_phys_addr_t addr)
+static uint64_t msix_mmio_read(void *opaque, target_phys_addr_t addr,
+                               unsigned size)
 {
     PCIDevice *dev = opaque;
     unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3;
@@ -91,12 +92,6 @@ static uint32_t msix_mmio_readl(void *opaque, target_phys_addr_t addr)
     return pci_get_long(page + offset);
 }
 
-static uint32_t msix_mmio_read_unallowed(void *opaque, target_phys_addr_t addr)
-{
-    fprintf(stderr, "MSI-X: only dword read is allowed!\n");
-    return 0;
-}
-
 static uint8_t msix_pending_mask(int vector)
 {
     return 1 << (vector % 8);
@@ -169,8 +164,8 @@ void msix_write_config(PCIDevice *dev, uint32_t addr,
     }
 }
 
-static void msix_mmio_writel(void *opaque, target_phys_addr_t addr,
-                             uint32_t val)
+static void msix_mmio_write(void *opaque, target_phys_addr_t addr,
+                            uint64_t val, unsigned size)
 {
     PCIDevice *dev = opaque;
     unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3;
@@ -179,37 +174,25 @@ static void msix_mmio_writel(void *opaque, target_phys_addr_t addr,
     msix_handle_mask_update(dev, vector);
 }
 
-static void msix_mmio_write_unallowed(void *opaque, target_phys_addr_t addr,
-                                      uint32_t val)
-{
-    fprintf(stderr, "MSI-X: only dword write is allowed!\n");
-}
-
-static CPUWriteMemoryFunc * const msix_mmio_write[] = {
-    msix_mmio_write_unallowed, msix_mmio_write_unallowed, msix_mmio_writel
-};
-
-static CPUReadMemoryFunc * const msix_mmio_read[] = {
-    msix_mmio_read_unallowed, msix_mmio_read_unallowed, msix_mmio_readl
+static MemoryRegionOps msix_mmio_ops = {
+    .read = msix_mmio_read,
+    .write = msix_mmio_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
 };
 
-/* Should be called from device's map method. */
-void msix_mmio_map(PCIDevice *d, int region_num,
-                   pcibus_t addr, pcibus_t size, int type)
+static void msix_mmio_setup(PCIDevice *d, MemoryRegion *bar)
 {
     uint8_t *config = d->config + d->msix_cap;
     uint32_t table = pci_get_long(config + PCI_MSIX_TABLE);
     uint32_t offset = table & ~(MSIX_PAGE_SIZE - 1);
     /* TODO: for assigned devices, we'll want to make it possible to map
      * pending bits separately in case they are in a separate bar. */
-    int table_bir = table & PCI_MSIX_FLAGS_BIRMASK;
 
-    if (table_bir != region_num)
-        return;
-    if (size <= offset)
-        return;
-    cpu_register_physical_memory(addr + offset, size - offset,
-                                 d->msix_mmio_index);
+    memory_region_add_subregion(bar, offset, &d->msix_mmio);
 }
 
 static void msix_mask_all(struct PCIDevice *dev, unsigned nentries)
@@ -225,6 +208,7 @@ static void msix_mask_all(struct PCIDevice *dev, unsigned nentries)
 /* Initialize the MSI-X structures. Note: if MSI-X is supported, BAR size is
  * modified, it should be retrieved with msix_bar_size. */
 int msix_init(struct PCIDevice *dev, unsigned short nentries,
+              MemoryRegion *bar,
               unsigned bar_nr, unsigned bar_size)
 {
     int ret;
@@ -241,13 +225,8 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries,
     dev->msix_table_page = qemu_mallocz(MSIX_PAGE_SIZE);
     msix_mask_all(dev, nentries);
 
-    dev->msix_mmio_index = cpu_register_io_memory(msix_mmio_read,
-                                                  msix_mmio_write, dev,
-                                                  DEVICE_NATIVE_ENDIAN);
-    if (dev->msix_mmio_index == -1) {
-        ret = -EBUSY;
-        goto err_index;
-    }
+    memory_region_init_io(&dev->msix_mmio, &msix_mmio_ops, dev,
+                          "msix", MSIX_PAGE_SIZE);
 
     dev->msix_entries_nr = nentries;
     ret = msix_add_config(dev, nentries, bar_nr, bar_size);
@@ -255,12 +234,12 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries,
         goto err_config;
 
     dev->cap_present |= QEMU_PCI_CAP_MSIX;
+    msix_mmio_setup(dev, bar);
     return 0;
 
 err_config:
     dev->msix_entries_nr = 0;
-    cpu_unregister_io_memory(dev->msix_mmio_index);
-err_index:
+    memory_region_destroy(&dev->msix_mmio);
     qemu_free(dev->msix_table_page);
     dev->msix_table_page = NULL;
     qemu_free(dev->msix_entry_used);
@@ -279,7 +258,7 @@ static void msix_free_irq_entries(PCIDevice *dev)
 }
 
 /* Clean up resources for the device. */
-int msix_uninit(PCIDevice *dev)
+int msix_uninit(PCIDevice *dev, MemoryRegion *bar)
 {
     if (!(dev->cap_present & QEMU_PCI_CAP_MSIX))
         return 0;
@@ -287,7 +266,8 @@ int msix_uninit(PCIDevice *dev)
     dev->msix_cap = 0;
     msix_free_irq_entries(dev);
     dev->msix_entries_nr = 0;
-    cpu_unregister_io_memory(dev->msix_mmio_index);
+    memory_region_del_subregion(bar, &dev->msix_mmio);
+    memory_region_destroy(&dev->msix_mmio);
     qemu_free(dev->msix_table_page);
     dev->msix_table_page = NULL;
     qemu_free(dev->msix_entry_used);
diff --git a/hw/msix.h b/hw/msix.h
index a9f7993..7e04336 100644
--- a/hw/msix.h
+++ b/hw/msix.h
@@ -5,15 +5,13 @@
 #include "pci.h"
 
 int msix_init(PCIDevice *pdev, unsigned short nentries,
+              MemoryRegion *bar,
               unsigned bar_nr, unsigned bar_size);
 
 void msix_write_config(PCIDevice *pci_dev, uint32_t address,
                        uint32_t val, int len);
 
-void msix_mmio_map(PCIDevice *pci_dev, int region_num,
-                   pcibus_t addr, pcibus_t size, int type);
-
-int msix_uninit(PCIDevice *d);
+int msix_uninit(PCIDevice *d, MemoryRegion *bar);
 
 void msix_save(PCIDevice *dev, QEMUFile *f);
 void msix_load(PCIDevice *dev, QEMUFile *f);
diff --git a/hw/pci.h b/hw/pci.h
index 928e96c..a95e2ad 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -176,7 +176,7 @@ struct PCIDevice {
     /* Space to store MSIX table */
     uint8_t *msix_table_page;
     /* MMIO index used to map MSIX table and pending bit entries. */
-    int msix_mmio_index;
+    MemoryRegion msix_mmio;
     /* Reference-count for entries actually in use by driver. */
     unsigned *msix_entry_used;
     /* Region including the MSI-X table */
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 20e6c5b..9aaac67 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -665,11 +665,12 @@ void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
     pci_set_word(config + 0x2e, vdev->device_id);
     config[0x3d] = 1;
 
-    if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors, 1, 0)) {
-        pci_register_bar(&proxy->pci_dev, 1,
-                         msix_bar_size(&proxy->pci_dev),
-                         PCI_BASE_ADDRESS_SPACE_MEMORY,
-                         msix_mmio_map);
+    memory_region_init(&proxy->msix_bar, "virtio-msix", 4096);
+    if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors,
+                                     &proxy->msix_bar, 1, 0)) {
+        pci_register_bar_region(&proxy->pci_dev, 1,
+                                PCI_BASE_ADDRESS_SPACE_MEMORY,
+                                &proxy->msix_bar);
     } else
         vdev->nvectors = 0;
 
@@ -717,9 +718,12 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev)
 static int virtio_exit_pci(PCIDevice *pci_dev)
 {
     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+    int r;
 
     memory_region_destroy(&proxy->bar);
-    return msix_uninit(pci_dev);
+    r = msix_uninit(pci_dev, &proxy->msix_bar);
+    memory_region_destroy(&proxy->msix_bar);
+    return r;
 }
 
 static int virtio_blk_exit_pci(PCIDevice *pci_dev)
diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
index d17e5fc..628466f 100644
--- a/hw/virtio-pci.h
+++ b/hw/virtio-pci.h
@@ -22,6 +22,7 @@ typedef struct {
     PCIDevice pci_dev;
     VirtIODevice *vdev;
     MemoryRegion bar;
+    MemoryRegion msix_bar;
     uint32_t flags;
     uint32_t class_code;
     uint32_t nvectors;
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 51/56] msix: convert to memory API
@ 2011-07-10 18:15   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

The msix table is defined as a subregion, to allow for a BAR that
mixes device specific regions with the msix table.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/ivshmem.c    |   11 +++++----
 hw/msix.c       |   64 +++++++++++++++++++------------------------------------
 hw/msix.h       |    6 +---
 hw/pci.h        |    2 +-
 hw/virtio-pci.c |   16 ++++++++-----
 hw/virtio-pci.h |    1 +
 6 files changed, 42 insertions(+), 58 deletions(-)

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index e028b19..77695a8 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -65,6 +65,7 @@ typedef struct IVShmemState {
      */
     MemoryRegion bar;
     MemoryRegion ivshmem;
+    MemoryRegion msix_bar;
     uint64_t ivshmem_size; /* size of shared memory region */
     int shm_fd; /* shared memory file descriptor */
 
@@ -540,11 +541,11 @@ static void ivshmem_setup_msi(IVShmemState * s) {
 
     /* allocate the MSI-X vectors */
 
-    if (!msix_init(&s->dev, s->vectors, 1, 0)) {
-        pci_register_bar(&s->dev, 1,
-                         msix_bar_size(&s->dev),
-                         PCI_BASE_ADDRESS_SPACE_MEMORY,
-                         msix_mmio_map);
+    memory_region_init(&s->msix_bar, "ivshmem-msix", 4096);
+    if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) {
+        pci_register_bar_region(&s->dev, 1,
+                                PCI_BASE_ADDRESS_SPACE_MEMORY,
+                                &s->msix_bar);
         IVSHMEM_DPRINTF("msix initialized (%d vectors)\n", s->vectors);
     } else {
         IVSHMEM_DPRINTF("msix initialization failed\n");
diff --git a/hw/msix.c b/hw/msix.c
index 03d7bec..c69f6d1 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -82,7 +82,8 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,
     return 0;
 }
 
-static uint32_t msix_mmio_readl(void *opaque, target_phys_addr_t addr)
+static uint64_t msix_mmio_read(void *opaque, target_phys_addr_t addr,
+                               unsigned size)
 {
     PCIDevice *dev = opaque;
     unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3;
@@ -91,12 +92,6 @@ static uint32_t msix_mmio_readl(void *opaque, target_phys_addr_t addr)
     return pci_get_long(page + offset);
 }
 
-static uint32_t msix_mmio_read_unallowed(void *opaque, target_phys_addr_t addr)
-{
-    fprintf(stderr, "MSI-X: only dword read is allowed!\n");
-    return 0;
-}
-
 static uint8_t msix_pending_mask(int vector)
 {
     return 1 << (vector % 8);
@@ -169,8 +164,8 @@ void msix_write_config(PCIDevice *dev, uint32_t addr,
     }
 }
 
-static void msix_mmio_writel(void *opaque, target_phys_addr_t addr,
-                             uint32_t val)
+static void msix_mmio_write(void *opaque, target_phys_addr_t addr,
+                            uint64_t val, unsigned size)
 {
     PCIDevice *dev = opaque;
     unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3;
@@ -179,37 +174,25 @@ static void msix_mmio_writel(void *opaque, target_phys_addr_t addr,
     msix_handle_mask_update(dev, vector);
 }
 
-static void msix_mmio_write_unallowed(void *opaque, target_phys_addr_t addr,
-                                      uint32_t val)
-{
-    fprintf(stderr, "MSI-X: only dword write is allowed!\n");
-}
-
-static CPUWriteMemoryFunc * const msix_mmio_write[] = {
-    msix_mmio_write_unallowed, msix_mmio_write_unallowed, msix_mmio_writel
-};
-
-static CPUReadMemoryFunc * const msix_mmio_read[] = {
-    msix_mmio_read_unallowed, msix_mmio_read_unallowed, msix_mmio_readl
+static MemoryRegionOps msix_mmio_ops = {
+    .read = msix_mmio_read,
+    .write = msix_mmio_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
 };
 
-/* Should be called from device's map method. */
-void msix_mmio_map(PCIDevice *d, int region_num,
-                   pcibus_t addr, pcibus_t size, int type)
+static void msix_mmio_setup(PCIDevice *d, MemoryRegion *bar)
 {
     uint8_t *config = d->config + d->msix_cap;
     uint32_t table = pci_get_long(config + PCI_MSIX_TABLE);
     uint32_t offset = table & ~(MSIX_PAGE_SIZE - 1);
     /* TODO: for assigned devices, we'll want to make it possible to map
      * pending bits separately in case they are in a separate bar. */
-    int table_bir = table & PCI_MSIX_FLAGS_BIRMASK;
 
-    if (table_bir != region_num)
-        return;
-    if (size <= offset)
-        return;
-    cpu_register_physical_memory(addr + offset, size - offset,
-                                 d->msix_mmio_index);
+    memory_region_add_subregion(bar, offset, &d->msix_mmio);
 }
 
 static void msix_mask_all(struct PCIDevice *dev, unsigned nentries)
@@ -225,6 +208,7 @@ static void msix_mask_all(struct PCIDevice *dev, unsigned nentries)
 /* Initialize the MSI-X structures. Note: if MSI-X is supported, BAR size is
  * modified, it should be retrieved with msix_bar_size. */
 int msix_init(struct PCIDevice *dev, unsigned short nentries,
+              MemoryRegion *bar,
               unsigned bar_nr, unsigned bar_size)
 {
     int ret;
@@ -241,13 +225,8 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries,
     dev->msix_table_page = qemu_mallocz(MSIX_PAGE_SIZE);
     msix_mask_all(dev, nentries);
 
-    dev->msix_mmio_index = cpu_register_io_memory(msix_mmio_read,
-                                                  msix_mmio_write, dev,
-                                                  DEVICE_NATIVE_ENDIAN);
-    if (dev->msix_mmio_index == -1) {
-        ret = -EBUSY;
-        goto err_index;
-    }
+    memory_region_init_io(&dev->msix_mmio, &msix_mmio_ops, dev,
+                          "msix", MSIX_PAGE_SIZE);
 
     dev->msix_entries_nr = nentries;
     ret = msix_add_config(dev, nentries, bar_nr, bar_size);
@@ -255,12 +234,12 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries,
         goto err_config;
 
     dev->cap_present |= QEMU_PCI_CAP_MSIX;
+    msix_mmio_setup(dev, bar);
     return 0;
 
 err_config:
     dev->msix_entries_nr = 0;
-    cpu_unregister_io_memory(dev->msix_mmio_index);
-err_index:
+    memory_region_destroy(&dev->msix_mmio);
     qemu_free(dev->msix_table_page);
     dev->msix_table_page = NULL;
     qemu_free(dev->msix_entry_used);
@@ -279,7 +258,7 @@ static void msix_free_irq_entries(PCIDevice *dev)
 }
 
 /* Clean up resources for the device. */
-int msix_uninit(PCIDevice *dev)
+int msix_uninit(PCIDevice *dev, MemoryRegion *bar)
 {
     if (!(dev->cap_present & QEMU_PCI_CAP_MSIX))
         return 0;
@@ -287,7 +266,8 @@ int msix_uninit(PCIDevice *dev)
     dev->msix_cap = 0;
     msix_free_irq_entries(dev);
     dev->msix_entries_nr = 0;
-    cpu_unregister_io_memory(dev->msix_mmio_index);
+    memory_region_del_subregion(bar, &dev->msix_mmio);
+    memory_region_destroy(&dev->msix_mmio);
     qemu_free(dev->msix_table_page);
     dev->msix_table_page = NULL;
     qemu_free(dev->msix_entry_used);
diff --git a/hw/msix.h b/hw/msix.h
index a9f7993..7e04336 100644
--- a/hw/msix.h
+++ b/hw/msix.h
@@ -5,15 +5,13 @@
 #include "pci.h"
 
 int msix_init(PCIDevice *pdev, unsigned short nentries,
+              MemoryRegion *bar,
               unsigned bar_nr, unsigned bar_size);
 
 void msix_write_config(PCIDevice *pci_dev, uint32_t address,
                        uint32_t val, int len);
 
-void msix_mmio_map(PCIDevice *pci_dev, int region_num,
-                   pcibus_t addr, pcibus_t size, int type);
-
-int msix_uninit(PCIDevice *d);
+int msix_uninit(PCIDevice *d, MemoryRegion *bar);
 
 void msix_save(PCIDevice *dev, QEMUFile *f);
 void msix_load(PCIDevice *dev, QEMUFile *f);
diff --git a/hw/pci.h b/hw/pci.h
index 928e96c..a95e2ad 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -176,7 +176,7 @@ struct PCIDevice {
     /* Space to store MSIX table */
     uint8_t *msix_table_page;
     /* MMIO index used to map MSIX table and pending bit entries. */
-    int msix_mmio_index;
+    MemoryRegion msix_mmio;
     /* Reference-count for entries actually in use by driver. */
     unsigned *msix_entry_used;
     /* Region including the MSI-X table */
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 20e6c5b..9aaac67 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -665,11 +665,12 @@ void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
     pci_set_word(config + 0x2e, vdev->device_id);
     config[0x3d] = 1;
 
-    if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors, 1, 0)) {
-        pci_register_bar(&proxy->pci_dev, 1,
-                         msix_bar_size(&proxy->pci_dev),
-                         PCI_BASE_ADDRESS_SPACE_MEMORY,
-                         msix_mmio_map);
+    memory_region_init(&proxy->msix_bar, "virtio-msix", 4096);
+    if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors,
+                                     &proxy->msix_bar, 1, 0)) {
+        pci_register_bar_region(&proxy->pci_dev, 1,
+                                PCI_BASE_ADDRESS_SPACE_MEMORY,
+                                &proxy->msix_bar);
     } else
         vdev->nvectors = 0;
 
@@ -717,9 +718,12 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev)
 static int virtio_exit_pci(PCIDevice *pci_dev)
 {
     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+    int r;
 
     memory_region_destroy(&proxy->bar);
-    return msix_uninit(pci_dev);
+    r = msix_uninit(pci_dev, &proxy->msix_bar);
+    memory_region_destroy(&proxy->msix_bar);
+    return r;
 }
 
 static int virtio_blk_exit_pci(PCIDevice *pci_dev)
diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
index d17e5fc..628466f 100644
--- a/hw/virtio-pci.h
+++ b/hw/virtio-pci.h
@@ -22,6 +22,7 @@ typedef struct {
     PCIDevice pci_dev;
     VirtIODevice *vdev;
     MemoryRegion bar;
+    MemoryRegion msix_bar;
     uint32_t flags;
     uint32_t class_code;
     uint32_t nvectors;
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 52/56] pci: remove pci_register_bar_simple()
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:15   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Superceded by pci_register_bar_region().

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pci.c |   16 ----------------
 hw/pci.h |    2 --
 2 files changed, 0 insertions(+), 18 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 980840f..9db6fc8 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -923,13 +923,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
     }
 }
 
-static void pci_simple_bar_mapfunc(PCIDevice *pci_dev, int region_num,
-                                   pcibus_t addr, pcibus_t size, int type)
-{
-    cpu_register_physical_memory(addr, size,
-                                 pci_dev->io_regions[region_num].ram_addr);
-}
-
 static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num,
                                           pcibus_t addr, pcibus_t size,
                                           int type)
@@ -942,15 +935,6 @@ static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num,
                                         1);
 }
 
-void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
-                             pcibus_t size,  uint8_t attr, ram_addr_t ram_addr)
-{
-    pci_register_bar(pci_dev, region_num, size,
-                     PCI_BASE_ADDRESS_SPACE_MEMORY | attr,
-                     pci_simple_bar_mapfunc);
-    pci_dev->io_regions[region_num].ram_addr = ram_addr;
-}
-
 void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
                              uint8_t attr, MemoryRegion *memory)
 {
diff --git a/hw/pci.h b/hw/pci.h
index a95e2ad..5209964 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -204,8 +204,6 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
 void pci_register_bar(PCIDevice *pci_dev, int region_num,
                             pcibus_t size, uint8_t type,
                             PCIMapIORegionFunc *map_func);
-void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
-                             pcibus_t size, uint8_t attr, ram_addr_t ram_addr);
 void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
                              uint8_t attr, MemoryRegion *memory);
 pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num);
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 52/56] pci: remove pci_register_bar_simple()
@ 2011-07-10 18:15   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Superceded by pci_register_bar_region().

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pci.c |   16 ----------------
 hw/pci.h |    2 --
 2 files changed, 0 insertions(+), 18 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 980840f..9db6fc8 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -923,13 +923,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
     }
 }
 
-static void pci_simple_bar_mapfunc(PCIDevice *pci_dev, int region_num,
-                                   pcibus_t addr, pcibus_t size, int type)
-{
-    cpu_register_physical_memory(addr, size,
-                                 pci_dev->io_regions[region_num].ram_addr);
-}
-
 static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num,
                                           pcibus_t addr, pcibus_t size,
                                           int type)
@@ -942,15 +935,6 @@ static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num,
                                         1);
 }
 
-void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
-                             pcibus_t size,  uint8_t attr, ram_addr_t ram_addr)
-{
-    pci_register_bar(pci_dev, region_num, size,
-                     PCI_BASE_ADDRESS_SPACE_MEMORY | attr,
-                     pci_simple_bar_mapfunc);
-    pci_dev->io_regions[region_num].ram_addr = ram_addr;
-}
-
 void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
                              uint8_t attr, MemoryRegion *memory)
 {
diff --git a/hw/pci.h b/hw/pci.h
index a95e2ad..5209964 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -204,8 +204,6 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
 void pci_register_bar(PCIDevice *pci_dev, int region_num,
                             pcibus_t size, uint8_t type,
                             PCIMapIORegionFunc *map_func);
-void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
-                             pcibus_t size, uint8_t attr, ram_addr_t ram_addr);
 void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
                              uint8_t attr, MemoryRegion *memory);
 pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num);
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 53/56] pci: convert pci rom to memory API
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:15   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pci.c |   20 +++++++-------------
 hw/pci.h |    3 ++-
 2 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 9db6fc8..8c7a418 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1858,11 +1858,6 @@ 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);
-}
-
 /* Patch the PCI vendor and device ids in a PCI rom image if necessary.
    This is needed for an option rom which is used for more than one device. */
 static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, int size)
@@ -1966,9 +1961,9 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
         snprintf(name, sizeof(name), "%s.rom", pdev->qdev.info->vmsd->name);
     else
         snprintf(name, sizeof(name), "%s.rom", pdev->qdev.info->name);
-    pdev->rom_offset = qemu_ram_alloc(&pdev->qdev, name, size);
-
-    ptr = qemu_get_ram_ptr(pdev->rom_offset);
+    pdev->has_rom = true;
+    memory_region_init_ram(&pdev->rom, &pdev->qdev, name, size);
+    ptr = memory_region_get_ram_ptr(&pdev->rom);
     load_image(path, ptr);
     qemu_free(path);
 
@@ -1979,19 +1974,18 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
 
     qemu_put_ram_ptr(ptr);
 
-    pci_register_bar(pdev, PCI_ROM_SLOT, size,
-                     0, pci_map_option_rom);
+    pci_register_bar_region(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
 
     return 0;
 }
 
 static void pci_del_option_rom(PCIDevice *pdev)
 {
-    if (!pdev->rom_offset)
+    if (!pdev->has_rom)
         return;
 
-    qemu_ram_free(pdev->rom_offset);
-    pdev->rom_offset = 0;
+    memory_region_destroy(&pdev->rom);
+    pdev->has_rom = false;
 }
 
 /*
diff --git a/hw/pci.h b/hw/pci.h
index 5209964..c5174bd 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -192,7 +192,8 @@ struct PCIDevice {
 
     /* Location of option rom */
     char *romfile;
-    ram_addr_t rom_offset;
+    bool has_rom;
+    MemoryRegion rom;
     uint32_t rom_bar;
 };
 
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 53/56] pci: convert pci rom to memory API
@ 2011-07-10 18:15   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pci.c |   20 +++++++-------------
 hw/pci.h |    3 ++-
 2 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 9db6fc8..8c7a418 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1858,11 +1858,6 @@ 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);
-}
-
 /* Patch the PCI vendor and device ids in a PCI rom image if necessary.
    This is needed for an option rom which is used for more than one device. */
 static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, int size)
@@ -1966,9 +1961,9 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
         snprintf(name, sizeof(name), "%s.rom", pdev->qdev.info->vmsd->name);
     else
         snprintf(name, sizeof(name), "%s.rom", pdev->qdev.info->name);
-    pdev->rom_offset = qemu_ram_alloc(&pdev->qdev, name, size);
-
-    ptr = qemu_get_ram_ptr(pdev->rom_offset);
+    pdev->has_rom = true;
+    memory_region_init_ram(&pdev->rom, &pdev->qdev, name, size);
+    ptr = memory_region_get_ram_ptr(&pdev->rom);
     load_image(path, ptr);
     qemu_free(path);
 
@@ -1979,19 +1974,18 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
 
     qemu_put_ram_ptr(ptr);
 
-    pci_register_bar(pdev, PCI_ROM_SLOT, size,
-                     0, pci_map_option_rom);
+    pci_register_bar_region(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
 
     return 0;
 }
 
 static void pci_del_option_rom(PCIDevice *pdev)
 {
-    if (!pdev->rom_offset)
+    if (!pdev->has_rom)
         return;
 
-    qemu_ram_free(pdev->rom_offset);
-    pdev->rom_offset = 0;
+    memory_region_destroy(&pdev->rom);
+    pdev->has_rom = false;
 }
 
 /*
diff --git a/hw/pci.h b/hw/pci.h
index 5209964..c5174bd 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -192,7 +192,8 @@ struct PCIDevice {
 
     /* Location of option rom */
     char *romfile;
-    ram_addr_t rom_offset;
+    bool has_rom;
+    MemoryRegion rom;
     uint32_t rom_bar;
 };
 
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 54/56] pci: remove pci_register_bar()
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:15   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Superceded by pci_register_bar_region().  The implementations
are folded together.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pci.c |   42 +++++++++++++++++-------------------------
 hw/pci.h |    3 ---
 2 files changed, 17 insertions(+), 28 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 8c7a418..2543ced 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -881,13 +881,25 @@ static int pci_unregister_device(DeviceState *dev)
     return 0;
 }
 
-void pci_register_bar(PCIDevice *pci_dev, int region_num,
-                            pcibus_t size, uint8_t type,
-                            PCIMapIORegionFunc *map_func)
+static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num,
+                                          pcibus_t addr, pcibus_t size,
+                                          int type)
+{
+    PCIIORegion *r = &pci_dev->io_regions[region_num];
+
+    memory_region_add_subregion_overlap(r->address_space,
+                                        addr,
+                                        r->memory,
+                                        1);
+}
+
+void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
+                             uint8_t type, MemoryRegion *memory)
 {
     PCIIORegion *r;
     uint32_t addr;
     uint64_t wmask;
+    pcibus_t size = memory_region_size(memory);
 
     assert(region_num >= 0);
     assert(region_num < PCI_NUM_REGIONS);
@@ -902,7 +914,7 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
     r->size = size;
     r->filtered_size = size;
     r->type = type;
-    r->map_func = map_func;
+    r->map_func = pci_simple_bar_mapfunc_region;
     r->ram_addr = IO_MEM_UNASSIGNED;
     r->memory = NULL;
 
@@ -921,29 +933,9 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
         pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff);
         pci_set_long(pci_dev->cmask + addr, 0xffffffff);
     }
-}
-
-static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num,
-                                          pcibus_t addr, pcibus_t size,
-                                          int type)
-{
-    PCIIORegion *r = &pci_dev->io_regions[region_num];
-
-    memory_region_add_subregion_overlap(r->address_space,
-                                        addr,
-                                        r->memory,
-                                        1);
-}
-
-void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
-                             uint8_t attr, MemoryRegion *memory)
-{
-    pci_register_bar(pci_dev, region_num, memory_region_size(memory),
-                     attr,
-                     pci_simple_bar_mapfunc_region);
     pci_dev->io_regions[region_num].memory = memory;
     pci_dev->io_regions[region_num].address_space
-        = attr & PCI_BASE_ADDRESS_SPACE_IO
+        = type & PCI_BASE_ADDRESS_SPACE_IO
         ? pci_dev->bus->address_space_io
         : pci_dev->bus->address_space_mem;
 }
diff --git a/hw/pci.h b/hw/pci.h
index c5174bd..3751b13 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -202,9 +202,6 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
                                PCIConfigReadFunc *config_read,
                                PCIConfigWriteFunc *config_write);
 
-void pci_register_bar(PCIDevice *pci_dev, int region_num,
-                            pcibus_t size, uint8_t type,
-                            PCIMapIORegionFunc *map_func);
 void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
                              uint8_t attr, MemoryRegion *memory);
 pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num);
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 54/56] pci: remove pci_register_bar()
@ 2011-07-10 18:15   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Superceded by pci_register_bar_region().  The implementations
are folded together.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pci.c |   42 +++++++++++++++++-------------------------
 hw/pci.h |    3 ---
 2 files changed, 17 insertions(+), 28 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 8c7a418..2543ced 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -881,13 +881,25 @@ static int pci_unregister_device(DeviceState *dev)
     return 0;
 }
 
-void pci_register_bar(PCIDevice *pci_dev, int region_num,
-                            pcibus_t size, uint8_t type,
-                            PCIMapIORegionFunc *map_func)
+static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num,
+                                          pcibus_t addr, pcibus_t size,
+                                          int type)
+{
+    PCIIORegion *r = &pci_dev->io_regions[region_num];
+
+    memory_region_add_subregion_overlap(r->address_space,
+                                        addr,
+                                        r->memory,
+                                        1);
+}
+
+void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
+                             uint8_t type, MemoryRegion *memory)
 {
     PCIIORegion *r;
     uint32_t addr;
     uint64_t wmask;
+    pcibus_t size = memory_region_size(memory);
 
     assert(region_num >= 0);
     assert(region_num < PCI_NUM_REGIONS);
@@ -902,7 +914,7 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
     r->size = size;
     r->filtered_size = size;
     r->type = type;
-    r->map_func = map_func;
+    r->map_func = pci_simple_bar_mapfunc_region;
     r->ram_addr = IO_MEM_UNASSIGNED;
     r->memory = NULL;
 
@@ -921,29 +933,9 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
         pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff);
         pci_set_long(pci_dev->cmask + addr, 0xffffffff);
     }
-}
-
-static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num,
-                                          pcibus_t addr, pcibus_t size,
-                                          int type)
-{
-    PCIIORegion *r = &pci_dev->io_regions[region_num];
-
-    memory_region_add_subregion_overlap(r->address_space,
-                                        addr,
-                                        r->memory,
-                                        1);
-}
-
-void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
-                             uint8_t attr, MemoryRegion *memory)
-{
-    pci_register_bar(pci_dev, region_num, memory_region_size(memory),
-                     attr,
-                     pci_simple_bar_mapfunc_region);
     pci_dev->io_regions[region_num].memory = memory;
     pci_dev->io_regions[region_num].address_space
-        = attr & PCI_BASE_ADDRESS_SPACE_IO
+        = type & PCI_BASE_ADDRESS_SPACE_IO
         ? pci_dev->bus->address_space_io
         : pci_dev->bus->address_space_mem;
 }
diff --git a/hw/pci.h b/hw/pci.h
index c5174bd..3751b13 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -202,9 +202,6 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
                                PCIConfigReadFunc *config_read,
                                PCIConfigWriteFunc *config_write);
 
-void pci_register_bar(PCIDevice *pci_dev, int region_num,
-                            pcibus_t size, uint8_t type,
-                            PCIMapIORegionFunc *map_func);
 void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
                              uint8_t attr, MemoryRegion *memory);
 pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num);
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 55/56] pci: fold BAR mapping function into its caller
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:15   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

There is only one function, so no need for a function pointer.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pci.c |   25 +++++++++----------------
 hw/pci.h |    1 -
 2 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 2543ced..04b6372 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -881,18 +881,6 @@ static int pci_unregister_device(DeviceState *dev)
     return 0;
 }
 
-static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num,
-                                          pcibus_t addr, pcibus_t size,
-                                          int type)
-{
-    PCIIORegion *r = &pci_dev->io_regions[region_num];
-
-    memory_region_add_subregion_overlap(r->address_space,
-                                        addr,
-                                        r->memory,
-                                        1);
-}
-
 void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
                              uint8_t type, MemoryRegion *memory)
 {
@@ -914,7 +902,6 @@ void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
     r->size = size;
     r->filtered_size = size;
     r->type = type;
-    r->map_func = pci_simple_bar_mapfunc_region;
     r->ram_addr = IO_MEM_UNASSIGNED;
     r->memory = NULL;
 
@@ -1103,10 +1090,16 @@ static void pci_update_mappings(PCIDevice *d)
              * addr & (size - 1) != 0.
              */
             if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
-                r->map_func(d, i, r->addr, r->filtered_size, r->type);
+                memory_region_add_subregion_overlap(r->address_space,
+                                                    r->addr,
+                                                    r->memory,
+                                                    1);
             } else {
-                r->map_func(d, i, pci_to_cpu_addr(d->bus, r->addr),
-                            r->filtered_size, r->type);
+                memory_region_add_subregion_overlap(r->address_space,
+                                                    pci_to_cpu_addr(d->bus,
+                                                                    r->addr),
+                                                    r->memory,
+                                                    1);
             }
         }
     }
diff --git a/hw/pci.h b/hw/pci.h
index 3751b13..274d719 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -92,7 +92,6 @@ typedef struct PCIIORegion {
     pcibus_t size;
     pcibus_t filtered_size;
     uint8_t type;
-    PCIMapIORegionFunc *map_func;
     ram_addr_t ram_addr;
     MemoryRegion *memory;
     MemoryRegion *address_space;
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 55/56] pci: fold BAR mapping function into its caller
@ 2011-07-10 18:15   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

There is only one function, so no need for a function pointer.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/pci.c |   25 +++++++++----------------
 hw/pci.h |    1 -
 2 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 2543ced..04b6372 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -881,18 +881,6 @@ static int pci_unregister_device(DeviceState *dev)
     return 0;
 }
 
-static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num,
-                                          pcibus_t addr, pcibus_t size,
-                                          int type)
-{
-    PCIIORegion *r = &pci_dev->io_regions[region_num];
-
-    memory_region_add_subregion_overlap(r->address_space,
-                                        addr,
-                                        r->memory,
-                                        1);
-}
-
 void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
                              uint8_t type, MemoryRegion *memory)
 {
@@ -914,7 +902,6 @@ void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
     r->size = size;
     r->filtered_size = size;
     r->type = type;
-    r->map_func = pci_simple_bar_mapfunc_region;
     r->ram_addr = IO_MEM_UNASSIGNED;
     r->memory = NULL;
 
@@ -1103,10 +1090,16 @@ static void pci_update_mappings(PCIDevice *d)
              * addr & (size - 1) != 0.
              */
             if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
-                r->map_func(d, i, r->addr, r->filtered_size, r->type);
+                memory_region_add_subregion_overlap(r->address_space,
+                                                    r->addr,
+                                                    r->memory,
+                                                    1);
             } else {
-                r->map_func(d, i, pci_to_cpu_addr(d->bus, r->addr),
-                            r->filtered_size, r->type);
+                memory_region_add_subregion_overlap(r->address_space,
+                                                    pci_to_cpu_addr(d->bus,
+                                                                    r->addr),
+                                                    r->memory,
+                                                    1);
             }
         }
     }
diff --git a/hw/pci.h b/hw/pci.h
index 3751b13..274d719 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -92,7 +92,6 @@ typedef struct PCIIORegion {
     pcibus_t size;
     pcibus_t filtered_size;
     uint8_t type;
-    PCIMapIORegionFunc *map_func;
     ram_addr_t ram_addr;
     MemoryRegion *memory;
     MemoryRegion *address_space;
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [RFC v3 56/56] pci: rename pci_register_bar_region() to pci_register_bar()
  2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
@ 2011-07-10 18:15   ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/ac97.c         |    4 ++--
 hw/cirrus_vga.c   |    5 ++---
 hw/e1000.c        |    5 ++---
 hw/eepro100.c     |    7 +++----
 hw/es1370.c       |    2 +-
 hw/ide/cmd646.c   |   14 +++++---------
 hw/ide/ich.c      |    2 +-
 hw/ide/piix.c     |    3 +--
 hw/ide/via.c      |    3 +--
 hw/intel-hda.c    |    2 +-
 hw/ivshmem.c      |   15 +++++++--------
 hw/lsi53c895a.c   |    7 +++----
 hw/macio.c        |    3 +--
 hw/ne2000.c       |    2 +-
 hw/openpic.c      |    4 ++--
 hw/pci.c          |    6 +++---
 hw/pci.h          |    4 ++--
 hw/pcnet-pci.c    |    4 ++--
 hw/qxl.c          |   16 ++++++++--------
 hw/rtl8139.c      |    6 ++----
 hw/sun4u.c        |    6 ++----
 hw/usb-ehci.c     |    2 +-
 hw/usb-ohci.c     |    2 +-
 hw/usb-uhci.c     |    3 +--
 hw/vga-pci.c      |    3 +--
 hw/virtio-pci.c   |    9 ++++-----
 hw/vmware_vga.c   |    8 ++++----
 hw/wdt_i6300esb.c |    2 +-
 hw/xen_platform.c |    7 +++----
 29 files changed, 68 insertions(+), 88 deletions(-)

diff --git a/hw/ac97.c b/hw/ac97.c
index 72a0667..2089030 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -1352,8 +1352,8 @@ static int ac97_initfn (PCIDevice *dev)
     memory_region_init_io(&s->io_nam, &ac97_io_nam_ops, s, "ac97-nam", 1024);
     memory_region_init_io(&s->io_nabm, &ac97_io_nabm_ops, s, "ac97-nabm", 256);
 
-    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nam);
-    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nabm);
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nam);
+    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nabm);
     qemu_register_reset (ac97_on_reset, s);
     AUD_register_card ("ac97", &s->card);
     ac97_on_reset (s);
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 3fac365..7160584 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2951,10 +2951,9 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
      /* memory #0 LFB */
      /* memory #1 memory-mapped I/O */
      /* XXX: s->vga.vram_size must be a power of two */
-     pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH,
-                             &s->pci_bar);
+     pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->pci_bar);
      if (device_id == CIRRUS_ID_CLGD5446) {
-         pci_register_bar_region(&d->dev, 1, 0, &s->cirrus_mmio_io);
+         pci_register_bar(&d->dev, 1, 0, &s->cirrus_mmio_io);
      }
      return 0;
 }
diff --git a/hw/e1000.c b/hw/e1000.c
index 8e4830f..218d21a 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1158,10 +1158,9 @@ static int pci_e1000_init(PCIDevice *pci_dev)
 
     e1000_mmio_setup(d);
 
-    pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                            &d->mmio);
+    pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
 
-    pci_register_bar_region(&d->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->io);
+    pci_register_bar(&d->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->io);
 
     memmove(d->eeprom_data, e1000_eeprom_template,
         sizeof e1000_eeprom_template);
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 7b4171f..80b9480 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1879,15 +1879,14 @@ static int e100_nic_init(PCIDevice *pci_dev)
     /* Handler for memory-mapped I/O */
     memory_region_init_io(&s->mmio_bar, &eepro100_ops, s, "eepro100-mmio",
                           PCI_MEM_SIZE);
-    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH,
-                            &s->mmio_bar);
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->mmio_bar);
     memory_region_init_io(&s->io_bar, &eepro100_ops, s, "eepro100-io",
                           PCI_IO_SIZE);
-    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
+    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
     /* FIXME: flash aliases to mmio?! */
     memory_region_init_io(&s->flash_bar, &eepro100_ops, s, "eepro100-flash",
                           PCI_FLASH_SIZE);
-    pci_register_bar_region(&s->dev, 2, 0, &s->flash_bar);
+    pci_register_bar(&s->dev, 2, 0, &s->flash_bar);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     logout("macaddr: %s\n", nic_dump(&s->conf.macaddr.a[0], 6));
diff --git a/hw/es1370.c b/hw/es1370.c
index a696eb2..c814817 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -1026,7 +1026,7 @@ static int es1370_initfn (PCIDevice *dev)
     c[PCI_MAX_LAT] = 0x80;
 
     memory_region_init_io(&s->io, &es1370_io_ops, s, "es1370", 256);
-    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
     qemu_register_reset (es1370_on_reset, s);
 
     AUD_register_card ("es1370", &s->card);
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 699ad6b..904febb 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -270,16 +270,12 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
 
     setup_cmd646_bar(d, 0);
     setup_cmd646_bar(d, 1);
-    pci_register_bar_region(dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
-                            &d->cmd646_bar[0].data);
-    pci_register_bar_region(dev, 1, PCI_BASE_ADDRESS_SPACE_IO,
-                            &d->cmd646_bar[0].cmd);
-    pci_register_bar_region(dev, 2, PCI_BASE_ADDRESS_SPACE_IO,
-                            &d->cmd646_bar[1].data);
-    pci_register_bar_region(dev, 3, PCI_BASE_ADDRESS_SPACE_IO,
-                            &d->cmd646_bar[2].cmd);
+    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].data);
+    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].cmd);
+    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[1].data);
+    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[2].cmd);
     bmdma_setup_bar(d);
-    pci_register_bar_region(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
+    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
 
     /* TODO: RST# value should be 0 */
     pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 7e497c3..d5207e5 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -93,7 +93,7 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
     msi_init(dev, 0x50, 1, true, false);
     d->ahci.irq = d->card.irq[0];
 
-    pci_register_bar_region(&d->card, 5, 0, &d->ahci.mem);
+    pci_register_bar(&d->card, 5, 0, &d->ahci.mem);
 
     return 0;
 }
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index c11b960..cba46b8 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -155,8 +155,7 @@ static int pci_piix_ide_initfn(PCIDevice *dev)
     qemu_register_reset(piix3_reset, d);
 
     bmdma_setup_bar(d);
-    pci_register_bar_region(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO,
-                            &d->bmdma_bar);
+    pci_register_bar(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
 
     vmstate_register(&d->dev.qdev, 0, &vmstate_ide_pci, d);
 
diff --git a/hw/ide/via.c b/hw/ide/via.c
index eb6a409..c0b9d43 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -180,8 +180,7 @@ static int vt82c686b_ide_initfn(PCIDevice *dev)
 
     qemu_register_reset(via_reset, d);
     bmdma_setup_bar(d);
-    pci_register_bar_region(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO,
-                            &d->bmdma_bar);
+    pci_register_bar(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
 
     vmstate_register(&dev->qdev, 0, &vmstate_ide_pci, d);
 
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 0f5c6c4..35e55bc 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -1165,7 +1165,7 @@ static int intel_hda_init(PCIDevice *pci)
 
     memory_region_init_io(&d->mmio, &intel_hda_mmio_ops, d,
                           "intel-hda", 0x4000);
-    pci_register_bar_region(&d->pci, 0, 0, &d->mmio);
+    pci_register_bar(&d->pci, 0, 0, &d->mmio);
     if (d->msi) {
         msi_init(&d->pci, 0x50, 1, true, false);
     }
diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 77695a8..4467a47 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -336,7 +336,7 @@ static void create_shared_memory_BAR(IVShmemState *s, int fd) {
     memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
 
     /* region for shared memory */
-    pci_register_bar_region(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
+    pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
 }
 
 static void close_guest_eventfds(IVShmemState *s, int posn)
@@ -543,9 +543,8 @@ static void ivshmem_setup_msi(IVShmemState * s) {
 
     memory_region_init(&s->msix_bar, "ivshmem-msix", 4096);
     if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) {
-        pci_register_bar_region(&s->dev, 1,
-                                PCI_BASE_ADDRESS_SPACE_MEMORY,
-                                &s->msix_bar);
+        pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                         &s->msix_bar);
         IVSHMEM_DPRINTF("msix initialized (%d vectors)\n", s->vectors);
     } else {
         IVSHMEM_DPRINTF("msix initialization failed\n");
@@ -665,8 +664,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
     }
 
     /* region for registers*/
-    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                            &s->ivshmem_mmio);
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                     &s->ivshmem_mmio);
 
     memory_region_init(&s->bar, "ivshmem-bar2-container", s->ivshmem_size);
 
@@ -694,8 +693,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
         /* allocate/initialize space for interrupt handling */
         s->peers = qemu_mallocz(s->nb_peers * sizeof(Peer));
 
-        pci_register_bar_region(&s->dev, 2,
-                                PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ivshmem);
+        pci_register_bar(&s->dev, 2,
+                         PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ivshmem);
 
         s->eventfd_chr = qemu_mallocz(s->vectors * sizeof(CharDriverState *));
 
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index a433920..e614dea 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -2124,10 +2124,9 @@ static int lsi_scsi_init(PCIDevice *dev)
     memory_region_init_io(&s->ram_io, &lsi_ram_ops, s, "lsi-ram", 0x2000);
     memory_region_init_io(&s->io_io, &lsi_io_ops, s, "lsi-io", 256);
 
-    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_io);
-    pci_register_bar_region(&s->dev, 1, 0, &s->mmio_io);
-    pci_register_bar_region(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                            &s->ram_io);
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_io);
+    pci_register_bar(&s->dev, 1, 0, &s->mmio_io);
+    pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ram_io);
     QTAILQ_INIT(&s->queue);
 
     scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, &lsi_scsi_ops);
diff --git a/hw/macio.c b/hw/macio.c
index 71fa2a8..cc6ae40 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -111,6 +111,5 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld,
     d->config[0x3d] = 0x01; // interrupt on pin 1
 
     macio_bar_setup(macio_state);
-    pci_register_bar_region(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                            &macio_state->bar);
+    pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &macio_state->bar);
 }
diff --git a/hw/ne2000.c b/hw/ne2000.c
index ba20dc2..572ceab 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -754,7 +754,7 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
 
     s = &d->ne2000;
     ne2000_setup_io(s, 0x100);
-    pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
+    pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
     s->irq = d->dev.irq[0];
 
     qemu_macaddr_default_if_unset(&s->c.macaddr);
diff --git a/hw/openpic.c b/hw/openpic.c
index fd1ffba..8f72f4b 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -1177,8 +1177,8 @@ qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus,
 #endif
 
         /* Register I/O spaces */
-        pci_register_bar_region(&opp->pci_dev, 0,
-                                PCI_BASE_ADDRESS_SPACE_MEMORY, &opp->mem);
+        pci_register_bar(&opp->pci_dev, 0,
+                         PCI_BASE_ADDRESS_SPACE_MEMORY, &opp->mem);
     } else {
         opp = qemu_mallocz(sizeof(openpic_t));
         memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000);
diff --git a/hw/pci.c b/hw/pci.c
index 04b6372..d507845 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -881,8 +881,8 @@ static int pci_unregister_device(DeviceState *dev)
     return 0;
 }
 
-void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
-                             uint8_t type, MemoryRegion *memory)
+void pci_register_bar(PCIDevice *pci_dev, int region_num,
+                      uint8_t type, MemoryRegion *memory)
 {
     PCIIORegion *r;
     uint32_t addr;
@@ -1959,7 +1959,7 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
 
     qemu_put_ram_ptr(ptr);
 
-    pci_register_bar_region(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
+    pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
 
     return 0;
 }
diff --git a/hw/pci.h b/hw/pci.h
index 274d719..6ff4fdd 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -201,8 +201,8 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
                                PCIConfigReadFunc *config_read,
                                PCIConfigWriteFunc *config_write);
 
-void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
-                             uint8_t attr, MemoryRegion *memory);
+void pci_register_bar(PCIDevice *pci_dev, int region_num,
+                      uint8_t attr, MemoryRegion *memory);
 pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num);
 
 int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index fad0722..ece45c9 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -319,9 +319,9 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
 
     memory_region_init_io(&d->io_bar, &pcnet_io_ops, d, "pcnet-io",
                           PCNET_IOPORT_SIZE);
-    pci_register_bar_region(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->io_bar);
+    pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->io_bar);
 
-    pci_register_bar_region(pci_dev, 1, 0, &s->mmio);
+    pci_register_bar(pci_dev, 1, 0, &s->mmio);
 
     s->irq = pci_dev->irq[0];
     s->phys_mem_read = pci_physical_memory_read;
diff --git a/hw/qxl.c b/hw/qxl.c
index da323f6..569529d 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1220,17 +1220,17 @@ static int qxl_init_common(PCIQXLDevice *qxl)
     }
 
 
-    pci_register_bar_region(&qxl->pci, QXL_IO_RANGE_INDEX,
-                            PCI_BASE_ADDRESS_SPACE_IO, &qxl->io_bar);
+    pci_register_bar(&qxl->pci, QXL_IO_RANGE_INDEX,
+                     PCI_BASE_ADDRESS_SPACE_IO, &qxl->io_bar);
 
-    pci_register_bar_region(&qxl->pci, QXL_ROM_RANGE_INDEX,
-                            PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->rom_bar);
+    pci_register_bar(&qxl->pci, QXL_ROM_RANGE_INDEX,
+                     PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->rom_bar);
 
-    pci_register_bar_region(&qxl->pci, QXL_RAM_RANGE_INDEX,
-                            PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vga.vram);
+    pci_register_bar(&qxl->pci, QXL_RAM_RANGE_INDEX,
+                     PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vga.vram);
 
-    pci_register_bar_region(&qxl->pci, QXL_VRAM_RANGE_INDEX,
-                            PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vram_bar);
+    pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX,
+                     PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vram_bar);
 
     qxl->ssd.qxl.base.sif = &qxl_interface.base;
     qxl->ssd.qxl.id = qxl->id;
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index fa661fc..e425463 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3397,10 +3397,8 @@ static int pci_rtl8139_init(PCIDevice *dev)
 
     memory_region_init_io(&s->bar_io, &rtl8139_io_ops, s, "rtl8139", 0x100);
     memory_region_init_io(&s->bar_mem, &rtl8139_io_ops, s, "rtl8139", 0x100);
-    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
-                            &s->bar_io);
-    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                            &s->bar_mem);
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->bar_io);
+    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar_mem);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 74a06a8..160c004 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -554,11 +554,9 @@ pci_ebus_init1(PCIDevice *pci_dev)
     pci_dev->config[0x0D] = 0x0a; // latency_timer
 
     isa_mmio_setup(&s->bar0, 0x1000000);
-    pci_register_bar_region(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                            &s->bar0);
+    pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar0);
     isa_mmio_setup(&s->bar1, 0x800000);
-    pci_register_bar_region(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                            &s->bar1);
+    pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar1);
     return 0;
 }
 
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index bd7fdcb..c433795 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -2224,7 +2224,7 @@ static int usb_ehci_initfn(PCIDevice *dev)
     qemu_register_reset(ehci_reset, s);
 
     memory_region_init_io(&s->mem, &ehci_mem_ops, s, "ehci", MMIO_SIZE);
-    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);
 
     fprintf(stderr, "*** EHCI support is under development ***\n");
 
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 36885cb..50c8e69 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1759,7 +1759,7 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev)
     ohci->state.irq = ohci->pci_dev.irq[0];
 
     /* TODO: avoid cast below by using dev */
-    pci_register_bar_region(&ohci->pci_dev, 0, 0, &ohci->state.mem);
+    pci_register_bar(&ohci->pci_dev, 0, 0, &ohci->state.mem);
     return 0;
 }
 
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 95ef260..1602a58 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1160,8 +1160,7 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
     memory_region_init_io(&s->io_bar, &uhci_ioport_ops, s, "uhci", 0x20);
     /* Use region 4 for consistency with real hardware.  BSD guests seem
        to rely on this.  */
-    pci_register_bar_region(&s->dev, 4,
-                            PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
+    pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
 
     return 0;
 }
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index 7062c4d..c67be0a 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -60,8 +60,7 @@ static int pci_vga_initfn(PCIDevice *dev)
                                   s->screen_dump, s->text_update, s);
 
      /* XXX: VGA_RAM_SIZE must be a power of two */
-     pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH,
-                             &s->vram);
+     pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
 
      if (!dev->rom_bar) {
          /* compatibility with pc-0.13 and older */
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 9aaac67..5e4ccbe 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -668,9 +668,8 @@ void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
     memory_region_init(&proxy->msix_bar, "virtio-msix", 4096);
     if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors,
                                      &proxy->msix_bar, 1, 0)) {
-        pci_register_bar_region(&proxy->pci_dev, 1,
-                                PCI_BASE_ADDRESS_SPACE_MEMORY,
-                                &proxy->msix_bar);
+        pci_register_bar(&proxy->pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                         &proxy->msix_bar);
     } else
         vdev->nvectors = 0;
 
@@ -682,8 +681,8 @@ void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
 
     memory_region_init_io(&proxy->bar, &virtio_pci_config_ops, proxy,
                           "virtio-pci", size);
-    pci_register_bar_region(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
-                            &proxy->bar);
+    pci_register_bar(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
+                     &proxy->bar);
 
     if (!kvm_has_many_ioeventfds()) {
         proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index feb7197..baff423 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1315,13 +1315,13 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
 
     memory_region_init_io(&s->io_bar, &vmsvga_io_ops, &s->chip,
                           "vmsvga-io", 0x10);
-    pci_register_bar_region(&s->card, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
+    pci_register_bar(&s->card, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
 
     vmsvga_init(&s->chip, VGA_RAM_SIZE);
 
-    pci_register_bar_region(&s->card, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, iomem);
-    pci_register_bar_region(&s->card, 2, PCI_BASE_ADDRESS_MEM_PREFETCH,
-                            &s->chip.fifo_ram);
+    pci_register_bar(&s->card, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, iomem);
+    pci_register_bar(&s->card, 2, PCI_BASE_ADDRESS_MEM_PREFETCH,
+                     &s->chip.fifo_ram);
 
     if (!dev->rom_bar) {
         /* compatibility with pc-0.13 and older */
diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c
index 242a8fa..c9a778c 100644
--- a/hw/wdt_i6300esb.c
+++ b/hw/wdt_i6300esb.c
@@ -421,7 +421,7 @@ static int i6300esb_init(PCIDevice *dev)
     d->previous_reboot_flag = 0;
 
     memory_region_init_io(&d->io_mem, &i6300esb_ops, d, "i6300esb", 0x10);
-    pci_register_bar_region(&d->dev, 0, 0, &d->io_mem);
+    pci_register_bar(&d->dev, 0, 0, &d->io_mem);
     /* qemu_register_coalesced_mmio (addr, 0x10); ? */
 
     return 0;
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
index b5da08f..d23a621 100644
--- a/hw/xen_platform.c
+++ b/hw/xen_platform.c
@@ -345,13 +345,12 @@ static int xen_platform_initfn(PCIDevice *dev)
     pci_conf[PCI_INTERRUPT_PIN] = 1;
 
     platform_ioport_bar_setup(d);
-    pci_register_bar_region(&d->pci_dev, 0,
-                            PCI_BASE_ADDRESS_SPACE_IO, &d->bar);
+    pci_register_bar(&d->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->bar);
 
     /* reserve 16MB mmio address for share memory*/
     platform_mmio_setup(d);
-    pci_register_bar_region(&d->pci_dev, 1,
-                            PCI_BASE_ADDRESS_MEM_PREFETCH, &d->mmio_bar);
+    pci_register_bar(&d->pci_dev, 1, PCI_BASE_ADDRESS_MEM_PREFETCH,
+                     &d->mmio_bar);
 
     platform_fixed_ioport_init(d);
 
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* [Qemu-devel] [RFC v3 56/56] pci: rename pci_register_bar_region() to pci_register_bar()
@ 2011-07-10 18:15   ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-10 18:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/ac97.c         |    4 ++--
 hw/cirrus_vga.c   |    5 ++---
 hw/e1000.c        |    5 ++---
 hw/eepro100.c     |    7 +++----
 hw/es1370.c       |    2 +-
 hw/ide/cmd646.c   |   14 +++++---------
 hw/ide/ich.c      |    2 +-
 hw/ide/piix.c     |    3 +--
 hw/ide/via.c      |    3 +--
 hw/intel-hda.c    |    2 +-
 hw/ivshmem.c      |   15 +++++++--------
 hw/lsi53c895a.c   |    7 +++----
 hw/macio.c        |    3 +--
 hw/ne2000.c       |    2 +-
 hw/openpic.c      |    4 ++--
 hw/pci.c          |    6 +++---
 hw/pci.h          |    4 ++--
 hw/pcnet-pci.c    |    4 ++--
 hw/qxl.c          |   16 ++++++++--------
 hw/rtl8139.c      |    6 ++----
 hw/sun4u.c        |    6 ++----
 hw/usb-ehci.c     |    2 +-
 hw/usb-ohci.c     |    2 +-
 hw/usb-uhci.c     |    3 +--
 hw/vga-pci.c      |    3 +--
 hw/virtio-pci.c   |    9 ++++-----
 hw/vmware_vga.c   |    8 ++++----
 hw/wdt_i6300esb.c |    2 +-
 hw/xen_platform.c |    7 +++----
 29 files changed, 68 insertions(+), 88 deletions(-)

diff --git a/hw/ac97.c b/hw/ac97.c
index 72a0667..2089030 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -1352,8 +1352,8 @@ static int ac97_initfn (PCIDevice *dev)
     memory_region_init_io(&s->io_nam, &ac97_io_nam_ops, s, "ac97-nam", 1024);
     memory_region_init_io(&s->io_nabm, &ac97_io_nabm_ops, s, "ac97-nabm", 256);
 
-    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nam);
-    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nabm);
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nam);
+    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nabm);
     qemu_register_reset (ac97_on_reset, s);
     AUD_register_card ("ac97", &s->card);
     ac97_on_reset (s);
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 3fac365..7160584 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2951,10 +2951,9 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
      /* memory #0 LFB */
      /* memory #1 memory-mapped I/O */
      /* XXX: s->vga.vram_size must be a power of two */
-     pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH,
-                             &s->pci_bar);
+     pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->pci_bar);
      if (device_id == CIRRUS_ID_CLGD5446) {
-         pci_register_bar_region(&d->dev, 1, 0, &s->cirrus_mmio_io);
+         pci_register_bar(&d->dev, 1, 0, &s->cirrus_mmio_io);
      }
      return 0;
 }
diff --git a/hw/e1000.c b/hw/e1000.c
index 8e4830f..218d21a 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1158,10 +1158,9 @@ static int pci_e1000_init(PCIDevice *pci_dev)
 
     e1000_mmio_setup(d);
 
-    pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                            &d->mmio);
+    pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
 
-    pci_register_bar_region(&d->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->io);
+    pci_register_bar(&d->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->io);
 
     memmove(d->eeprom_data, e1000_eeprom_template,
         sizeof e1000_eeprom_template);
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 7b4171f..80b9480 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1879,15 +1879,14 @@ static int e100_nic_init(PCIDevice *pci_dev)
     /* Handler for memory-mapped I/O */
     memory_region_init_io(&s->mmio_bar, &eepro100_ops, s, "eepro100-mmio",
                           PCI_MEM_SIZE);
-    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH,
-                            &s->mmio_bar);
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->mmio_bar);
     memory_region_init_io(&s->io_bar, &eepro100_ops, s, "eepro100-io",
                           PCI_IO_SIZE);
-    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
+    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
     /* FIXME: flash aliases to mmio?! */
     memory_region_init_io(&s->flash_bar, &eepro100_ops, s, "eepro100-flash",
                           PCI_FLASH_SIZE);
-    pci_register_bar_region(&s->dev, 2, 0, &s->flash_bar);
+    pci_register_bar(&s->dev, 2, 0, &s->flash_bar);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     logout("macaddr: %s\n", nic_dump(&s->conf.macaddr.a[0], 6));
diff --git a/hw/es1370.c b/hw/es1370.c
index a696eb2..c814817 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -1026,7 +1026,7 @@ static int es1370_initfn (PCIDevice *dev)
     c[PCI_MAX_LAT] = 0x80;
 
     memory_region_init_io(&s->io, &es1370_io_ops, s, "es1370", 256);
-    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
     qemu_register_reset (es1370_on_reset, s);
 
     AUD_register_card ("es1370", &s->card);
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 699ad6b..904febb 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -270,16 +270,12 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
 
     setup_cmd646_bar(d, 0);
     setup_cmd646_bar(d, 1);
-    pci_register_bar_region(dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
-                            &d->cmd646_bar[0].data);
-    pci_register_bar_region(dev, 1, PCI_BASE_ADDRESS_SPACE_IO,
-                            &d->cmd646_bar[0].cmd);
-    pci_register_bar_region(dev, 2, PCI_BASE_ADDRESS_SPACE_IO,
-                            &d->cmd646_bar[1].data);
-    pci_register_bar_region(dev, 3, PCI_BASE_ADDRESS_SPACE_IO,
-                            &d->cmd646_bar[2].cmd);
+    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].data);
+    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].cmd);
+    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[1].data);
+    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[2].cmd);
     bmdma_setup_bar(d);
-    pci_register_bar_region(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
+    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
 
     /* TODO: RST# value should be 0 */
     pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 7e497c3..d5207e5 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -93,7 +93,7 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
     msi_init(dev, 0x50, 1, true, false);
     d->ahci.irq = d->card.irq[0];
 
-    pci_register_bar_region(&d->card, 5, 0, &d->ahci.mem);
+    pci_register_bar(&d->card, 5, 0, &d->ahci.mem);
 
     return 0;
 }
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index c11b960..cba46b8 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -155,8 +155,7 @@ static int pci_piix_ide_initfn(PCIDevice *dev)
     qemu_register_reset(piix3_reset, d);
 
     bmdma_setup_bar(d);
-    pci_register_bar_region(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO,
-                            &d->bmdma_bar);
+    pci_register_bar(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
 
     vmstate_register(&d->dev.qdev, 0, &vmstate_ide_pci, d);
 
diff --git a/hw/ide/via.c b/hw/ide/via.c
index eb6a409..c0b9d43 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -180,8 +180,7 @@ static int vt82c686b_ide_initfn(PCIDevice *dev)
 
     qemu_register_reset(via_reset, d);
     bmdma_setup_bar(d);
-    pci_register_bar_region(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO,
-                            &d->bmdma_bar);
+    pci_register_bar(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
 
     vmstate_register(&dev->qdev, 0, &vmstate_ide_pci, d);
 
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 0f5c6c4..35e55bc 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -1165,7 +1165,7 @@ static int intel_hda_init(PCIDevice *pci)
 
     memory_region_init_io(&d->mmio, &intel_hda_mmio_ops, d,
                           "intel-hda", 0x4000);
-    pci_register_bar_region(&d->pci, 0, 0, &d->mmio);
+    pci_register_bar(&d->pci, 0, 0, &d->mmio);
     if (d->msi) {
         msi_init(&d->pci, 0x50, 1, true, false);
     }
diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 77695a8..4467a47 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -336,7 +336,7 @@ static void create_shared_memory_BAR(IVShmemState *s, int fd) {
     memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
 
     /* region for shared memory */
-    pci_register_bar_region(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
+    pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
 }
 
 static void close_guest_eventfds(IVShmemState *s, int posn)
@@ -543,9 +543,8 @@ static void ivshmem_setup_msi(IVShmemState * s) {
 
     memory_region_init(&s->msix_bar, "ivshmem-msix", 4096);
     if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) {
-        pci_register_bar_region(&s->dev, 1,
-                                PCI_BASE_ADDRESS_SPACE_MEMORY,
-                                &s->msix_bar);
+        pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                         &s->msix_bar);
         IVSHMEM_DPRINTF("msix initialized (%d vectors)\n", s->vectors);
     } else {
         IVSHMEM_DPRINTF("msix initialization failed\n");
@@ -665,8 +664,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
     }
 
     /* region for registers*/
-    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                            &s->ivshmem_mmio);
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                     &s->ivshmem_mmio);
 
     memory_region_init(&s->bar, "ivshmem-bar2-container", s->ivshmem_size);
 
@@ -694,8 +693,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
         /* allocate/initialize space for interrupt handling */
         s->peers = qemu_mallocz(s->nb_peers * sizeof(Peer));
 
-        pci_register_bar_region(&s->dev, 2,
-                                PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ivshmem);
+        pci_register_bar(&s->dev, 2,
+                         PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ivshmem);
 
         s->eventfd_chr = qemu_mallocz(s->vectors * sizeof(CharDriverState *));
 
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index a433920..e614dea 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -2124,10 +2124,9 @@ static int lsi_scsi_init(PCIDevice *dev)
     memory_region_init_io(&s->ram_io, &lsi_ram_ops, s, "lsi-ram", 0x2000);
     memory_region_init_io(&s->io_io, &lsi_io_ops, s, "lsi-io", 256);
 
-    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_io);
-    pci_register_bar_region(&s->dev, 1, 0, &s->mmio_io);
-    pci_register_bar_region(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                            &s->ram_io);
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_io);
+    pci_register_bar(&s->dev, 1, 0, &s->mmio_io);
+    pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ram_io);
     QTAILQ_INIT(&s->queue);
 
     scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, &lsi_scsi_ops);
diff --git a/hw/macio.c b/hw/macio.c
index 71fa2a8..cc6ae40 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -111,6 +111,5 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld,
     d->config[0x3d] = 0x01; // interrupt on pin 1
 
     macio_bar_setup(macio_state);
-    pci_register_bar_region(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                            &macio_state->bar);
+    pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &macio_state->bar);
 }
diff --git a/hw/ne2000.c b/hw/ne2000.c
index ba20dc2..572ceab 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -754,7 +754,7 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
 
     s = &d->ne2000;
     ne2000_setup_io(s, 0x100);
-    pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
+    pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
     s->irq = d->dev.irq[0];
 
     qemu_macaddr_default_if_unset(&s->c.macaddr);
diff --git a/hw/openpic.c b/hw/openpic.c
index fd1ffba..8f72f4b 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -1177,8 +1177,8 @@ qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus,
 #endif
 
         /* Register I/O spaces */
-        pci_register_bar_region(&opp->pci_dev, 0,
-                                PCI_BASE_ADDRESS_SPACE_MEMORY, &opp->mem);
+        pci_register_bar(&opp->pci_dev, 0,
+                         PCI_BASE_ADDRESS_SPACE_MEMORY, &opp->mem);
     } else {
         opp = qemu_mallocz(sizeof(openpic_t));
         memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000);
diff --git a/hw/pci.c b/hw/pci.c
index 04b6372..d507845 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -881,8 +881,8 @@ static int pci_unregister_device(DeviceState *dev)
     return 0;
 }
 
-void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
-                             uint8_t type, MemoryRegion *memory)
+void pci_register_bar(PCIDevice *pci_dev, int region_num,
+                      uint8_t type, MemoryRegion *memory)
 {
     PCIIORegion *r;
     uint32_t addr;
@@ -1959,7 +1959,7 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
 
     qemu_put_ram_ptr(ptr);
 
-    pci_register_bar_region(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
+    pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
 
     return 0;
 }
diff --git a/hw/pci.h b/hw/pci.h
index 274d719..6ff4fdd 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -201,8 +201,8 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
                                PCIConfigReadFunc *config_read,
                                PCIConfigWriteFunc *config_write);
 
-void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
-                             uint8_t attr, MemoryRegion *memory);
+void pci_register_bar(PCIDevice *pci_dev, int region_num,
+                      uint8_t attr, MemoryRegion *memory);
 pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num);
 
 int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index fad0722..ece45c9 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -319,9 +319,9 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
 
     memory_region_init_io(&d->io_bar, &pcnet_io_ops, d, "pcnet-io",
                           PCNET_IOPORT_SIZE);
-    pci_register_bar_region(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->io_bar);
+    pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->io_bar);
 
-    pci_register_bar_region(pci_dev, 1, 0, &s->mmio);
+    pci_register_bar(pci_dev, 1, 0, &s->mmio);
 
     s->irq = pci_dev->irq[0];
     s->phys_mem_read = pci_physical_memory_read;
diff --git a/hw/qxl.c b/hw/qxl.c
index da323f6..569529d 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1220,17 +1220,17 @@ static int qxl_init_common(PCIQXLDevice *qxl)
     }
 
 
-    pci_register_bar_region(&qxl->pci, QXL_IO_RANGE_INDEX,
-                            PCI_BASE_ADDRESS_SPACE_IO, &qxl->io_bar);
+    pci_register_bar(&qxl->pci, QXL_IO_RANGE_INDEX,
+                     PCI_BASE_ADDRESS_SPACE_IO, &qxl->io_bar);
 
-    pci_register_bar_region(&qxl->pci, QXL_ROM_RANGE_INDEX,
-                            PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->rom_bar);
+    pci_register_bar(&qxl->pci, QXL_ROM_RANGE_INDEX,
+                     PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->rom_bar);
 
-    pci_register_bar_region(&qxl->pci, QXL_RAM_RANGE_INDEX,
-                            PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vga.vram);
+    pci_register_bar(&qxl->pci, QXL_RAM_RANGE_INDEX,
+                     PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vga.vram);
 
-    pci_register_bar_region(&qxl->pci, QXL_VRAM_RANGE_INDEX,
-                            PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vram_bar);
+    pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX,
+                     PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vram_bar);
 
     qxl->ssd.qxl.base.sif = &qxl_interface.base;
     qxl->ssd.qxl.id = qxl->id;
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index fa661fc..e425463 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3397,10 +3397,8 @@ static int pci_rtl8139_init(PCIDevice *dev)
 
     memory_region_init_io(&s->bar_io, &rtl8139_io_ops, s, "rtl8139", 0x100);
     memory_region_init_io(&s->bar_mem, &rtl8139_io_ops, s, "rtl8139", 0x100);
-    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
-                            &s->bar_io);
-    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                            &s->bar_mem);
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->bar_io);
+    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar_mem);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 74a06a8..160c004 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -554,11 +554,9 @@ pci_ebus_init1(PCIDevice *pci_dev)
     pci_dev->config[0x0D] = 0x0a; // latency_timer
 
     isa_mmio_setup(&s->bar0, 0x1000000);
-    pci_register_bar_region(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                            &s->bar0);
+    pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar0);
     isa_mmio_setup(&s->bar1, 0x800000);
-    pci_register_bar_region(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                            &s->bar1);
+    pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar1);
     return 0;
 }
 
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index bd7fdcb..c433795 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -2224,7 +2224,7 @@ static int usb_ehci_initfn(PCIDevice *dev)
     qemu_register_reset(ehci_reset, s);
 
     memory_region_init_io(&s->mem, &ehci_mem_ops, s, "ehci", MMIO_SIZE);
-    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);
 
     fprintf(stderr, "*** EHCI support is under development ***\n");
 
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 36885cb..50c8e69 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1759,7 +1759,7 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev)
     ohci->state.irq = ohci->pci_dev.irq[0];
 
     /* TODO: avoid cast below by using dev */
-    pci_register_bar_region(&ohci->pci_dev, 0, 0, &ohci->state.mem);
+    pci_register_bar(&ohci->pci_dev, 0, 0, &ohci->state.mem);
     return 0;
 }
 
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 95ef260..1602a58 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1160,8 +1160,7 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
     memory_region_init_io(&s->io_bar, &uhci_ioport_ops, s, "uhci", 0x20);
     /* Use region 4 for consistency with real hardware.  BSD guests seem
        to rely on this.  */
-    pci_register_bar_region(&s->dev, 4,
-                            PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
+    pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
 
     return 0;
 }
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index 7062c4d..c67be0a 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -60,8 +60,7 @@ static int pci_vga_initfn(PCIDevice *dev)
                                   s->screen_dump, s->text_update, s);
 
      /* XXX: VGA_RAM_SIZE must be a power of two */
-     pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH,
-                             &s->vram);
+     pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
 
      if (!dev->rom_bar) {
          /* compatibility with pc-0.13 and older */
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 9aaac67..5e4ccbe 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -668,9 +668,8 @@ void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
     memory_region_init(&proxy->msix_bar, "virtio-msix", 4096);
     if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors,
                                      &proxy->msix_bar, 1, 0)) {
-        pci_register_bar_region(&proxy->pci_dev, 1,
-                                PCI_BASE_ADDRESS_SPACE_MEMORY,
-                                &proxy->msix_bar);
+        pci_register_bar(&proxy->pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
+                         &proxy->msix_bar);
     } else
         vdev->nvectors = 0;
 
@@ -682,8 +681,8 @@ void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
 
     memory_region_init_io(&proxy->bar, &virtio_pci_config_ops, proxy,
                           "virtio-pci", size);
-    pci_register_bar_region(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
-                            &proxy->bar);
+    pci_register_bar(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
+                     &proxy->bar);
 
     if (!kvm_has_many_ioeventfds()) {
         proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index feb7197..baff423 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1315,13 +1315,13 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
 
     memory_region_init_io(&s->io_bar, &vmsvga_io_ops, &s->chip,
                           "vmsvga-io", 0x10);
-    pci_register_bar_region(&s->card, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
+    pci_register_bar(&s->card, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
 
     vmsvga_init(&s->chip, VGA_RAM_SIZE);
 
-    pci_register_bar_region(&s->card, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, iomem);
-    pci_register_bar_region(&s->card, 2, PCI_BASE_ADDRESS_MEM_PREFETCH,
-                            &s->chip.fifo_ram);
+    pci_register_bar(&s->card, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, iomem);
+    pci_register_bar(&s->card, 2, PCI_BASE_ADDRESS_MEM_PREFETCH,
+                     &s->chip.fifo_ram);
 
     if (!dev->rom_bar) {
         /* compatibility with pc-0.13 and older */
diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c
index 242a8fa..c9a778c 100644
--- a/hw/wdt_i6300esb.c
+++ b/hw/wdt_i6300esb.c
@@ -421,7 +421,7 @@ static int i6300esb_init(PCIDevice *dev)
     d->previous_reboot_flag = 0;
 
     memory_region_init_io(&d->io_mem, &i6300esb_ops, d, "i6300esb", 0x10);
-    pci_register_bar_region(&d->dev, 0, 0, &d->io_mem);
+    pci_register_bar(&d->dev, 0, 0, &d->io_mem);
     /* qemu_register_coalesced_mmio (addr, 0x10); ? */
 
     return 0;
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
index b5da08f..d23a621 100644
--- a/hw/xen_platform.c
+++ b/hw/xen_platform.c
@@ -345,13 +345,12 @@ static int xen_platform_initfn(PCIDevice *dev)
     pci_conf[PCI_INTERRUPT_PIN] = 1;
 
     platform_ioport_bar_setup(d);
-    pci_register_bar_region(&d->pci_dev, 0,
-                            PCI_BASE_ADDRESS_SPACE_IO, &d->bar);
+    pci_register_bar(&d->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->bar);
 
     /* reserve 16MB mmio address for share memory*/
     platform_mmio_setup(d);
-    pci_register_bar_region(&d->pci_dev, 1,
-                            PCI_BASE_ADDRESS_MEM_PREFETCH, &d->mmio_bar);
+    pci_register_bar(&d->pci_dev, 1, PCI_BASE_ADDRESS_MEM_PREFETCH,
+                     &d->mmio_bar);
 
     platform_fixed_ioport_init(d);
 
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* Re: [Qemu-devel] [RFC v3 31/56] ac97: convert to memory API
  2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
  (?)
@ 2011-07-10 20:33   ` malc
  2011-07-11  1:42       ` Anthony Liguori
  -1 siblings, 1 reply; 131+ messages in thread
From: malc @ 2011-07-10 20:33 UTC (permalink / raw)
  To: Avi Kivity; +Cc: qemu-devel, kvm

On Sun, 10 Jul 2011, Avi Kivity wrote:

> fixes BAR sizing as well.

I find this patch disgusting, the read and write handlers in particular.

[..snip..]

-- 
mailto:av1474@comtv.ru

^ permalink raw reply	[flat|nested] 131+ messages in thread

* Re: [Qemu-devel] [RFC v3 31/56] ac97: convert to memory API
  2011-07-10 20:33   ` malc
@ 2011-07-11  1:42       ` Anthony Liguori
  0 siblings, 0 replies; 131+ messages in thread
From: Anthony Liguori @ 2011-07-11  1:42 UTC (permalink / raw)
  To: malc; +Cc: Avi Kivity, qemu-devel, kvm

On 07/10/2011 03:33 PM, malc wrote:
> On Sun, 10 Jul 2011, Avi Kivity wrote:
>
>> fixes BAR sizing as well.
>
> I find this patch disgusting, the read and write handlers in particular.

Shouldn't it be possible to do something like:

typedef struct OldMemoryRegionOps {
     MemoryRegionOps parent_ops;
     CPUReadMemoryFunc *readfn[3];
     CPUWriteMemoryFunc *writefn[3];
     void *opaque;
} OldMemoryRegionOps;

That should allow old-style implementations to be converted without 
introducing trampoline functions everywhere.

Regards,

Anthony Liguori

>
> [..snip..]
>


^ permalink raw reply	[flat|nested] 131+ messages in thread

* Re: [Qemu-devel] [RFC v3 31/56] ac97: convert to memory API
@ 2011-07-11  1:42       ` Anthony Liguori
  0 siblings, 0 replies; 131+ messages in thread
From: Anthony Liguori @ 2011-07-11  1:42 UTC (permalink / raw)
  To: malc; +Cc: Avi Kivity, kvm, qemu-devel

On 07/10/2011 03:33 PM, malc wrote:
> On Sun, 10 Jul 2011, Avi Kivity wrote:
>
>> fixes BAR sizing as well.
>
> I find this patch disgusting, the read and write handlers in particular.

Shouldn't it be possible to do something like:

typedef struct OldMemoryRegionOps {
     MemoryRegionOps parent_ops;
     CPUReadMemoryFunc *readfn[3];
     CPUWriteMemoryFunc *writefn[3];
     void *opaque;
} OldMemoryRegionOps;

That should allow old-style implementations to be converted without 
introducing trampoline functions everywhere.

Regards,

Anthony Liguori

>
> [..snip..]
>

^ permalink raw reply	[flat|nested] 131+ messages in thread

* Re: [Qemu-devel] [RFC v3 31/56] ac97: convert to memory API
  2011-07-11  1:42       ` Anthony Liguori
@ 2011-07-11  6:49         ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-11  6:49 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, kvm, malc

> 
> Shouldn't it be possible to do something like:
> 
> typedef struct OldMemoryRegionOps {
> MemoryRegionOps parent_ops;
> CPUReadMemoryFunc *readfn[3];
> CPUWriteMemoryFunc *writefn[3];
> void *opaque;
> } OldMemoryRegionOps;
> 
> That should allow old-style implementations to be converted without
> introducing trampoline functions everywhere.
> 

I should, I'll give it a go.

^ permalink raw reply	[flat|nested] 131+ messages in thread

* Re: [Qemu-devel] [RFC v3 31/56] ac97: convert to memory API
@ 2011-07-11  6:49         ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-11  6:49 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, kvm

> 
> Shouldn't it be possible to do something like:
> 
> typedef struct OldMemoryRegionOps {
> MemoryRegionOps parent_ops;
> CPUReadMemoryFunc *readfn[3];
> CPUWriteMemoryFunc *writefn[3];
> void *opaque;
> } OldMemoryRegionOps;
> 
> That should allow old-style implementations to be converted without
> introducing trampoline functions everywhere.
> 

I should, I'll give it a go.

^ permalink raw reply	[flat|nested] 131+ messages in thread

* Re: [Qemu-devel] [RFC v3 31/56] ac97: convert to memory API
  2011-07-11  1:42       ` Anthony Liguori
@ 2011-07-11 10:47         ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-11 10:47 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: malc, qemu-devel, kvm

On 07/11/2011 04:42 AM, Anthony Liguori wrote:
> On 07/10/2011 03:33 PM, malc wrote:
>> On Sun, 10 Jul 2011, Avi Kivity wrote:
>>
>>> fixes BAR sizing as well.
>>
>> I find this patch disgusting, the read and write handlers in particular.
>
> Shouldn't it be possible to do something like:
>
> typedef struct OldMemoryRegionOps {
>     MemoryRegionOps parent_ops;
>     CPUReadMemoryFunc *readfn[3];
>     CPUWriteMemoryFunc *writefn[3];
>     void *opaque;
> } OldMemoryRegionOps;
>
> That should allow old-style implementations to be converted without 
> introducing trampoline functions everywhere.

Here's a new version:


diff --git a/hw/ac97.c b/hw/ac97.c
index 0b59896..b4f377d 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -160,8 +160,9 @@ typedef struct AC97LinkState {
      SWVoiceIn *voice_mc;
      int invalid_freq[3];
      uint8_t silence[128];
-    uint32_t base[2];
      int bup_flag;
+    MemoryRegion io_nam;
+    MemoryRegion io_nabm;
  } AC97LinkState;

  enum {
@@ -583,7 +584,7 @@ static uint32_t nam_readw (void *opaque, uint32_t addr)
  {
      AC97LinkState *s = opaque;
      uint32_t val = ~0U;
-    uint32_t index = addr - s->base[0];
+    uint32_t index = addr;
      s->cas = 0;
      val = mixer_load (s, index);
      return val;
@@ -611,7 +612,7 @@ static void nam_writeb (void *opaque, uint32_t addr, 
uint32_t val)
  static void nam_writew (void *opaque, uint32_t addr, uint32_t val)
  {
      AC97LinkState *s = opaque;
-    uint32_t index = addr - s->base[0];
+    uint32_t index = addr;
      s->cas = 0;
      switch (index) {
      case AC97_Reset:
@@ -714,7 +715,7 @@ static uint32_t nabm_readb (void *opaque, uint32_t addr)
  {
      AC97LinkState *s = opaque;
      AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
      uint32_t val = ~0U;

      switch (index) {
@@ -769,7 +770,7 @@ static uint32_t nabm_readw (void *opaque, uint32_t addr)
  {
      AC97LinkState *s = opaque;
      AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
      uint32_t val = ~0U;

      switch (index) {
@@ -798,7 +799,7 @@ static uint32_t nabm_readl (void *opaque, uint32_t addr)
  {
      AC97LinkState *s = opaque;
      AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
      uint32_t val = ~0U;

      switch (index) {
@@ -848,7 +849,7 @@ static void nabm_writeb (void *opaque, uint32_t 
addr, uint32_t val)
  {
      AC97LinkState *s = opaque;
      AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
      switch (index) {
      case PI_LVI:
      case PO_LVI:
@@ -904,7 +905,7 @@ static void nabm_writew (void *opaque, uint32_t 
addr, uint32_t val)
  {
      AC97LinkState *s = opaque;
      AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
      switch (index) {
      case PI_SR:
      case PO_SR:
@@ -924,7 +925,7 @@ static void nabm_writel (void *opaque, uint32_t 
addr, uint32_t val)
  {
      AC97LinkState *s = opaque;
      AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
      switch (index) {
      case PI_BDBAR:
      case PO_BDBAR:
@@ -1230,31 +1231,33 @@ static const VMStateDescription vmstate_ac97 = {
      }
  };

-static void ac97_map (PCIDevice *pci_dev, int region_num,
-                      pcibus_t addr, pcibus_t size, int type)
-{
-    AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, pci_dev);
-    PCIDevice *d = &s->dev;
-
-    if (!region_num) {
-        s->base[0] = addr;
-        register_ioport_read (addr, 256 * 1, 1, nam_readb, d);
-        register_ioport_read (addr, 256 * 2, 2, nam_readw, d);
-        register_ioport_read (addr, 256 * 4, 4, nam_readl, d);
-        register_ioport_write (addr, 256 * 1, 1, nam_writeb, d);
-        register_ioport_write (addr, 256 * 2, 2, nam_writew, d);
-        register_ioport_write (addr, 256 * 4, 4, nam_writel, d);
-    }
-    else {
-        s->base[1] = addr;
-        register_ioport_read (addr, 64 * 1, 1, nabm_readb, d);
-        register_ioport_read (addr, 64 * 2, 2, nabm_readw, d);
-        register_ioport_read (addr, 64 * 4, 4, nabm_readl, d);
-        register_ioport_write (addr, 64 * 1, 1, nabm_writeb, d);
-        register_ioport_write (addr, 64 * 2, 2, nabm_writew, d);
-        register_ioport_write (addr, 64 * 4, 4, nabm_writel, d);
-    }
-}
+static const MemoryRegionPortio nam_portio[] = {
+    { 0, 256 * 1, 1, .read = nam_readb, },
+    { 0, 256 * 2, 2, .read = nam_readw, },
+    { 0, 256 * 4, 4, .read = nam_readl, },
+    { 0, 256 * 1, 1, .write = nam_writeb, },
+    { 0, 256 * 2, 2, .write = nam_writew, },
+    { 0, 256 * 4, 4, .write = nam_writel, },
+    PORTIO_END,
+};
+
+static MemoryRegionOps ac97_io_nam_ops = {
+    .old_portio = nam_portio,
+};
+
+static const MemoryRegionPortio nabm_portio[] = {
+    { 0, 64 * 1, 1, .read = nabm_readb, },
+    { 0, 64 * 2, 2, .read = nabm_readw, },
+    { 0, 64 * 4, 4, .read = nabm_readl, },
+    { 0, 64 * 1, 1, .write = nabm_writeb, },
+    { 0, 64 * 2, 2, .write = nabm_writew, },
+    { 0, 64 * 4, 4, .write = nabm_writel, },
+    PORTIO_END
+};
+
+static MemoryRegionOps ac97_io_nabm_ops = {
+    .old_portio = nabm_portio,
+};

  static void ac97_on_reset (void *opaque)
  {
@@ -1311,15 +1314,26 @@ static int ac97_initfn (PCIDevice *dev)
      /* TODO: RST# value should be 0. */
      c[PCI_INTERRUPT_PIN] = 0x01;      /* intr_pn interrupt pin ro */

-    pci_register_bar (&s->dev, 0, 256 * 4, PCI_BASE_ADDRESS_SPACE_IO,
-                      ac97_map);
-    pci_register_bar (&s->dev, 1, 64 * 4, PCI_BASE_ADDRESS_SPACE_IO, 
ac97_map);
+    memory_region_init_io(&s->io_nam, &ac97_io_nam_ops, s, "ac97-nam", 
1024);
+    memory_region_init_io(&s->io_nabm, &ac97_io_nabm_ops, s, 
"ac97-nabm", 256);
+    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, 
&s->io_nam);
+    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, 
&s->io_nabm);
      qemu_register_reset (ac97_on_reset, s);
      AUD_register_card ("ac97", &s->card);
      ac97_on_reset (s);
      return 0;
  }

+static int ac97_exitfn(PCIDevice *dev)
+{
+    AC97LinkState *s = DO_UPCAST(AC97LinkState, dev, dev);
+
+    memory_region_destroy(&s->io_nam);
+    memory_region_destroy(&s->io_nabm);
+    return 0;
+}
+
  int ac97_init (PCIBus *bus)
  {
      pci_create_simple (bus, -1, "AC97");
@@ -1332,6 +1346,7 @@ static PCIDeviceInfo ac97_info = {
      .qdev.size    = sizeof (AC97LinkState),
      .qdev.vmsd    = &vmstate_ac97,
      .init         = ac97_initfn,
+    .exit         = ac97_exitfn,
      .vendor_id    = PCI_VENDOR_ID_INTEL,
      .device_id    = PCI_DEVICE_ID_INTEL_82801AA_5,
      .revision     = 0x01,

Callbacks are registered with an offset/size pair, since many BARs use 
different callbacks for different registers within the BARs.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.


^ permalink raw reply related	[flat|nested] 131+ messages in thread

* Re: [Qemu-devel] [RFC v3 31/56] ac97: convert to memory API
@ 2011-07-11 10:47         ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-11 10:47 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, kvm

On 07/11/2011 04:42 AM, Anthony Liguori wrote:
> On 07/10/2011 03:33 PM, malc wrote:
>> On Sun, 10 Jul 2011, Avi Kivity wrote:
>>
>>> fixes BAR sizing as well.
>>
>> I find this patch disgusting, the read and write handlers in particular.
>
> Shouldn't it be possible to do something like:
>
> typedef struct OldMemoryRegionOps {
>     MemoryRegionOps parent_ops;
>     CPUReadMemoryFunc *readfn[3];
>     CPUWriteMemoryFunc *writefn[3];
>     void *opaque;
> } OldMemoryRegionOps;
>
> That should allow old-style implementations to be converted without 
> introducing trampoline functions everywhere.

Here's a new version:


diff --git a/hw/ac97.c b/hw/ac97.c
index 0b59896..b4f377d 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -160,8 +160,9 @@ typedef struct AC97LinkState {
      SWVoiceIn *voice_mc;
      int invalid_freq[3];
      uint8_t silence[128];
-    uint32_t base[2];
      int bup_flag;
+    MemoryRegion io_nam;
+    MemoryRegion io_nabm;
  } AC97LinkState;

  enum {
@@ -583,7 +584,7 @@ static uint32_t nam_readw (void *opaque, uint32_t addr)
  {
      AC97LinkState *s = opaque;
      uint32_t val = ~0U;
-    uint32_t index = addr - s->base[0];
+    uint32_t index = addr;
      s->cas = 0;
      val = mixer_load (s, index);
      return val;
@@ -611,7 +612,7 @@ static void nam_writeb (void *opaque, uint32_t addr, 
uint32_t val)
  static void nam_writew (void *opaque, uint32_t addr, uint32_t val)
  {
      AC97LinkState *s = opaque;
-    uint32_t index = addr - s->base[0];
+    uint32_t index = addr;
      s->cas = 0;
      switch (index) {
      case AC97_Reset:
@@ -714,7 +715,7 @@ static uint32_t nabm_readb (void *opaque, uint32_t addr)
  {
      AC97LinkState *s = opaque;
      AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
      uint32_t val = ~0U;

      switch (index) {
@@ -769,7 +770,7 @@ static uint32_t nabm_readw (void *opaque, uint32_t addr)
  {
      AC97LinkState *s = opaque;
      AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
      uint32_t val = ~0U;

      switch (index) {
@@ -798,7 +799,7 @@ static uint32_t nabm_readl (void *opaque, uint32_t addr)
  {
      AC97LinkState *s = opaque;
      AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
      uint32_t val = ~0U;

      switch (index) {
@@ -848,7 +849,7 @@ static void nabm_writeb (void *opaque, uint32_t 
addr, uint32_t val)
  {
      AC97LinkState *s = opaque;
      AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
      switch (index) {
      case PI_LVI:
      case PO_LVI:
@@ -904,7 +905,7 @@ static void nabm_writew (void *opaque, uint32_t 
addr, uint32_t val)
  {
      AC97LinkState *s = opaque;
      AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
      switch (index) {
      case PI_SR:
      case PO_SR:
@@ -924,7 +925,7 @@ static void nabm_writel (void *opaque, uint32_t 
addr, uint32_t val)
  {
      AC97LinkState *s = opaque;
      AC97BusMasterRegs *r = NULL;
-    uint32_t index = addr - s->base[1];
+    uint32_t index = addr;
      switch (index) {
      case PI_BDBAR:
      case PO_BDBAR:
@@ -1230,31 +1231,33 @@ static const VMStateDescription vmstate_ac97 = {
      }
  };

-static void ac97_map (PCIDevice *pci_dev, int region_num,
-                      pcibus_t addr, pcibus_t size, int type)
-{
-    AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, pci_dev);
-    PCIDevice *d = &s->dev;
-
-    if (!region_num) {
-        s->base[0] = addr;
-        register_ioport_read (addr, 256 * 1, 1, nam_readb, d);
-        register_ioport_read (addr, 256 * 2, 2, nam_readw, d);
-        register_ioport_read (addr, 256 * 4, 4, nam_readl, d);
-        register_ioport_write (addr, 256 * 1, 1, nam_writeb, d);
-        register_ioport_write (addr, 256 * 2, 2, nam_writew, d);
-        register_ioport_write (addr, 256 * 4, 4, nam_writel, d);
-    }
-    else {
-        s->base[1] = addr;
-        register_ioport_read (addr, 64 * 1, 1, nabm_readb, d);
-        register_ioport_read (addr, 64 * 2, 2, nabm_readw, d);
-        register_ioport_read (addr, 64 * 4, 4, nabm_readl, d);
-        register_ioport_write (addr, 64 * 1, 1, nabm_writeb, d);
-        register_ioport_write (addr, 64 * 2, 2, nabm_writew, d);
-        register_ioport_write (addr, 64 * 4, 4, nabm_writel, d);
-    }
-}
+static const MemoryRegionPortio nam_portio[] = {
+    { 0, 256 * 1, 1, .read = nam_readb, },
+    { 0, 256 * 2, 2, .read = nam_readw, },
+    { 0, 256 * 4, 4, .read = nam_readl, },
+    { 0, 256 * 1, 1, .write = nam_writeb, },
+    { 0, 256 * 2, 2, .write = nam_writew, },
+    { 0, 256 * 4, 4, .write = nam_writel, },
+    PORTIO_END,
+};
+
+static MemoryRegionOps ac97_io_nam_ops = {
+    .old_portio = nam_portio,
+};
+
+static const MemoryRegionPortio nabm_portio[] = {
+    { 0, 64 * 1, 1, .read = nabm_readb, },
+    { 0, 64 * 2, 2, .read = nabm_readw, },
+    { 0, 64 * 4, 4, .read = nabm_readl, },
+    { 0, 64 * 1, 1, .write = nabm_writeb, },
+    { 0, 64 * 2, 2, .write = nabm_writew, },
+    { 0, 64 * 4, 4, .write = nabm_writel, },
+    PORTIO_END
+};
+
+static MemoryRegionOps ac97_io_nabm_ops = {
+    .old_portio = nabm_portio,
+};

  static void ac97_on_reset (void *opaque)
  {
@@ -1311,15 +1314,26 @@ static int ac97_initfn (PCIDevice *dev)
      /* TODO: RST# value should be 0. */
      c[PCI_INTERRUPT_PIN] = 0x01;      /* intr_pn interrupt pin ro */

-    pci_register_bar (&s->dev, 0, 256 * 4, PCI_BASE_ADDRESS_SPACE_IO,
-                      ac97_map);
-    pci_register_bar (&s->dev, 1, 64 * 4, PCI_BASE_ADDRESS_SPACE_IO, 
ac97_map);
+    memory_region_init_io(&s->io_nam, &ac97_io_nam_ops, s, "ac97-nam", 
1024);
+    memory_region_init_io(&s->io_nabm, &ac97_io_nabm_ops, s, 
"ac97-nabm", 256);
+    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, 
&s->io_nam);
+    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, 
&s->io_nabm);
      qemu_register_reset (ac97_on_reset, s);
      AUD_register_card ("ac97", &s->card);
      ac97_on_reset (s);
      return 0;
  }

+static int ac97_exitfn(PCIDevice *dev)
+{
+    AC97LinkState *s = DO_UPCAST(AC97LinkState, dev, dev);
+
+    memory_region_destroy(&s->io_nam);
+    memory_region_destroy(&s->io_nabm);
+    return 0;
+}
+
  int ac97_init (PCIBus *bus)
  {
      pci_create_simple (bus, -1, "AC97");
@@ -1332,6 +1346,7 @@ static PCIDeviceInfo ac97_info = {
      .qdev.size    = sizeof (AC97LinkState),
      .qdev.vmsd    = &vmstate_ac97,
      .init         = ac97_initfn,
+    .exit         = ac97_exitfn,
      .vendor_id    = PCI_VENDOR_ID_INTEL,
      .device_id    = PCI_DEVICE_ID_INTEL_82801AA_5,
      .revision     = 0x01,

Callbacks are registered with an offset/size pair, since many BARs use 
different callbacks for different registers within the BARs.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

^ permalink raw reply related	[flat|nested] 131+ messages in thread

* Re: [Qemu-devel] [RFC v3 31/56] ac97: convert to memory API
  2011-07-11 10:47         ` Avi Kivity
@ 2011-07-11 22:03           ` malc
  -1 siblings, 0 replies; 131+ messages in thread
From: malc @ 2011-07-11 22:03 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Anthony Liguori, qemu-devel, kvm

On Mon, 11 Jul 2011, Avi Kivity wrote:

> On 07/11/2011 04:42 AM, Anthony Liguori wrote:
> > On 07/10/2011 03:33 PM, malc wrote:
> > > On Sun, 10 Jul 2011, Avi Kivity wrote:
> > > 
> > > > fixes BAR sizing as well.
> > > 
> > > I find this patch disgusting, the read and write handlers in particular.
> > 
> > Shouldn't it be possible to do something like:
> > 
> > typedef struct OldMemoryRegionOps {
> >     MemoryRegionOps parent_ops;
> >     CPUReadMemoryFunc *readfn[3];
> >     CPUWriteMemoryFunc *writefn[3];
> >     void *opaque;
> > } OldMemoryRegionOps;
> > 
> > That should allow old-style implementations to be converted without
> > introducing trampoline functions everywhere.
> 
> Here's a new version:

This one looks acceptable[1], original submission said:
"fixes BAR sizing as well." what was wrong with it?

[..snip..] 

P.S. Sans minor inconsistency with trailing commas.

-- 
mailto:av1474@comtv.ru

^ permalink raw reply	[flat|nested] 131+ messages in thread

* Re: [Qemu-devel] [RFC v3 31/56] ac97: convert to memory API
@ 2011-07-11 22:03           ` malc
  0 siblings, 0 replies; 131+ messages in thread
From: malc @ 2011-07-11 22:03 UTC (permalink / raw)
  To: Avi Kivity; +Cc: qemu-devel, kvm

On Mon, 11 Jul 2011, Avi Kivity wrote:

> On 07/11/2011 04:42 AM, Anthony Liguori wrote:
> > On 07/10/2011 03:33 PM, malc wrote:
> > > On Sun, 10 Jul 2011, Avi Kivity wrote:
> > > 
> > > > fixes BAR sizing as well.
> > > 
> > > I find this patch disgusting, the read and write handlers in particular.
> > 
> > Shouldn't it be possible to do something like:
> > 
> > typedef struct OldMemoryRegionOps {
> >     MemoryRegionOps parent_ops;
> >     CPUReadMemoryFunc *readfn[3];
> >     CPUWriteMemoryFunc *writefn[3];
> >     void *opaque;
> > } OldMemoryRegionOps;
> > 
> > That should allow old-style implementations to be converted without
> > introducing trampoline functions everywhere.
> 
> Here's a new version:

This one looks acceptable[1], original submission said:
"fixes BAR sizing as well." what was wrong with it?

[..snip..] 

P.S. Sans minor inconsistency with trailing commas.

-- 
mailto:av1474@comtv.ru

^ permalink raw reply	[flat|nested] 131+ messages in thread

* Re: [Qemu-devel] [RFC v3 31/56] ac97: convert to memory API
  2011-07-11 22:03           ` malc
@ 2011-07-12  7:14             ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-12  7:14 UTC (permalink / raw)
  To: malc; +Cc: Anthony Liguori, qemu-devel, kvm

On 07/12/2011 01:03 AM, malc wrote:
> >
> >  Here's a new version:
>
> This one looks acceptable[1], original submission said:
> "fixes BAR sizing as well." what was wrong with it?

The nabm BAR, for example, was registered as 64 bytes of byte ioports, 
128 bytes of word ioports, and 256 bytes of long ioports.  I expect this 
was an error.

The new patch preserves the error.

> [..snip..]
>
> P.S. Sans minor inconsistency with trailing commas.
>

Where I expect more fields, I leave a trailing comma.  It makes further 
patches nicer.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.


^ permalink raw reply	[flat|nested] 131+ messages in thread

* Re: [Qemu-devel] [RFC v3 31/56] ac97: convert to memory API
@ 2011-07-12  7:14             ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-12  7:14 UTC (permalink / raw)
  To: malc; +Cc: qemu-devel, kvm

On 07/12/2011 01:03 AM, malc wrote:
> >
> >  Here's a new version:
>
> This one looks acceptable[1], original submission said:
> "fixes BAR sizing as well." what was wrong with it?

The nabm BAR, for example, was registered as 64 bytes of byte ioports, 
128 bytes of word ioports, and 256 bytes of long ioports.  I expect this 
was an error.

The new patch preserves the error.

> [..snip..]
>
> P.S. Sans minor inconsistency with trailing commas.
>

Where I expect more fields, I leave a trailing comma.  It makes further 
patches nicer.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

^ permalink raw reply	[flat|nested] 131+ messages in thread

* Re: [RFC v3 30/56] rtl8139: convert to memory API
  2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
@ 2011-07-12 22:41     ` Alex Williamson
  -1 siblings, 0 replies; 131+ messages in thread
From: Alex Williamson @ 2011-07-12 22:41 UTC (permalink / raw)
  To: Avi Kivity; +Cc: qemu-devel, kvm

On Sun, 2011-07-10 at 21:14 +0300, Avi Kivity wrote:
> Signed-off-by: Avi Kivity <avi@redhat.com>
> ---
>  hw/rtl8139.c |  172 +++++++++++++++++-----------------------------------------
>  1 files changed, 51 insertions(+), 121 deletions(-)
> 
> diff --git a/hw/rtl8139.c b/hw/rtl8139.c
> index 5214b8c..fa661fc 100644
> --- a/hw/rtl8139.c
> +++ b/hw/rtl8139.c
> @@ -474,7 +474,6 @@ typedef struct RTL8139State {
>  
>      NICState *nic;
>      NICConf conf;
> -    int rtl8139_mmio_io_addr;
>  
>      /* C ring mode */
>      uint32_t   currTxDesc;
> @@ -506,6 +505,9 @@ typedef struct RTL8139State {
>      QEMUTimer *timer;
>      int64_t TimerExpire;
>  
> +    MemoryRegion bar_io;
> +    MemoryRegion bar_mem;
> +
>      /* Support migration to/from old versions */
>      int rtl8139_mmio_io_addr_dummy;
>  } RTL8139State;
> @@ -2705,12 +2707,8 @@ static uint32_t rtl8139_MultiIntr_read(RTL8139State *s)
>      return ret;
>  }
>  
> -static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
> +static void rtl8139_io_writeb(RTL8139State *s, uint8_t addr, uint32_t val)
>  {
> -    RTL8139State *s = opaque;
> -
> -    addr &= 0xff;
> -
>      switch (addr)
>      {
>          case MAC0 ... MAC0+5:
> @@ -2792,10 +2790,8 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
>      }
>  }
>  
> -static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
> +static void rtl8139_io_writew(RTL8139State *s, uint8_t addr, uint32_t val)
>  {
> -    RTL8139State *s = opaque;
> -
>      addr &= 0xfe;
>  
>      switch (addr)
> @@ -2846,8 +2842,8 @@ static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
>              DPRINTF("ioport write(w) addr=0x%x val=0x%04x via write(b)\n",
>                  addr, val);
>  
> -            rtl8139_io_writeb(opaque, addr, val & 0xff);
> -            rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
> +            rtl8139_io_writeb(s, addr, val & 0xff);
> +            rtl8139_io_writeb(s, addr + 1, (val >> 8) & 0xff);
>              break;
>      }
>  }
> @@ -2892,10 +2888,8 @@ static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time)
>      }
>  }
>  
> -static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
> +static void rtl8139_io_writel(RTL8139State *s, uint8_t addr, uint32_t val)
>  {
> -    RTL8139State *s = opaque;
> -
>      addr &= 0xfc;
>  
>      switch (addr)
> @@ -2952,21 +2946,18 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
>          default:
>              DPRINTF("ioport write(l) addr=0x%x val=0x%08x via write(b)\n",
>                  addr, val);
> -            rtl8139_io_writeb(opaque, addr, val & 0xff);
> -            rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
> -            rtl8139_io_writeb(opaque, addr + 2, (val >> 16) & 0xff);
> -            rtl8139_io_writeb(opaque, addr + 3, (val >> 24) & 0xff);
> +            rtl8139_io_writeb(s, addr, val & 0xff);
> +            rtl8139_io_writeb(s, addr + 1, (val >> 8) & 0xff);
> +            rtl8139_io_writeb(s, addr + 2, (val >> 16) & 0xff);
> +            rtl8139_io_writeb(s, addr + 3, (val >> 24) & 0xff);
>              break;
>      }
>  }
>  
> -static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
> +static uint32_t rtl8139_io_readb(RTL8139State *s, uint8_t addr)
>  {
> -    RTL8139State *s = opaque;
>      int ret;
>  
> -    addr &= 0xff;
> -
>      switch (addr)
>      {
>          case MAC0 ... MAC0+5:
> @@ -3034,9 +3025,8 @@ static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
>      return ret;
>  }
>  
> -static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
> +static uint32_t rtl8139_io_readw(RTL8139State *s, uint8_t addr)
>  {
> -    RTL8139State *s = opaque;
>      uint32_t ret;
>  
>      addr &= 0xfe; /* mask lower bit */
> @@ -3101,8 +3091,8 @@ static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
>          default:
>              DPRINTF("ioport read(w) addr=0x%x via read(b)\n", addr);
>  
> -            ret  = rtl8139_io_readb(opaque, addr);
> -            ret |= rtl8139_io_readb(opaque, addr + 1) << 8;
> +            ret  = rtl8139_io_readb(s, addr);
> +            ret |= rtl8139_io_readb(s, addr + 1) << 8;
>  
>              DPRINTF("ioport read(w) addr=0x%x val=0x%04x\n", addr, ret);
>              break;
> @@ -3182,71 +3172,40 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
>      return ret;
>  }
>  
> -/* */
> -
> -static void rtl8139_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
> -{
> -    rtl8139_io_writeb(opaque, addr & 0xFF, val);
> -}
> -
> -static void rtl8139_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
> -{
> -    rtl8139_io_writew(opaque, addr & 0xFF, val);
> -}
> -
> -static void rtl8139_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
> -{
> -    rtl8139_io_writel(opaque, addr & 0xFF, val);
> -}
> -
> -static uint32_t rtl8139_ioport_readb(void *opaque, uint32_t addr)
> +static uint64_t rtl8139_io_read(void *opaque,
> +                                target_phys_addr_t addr,
> +                                unsigned size)
>  {
> -    return rtl8139_io_readb(opaque, addr & 0xFF);
> -}
> -
> -static uint32_t rtl8139_ioport_readw(void *opaque, uint32_t addr)
> -{
> -    return rtl8139_io_readw(opaque, addr & 0xFF);
> -}
> -
> -static uint32_t rtl8139_ioport_readl(void *opaque, uint32_t addr)
> -{
> -    return rtl8139_io_readl(opaque, addr & 0xFF);
> -}
> -
> -/* */
> -
> -static void rtl8139_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
> -{
> -    rtl8139_io_writeb(opaque, addr & 0xFF, val);
> -}
> -
> -static void rtl8139_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
> -{
> -    rtl8139_io_writew(opaque, addr & 0xFF, val);
> -}
> +    RTL8139State *s = opaque;
>  
> -static void rtl8139_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
> -{
> -    rtl8139_io_writel(opaque, addr & 0xFF, val);
> +    switch (size) {
> +    case 1: return rtl8139_io_readb(s, addr);
> +    case 2: return rtl8139_io_readw(s, addr);
> +    case 4: return rtl8139_io_readl(s, addr);
> +    default: abort();
> +    }
>  }
>  
> -static uint32_t rtl8139_mmio_readb(void *opaque, target_phys_addr_t addr)
> +static void rtl8139_io_write(void *opaque,
> +                             target_phys_addr_t addr,
> +                             uint64_t data,
> +                             unsigned size)
>  {
> -    return rtl8139_io_readb(opaque, addr & 0xFF);
> -}
> +    RTL8139State *s = opaque;
>  
> -static uint32_t rtl8139_mmio_readw(void *opaque, target_phys_addr_t addr)
> -{
> -    uint32_t val = rtl8139_io_readw(opaque, addr & 0xFF);
> -    return val;
> +    switch (size) {
> +    case 1: return rtl8139_io_writeb(s, addr, data);
> +    case 2: return rtl8139_io_writew(s, addr, data);
> +    case 4: return rtl8139_io_writel(s, addr, data);
> +    default: abort();
> +    }
>  }
>  
> -static uint32_t rtl8139_mmio_readl(void *opaque, target_phys_addr_t addr)
> -{
> -    uint32_t val = rtl8139_io_readl(opaque, addr & 0xFF);
> -    return val;
> -}
> +static MemoryRegionOps rtl8139_io_ops = {
> +    .read = rtl8139_io_read,
> +    .write = rtl8139_io_write,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
> +};
>  
>  static int rtl8139_post_load(void *opaque, int version_id)
>  {
> @@ -3283,7 +3242,7 @@ static void rtl8139_pre_save(void *opaque)
>      rtl8139_set_next_tctr_time(s, current_time);
>      s->TCTR = muldiv64(current_time - s->TCTR_base, PCI_FREQUENCY,
>                         get_ticks_per_sec());
> -    s->rtl8139_mmio_io_addr_dummy = s->rtl8139_mmio_io_addr;
> +    s->rtl8139_mmio_io_addr_dummy = 0;

This makes the dummy value fairly useless for preserving new->old
migration.  Drop it altogether and bump the version or add a subsection
to prevent migration to old versions that consume this?

Alex


>  }
>  
>  static const VMStateDescription vmstate_rtl8139 = {
> @@ -3379,33 +3338,6 @@ static const VMStateDescription vmstate_rtl8139 = {
>  /***********************************************************/
>  /* PCI RTL8139 definitions */
>  
> -static void rtl8139_ioport_map(PCIDevice *pci_dev, int region_num,
> -                       pcibus_t addr, pcibus_t size, int type)
> -{
> -    RTL8139State *s = DO_UPCAST(RTL8139State, dev, pci_dev);
> -
> -    register_ioport_write(addr, 0x100, 1, rtl8139_ioport_writeb, s);
> -    register_ioport_read( addr, 0x100, 1, rtl8139_ioport_readb,  s);
> -
> -    register_ioport_write(addr, 0x100, 2, rtl8139_ioport_writew, s);
> -    register_ioport_read( addr, 0x100, 2, rtl8139_ioport_readw,  s);
> -
> -    register_ioport_write(addr, 0x100, 4, rtl8139_ioport_writel, s);
> -    register_ioport_read( addr, 0x100, 4, rtl8139_ioport_readl,  s);
> -}
> -
> -static CPUReadMemoryFunc * const rtl8139_mmio_read[3] = {
> -    rtl8139_mmio_readb,
> -    rtl8139_mmio_readw,
> -    rtl8139_mmio_readl,
> -};
> -
> -static CPUWriteMemoryFunc * const rtl8139_mmio_write[3] = {
> -    rtl8139_mmio_writeb,
> -    rtl8139_mmio_writew,
> -    rtl8139_mmio_writel,
> -};
> -
>  static void rtl8139_timer(void *opaque)
>  {
>      RTL8139State *s = opaque;
> @@ -3432,7 +3364,8 @@ static int pci_rtl8139_uninit(PCIDevice *dev)
>  {
>      RTL8139State *s = DO_UPCAST(RTL8139State, dev, dev);
>  
> -    cpu_unregister_io_memory(s->rtl8139_mmio_io_addr);
> +    memory_region_destroy(&s->bar_io);
> +    memory_region_destroy(&s->bar_mem);
>      if (s->cplus_txbuffer) {
>          qemu_free(s->cplus_txbuffer);
>          s->cplus_txbuffer = NULL;
> @@ -3462,15 +3395,12 @@ static int pci_rtl8139_init(PCIDevice *dev)
>       * list bit in status register, and offset 0xdc seems unused. */
>      pci_conf[PCI_CAPABILITY_LIST] = 0xdc;
>  
> -    /* I/O handler for memory-mapped I/O */
> -    s->rtl8139_mmio_io_addr =
> -        cpu_register_io_memory(rtl8139_mmio_read, rtl8139_mmio_write, s,
> -                               DEVICE_LITTLE_ENDIAN);
> -
> -    pci_register_bar(&s->dev, 0, 0x100,
> -                           PCI_BASE_ADDRESS_SPACE_IO,  rtl8139_ioport_map);
> -
> -    pci_register_bar_simple(&s->dev, 1, 0x100, 0, s->rtl8139_mmio_io_addr);
> +    memory_region_init_io(&s->bar_io, &rtl8139_io_ops, s, "rtl8139", 0x100);
> +    memory_region_init_io(&s->bar_mem, &rtl8139_io_ops, s, "rtl8139", 0x100);
> +    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
> +                            &s->bar_io);
> +    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
> +                            &s->bar_mem);
>  
>      qemu_macaddr_default_if_unset(&s->conf.macaddr);
>  




^ permalink raw reply	[flat|nested] 131+ messages in thread

* Re: [Qemu-devel] [RFC v3 30/56] rtl8139: convert to memory API
@ 2011-07-12 22:41     ` Alex Williamson
  0 siblings, 0 replies; 131+ messages in thread
From: Alex Williamson @ 2011-07-12 22:41 UTC (permalink / raw)
  To: Avi Kivity; +Cc: qemu-devel, kvm

On Sun, 2011-07-10 at 21:14 +0300, Avi Kivity wrote:
> Signed-off-by: Avi Kivity <avi@redhat.com>
> ---
>  hw/rtl8139.c |  172 +++++++++++++++++-----------------------------------------
>  1 files changed, 51 insertions(+), 121 deletions(-)
> 
> diff --git a/hw/rtl8139.c b/hw/rtl8139.c
> index 5214b8c..fa661fc 100644
> --- a/hw/rtl8139.c
> +++ b/hw/rtl8139.c
> @@ -474,7 +474,6 @@ typedef struct RTL8139State {
>  
>      NICState *nic;
>      NICConf conf;
> -    int rtl8139_mmio_io_addr;
>  
>      /* C ring mode */
>      uint32_t   currTxDesc;
> @@ -506,6 +505,9 @@ typedef struct RTL8139State {
>      QEMUTimer *timer;
>      int64_t TimerExpire;
>  
> +    MemoryRegion bar_io;
> +    MemoryRegion bar_mem;
> +
>      /* Support migration to/from old versions */
>      int rtl8139_mmio_io_addr_dummy;
>  } RTL8139State;
> @@ -2705,12 +2707,8 @@ static uint32_t rtl8139_MultiIntr_read(RTL8139State *s)
>      return ret;
>  }
>  
> -static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
> +static void rtl8139_io_writeb(RTL8139State *s, uint8_t addr, uint32_t val)
>  {
> -    RTL8139State *s = opaque;
> -
> -    addr &= 0xff;
> -
>      switch (addr)
>      {
>          case MAC0 ... MAC0+5:
> @@ -2792,10 +2790,8 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
>      }
>  }
>  
> -static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
> +static void rtl8139_io_writew(RTL8139State *s, uint8_t addr, uint32_t val)
>  {
> -    RTL8139State *s = opaque;
> -
>      addr &= 0xfe;
>  
>      switch (addr)
> @@ -2846,8 +2842,8 @@ static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
>              DPRINTF("ioport write(w) addr=0x%x val=0x%04x via write(b)\n",
>                  addr, val);
>  
> -            rtl8139_io_writeb(opaque, addr, val & 0xff);
> -            rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
> +            rtl8139_io_writeb(s, addr, val & 0xff);
> +            rtl8139_io_writeb(s, addr + 1, (val >> 8) & 0xff);
>              break;
>      }
>  }
> @@ -2892,10 +2888,8 @@ static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time)
>      }
>  }
>  
> -static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
> +static void rtl8139_io_writel(RTL8139State *s, uint8_t addr, uint32_t val)
>  {
> -    RTL8139State *s = opaque;
> -
>      addr &= 0xfc;
>  
>      switch (addr)
> @@ -2952,21 +2946,18 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
>          default:
>              DPRINTF("ioport write(l) addr=0x%x val=0x%08x via write(b)\n",
>                  addr, val);
> -            rtl8139_io_writeb(opaque, addr, val & 0xff);
> -            rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
> -            rtl8139_io_writeb(opaque, addr + 2, (val >> 16) & 0xff);
> -            rtl8139_io_writeb(opaque, addr + 3, (val >> 24) & 0xff);
> +            rtl8139_io_writeb(s, addr, val & 0xff);
> +            rtl8139_io_writeb(s, addr + 1, (val >> 8) & 0xff);
> +            rtl8139_io_writeb(s, addr + 2, (val >> 16) & 0xff);
> +            rtl8139_io_writeb(s, addr + 3, (val >> 24) & 0xff);
>              break;
>      }
>  }
>  
> -static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
> +static uint32_t rtl8139_io_readb(RTL8139State *s, uint8_t addr)
>  {
> -    RTL8139State *s = opaque;
>      int ret;
>  
> -    addr &= 0xff;
> -
>      switch (addr)
>      {
>          case MAC0 ... MAC0+5:
> @@ -3034,9 +3025,8 @@ static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
>      return ret;
>  }
>  
> -static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
> +static uint32_t rtl8139_io_readw(RTL8139State *s, uint8_t addr)
>  {
> -    RTL8139State *s = opaque;
>      uint32_t ret;
>  
>      addr &= 0xfe; /* mask lower bit */
> @@ -3101,8 +3091,8 @@ static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
>          default:
>              DPRINTF("ioport read(w) addr=0x%x via read(b)\n", addr);
>  
> -            ret  = rtl8139_io_readb(opaque, addr);
> -            ret |= rtl8139_io_readb(opaque, addr + 1) << 8;
> +            ret  = rtl8139_io_readb(s, addr);
> +            ret |= rtl8139_io_readb(s, addr + 1) << 8;
>  
>              DPRINTF("ioport read(w) addr=0x%x val=0x%04x\n", addr, ret);
>              break;
> @@ -3182,71 +3172,40 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
>      return ret;
>  }
>  
> -/* */
> -
> -static void rtl8139_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
> -{
> -    rtl8139_io_writeb(opaque, addr & 0xFF, val);
> -}
> -
> -static void rtl8139_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
> -{
> -    rtl8139_io_writew(opaque, addr & 0xFF, val);
> -}
> -
> -static void rtl8139_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
> -{
> -    rtl8139_io_writel(opaque, addr & 0xFF, val);
> -}
> -
> -static uint32_t rtl8139_ioport_readb(void *opaque, uint32_t addr)
> +static uint64_t rtl8139_io_read(void *opaque,
> +                                target_phys_addr_t addr,
> +                                unsigned size)
>  {
> -    return rtl8139_io_readb(opaque, addr & 0xFF);
> -}
> -
> -static uint32_t rtl8139_ioport_readw(void *opaque, uint32_t addr)
> -{
> -    return rtl8139_io_readw(opaque, addr & 0xFF);
> -}
> -
> -static uint32_t rtl8139_ioport_readl(void *opaque, uint32_t addr)
> -{
> -    return rtl8139_io_readl(opaque, addr & 0xFF);
> -}
> -
> -/* */
> -
> -static void rtl8139_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
> -{
> -    rtl8139_io_writeb(opaque, addr & 0xFF, val);
> -}
> -
> -static void rtl8139_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
> -{
> -    rtl8139_io_writew(opaque, addr & 0xFF, val);
> -}
> +    RTL8139State *s = opaque;
>  
> -static void rtl8139_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
> -{
> -    rtl8139_io_writel(opaque, addr & 0xFF, val);
> +    switch (size) {
> +    case 1: return rtl8139_io_readb(s, addr);
> +    case 2: return rtl8139_io_readw(s, addr);
> +    case 4: return rtl8139_io_readl(s, addr);
> +    default: abort();
> +    }
>  }
>  
> -static uint32_t rtl8139_mmio_readb(void *opaque, target_phys_addr_t addr)
> +static void rtl8139_io_write(void *opaque,
> +                             target_phys_addr_t addr,
> +                             uint64_t data,
> +                             unsigned size)
>  {
> -    return rtl8139_io_readb(opaque, addr & 0xFF);
> -}
> +    RTL8139State *s = opaque;
>  
> -static uint32_t rtl8139_mmio_readw(void *opaque, target_phys_addr_t addr)
> -{
> -    uint32_t val = rtl8139_io_readw(opaque, addr & 0xFF);
> -    return val;
> +    switch (size) {
> +    case 1: return rtl8139_io_writeb(s, addr, data);
> +    case 2: return rtl8139_io_writew(s, addr, data);
> +    case 4: return rtl8139_io_writel(s, addr, data);
> +    default: abort();
> +    }
>  }
>  
> -static uint32_t rtl8139_mmio_readl(void *opaque, target_phys_addr_t addr)
> -{
> -    uint32_t val = rtl8139_io_readl(opaque, addr & 0xFF);
> -    return val;
> -}
> +static MemoryRegionOps rtl8139_io_ops = {
> +    .read = rtl8139_io_read,
> +    .write = rtl8139_io_write,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
> +};
>  
>  static int rtl8139_post_load(void *opaque, int version_id)
>  {
> @@ -3283,7 +3242,7 @@ static void rtl8139_pre_save(void *opaque)
>      rtl8139_set_next_tctr_time(s, current_time);
>      s->TCTR = muldiv64(current_time - s->TCTR_base, PCI_FREQUENCY,
>                         get_ticks_per_sec());
> -    s->rtl8139_mmio_io_addr_dummy = s->rtl8139_mmio_io_addr;
> +    s->rtl8139_mmio_io_addr_dummy = 0;

This makes the dummy value fairly useless for preserving new->old
migration.  Drop it altogether and bump the version or add a subsection
to prevent migration to old versions that consume this?

Alex


>  }
>  
>  static const VMStateDescription vmstate_rtl8139 = {
> @@ -3379,33 +3338,6 @@ static const VMStateDescription vmstate_rtl8139 = {
>  /***********************************************************/
>  /* PCI RTL8139 definitions */
>  
> -static void rtl8139_ioport_map(PCIDevice *pci_dev, int region_num,
> -                       pcibus_t addr, pcibus_t size, int type)
> -{
> -    RTL8139State *s = DO_UPCAST(RTL8139State, dev, pci_dev);
> -
> -    register_ioport_write(addr, 0x100, 1, rtl8139_ioport_writeb, s);
> -    register_ioport_read( addr, 0x100, 1, rtl8139_ioport_readb,  s);
> -
> -    register_ioport_write(addr, 0x100, 2, rtl8139_ioport_writew, s);
> -    register_ioport_read( addr, 0x100, 2, rtl8139_ioport_readw,  s);
> -
> -    register_ioport_write(addr, 0x100, 4, rtl8139_ioport_writel, s);
> -    register_ioport_read( addr, 0x100, 4, rtl8139_ioport_readl,  s);
> -}
> -
> -static CPUReadMemoryFunc * const rtl8139_mmio_read[3] = {
> -    rtl8139_mmio_readb,
> -    rtl8139_mmio_readw,
> -    rtl8139_mmio_readl,
> -};
> -
> -static CPUWriteMemoryFunc * const rtl8139_mmio_write[3] = {
> -    rtl8139_mmio_writeb,
> -    rtl8139_mmio_writew,
> -    rtl8139_mmio_writel,
> -};
> -
>  static void rtl8139_timer(void *opaque)
>  {
>      RTL8139State *s = opaque;
> @@ -3432,7 +3364,8 @@ static int pci_rtl8139_uninit(PCIDevice *dev)
>  {
>      RTL8139State *s = DO_UPCAST(RTL8139State, dev, dev);
>  
> -    cpu_unregister_io_memory(s->rtl8139_mmio_io_addr);
> +    memory_region_destroy(&s->bar_io);
> +    memory_region_destroy(&s->bar_mem);
>      if (s->cplus_txbuffer) {
>          qemu_free(s->cplus_txbuffer);
>          s->cplus_txbuffer = NULL;
> @@ -3462,15 +3395,12 @@ static int pci_rtl8139_init(PCIDevice *dev)
>       * list bit in status register, and offset 0xdc seems unused. */
>      pci_conf[PCI_CAPABILITY_LIST] = 0xdc;
>  
> -    /* I/O handler for memory-mapped I/O */
> -    s->rtl8139_mmio_io_addr =
> -        cpu_register_io_memory(rtl8139_mmio_read, rtl8139_mmio_write, s,
> -                               DEVICE_LITTLE_ENDIAN);
> -
> -    pci_register_bar(&s->dev, 0, 0x100,
> -                           PCI_BASE_ADDRESS_SPACE_IO,  rtl8139_ioport_map);
> -
> -    pci_register_bar_simple(&s->dev, 1, 0x100, 0, s->rtl8139_mmio_io_addr);
> +    memory_region_init_io(&s->bar_io, &rtl8139_io_ops, s, "rtl8139", 0x100);
> +    memory_region_init_io(&s->bar_mem, &rtl8139_io_ops, s, "rtl8139", 0x100);
> +    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
> +                            &s->bar_io);
> +    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
> +                            &s->bar_mem);
>  
>      qemu_macaddr_default_if_unset(&s->conf.macaddr);
>  

^ permalink raw reply	[flat|nested] 131+ messages in thread

* Re: [RFC v3 30/56] rtl8139: convert to memory API
  2011-07-12 22:41     ` [Qemu-devel] " Alex Williamson
@ 2011-07-12 22:47       ` Alex Williamson
  -1 siblings, 0 replies; 131+ messages in thread
From: Alex Williamson @ 2011-07-12 22:47 UTC (permalink / raw)
  To: Avi Kivity; +Cc: qemu-devel, kvm

On Tue, 2011-07-12 at 16:41 -0600, Alex Williamson wrote:
> On Sun, 2011-07-10 at 21:14 +0300, Avi Kivity wrote:
> > Signed-off-by: Avi Kivity <avi@redhat.com>
> > ---
> >  hw/rtl8139.c |  172 +++++++++++++++++-----------------------------------------
> >  1 files changed, 51 insertions(+), 121 deletions(-)
> > 
> > diff --git a/hw/rtl8139.c b/hw/rtl8139.c
> > index 5214b8c..fa661fc 100644
> > --- a/hw/rtl8139.c
> > +++ b/hw/rtl8139.c
> > @@ -474,7 +474,6 @@ typedef struct RTL8139State {
> >  
> >      NICState *nic;
> >      NICConf conf;
> > -    int rtl8139_mmio_io_addr;
> >  
> >      /* C ring mode */
> >      uint32_t   currTxDesc;
> > @@ -506,6 +505,9 @@ typedef struct RTL8139State {
> >      QEMUTimer *timer;
> >      int64_t TimerExpire;
> >  
> > +    MemoryRegion bar_io;
> > +    MemoryRegion bar_mem;
> > +
> >      /* Support migration to/from old versions */
> >      int rtl8139_mmio_io_addr_dummy;
> >  } RTL8139State;
> > @@ -2705,12 +2707,8 @@ static uint32_t rtl8139_MultiIntr_read(RTL8139State *s)
> >      return ret;
> >  }
> >  
> > -static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
> > +static void rtl8139_io_writeb(RTL8139State *s, uint8_t addr, uint32_t val)
> >  {
> > -    RTL8139State *s = opaque;
> > -
> > -    addr &= 0xff;
> > -
> >      switch (addr)
> >      {
> >          case MAC0 ... MAC0+5:
> > @@ -2792,10 +2790,8 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
> >      }
> >  }
> >  
> > -static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
> > +static void rtl8139_io_writew(RTL8139State *s, uint8_t addr, uint32_t val)
> >  {
> > -    RTL8139State *s = opaque;
> > -
> >      addr &= 0xfe;
> >  
> >      switch (addr)
> > @@ -2846,8 +2842,8 @@ static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
> >              DPRINTF("ioport write(w) addr=0x%x val=0x%04x via write(b)\n",
> >                  addr, val);
> >  
> > -            rtl8139_io_writeb(opaque, addr, val & 0xff);
> > -            rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
> > +            rtl8139_io_writeb(s, addr, val & 0xff);
> > +            rtl8139_io_writeb(s, addr + 1, (val >> 8) & 0xff);
> >              break;
> >      }
> >  }
> > @@ -2892,10 +2888,8 @@ static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time)
> >      }
> >  }
> >  
> > -static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
> > +static void rtl8139_io_writel(RTL8139State *s, uint8_t addr, uint32_t val)
> >  {
> > -    RTL8139State *s = opaque;
> > -
> >      addr &= 0xfc;
> >  
> >      switch (addr)
> > @@ -2952,21 +2946,18 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
> >          default:
> >              DPRINTF("ioport write(l) addr=0x%x val=0x%08x via write(b)\n",
> >                  addr, val);
> > -            rtl8139_io_writeb(opaque, addr, val & 0xff);
> > -            rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
> > -            rtl8139_io_writeb(opaque, addr + 2, (val >> 16) & 0xff);
> > -            rtl8139_io_writeb(opaque, addr + 3, (val >> 24) & 0xff);
> > +            rtl8139_io_writeb(s, addr, val & 0xff);
> > +            rtl8139_io_writeb(s, addr + 1, (val >> 8) & 0xff);
> > +            rtl8139_io_writeb(s, addr + 2, (val >> 16) & 0xff);
> > +            rtl8139_io_writeb(s, addr + 3, (val >> 24) & 0xff);
> >              break;
> >      }
> >  }
> >  
> > -static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
> > +static uint32_t rtl8139_io_readb(RTL8139State *s, uint8_t addr)
> >  {
> > -    RTL8139State *s = opaque;
> >      int ret;
> >  
> > -    addr &= 0xff;
> > -
> >      switch (addr)
> >      {
> >          case MAC0 ... MAC0+5:
> > @@ -3034,9 +3025,8 @@ static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
> >      return ret;
> >  }
> >  
> > -static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
> > +static uint32_t rtl8139_io_readw(RTL8139State *s, uint8_t addr)
> >  {
> > -    RTL8139State *s = opaque;
> >      uint32_t ret;
> >  
> >      addr &= 0xfe; /* mask lower bit */
> > @@ -3101,8 +3091,8 @@ static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
> >          default:
> >              DPRINTF("ioport read(w) addr=0x%x via read(b)\n", addr);
> >  
> > -            ret  = rtl8139_io_readb(opaque, addr);
> > -            ret |= rtl8139_io_readb(opaque, addr + 1) << 8;
> > +            ret  = rtl8139_io_readb(s, addr);
> > +            ret |= rtl8139_io_readb(s, addr + 1) << 8;
> >  
> >              DPRINTF("ioport read(w) addr=0x%x val=0x%04x\n", addr, ret);
> >              break;
> > @@ -3182,71 +3172,40 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
> >      return ret;
> >  }
> >  
> > -/* */
> > -
> > -static void rtl8139_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
> > -{
> > -    rtl8139_io_writeb(opaque, addr & 0xFF, val);
> > -}
> > -
> > -static void rtl8139_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
> > -{
> > -    rtl8139_io_writew(opaque, addr & 0xFF, val);
> > -}
> > -
> > -static void rtl8139_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
> > -{
> > -    rtl8139_io_writel(opaque, addr & 0xFF, val);
> > -}
> > -
> > -static uint32_t rtl8139_ioport_readb(void *opaque, uint32_t addr)
> > +static uint64_t rtl8139_io_read(void *opaque,
> > +                                target_phys_addr_t addr,
> > +                                unsigned size)
> >  {
> > -    return rtl8139_io_readb(opaque, addr & 0xFF);
> > -}
> > -
> > -static uint32_t rtl8139_ioport_readw(void *opaque, uint32_t addr)
> > -{
> > -    return rtl8139_io_readw(opaque, addr & 0xFF);
> > -}
> > -
> > -static uint32_t rtl8139_ioport_readl(void *opaque, uint32_t addr)
> > -{
> > -    return rtl8139_io_readl(opaque, addr & 0xFF);
> > -}
> > -
> > -/* */
> > -
> > -static void rtl8139_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
> > -{
> > -    rtl8139_io_writeb(opaque, addr & 0xFF, val);
> > -}
> > -
> > -static void rtl8139_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
> > -{
> > -    rtl8139_io_writew(opaque, addr & 0xFF, val);
> > -}
> > +    RTL8139State *s = opaque;
> >  
> > -static void rtl8139_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
> > -{
> > -    rtl8139_io_writel(opaque, addr & 0xFF, val);
> > +    switch (size) {
> > +    case 1: return rtl8139_io_readb(s, addr);
> > +    case 2: return rtl8139_io_readw(s, addr);
> > +    case 4: return rtl8139_io_readl(s, addr);
> > +    default: abort();
> > +    }
> >  }
> >  
> > -static uint32_t rtl8139_mmio_readb(void *opaque, target_phys_addr_t addr)
> > +static void rtl8139_io_write(void *opaque,
> > +                             target_phys_addr_t addr,
> > +                             uint64_t data,
> > +                             unsigned size)
> >  {
> > -    return rtl8139_io_readb(opaque, addr & 0xFF);
> > -}
> > +    RTL8139State *s = opaque;
> >  
> > -static uint32_t rtl8139_mmio_readw(void *opaque, target_phys_addr_t addr)
> > -{
> > -    uint32_t val = rtl8139_io_readw(opaque, addr & 0xFF);
> > -    return val;
> > +    switch (size) {
> > +    case 1: return rtl8139_io_writeb(s, addr, data);
> > +    case 2: return rtl8139_io_writew(s, addr, data);
> > +    case 4: return rtl8139_io_writel(s, addr, data);
> > +    default: abort();
> > +    }
> >  }
> >  
> > -static uint32_t rtl8139_mmio_readl(void *opaque, target_phys_addr_t addr)
> > -{
> > -    uint32_t val = rtl8139_io_readl(opaque, addr & 0xFF);
> > -    return val;
> > -}
> > +static MemoryRegionOps rtl8139_io_ops = {
> > +    .read = rtl8139_io_read,
> > +    .write = rtl8139_io_write,
> > +    .endianness = DEVICE_LITTLE_ENDIAN,
> > +};
> >  
> >  static int rtl8139_post_load(void *opaque, int version_id)
> >  {
> > @@ -3283,7 +3242,7 @@ static void rtl8139_pre_save(void *opaque)
> >      rtl8139_set_next_tctr_time(s, current_time);
> >      s->TCTR = muldiv64(current_time - s->TCTR_base, PCI_FREQUENCY,
> >                         get_ticks_per_sec());
> > -    s->rtl8139_mmio_io_addr_dummy = s->rtl8139_mmio_io_addr;
> > +    s->rtl8139_mmio_io_addr_dummy = 0;
> 
> This makes the dummy value fairly useless for preserving new->old
> migration.  Drop it altogether and bump the version or add a subsection
> to prevent migration to old versions that consume this?

I guess to preserve as much as we can, rtl8139_hotplug_ready_needed()
would just return 1 and we'd stuff VMSTATE_UNUSED to fill the gap from
dummy in the vmstate.

Alex

> >  }
> >  
> >  static const VMStateDescription vmstate_rtl8139 = {
> > @@ -3379,33 +3338,6 @@ static const VMStateDescription vmstate_rtl8139 = {
> >  /***********************************************************/
> >  /* PCI RTL8139 definitions */
> >  
> > -static void rtl8139_ioport_map(PCIDevice *pci_dev, int region_num,
> > -                       pcibus_t addr, pcibus_t size, int type)
> > -{
> > -    RTL8139State *s = DO_UPCAST(RTL8139State, dev, pci_dev);
> > -
> > -    register_ioport_write(addr, 0x100, 1, rtl8139_ioport_writeb, s);
> > -    register_ioport_read( addr, 0x100, 1, rtl8139_ioport_readb,  s);
> > -
> > -    register_ioport_write(addr, 0x100, 2, rtl8139_ioport_writew, s);
> > -    register_ioport_read( addr, 0x100, 2, rtl8139_ioport_readw,  s);
> > -
> > -    register_ioport_write(addr, 0x100, 4, rtl8139_ioport_writel, s);
> > -    register_ioport_read( addr, 0x100, 4, rtl8139_ioport_readl,  s);
> > -}
> > -
> > -static CPUReadMemoryFunc * const rtl8139_mmio_read[3] = {
> > -    rtl8139_mmio_readb,
> > -    rtl8139_mmio_readw,
> > -    rtl8139_mmio_readl,
> > -};
> > -
> > -static CPUWriteMemoryFunc * const rtl8139_mmio_write[3] = {
> > -    rtl8139_mmio_writeb,
> > -    rtl8139_mmio_writew,
> > -    rtl8139_mmio_writel,
> > -};
> > -
> >  static void rtl8139_timer(void *opaque)
> >  {
> >      RTL8139State *s = opaque;
> > @@ -3432,7 +3364,8 @@ static int pci_rtl8139_uninit(PCIDevice *dev)
> >  {
> >      RTL8139State *s = DO_UPCAST(RTL8139State, dev, dev);
> >  
> > -    cpu_unregister_io_memory(s->rtl8139_mmio_io_addr);
> > +    memory_region_destroy(&s->bar_io);
> > +    memory_region_destroy(&s->bar_mem);
> >      if (s->cplus_txbuffer) {
> >          qemu_free(s->cplus_txbuffer);
> >          s->cplus_txbuffer = NULL;
> > @@ -3462,15 +3395,12 @@ static int pci_rtl8139_init(PCIDevice *dev)
> >       * list bit in status register, and offset 0xdc seems unused. */
> >      pci_conf[PCI_CAPABILITY_LIST] = 0xdc;
> >  
> > -    /* I/O handler for memory-mapped I/O */
> > -    s->rtl8139_mmio_io_addr =
> > -        cpu_register_io_memory(rtl8139_mmio_read, rtl8139_mmio_write, s,
> > -                               DEVICE_LITTLE_ENDIAN);
> > -
> > -    pci_register_bar(&s->dev, 0, 0x100,
> > -                           PCI_BASE_ADDRESS_SPACE_IO,  rtl8139_ioport_map);
> > -
> > -    pci_register_bar_simple(&s->dev, 1, 0x100, 0, s->rtl8139_mmio_io_addr);
> > +    memory_region_init_io(&s->bar_io, &rtl8139_io_ops, s, "rtl8139", 0x100);
> > +    memory_region_init_io(&s->bar_mem, &rtl8139_io_ops, s, "rtl8139", 0x100);
> > +    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
> > +                            &s->bar_io);
> > +    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
> > +                            &s->bar_mem);
> >  
> >      qemu_macaddr_default_if_unset(&s->conf.macaddr);
> >  
> 
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html




^ permalink raw reply	[flat|nested] 131+ messages in thread

* Re: [Qemu-devel] [RFC v3 30/56] rtl8139: convert to memory API
@ 2011-07-12 22:47       ` Alex Williamson
  0 siblings, 0 replies; 131+ messages in thread
From: Alex Williamson @ 2011-07-12 22:47 UTC (permalink / raw)
  To: Avi Kivity; +Cc: qemu-devel, kvm

On Tue, 2011-07-12 at 16:41 -0600, Alex Williamson wrote:
> On Sun, 2011-07-10 at 21:14 +0300, Avi Kivity wrote:
> > Signed-off-by: Avi Kivity <avi@redhat.com>
> > ---
> >  hw/rtl8139.c |  172 +++++++++++++++++-----------------------------------------
> >  1 files changed, 51 insertions(+), 121 deletions(-)
> > 
> > diff --git a/hw/rtl8139.c b/hw/rtl8139.c
> > index 5214b8c..fa661fc 100644
> > --- a/hw/rtl8139.c
> > +++ b/hw/rtl8139.c
> > @@ -474,7 +474,6 @@ typedef struct RTL8139State {
> >  
> >      NICState *nic;
> >      NICConf conf;
> > -    int rtl8139_mmio_io_addr;
> >  
> >      /* C ring mode */
> >      uint32_t   currTxDesc;
> > @@ -506,6 +505,9 @@ typedef struct RTL8139State {
> >      QEMUTimer *timer;
> >      int64_t TimerExpire;
> >  
> > +    MemoryRegion bar_io;
> > +    MemoryRegion bar_mem;
> > +
> >      /* Support migration to/from old versions */
> >      int rtl8139_mmio_io_addr_dummy;
> >  } RTL8139State;
> > @@ -2705,12 +2707,8 @@ static uint32_t rtl8139_MultiIntr_read(RTL8139State *s)
> >      return ret;
> >  }
> >  
> > -static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
> > +static void rtl8139_io_writeb(RTL8139State *s, uint8_t addr, uint32_t val)
> >  {
> > -    RTL8139State *s = opaque;
> > -
> > -    addr &= 0xff;
> > -
> >      switch (addr)
> >      {
> >          case MAC0 ... MAC0+5:
> > @@ -2792,10 +2790,8 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
> >      }
> >  }
> >  
> > -static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
> > +static void rtl8139_io_writew(RTL8139State *s, uint8_t addr, uint32_t val)
> >  {
> > -    RTL8139State *s = opaque;
> > -
> >      addr &= 0xfe;
> >  
> >      switch (addr)
> > @@ -2846,8 +2842,8 @@ static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
> >              DPRINTF("ioport write(w) addr=0x%x val=0x%04x via write(b)\n",
> >                  addr, val);
> >  
> > -            rtl8139_io_writeb(opaque, addr, val & 0xff);
> > -            rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
> > +            rtl8139_io_writeb(s, addr, val & 0xff);
> > +            rtl8139_io_writeb(s, addr + 1, (val >> 8) & 0xff);
> >              break;
> >      }
> >  }
> > @@ -2892,10 +2888,8 @@ static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time)
> >      }
> >  }
> >  
> > -static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
> > +static void rtl8139_io_writel(RTL8139State *s, uint8_t addr, uint32_t val)
> >  {
> > -    RTL8139State *s = opaque;
> > -
> >      addr &= 0xfc;
> >  
> >      switch (addr)
> > @@ -2952,21 +2946,18 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
> >          default:
> >              DPRINTF("ioport write(l) addr=0x%x val=0x%08x via write(b)\n",
> >                  addr, val);
> > -            rtl8139_io_writeb(opaque, addr, val & 0xff);
> > -            rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
> > -            rtl8139_io_writeb(opaque, addr + 2, (val >> 16) & 0xff);
> > -            rtl8139_io_writeb(opaque, addr + 3, (val >> 24) & 0xff);
> > +            rtl8139_io_writeb(s, addr, val & 0xff);
> > +            rtl8139_io_writeb(s, addr + 1, (val >> 8) & 0xff);
> > +            rtl8139_io_writeb(s, addr + 2, (val >> 16) & 0xff);
> > +            rtl8139_io_writeb(s, addr + 3, (val >> 24) & 0xff);
> >              break;
> >      }
> >  }
> >  
> > -static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
> > +static uint32_t rtl8139_io_readb(RTL8139State *s, uint8_t addr)
> >  {
> > -    RTL8139State *s = opaque;
> >      int ret;
> >  
> > -    addr &= 0xff;
> > -
> >      switch (addr)
> >      {
> >          case MAC0 ... MAC0+5:
> > @@ -3034,9 +3025,8 @@ static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
> >      return ret;
> >  }
> >  
> > -static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
> > +static uint32_t rtl8139_io_readw(RTL8139State *s, uint8_t addr)
> >  {
> > -    RTL8139State *s = opaque;
> >      uint32_t ret;
> >  
> >      addr &= 0xfe; /* mask lower bit */
> > @@ -3101,8 +3091,8 @@ static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
> >          default:
> >              DPRINTF("ioport read(w) addr=0x%x via read(b)\n", addr);
> >  
> > -            ret  = rtl8139_io_readb(opaque, addr);
> > -            ret |= rtl8139_io_readb(opaque, addr + 1) << 8;
> > +            ret  = rtl8139_io_readb(s, addr);
> > +            ret |= rtl8139_io_readb(s, addr + 1) << 8;
> >  
> >              DPRINTF("ioport read(w) addr=0x%x val=0x%04x\n", addr, ret);
> >              break;
> > @@ -3182,71 +3172,40 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
> >      return ret;
> >  }
> >  
> > -/* */
> > -
> > -static void rtl8139_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
> > -{
> > -    rtl8139_io_writeb(opaque, addr & 0xFF, val);
> > -}
> > -
> > -static void rtl8139_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
> > -{
> > -    rtl8139_io_writew(opaque, addr & 0xFF, val);
> > -}
> > -
> > -static void rtl8139_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
> > -{
> > -    rtl8139_io_writel(opaque, addr & 0xFF, val);
> > -}
> > -
> > -static uint32_t rtl8139_ioport_readb(void *opaque, uint32_t addr)
> > +static uint64_t rtl8139_io_read(void *opaque,
> > +                                target_phys_addr_t addr,
> > +                                unsigned size)
> >  {
> > -    return rtl8139_io_readb(opaque, addr & 0xFF);
> > -}
> > -
> > -static uint32_t rtl8139_ioport_readw(void *opaque, uint32_t addr)
> > -{
> > -    return rtl8139_io_readw(opaque, addr & 0xFF);
> > -}
> > -
> > -static uint32_t rtl8139_ioport_readl(void *opaque, uint32_t addr)
> > -{
> > -    return rtl8139_io_readl(opaque, addr & 0xFF);
> > -}
> > -
> > -/* */
> > -
> > -static void rtl8139_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
> > -{
> > -    rtl8139_io_writeb(opaque, addr & 0xFF, val);
> > -}
> > -
> > -static void rtl8139_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
> > -{
> > -    rtl8139_io_writew(opaque, addr & 0xFF, val);
> > -}
> > +    RTL8139State *s = opaque;
> >  
> > -static void rtl8139_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
> > -{
> > -    rtl8139_io_writel(opaque, addr & 0xFF, val);
> > +    switch (size) {
> > +    case 1: return rtl8139_io_readb(s, addr);
> > +    case 2: return rtl8139_io_readw(s, addr);
> > +    case 4: return rtl8139_io_readl(s, addr);
> > +    default: abort();
> > +    }
> >  }
> >  
> > -static uint32_t rtl8139_mmio_readb(void *opaque, target_phys_addr_t addr)
> > +static void rtl8139_io_write(void *opaque,
> > +                             target_phys_addr_t addr,
> > +                             uint64_t data,
> > +                             unsigned size)
> >  {
> > -    return rtl8139_io_readb(opaque, addr & 0xFF);
> > -}
> > +    RTL8139State *s = opaque;
> >  
> > -static uint32_t rtl8139_mmio_readw(void *opaque, target_phys_addr_t addr)
> > -{
> > -    uint32_t val = rtl8139_io_readw(opaque, addr & 0xFF);
> > -    return val;
> > +    switch (size) {
> > +    case 1: return rtl8139_io_writeb(s, addr, data);
> > +    case 2: return rtl8139_io_writew(s, addr, data);
> > +    case 4: return rtl8139_io_writel(s, addr, data);
> > +    default: abort();
> > +    }
> >  }
> >  
> > -static uint32_t rtl8139_mmio_readl(void *opaque, target_phys_addr_t addr)
> > -{
> > -    uint32_t val = rtl8139_io_readl(opaque, addr & 0xFF);
> > -    return val;
> > -}
> > +static MemoryRegionOps rtl8139_io_ops = {
> > +    .read = rtl8139_io_read,
> > +    .write = rtl8139_io_write,
> > +    .endianness = DEVICE_LITTLE_ENDIAN,
> > +};
> >  
> >  static int rtl8139_post_load(void *opaque, int version_id)
> >  {
> > @@ -3283,7 +3242,7 @@ static void rtl8139_pre_save(void *opaque)
> >      rtl8139_set_next_tctr_time(s, current_time);
> >      s->TCTR = muldiv64(current_time - s->TCTR_base, PCI_FREQUENCY,
> >                         get_ticks_per_sec());
> > -    s->rtl8139_mmio_io_addr_dummy = s->rtl8139_mmio_io_addr;
> > +    s->rtl8139_mmio_io_addr_dummy = 0;
> 
> This makes the dummy value fairly useless for preserving new->old
> migration.  Drop it altogether and bump the version or add a subsection
> to prevent migration to old versions that consume this?

I guess to preserve as much as we can, rtl8139_hotplug_ready_needed()
would just return 1 and we'd stuff VMSTATE_UNUSED to fill the gap from
dummy in the vmstate.

Alex

> >  }
> >  
> >  static const VMStateDescription vmstate_rtl8139 = {
> > @@ -3379,33 +3338,6 @@ static const VMStateDescription vmstate_rtl8139 = {
> >  /***********************************************************/
> >  /* PCI RTL8139 definitions */
> >  
> > -static void rtl8139_ioport_map(PCIDevice *pci_dev, int region_num,
> > -                       pcibus_t addr, pcibus_t size, int type)
> > -{
> > -    RTL8139State *s = DO_UPCAST(RTL8139State, dev, pci_dev);
> > -
> > -    register_ioport_write(addr, 0x100, 1, rtl8139_ioport_writeb, s);
> > -    register_ioport_read( addr, 0x100, 1, rtl8139_ioport_readb,  s);
> > -
> > -    register_ioport_write(addr, 0x100, 2, rtl8139_ioport_writew, s);
> > -    register_ioport_read( addr, 0x100, 2, rtl8139_ioport_readw,  s);
> > -
> > -    register_ioport_write(addr, 0x100, 4, rtl8139_ioport_writel, s);
> > -    register_ioport_read( addr, 0x100, 4, rtl8139_ioport_readl,  s);
> > -}
> > -
> > -static CPUReadMemoryFunc * const rtl8139_mmio_read[3] = {
> > -    rtl8139_mmio_readb,
> > -    rtl8139_mmio_readw,
> > -    rtl8139_mmio_readl,
> > -};
> > -
> > -static CPUWriteMemoryFunc * const rtl8139_mmio_write[3] = {
> > -    rtl8139_mmio_writeb,
> > -    rtl8139_mmio_writew,
> > -    rtl8139_mmio_writel,
> > -};
> > -
> >  static void rtl8139_timer(void *opaque)
> >  {
> >      RTL8139State *s = opaque;
> > @@ -3432,7 +3364,8 @@ static int pci_rtl8139_uninit(PCIDevice *dev)
> >  {
> >      RTL8139State *s = DO_UPCAST(RTL8139State, dev, dev);
> >  
> > -    cpu_unregister_io_memory(s->rtl8139_mmio_io_addr);
> > +    memory_region_destroy(&s->bar_io);
> > +    memory_region_destroy(&s->bar_mem);
> >      if (s->cplus_txbuffer) {
> >          qemu_free(s->cplus_txbuffer);
> >          s->cplus_txbuffer = NULL;
> > @@ -3462,15 +3395,12 @@ static int pci_rtl8139_init(PCIDevice *dev)
> >       * list bit in status register, and offset 0xdc seems unused. */
> >      pci_conf[PCI_CAPABILITY_LIST] = 0xdc;
> >  
> > -    /* I/O handler for memory-mapped I/O */
> > -    s->rtl8139_mmio_io_addr =
> > -        cpu_register_io_memory(rtl8139_mmio_read, rtl8139_mmio_write, s,
> > -                               DEVICE_LITTLE_ENDIAN);
> > -
> > -    pci_register_bar(&s->dev, 0, 0x100,
> > -                           PCI_BASE_ADDRESS_SPACE_IO,  rtl8139_ioport_map);
> > -
> > -    pci_register_bar_simple(&s->dev, 1, 0x100, 0, s->rtl8139_mmio_io_addr);
> > +    memory_region_init_io(&s->bar_io, &rtl8139_io_ops, s, "rtl8139", 0x100);
> > +    memory_region_init_io(&s->bar_mem, &rtl8139_io_ops, s, "rtl8139", 0x100);
> > +    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
> > +                            &s->bar_io);
> > +    pci_register_bar_region(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
> > +                            &s->bar_mem);
> >  
> >      qemu_macaddr_default_if_unset(&s->conf.macaddr);
> >  
> 
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 131+ messages in thread

* Re: [RFC v3 30/56] rtl8139: convert to memory API
  2011-07-12 22:41     ` [Qemu-devel] " Alex Williamson
@ 2011-07-13  6:52       ` Avi Kivity
  -1 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-13  6:52 UTC (permalink / raw)
  To: Alex Williamson, Anthony Liguori; +Cc: qemu-devel, kvm

On 07/13/2011 01:41 AM, Alex Williamson wrote:
> >   static int rtl8139_post_load(void *opaque, int version_id)
> >   {
> >  @@ -3283,7 +3242,7 @@ static void rtl8139_pre_save(void *opaque)
> >       rtl8139_set_next_tctr_time(s, current_time);
> >       s->TCTR = muldiv64(current_time - s->TCTR_base, PCI_FREQUENCY,
> >                          get_ticks_per_sec());
> >  -    s->rtl8139_mmio_io_addr_dummy = s->rtl8139_mmio_io_addr;
> >  +    s->rtl8139_mmio_io_addr_dummy = 0;
>
> This makes the dummy value fairly useless for preserving new->old
> migration.

> Drop it altogether and bump the version or add a subsection
> to prevent migration to old versions that consume this?

That means we can't migrate to 0.14, even though 0.14 is safe.

How about we fix 0.13.blah?  And make the rule that we only support 
backwards migration to fully patched releases.  There's no problem 
requiring an updated target; only an updated source is an issue.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.


^ permalink raw reply	[flat|nested] 131+ messages in thread

* Re: [Qemu-devel] [RFC v3 30/56] rtl8139: convert to memory API
@ 2011-07-13  6:52       ` Avi Kivity
  0 siblings, 0 replies; 131+ messages in thread
From: Avi Kivity @ 2011-07-13  6:52 UTC (permalink / raw)
  To: Alex Williamson, Anthony Liguori; +Cc: qemu-devel, kvm

On 07/13/2011 01:41 AM, Alex Williamson wrote:
> >   static int rtl8139_post_load(void *opaque, int version_id)
> >   {
> >  @@ -3283,7 +3242,7 @@ static void rtl8139_pre_save(void *opaque)
> >       rtl8139_set_next_tctr_time(s, current_time);
> >       s->TCTR = muldiv64(current_time - s->TCTR_base, PCI_FREQUENCY,
> >                          get_ticks_per_sec());
> >  -    s->rtl8139_mmio_io_addr_dummy = s->rtl8139_mmio_io_addr;
> >  +    s->rtl8139_mmio_io_addr_dummy = 0;
>
> This makes the dummy value fairly useless for preserving new->old
> migration.

> Drop it altogether and bump the version or add a subsection
> to prevent migration to old versions that consume this?

That means we can't migrate to 0.14, even though 0.14 is safe.

How about we fix 0.13.blah?  And make the rule that we only support 
backwards migration to fully patched releases.  There's no problem 
requiring an updated target; only an updated source is an issue.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

^ permalink raw reply	[flat|nested] 131+ messages in thread

end of thread, other threads:[~2011-07-13  6:53 UTC | newest]

Thread overview: 131+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-10 18:14 [RFC v3 00/56] Memory API Avi Kivity
2011-07-10 18:14 ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 01/56] Hierarchical memory region API Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 02/56] memory: implement dirty tracking Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 03/56] memory: merge adjacent segments of a single memory region Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 04/56] Internal interfaces for memory API Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 05/56] memory: abstract address space operations Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 06/56] memory: rename MemoryRegion::has_ram_addr to ::terminates Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 07/56] memory: late initialization of ram_addr Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 08/56] memory: I/O address space support Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 09/56] exec.c: initialize memory map Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 10/56] ioport: register ranges by byte aligned addresses always Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 11/56] pc: grab system_memory Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 12/56] pc: convert pc_memory_init() to memory API Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 13/56] pc: move global memory map out of pc_init1() and into its callers Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 14/56] pci: pass address space to pci bus when created Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 15/56] pci: add MemoryRegion based BAR management API Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 16/56] sysbus: add MemoryRegion based memory " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 17/56] usb-ohci: convert to MemoryRegion Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 18/56] pci: add API to get a BAR's mapped address Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 19/56] vmsvga: don't remember pci BAR address in callback any more Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 20/56] vga: convert vga and its derivatives to the memory API Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 21/56] cirrus: simplify mmio BAR access functions Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 22/56] cirrus: simplify bitblt " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 23/56] cirrus: simplify vga window mmio " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 24/56] vga: " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 25/56] cirrus: simplify linear framebuffer " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 26/56] Integrate I/O memory regions into qemu Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 27/56] exec.c: fix initialization of system I/O memory region Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 28/56] pci: pass I/O address space to new PCI bus Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 29/56] pci: allow I/O BARs to be registered with pci_register_bar_region() Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 30/56] rtl8139: convert to memory API Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-12 22:41   ` Alex Williamson
2011-07-12 22:41     ` [Qemu-devel] " Alex Williamson
2011-07-12 22:47     ` Alex Williamson
2011-07-12 22:47       ` [Qemu-devel] " Alex Williamson
2011-07-13  6:52     ` Avi Kivity
2011-07-13  6:52       ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 31/56] ac97: " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 20:33   ` malc
2011-07-11  1:42     ` Anthony Liguori
2011-07-11  1:42       ` Anthony Liguori
2011-07-11  6:49       ` Avi Kivity
2011-07-11  6:49         ` Avi Kivity
2011-07-11 10:47       ` Avi Kivity
2011-07-11 10:47         ` Avi Kivity
2011-07-11 22:03         ` malc
2011-07-11 22:03           ` malc
2011-07-12  7:14           ` Avi Kivity
2011-07-12  7:14             ` Avi Kivity
2011-07-10 18:14 ` [RFC v3 32/56] e1000: " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 33/56] eepro100: " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 34/56] es1370: " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 35/56] ide: " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 36/56] memory: add ioeventfd support Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 37/56] ivshmem: convert to memory API Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 38/56] virtio-pci: " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 39/56] ahci: " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 40/56] intel-hda: " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 41/56] lsi53c895a: " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 42/56] ppc: " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 43/56] ne2000: " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 44/56] pcnet: " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 45/56] i6300esb: " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:14 ` [RFC v3 46/56] isa-mmio: concert " Avi Kivity
2011-07-10 18:14   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:15 ` [RFC v3 47/56] sun4u: convert " Avi Kivity
2011-07-10 18:15   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:15 ` [RFC v3 48/56] ehci: " Avi Kivity
2011-07-10 18:15   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:15 ` [RFC v3 49/56] uhci: " Avi Kivity
2011-07-10 18:15   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:15 ` [RFC v3 50/56] xen-platform: " Avi Kivity
2011-07-10 18:15   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:15 ` [RFC v3 51/56] msix: " Avi Kivity
2011-07-10 18:15   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:15 ` [RFC v3 52/56] pci: remove pci_register_bar_simple() Avi Kivity
2011-07-10 18:15   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:15 ` [RFC v3 53/56] pci: convert pci rom to memory API Avi Kivity
2011-07-10 18:15   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:15 ` [RFC v3 54/56] pci: remove pci_register_bar() Avi Kivity
2011-07-10 18:15   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:15 ` [RFC v3 55/56] pci: fold BAR mapping function into its caller Avi Kivity
2011-07-10 18:15   ` [Qemu-devel] " Avi Kivity
2011-07-10 18:15 ` [RFC v3 56/56] pci: rename pci_register_bar_region() to pci_register_bar() Avi Kivity
2011-07-10 18:15   ` [Qemu-devel] " Avi Kivity

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.