@@ -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);
@@ -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;
}
@@ -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, "/floppy@0");
add_boot_device_path(isa->bootindexB, &dev->qdev, "/floppy@1");
@@ -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)
@@ -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;
@@ -130,6 +130,9 @@ static int isa_qdev_init(DeviceState *qdev)
return klass->init(dev);
}
+ /* iommu setup */
+ dev->dma = NULL;
+
return 0;
}
@@ -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
@@ -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);
@@ -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)
{
@@ -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)
{
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 <jbaron@redhat.com> --- 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(-)