diff mbox

[V3,6/8] hw/dma.c: replace register_ioport*

Message ID 4f5403248302efb8511d6f92b9603d5a651c25bd.1333639502.git.julien.grall@citrix.com
State New
Headers show

Commit Message

Julien Grall April 5, 2012, 3:33 p.m. UTC
This patch replaces all register_ioport* be the new memory API functions.
It permits to use the new Memory stuff like listener.

Signed-off-by: Julien Grall <julien.grall@citrix.com>
---
 hw/dma.c |   84 ++++++++++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 60 insertions(+), 24 deletions(-)

Comments

Avi Kivity April 8, 2012, 2:09 p.m. UTC | #1
On 04/05/2012 06:33 PM, Julien Grall wrote:
> This patch replaces all register_ioport* be the new memory API functions.
> It permits to use the new Memory stuff like listener.

I see

/home/tlv/akivity/qemu/hw/dma.c:483:5: error: initialization from
incompatible pointer type [-Werror]
/home/tlv/akivity/qemu/hw/dma.c:483:5: error: (near initialization for
‘channel_io_ops.read’) [-Werror]
Avi Kivity April 8, 2012, 2:21 p.m. UTC | #2
On 04/05/2012 06:33 PM, Julien Grall wrote:
> This patch replaces all register_ioport* be the new memory API functions.
> It permits to use the new Memory stuff like listener.
>
>  enum {
> @@ -149,7 +151,7 @@ static inline int getff (struct dma_cont *d)
>      return ff;
>  }
>  
> -static uint32_t read_chan (void *opaque, uint32_t nport)
> +static uint64_t read_chan(void *opaque, uint64_t nport, unsigned size)
>  {
>      struct dma_cont *d = opaque;
>      int ichan, nreg, iport, ff, val, dir;
> @@ -171,7 +173,8 @@ static uint32_t read_chan (void *opaque, uint32_t nport)
>      return (val >> (d->dshift + (ff << 3))) & 0xff;
>  }
>  
> -static void write_chan (void *opaque, uint32_t nport, uint32_t data)
> +static void write_chan(void *opaque, target_phys_addr_t nport, uint64_t data,
> +                       unsigned size)
>  {
>      struct dma_cont *d = opaque;
>      int iport, ichan, nreg;
> @@ -189,7 +192,8 @@ static void write_chan (void *opaque, uint32_t nport, uint32_t data)
>      }
>  }
>  
> +
>  /* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */
>  static void dma_init2(struct dma_cont *d, int base, int dshift,
>                        int page_base, int pageh_base,
>                        qemu_irq *cpu_request_exit)
>  {
> -    static const int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 };
>      int i;
>  
>      d->dshift = dshift;
>      d->cpu_request_exit = cpu_request_exit;
>      for (i = 0; i < 8; i++) {
> -        register_ioport_write (base + (i << dshift), 1, 1, write_chan, d);
> -        register_ioport_read (base + (i << dshift), 1, 1, read_chan, d);
> +        memory_region_init_io(&d->channel_io[i], &channel_io_ops, d,
> +                              "dma-chan", 1);
> +        memory_region_add_subregion(isa_address_space_io(NULL),
> +                                    base + (i << dshift), &d->channel_io[i]);
>      }
>

This isn't quite correct.  MemoryRegion callback addresses are offsets,
so 'nport' will always be 0 and ichan/nreg will be incorrect in
read_chan() write_chan().

This is fixable, but dshift makes it quite hard.  We need either two
separate regions for even i and odd i (one region per register), or make
one region per channel of size (2 << dshift), and pass the channel as
the opaque instead of the .  Or even one large region of size (8 <<
dshift), then nport becomes correct again.

Please verify that the other conversions don't suffer from this problem.
diff mbox

Patch

diff --git a/hw/dma.c b/hw/dma.c
index 0a9322d..d423ddd 100644
--- a/hw/dma.c
+++ b/hw/dma.c
@@ -58,6 +58,8 @@  static struct dma_cont {
     int dshift;
     struct dma_regs regs[4];
     qemu_irq *cpu_request_exit;
+    MemoryRegion channel_io[8];
+    MemoryRegion cont_io[8];
 } dma_controllers[2];
 
 enum {
@@ -149,7 +151,7 @@  static inline int getff (struct dma_cont *d)
     return ff;
 }
 
-static uint32_t read_chan (void *opaque, uint32_t nport)
+static uint64_t read_chan(void *opaque, uint64_t nport, unsigned size)
 {
     struct dma_cont *d = opaque;
     int ichan, nreg, iport, ff, val, dir;
@@ -171,7 +173,8 @@  static uint32_t read_chan (void *opaque, uint32_t nport)
     return (val >> (d->dshift + (ff << 3))) & 0xff;
 }
 
-static void write_chan (void *opaque, uint32_t nport, uint32_t data)
+static void write_chan(void *opaque, target_phys_addr_t nport, uint64_t data,
+                       unsigned size)
 {
     struct dma_cont *d = opaque;
     int iport, ichan, nreg;
@@ -189,7 +192,8 @@  static void write_chan (void *opaque, uint32_t nport, uint32_t data)
     }
 }
 
-static void write_cont (void *opaque, uint32_t nport, uint32_t data)
+static void write_cont(void *opaque, target_phys_addr_t nport, uint64_t data,
+                       unsigned size)
 {
     struct dma_cont *d = opaque;
     int iport, ichan = 0;
@@ -198,7 +202,7 @@  static void write_cont (void *opaque, uint32_t nport, uint32_t data)
     switch (iport) {
     case 0x08:                  /* command */
         if ((data != 0) && (data & CMD_NOT_SUPPORTED)) {
-            dolog ("command %#x not supported\n", data);
+            dolog("command %#lx not supported\n", data);
             return;
         }
         d->command = data;
@@ -277,7 +281,8 @@  static void write_cont (void *opaque, uint32_t nport, uint32_t data)
 #endif
 }
 
-static uint32_t read_cont (void *opaque, uint32_t nport)
+static uint64_t read_cont(void *opaque, target_phys_addr_t nport,
+                          unsigned size)
 {
     struct dma_cont *d = opaque;
     int iport, val;
@@ -463,7 +468,7 @@  void DMA_schedule(int nchan)
 static void dma_reset(void *opaque)
 {
     struct dma_cont *d = opaque;
-    write_cont (d, (0x0d << d->dshift), 0);
+    write_cont(d, (0x0d << d->dshift), 0, 1);
 }
 
 static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len)
@@ -473,37 +478,68 @@  static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len)
     return dma_pos;
 }
 
+
+static const MemoryRegionOps channel_io_ops = {
+    .read = read_chan,
+    .write = write_chan,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
+/* IOport from page_base */
+static const MemoryRegionPortio page_portio_list[] = {
+    { 0x01, 3, 1, .write = write_page, .read = read_page, },
+    { 0x07, 1, 1, .write = write_page, .read = read_page, },
+    PORTIO_END_OF_LIST(),
+};
+
+/* IOport from pageh_base */
+static const MemoryRegionPortio pageh_portio_list[] = {
+    { 0x01, 3, 1, .write = write_pageh, .read = read_pageh, },
+    { 0x07, 3, 1, .write = write_pageh, .read = read_pageh, },
+    PORTIO_END_OF_LIST(),
+};
+
+static const MemoryRegionOps cont_io_ops = {
+    .read = read_cont,
+    .write = write_cont,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
 /* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */
 static void dma_init2(struct dma_cont *d, int base, int dshift,
                       int page_base, int pageh_base,
                       qemu_irq *cpu_request_exit)
 {
-    static const int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 };
     int i;
 
     d->dshift = dshift;
     d->cpu_request_exit = cpu_request_exit;
     for (i = 0; i < 8; i++) {
-        register_ioport_write (base + (i << dshift), 1, 1, write_chan, d);
-        register_ioport_read (base + (i << dshift), 1, 1, read_chan, d);
+        memory_region_init_io(&d->channel_io[i], &channel_io_ops, d,
+                              "dma-chan", 1);
+        memory_region_add_subregion(isa_address_space_io(NULL),
+                                    base + (i << dshift), &d->channel_io[i]);
     }
-    for (i = 0; i < ARRAY_SIZE (page_port_list); i++) {
-        register_ioport_write (page_base + page_port_list[i], 1, 1,
-                               write_page, d);
-        register_ioport_read (page_base + page_port_list[i], 1, 1,
-                              read_page, d);
-        if (pageh_base >= 0) {
-            register_ioport_write (pageh_base + page_port_list[i], 1, 1,
-                                   write_pageh, d);
-            register_ioport_read (pageh_base + page_port_list[i], 1, 1,
-                                  read_pageh, d);
-        }
+
+    isa_register_portio_list(NULL, page_base, page_portio_list, d,
+                             "dma-page");
+    if (pageh_base >= 0) {
+        isa_register_portio_list(NULL, pageh_base, pageh_portio_list, d,
+                                 "dma-pageh");
     }
     for (i = 0; i < 8; i++) {
-        register_ioport_write (base + ((i + 8) << dshift), 1, 1,
-                               write_cont, d);
-        register_ioport_read (base + ((i + 8) << dshift), 1, 1,
-                              read_cont, d);
+        memory_region_init_io(&d->cont_io[i], &cont_io_ops, d, "dma-cont", 1);
+        memory_region_add_subregion(isa_address_space_io(NULL),
+                                    base + ((i + 8) << dshift),
+                                    &d->cont_io[i]);
     }
     qemu_register_reset(dma_reset, d);
     dma_reset(d);