qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC PATCH v1 11/11] dma: axidma: Convert to PMA


From: Peter Crosthwaite
Subject: [Qemu-devel] [RFC PATCH v1 11/11] dma: axidma: Convert to PMA
Date: Mon, 2 Jun 2014 19:12:42 -0700

Add MemoryRegion and AddressSpace's for the master attachments of
the DMA engine. The MemoryRegions are exposed as links to be set by
the machine model (or whatever). At realize time, the memory regions
are used to construct the masterable AddressSpace's.

Could have been done simpler as just one AS, but we make an attempt
here to be true to real hardware. The core does physically have three
AXI bus master attachments that could in theory be attached to
different buses. We facilitate that, even though the only user
as of now, connects them all to the one place (the DDR controller
in petalogix_ml605).

Update petalogix_ml605 to make it's connection properly. The changes
to axidma do not support a fallback, so we must make both the
device and machine changes concurrently.

Signed-off-by: Peter Crosthwaite <address@hidden>
---

 hw/dma/xilinx_axidma.c              | 38 ++++++++++++++++++++++++++++++++-----
 hw/microblaze/petalogix_ml605_mmu.c |  4 ++++
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index fb741b8..ab5e1f2 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -29,6 +29,7 @@
 #include "qapi/qmp/qerror.h"
 #include "qemu/main-loop.h"
 
+#include "sysemu/dma.h"
 #include "hw/stream.h"
 
 #define D(x)
@@ -110,6 +111,10 @@ struct Stream {
     unsigned int complete_cnt;
     uint32_t regs[R_MAX];
     uint8_t app[20];
+
+    MemoryRegion *data_mr;
+    AddressSpace *data_as;
+    AddressSpace *sg_as;
 };
 
 struct XilinxAXIDMAStreamSlave {
@@ -129,6 +134,8 @@ struct XilinxAXIDMA {
 
     struct Stream streams[2];
 
+    MemoryRegion *sg_mr;
+
     StreamCanPushNotifyFn notify;
     void *notify_opaque;
 };
@@ -197,7 +204,7 @@ static void stream_desc_load(struct Stream *s, hwaddr addr)
 {
     struct SDesc *d = &s->desc;
 
-    cpu_physical_memory_read(addr, d, sizeof *d);
+    dma_memory_read(s->sg_as, addr, d, sizeof *d);
 
     /* Convert from LE into host endianness.  */
     d->buffer_address = le64_to_cpu(d->buffer_address);
@@ -215,7 +222,7 @@ static void stream_desc_store(struct Stream *s, hwaddr addr)
     d->nxtdesc = cpu_to_le64(d->nxtdesc);
     d->control = cpu_to_le32(d->control);
     d->status = cpu_to_le32(d->status);
-    cpu_physical_memory_write(addr, d, sizeof *d);
+    dma_memory_write(s->sg_as, addr, d, sizeof *d);
 }
 
 static void stream_update_irq(struct Stream *s)
@@ -296,8 +303,8 @@ static void stream_process_mem2s(struct Stream *s, 
StreamSlave *tx_data_dev,
                      txlen + s->pos);
         }
 
-        cpu_physical_memory_read(s->desc.buffer_address,
-                                 txbuf + s->pos, txlen);
+        dma_memory_read(s->data_as, s->desc.buffer_address,
+                        txbuf + s->pos, txlen);
         s->pos += txlen;
 
         if (stream_desc_eof(&s->desc)) {
@@ -346,7 +353,7 @@ static size_t stream_process_s2mem(struct Stream *s, 
unsigned char *buf,
             rxlen = len;
         }
 
-        cpu_physical_memory_write(s->desc.buffer_address, buf + pos, rxlen);
+        dma_memory_write(s->data_as, s->desc.buffer_address, buf + pos, rxlen);
         len -= rxlen;
         pos += rxlen;
 
@@ -535,6 +542,7 @@ static void xilinx_axidma_realize(DeviceState *dev, Error 
**errp)
     XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(
                                                             
&s->rx_control_dev);
     Error *local_err = NULL;
+    AddressSpace *sg_as;
 
     object_property_add_link(OBJECT(ds), "dma", TYPE_XILINX_AXI_DMA,
                              (Object **)&ds->dma,
@@ -557,12 +565,16 @@ static void xilinx_axidma_realize(DeviceState *dev, Error 
**errp)
 
     int i;
 
+    sg_as = address_space_init_shareable(s->sg_mr, NULL);
+
     for (i = 0; i < 2; i++) {
         struct Stream *st = &s->streams[i];
         st->nr = i;
         st->bh = qemu_bh_new(timer_hit, st);
         st->ptimer = ptimer_init(st->bh);
         ptimer_set_freq(st->ptimer, s->freqhz);
+        st->data_as = address_space_init_shareable(st->data_mr, NULL);
+        st->sg_as = sg_as;
     }
     return;
 
@@ -604,6 +616,22 @@ static void xilinx_axidma_init(Object *obj)
     memory_region_init_io(&s->iomem, obj, &axidma_ops, s,
                           "xlnx.axi-dma", R_MAX * 4 * 2);
     sysbus_init_mmio(sbd, &s->iomem);
+
+    object_property_add_link(obj, "mm2s", TYPE_MEMORY_REGION,
+                             (Object **)&s->streams[0].data_mr,
+                             qdev_prop_allow_set_link_before_realize,
+                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
+                             &error_abort);
+    object_property_add_link(obj, "s2mm", TYPE_MEMORY_REGION,
+                             (Object **)&s->streams[1].data_mr,
+                             qdev_prop_allow_set_link_before_realize,
+                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
+                             &error_abort);
+    object_property_add_link(obj, "sg", TYPE_MEMORY_REGION,
+                             (Object **)&s->sg_mr,
+                             qdev_prop_allow_set_link_before_realize,
+                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
+                             &error_abort);
 }
 
 static Property axidma_properties[] = {
diff --git a/hw/microblaze/petalogix_ml605_mmu.c 
b/hw/microblaze/petalogix_ml605_mmu.c
index baf330f..aa755f7 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -157,6 +157,10 @@ petalogix_ml605_init(MachineState *machine)
     eth0 = qdev_create(NULL, "xlnx.axi-ethernet");
     dma = qdev_create(NULL, "xlnx.axi-dma");
 
+    object_property_set_link(OBJECT(dma), OBJECT(ddr_mr), "sg", &error_abort);
+    object_property_set_link(OBJECT(dma), OBJECT(ddr_mr), "s2mm", 
&error_abort);
+    object_property_set_link(OBJECT(dma), OBJECT(ddr_mr), "mm2s", 
&error_abort);
+
     /* FIXME: attach to the sysbus instead */
     object_property_add_child(qdev_get_machine(), "xilinx-eth", OBJECT(eth0),
                               NULL);
-- 
2.0.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]