qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 2/3] iommu: add support for the isa dma engine


From: Jason Baron
Subject: [Qemu-devel] [PATCH 2/3] iommu: add support for the isa dma engine
Date: Wed, 20 Jun 2012 16:11:09 -0400

Provide infastructure for iommu support to the existing isa dma engine. This
allows chipsets to support an iommu sitting between memory and the dma engine.
Code is layered on top of Benjamin Herrenschmidt's generic iommu infastructure.

In addition, the patch more tightly couples isa devices with the existing
dma engine by changing the prototype of DMA_register channel:

-void DMA_register_channel (int nchan,
+void DMA_register_channel (ISADevice *dev, int nchan,
                            DMA_transfer_handler transfer_handler,
                            void *opaque)

Signed-off-by: Jason Baron <address@hidden>
---
 hw/cs4231a.c |    2 +-
 hw/dma.c     |   19 ++++++++++++-------
 hw/fdc.c     |   10 +++++-----
 hw/gus.c     |    2 +-
 hw/isa-bus.c |    3 +++
 hw/isa.h     |    4 +++-
 hw/sb16.c    |    4 ++--
 hw/sun4m.c   |    2 +-
 hw/sun4u.c   |    2 +-
 9 files changed, 29 insertions(+), 19 deletions(-)

diff --git a/hw/cs4231a.c b/hw/cs4231a.c
index e07b9d6..81163f9 100644
--- a/hw/cs4231a.c
+++ b/hw/cs4231a.c
@@ -650,7 +650,7 @@ static int cs4231a_initfn (ISADevice *dev)
     memory_region_init_io (&s->ioports, &cs_ioport_ops, s, "cs4231a", 4);
     isa_register_ioport (dev, &s->ioports, s->port);
 
-    DMA_register_channel (s->dma, cs_dma_read, s);
+    DMA_register_channel (dev, s->dma, cs_dma_read, s);
 
     qemu_register_reset (cs_reset, s);
     cs_reset (s);
diff --git a/hw/dma.c b/hw/dma.c
index 0a9322d..0a323c4 100644
--- a/hw/dma.c
+++ b/hw/dma.c
@@ -45,6 +45,7 @@ struct dma_regs {
     uint8_t eop;
     DMA_transfer_handler transfer_handler;
     void *opaque;
+    DMAContext *dma_ctx;
 };
 
 #define ADDR 0
@@ -393,7 +394,7 @@ static void DMA_run_bh(void *unused)
     DMA_run();
 }
 
-void DMA_register_channel (int nchan,
+void DMA_register_channel (ISADevice *dev, int nchan,
                            DMA_transfer_handler transfer_handler,
                            void *opaque)
 {
@@ -406,18 +407,22 @@ void DMA_register_channel (int nchan,
     r = dma_controllers[ncont].regs + ichan;
     r->transfer_handler = transfer_handler;
     r->opaque = opaque;
+    if (dev)
+        r->dma_ctx = dev->dma;
+    else
+        r->dma_ctx = NULL;
 }
 
 int DMA_read_memory (int nchan, void *buf, int pos, int len)
 {
     struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3];
-    target_phys_addr_t addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | 
r->now[ADDR];
+    dma_addr_t addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | 
r->now[ADDR];
 
     if (r->mode & 0x20) {
         int i;
         uint8_t *p = buf;
 
-        cpu_physical_memory_read (addr - pos - len, buf, len);
+        dma_memory_read(r->dma_ctx, addr - pos - len, buf, len);
         /* What about 16bit transfers? */
         for (i = 0; i < len >> 1; i++) {
             uint8_t b = p[len - i - 1];
@@ -425,7 +430,7 @@ int DMA_read_memory (int nchan, void *buf, int pos, int len)
         }
     }
     else
-        cpu_physical_memory_read (addr + pos, buf, len);
+        dma_memory_read(r->dma_ctx,  addr + pos, buf, len);
 
     return len;
 }
@@ -433,13 +438,13 @@ int DMA_read_memory (int nchan, void *buf, int pos, int 
len)
 int DMA_write_memory (int nchan, void *buf, int pos, int len)
 {
     struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3];
-    target_phys_addr_t addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | 
r->now[ADDR];
+    dma_addr_t addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | 
r->now[ADDR];
 
     if (r->mode & 0x20) {
         int i;
         uint8_t *p = buf;
 
-        cpu_physical_memory_write (addr - pos - len, buf, len);
+        dma_memory_write(r->dma_ctx, addr - pos - len, buf, len);
         /* What about 16bit transfers? */
         for (i = 0; i < len; i++) {
             uint8_t b = p[len - i - 1];
@@ -447,7 +452,7 @@ int DMA_write_memory (int nchan, void *buf, int pos, int 
len)
         }
     }
     else
-        cpu_physical_memory_write (addr + pos, buf, len);
+        dma_memory_write(r->dma_ctx, addr + pos, buf, len);
 
     return len;
 }
diff --git a/hw/fdc.c b/hw/fdc.c
index 78b4e33..8afc467 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -1951,7 +1951,7 @@ void sun4m_fdctrl_init(qemu_irq irq, target_phys_addr_t 
io_base,
     *fdc_tc = qdev_get_gpio_in(dev, 0);
 }
 
-static int fdctrl_init_common(FDCtrl *fdctrl)
+static int fdctrl_init_common(FDCtrl *fdctrl, ISADevice *dev)
 {
     int i, j;
     static int command_tables_inited = 0;
@@ -1979,7 +1979,7 @@ static int fdctrl_init_common(FDCtrl *fdctrl)
     fdctrl->num_floppies = MAX_FD;
 
     if (fdctrl->dma_chann != -1)
-        DMA_register_channel(fdctrl->dma_chann, &fdctrl_transfer_handler, 
fdctrl);
+        DMA_register_channel(dev, fdctrl->dma_chann, &fdctrl_transfer_handler, 
fdctrl);
     return fdctrl_connect_drives(fdctrl);
 }
 
@@ -2001,7 +2001,7 @@ static int isabus_fdc_init1(ISADevice *dev)
     fdctrl->dma_chann = isa->dma;
 
     qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 2);
-    ret = fdctrl_init_common(fdctrl);
+    ret = fdctrl_init_common(fdctrl, dev);
 
     add_boot_device_path(isa->bootindexA, &dev->qdev, "/address@hidden");
     add_boot_device_path(isa->bootindexB, &dev->qdev, "/address@hidden");
@@ -2022,7 +2022,7 @@ static int sysbus_fdc_init1(SysBusDevice *dev)
     fdctrl->dma_chann = -1;
 
     qdev_set_legacy_instance_id(&dev->qdev, 0 /* io */, 2); /* FIXME */
-    ret = fdctrl_init_common(fdctrl);
+    ret = fdctrl_init_common(fdctrl, NULL);
 
     return ret;
 }
@@ -2039,7 +2039,7 @@ static int sun4m_fdc_init1(SysBusDevice *dev)
 
     fdctrl->sun4m = 1;
     qdev_set_legacy_instance_id(&dev->qdev, 0 /* io */, 2); /* FIXME */
-    return fdctrl_init_common(fdctrl);
+    return fdctrl_init_common(fdctrl, NULL);
 }
 
 void fdc_get_bs(BlockDriverState *bs[], ISADevice *dev)
diff --git a/hw/gus.c b/hw/gus.c
index 840d098..d827337 100644
--- a/hw/gus.c
+++ b/hw/gus.c
@@ -282,7 +282,7 @@ static int gus_initfn (ISADevice *dev)
     isa_register_portio_list (dev, (s->port + 0x100) & 0xf00,
                               gus_portio_list2, s, "gus");
 
-    DMA_register_channel (s->emu.gusdma, GUS_read_DMA, s);
+    DMA_register_channel (dev, s->emu.gusdma, GUS_read_DMA, s);
     s->emu.himemaddr = s->himem;
     s->emu.gusdatapos = s->emu.himemaddr + 1024 * 1024 + 32;
     s->emu.opaque = s;
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index f9b2373..cfd7501 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -130,6 +130,9 @@ static int isa_qdev_init(DeviceState *qdev)
         return klass->init(dev);
     }
 
+    /* iommu setup */
+    dev->dma = NULL;
+
     return 0;
 }
 
diff --git a/hw/isa.h b/hw/isa.h
index dc97052..a1c3f25 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -6,6 +6,7 @@
 #include "ioport.h"
 #include "memory.h"
 #include "qdev.h"
+#include "dma.h"
 
 #define ISA_NUM_IRQS 16
 
@@ -36,6 +37,7 @@ struct ISADevice {
     uint32_t isairq[2];
     int nirqs;
     int ioport_id;
+    DMAContext *dma;
 };
 
 ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space_io);
@@ -95,7 +97,7 @@ void DMA_hold_DREQ (int nchan);
 void DMA_release_DREQ (int nchan);
 void DMA_schedule(int nchan);
 void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit);
-void DMA_register_channel (int nchan,
+void DMA_register_channel (ISADevice *dev, int nchan,
                            DMA_transfer_handler transfer_handler,
                            void *opaque);
 #endif
diff --git a/hw/sb16.c b/hw/sb16.c
index c81455d..d52dc57 100644
--- a/hw/sb16.c
+++ b/hw/sb16.c
@@ -1377,8 +1377,8 @@ static int sb16_initfn (ISADevice *dev)
 
     isa_register_portio_list (dev, s->port, sb16_ioport_list, s, "sb16");
 
-    DMA_register_channel (s->hdma, SB_read_DMA, s);
-    DMA_register_channel (s->dma, SB_read_DMA, s);
+    DMA_register_channel (dev, s->hdma, SB_read_DMA, s);
+    DMA_register_channel (dev, s->dma, SB_read_DMA, s);
     s->can_write = 1;
 
     AUD_register_card ("sb16", &s->card);
diff --git a/hw/sun4m.c b/hw/sun4m.c
index a959261..7a01c94 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -155,7 +155,7 @@ void DMA_init(int high_page_enable, qemu_irq 
*cpu_request_exit)
 {
 }
 
-void DMA_register_channel (int nchan,
+void DMA_register_channel (ISADevice *dev, int nchan,
                            DMA_transfer_handler transfer_handler,
                            void *opaque)
 {
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 137a7c6..5964559 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -117,7 +117,7 @@ void DMA_init(int high_page_enable, qemu_irq 
*cpu_request_exit)
 {
 }
 
-void DMA_register_channel (int nchan,
+void DMA_register_channel (ISADevice *dev, int nchan,
                            DMA_transfer_handler transfer_handler,
                            void *opaque)
 {
-- 
1.7.1




reply via email to

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