All of lore.kernel.org
 help / color / mirror / Atom feed
From: Avi Kivity <avi@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 13/16] Direct dispatch through MemoryRegion
Date: Mon,  2 Jan 2012 18:33:32 +0200	[thread overview]
Message-ID: <1325522015-503-14-git-send-email-avi@redhat.com> (raw)
In-Reply-To: <1325522015-503-1-git-send-email-avi@redhat.com>

Now that all mmio goes through MemoryRegions, we can convert
io_mem_opaque to be a MemoryRegion pointer, and remove the thunks
that convert from old-style CPU{Read,Write}MemoryFunc to MemoryRegionOps.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 exec-all.h      |    4 +-
 exec-obsolete.h |    5 +-
 exec.c          |   40 +++++-------------
 memory.c        |  122 ++++++++++++++++++-------------------------------------
 4 files changed, 53 insertions(+), 118 deletions(-)

diff --git a/exec-all.h b/exec-all.h
index 3d72952..51d01f2 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -302,9 +302,7 @@ extern void *tci_tb_ptr;
 uint64_t io_mem_read(int index, target_phys_addr_t addr, unsigned size);
 void io_mem_write(int index, target_phys_addr_t addr, uint64_t value,
                   unsigned size);
-extern CPUWriteMemoryFunc *_io_mem_write[IO_MEM_NB_ENTRIES][4];
-extern CPUReadMemoryFunc *_io_mem_read[IO_MEM_NB_ENTRIES][4];
-extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
+extern struct MemoryRegion *io_mem_region[IO_MEM_NB_ENTRIES];
 
 void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx,
               void *retaddr);
diff --git a/exec-obsolete.h b/exec-obsolete.h
index e08e750..f8af27e 100644
--- a/exec-obsolete.h
+++ b/exec-obsolete.h
@@ -31,9 +31,8 @@ ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
 void qemu_ram_free(ram_addr_t addr);
 void qemu_ram_free_from_ptr(ram_addr_t addr);
 
-int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read,
-                           CPUWriteMemoryFunc * const *mem_write,
-                           void *opaque);
+struct MemoryRegion;
+int cpu_register_io_memory(MemoryRegion *mr);
 void cpu_unregister_io_memory(int table_address);
 
 struct MemoryRegionSection;
diff --git a/exec.c b/exec.c
index fc1dcb7..b443dbb 100644
--- a/exec.c
+++ b/exec.c
@@ -208,9 +208,7 @@
 static void memory_map_init(void);
 
 /* io memory support */
-CPUWriteMemoryFunc *_io_mem_write[IO_MEM_NB_ENTRIES][4];
-CPUReadMemoryFunc *_io_mem_read[IO_MEM_NB_ENTRIES][4];
-void *io_mem_opaque[IO_MEM_NB_ENTRIES];
+MemoryRegion *io_mem_region[IO_MEM_NB_ENTRIES];
 static char io_mem_used[IO_MEM_NB_ENTRIES];
 static MemoryRegion io_mem_watch;
 #endif
@@ -2563,8 +2561,10 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section,
                                            &p->phys_offset, orig_memory,
                                            p->region_offset);
                 } else {
-                    subpage = io_mem_opaque[(orig_memory & ~TARGET_PAGE_MASK)
-                                            >> IO_MEM_SHIFT];
+                    MemoryRegion *mr
+                        = io_mem_region[(orig_memory & ~TARGET_PAGE_MASK)
+                                        >> IO_MEM_SHIFT];
+                    subpage = container_of(mr, subpage_t, iomem);
                 }
                 subpage_register(subpage, start_addr2, end_addr2, phys_offset,
                                  region_offset);
@@ -3427,13 +3427,8 @@ static int get_free_io_mem_idx(void)
    modified. If it is zero, a new io zone is allocated. The return
    value can be used with cpu_register_physical_memory(). (-1) is
    returned if error. */
-static int cpu_register_io_memory_fixed(int io_index,
-                                        CPUReadMemoryFunc * const *mem_read,
-                                        CPUWriteMemoryFunc * const *mem_write,
-                                        void *opaque)
+static int cpu_register_io_memory_fixed(int io_index, MemoryRegion *mr)
 {
-    int i;
-
     if (io_index <= 0) {
         io_index = get_free_io_mem_idx();
         if (io_index == -1)
@@ -3444,36 +3439,21 @@ static int cpu_register_io_memory_fixed(int io_index,
             return -1;
     }
 
-    for (i = 0; i < 3; ++i) {
-        assert(mem_read[i]);
-        _io_mem_read[io_index][i] = mem_read[i];
-    }
-    for (i = 0; i < 3; ++i) {
-        assert(mem_write[i]);
-        _io_mem_write[io_index][i] = mem_write[i];
-    }
-    io_mem_opaque[io_index] = opaque;
+    io_mem_region[io_index] = mr;
 
     return (io_index << IO_MEM_SHIFT);
 }
 
-int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read,
-                           CPUWriteMemoryFunc * const *mem_write,
-                           void *opaque)
+int cpu_register_io_memory(MemoryRegion *mr)
 {
-    return cpu_register_io_memory_fixed(0, mem_read, mem_write, opaque);
+    return cpu_register_io_memory_fixed(0, mr);
 }
 
 void cpu_unregister_io_memory(int io_table_address)
 {
-    int i;
     int io_index = io_table_address >> IO_MEM_SHIFT;
 
-    for (i=0;i < 3; i++) {
-        _io_mem_read[io_index][i] = NULL;
-        _io_mem_write[io_index][i] = NULL;
-    }
-    io_mem_opaque[io_index] = NULL;
+    io_mem_region[io_index] = NULL;
     io_mem_used[io_index] = 0;
 }
 
diff --git a/memory.c b/memory.c
index e34bc65..25b36ff 100644
--- a/memory.c
+++ b/memory.c
@@ -906,11 +906,10 @@ static bool memory_region_access_valid(MemoryRegion *mr,
     return true;
 }
 
-static uint32_t memory_region_read_thunk_n(void *_mr,
-                                           target_phys_addr_t addr,
-                                           unsigned size)
+static uint64_t memory_region_dispatch_read1(MemoryRegion *mr,
+                                             target_phys_addr_t addr,
+                                             unsigned size)
 {
-    MemoryRegion *mr = _mr;
     uint64_t data = 0;
 
     if (!memory_region_access_valid(mr, addr, size, false)) {
@@ -930,17 +929,45 @@ static uint32_t memory_region_read_thunk_n(void *_mr,
     return data;
 }
 
-static void memory_region_write_thunk_n(void *_mr,
-                                        target_phys_addr_t addr,
-                                        unsigned size,
-                                        uint64_t data)
+static void adjust_endianness(MemoryRegion *mr, uint64_t *data, unsigned size)
 {
-    MemoryRegion *mr = _mr;
+    if (memory_region_wrong_endianness(mr)) {
+        switch (size) {
+        case 1:
+            break;
+        case 2:
+            *data = bswap16(*data);
+            break;
+        case 4:
+            *data = bswap32(*data);
+        default:
+            abort();
+        }
+    }
+}
+
+static uint64_t memory_region_dispatch_read(MemoryRegion *mr,
+                                            target_phys_addr_t addr,
+                                            unsigned size)
+{
+    uint64_t ret;
+
+    ret = memory_region_dispatch_read1(mr, addr, size);
+    adjust_endianness(mr, &ret, size);
+    return ret;
+}
 
+static void memory_region_dispatch_write(MemoryRegion *mr,
+                                         target_phys_addr_t addr,
+                                         uint64_t data,
+                                         unsigned size)
+{
     if (!memory_region_access_valid(mr, addr, size, true)) {
         return; /* FIXME: better signalling */
     }
 
+    adjust_endianness(mr, &data, size);
+
     if (!mr->ops->write) {
         mr->ops->old_mmio.write[bitops_ffsl(size)](mr->opaque, addr, data);
         return;
@@ -953,69 +980,6 @@ static void memory_region_write_thunk_n(void *_mr,
                               memory_region_write_accessor, mr);
 }
 
-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)
-{
-    uint32_t data;
-
-    data = memory_region_read_thunk_n(mr, addr, 2);
-    if (memory_region_wrong_endianness(mr)) {
-        data = bswap16(data);
-    }
-    return data;
-}
-
-static uint32_t memory_region_read_thunk_l(void *mr, target_phys_addr_t addr)
-{
-    uint32_t data;
-
-    data = memory_region_read_thunk_n(mr, addr, 4);
-    if (memory_region_wrong_endianness(mr)) {
-        data = bswap32(data);
-    }
-    return data;
-}
-
-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)
-{
-    if (memory_region_wrong_endianness(mr)) {
-        data = bswap16(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)
-{
-    if (memory_region_wrong_endianness(mr)) {
-        data = bswap32(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,
@@ -1027,9 +991,7 @@ void memory_region_init_io(MemoryRegion *mr,
     mr->opaque = opaque;
     mr->terminates = true;
     mr->destructor = memory_region_destructor_iomem;
-    mr->ram_addr = cpu_register_io_memory(memory_region_read_thunk,
-                                          memory_region_write_thunk,
-                                          mr);
+    mr->ram_addr = cpu_register_io_memory(mr);
 }
 
 void memory_region_init_ram(MemoryRegion *mr,
@@ -1078,9 +1040,7 @@ void memory_region_init_rom_device(MemoryRegion *mr,
     mr->terminates = true;
     mr->destructor = memory_region_destructor_rom_device;
     mr->ram_addr = qemu_ram_alloc(size, mr);
-    mr->ram_addr |= cpu_register_io_memory(memory_region_read_thunk,
-                                           memory_region_write_thunk,
-                                           mr);
+    mr->ram_addr |= cpu_register_io_memory(mr);
     mr->ram_addr |= IO_MEM_ROMD;
 }
 
@@ -1552,15 +1512,13 @@ void set_system_io_map(MemoryRegion *mr)
 
 uint64_t io_mem_read(int io_index, target_phys_addr_t addr, unsigned size)
 {
-    return _io_mem_read[io_index][bitops_ffsl(size)](io_mem_opaque[io_index],
-                                                     addr);
+    return memory_region_dispatch_read(io_mem_region[io_index], addr, size);
 }
 
 void io_mem_write(int io_index, target_phys_addr_t addr,
                   uint64_t val, unsigned size)
 {
-    _io_mem_write[io_index][bitops_ffsl(size)](io_mem_opaque[io_index],
-                                               addr, val);
+    memory_region_dispatch_write(io_mem_region[io_index], addr, val, size);
 }
 
 typedef struct MemoryRegionList MemoryRegionList;
-- 
1.7.7.1

  parent reply	other threads:[~2012-01-02 16:34 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-01-02 16:33 [Qemu-devel] [PATCH 00/16] Kill old-style I/O dispatch Avi Kivity
2012-01-02 16:33 ` [Qemu-devel] [PATCH 01/16] memory: move endianness compensation to memory core Avi Kivity
2012-01-05 18:26   ` Andreas Färber
2012-01-07  7:52   ` Andreas Färber
2012-01-02 16:33 ` [Qemu-devel] [PATCH 02/16] exec: make phys_page_find() return a temporary Avi Kivity
2012-01-02 16:33 ` [Qemu-devel] [PATCH 03/16] memory: move mmio access to functions Avi Kivity
2012-01-02 16:33 ` [Qemu-devel] [PATCH 04/16] memory: remove MemoryRegion::backend_registered Avi Kivity
2012-01-02 16:33 ` [Qemu-devel] [PATCH 05/16] Fix wrong region_offset when overlaying a page with another Avi Kivity
2012-01-02 16:33 ` [Qemu-devel] [PATCH 06/16] Avoid range comparisons on io index types Avi Kivity
2012-01-02 21:58   ` Richard Henderson
2012-01-03  8:46     ` Avi Kivity
2012-01-02 16:33 ` [Qemu-devel] [PATCH 07/16] Uninline get_page_addr_code() Avi Kivity
2012-01-02 16:33 ` [Qemu-devel] [PATCH 08/16] Convert IO_MEM_{RAM, ROM, UNASSIGNED, NOTDIRTY} to MemoryRegions Avi Kivity
2012-01-02 22:16   ` Richard Henderson
2012-01-03  8:54     ` Avi Kivity
2012-01-06  8:31   ` Stefan Hajnoczi
2012-01-02 16:33 ` [Qemu-devel] [PATCH 09/16] Switch cpu_register_physical_memory_log() to use MemoryRegions Avi Kivity
2012-01-02 16:33 ` [Qemu-devel] [PATCH 10/16] Convert the subpage wrapper to be a MemoryRegion Avi Kivity
2012-01-02 16:33 ` [Qemu-devel] [PATCH 11/16] Convert IO_MEM_SUBPAGE_RAM " Avi Kivity
2012-01-02 16:33 ` [Qemu-devel] [PATCH 12/16] Convert io_mem_watch " Avi Kivity
2012-01-02 16:33 ` Avi Kivity [this message]
2012-01-07  7:55   ` [Qemu-devel] [PATCH 13/16] Direct dispatch through MemoryRegion Andreas Färber
2012-01-02 16:33 ` [Qemu-devel] [PATCH 14/16] Remove IO_MEM_SUBPAGE Avi Kivity
2012-01-02 16:33 ` [Qemu-devel] [PATCH 15/16] Drop IO_MEM_ROMD Avi Kivity
2012-01-02 16:33 ` [Qemu-devel] [PATCH 16/16] Remove IO_MEM_SHIFT Avi Kivity
2012-01-02 22:36 ` [Qemu-devel] [PATCH 00/16] Kill old-style I/O dispatch Richard Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1325522015-503-14-git-send-email-avi@redhat.com \
    --to=avi@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.