Index: qemu/hw/sun4m.c =================================================================== --- qemu.orig/hw/sun4m.c 2007-08-14 19:26:56.000000000 +0000 +++ qemu/hw/sun4m.c 2007-08-14 19:37:20.000000000 +0000 @@ -289,6 +289,12 @@ slavio_set_power_fail(slavio_misc, 1); } +static void sparc_dma_memory_rw(void *opaque, target_phys_addr_t addr, + uint8_t *buf, int len, int is_write) +{ + cpu_physical_memory_rw(addr, buf, len, is_write); +} + static void main_cpu_reset(void *opaque) { CPUState *env = opaque; @@ -315,6 +321,7 @@ const sparc_def_t *def; qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq, *espdma_irq, *ledma_irq; + qemu_dma *physical_dma, *dvma; /* init CPUs */ sparc_find_by_name(cpu_model, &def); @@ -343,7 +350,10 @@ /* allocate RAM */ cpu_register_physical_memory(0, RAM_size, 0); - iommu = iommu_init(hwdef->iommu_base); + physical_dma = qemu_init_dma(sparc_dma_memory_rw, NULL); + + iommu = iommu_init(hwdef->iommu_base, physical_dma, &dvma); + slavio_intctl = slavio_intctl_init(hwdef->intctl_base, hwdef->intctl_base + 0x10000ULL, &hwdef->intbit_to_level[0], Index: qemu/hw/iommu.c =================================================================== --- qemu.orig/hw/iommu.c 2007-08-14 19:27:35.000000000 +0000 +++ qemu/hw/iommu.c 2007-08-14 19:36:33.000000000 +0000 @@ -104,6 +104,7 @@ target_phys_addr_t addr; uint32_t regs[IOMMU_NREGS]; target_phys_addr_t iostart; + qemu_dma *parent_dma; } IOMMUState; static uint32_t iommu_mem_readw(void *opaque, target_phys_addr_t addr) @@ -245,6 +246,7 @@ void sparc_iommu_memory_rw(void *opaque, target_phys_addr_t addr, uint8_t *buf, int len, int is_write) { + IOMMUState *s = opaque; int l; uint32_t flags; target_phys_addr_t page, phys_addr; @@ -265,10 +267,8 @@ iommu_bad_addr(opaque, page, is_write); return; } - cpu_physical_memory_write(phys_addr, buf, len); - } else { - cpu_physical_memory_read(phys_addr, buf, len); } + dma_memory_rw(s->parent_dma, phys_addr, buf, len, is_write); len -= l; buf += l; addr += l; @@ -309,7 +309,8 @@ s->regs[IOMMU_CTRL] = IOMMU_VERSION; } -void *iommu_init(target_phys_addr_t addr) +void *iommu_init(target_phys_addr_t addr, qemu_dma *parent_dma, + qemu_dma **dvma) { IOMMUState *s; int iommu_io_memory; @@ -322,7 +323,10 @@ iommu_io_memory = cpu_register_io_memory(0, iommu_mem_read, iommu_mem_write, s); cpu_register_physical_memory(addr, IOMMU_NREGS * 4, iommu_io_memory); - + + s->parent_dma = parent_dma; + *dvma = qemu_init_dma(sparc_iommu_memory_rw, s); + register_savevm("iommu", addr, 2, iommu_save, iommu_load, s); qemu_register_reset(iommu_reset, s); return s; Index: qemu/vl.h =================================================================== --- qemu.orig/vl.h 2007-08-14 19:27:35.000000000 +0000 +++ qemu/vl.h 2007-08-14 19:36:54.000000000 +0000 @@ -1263,7 +1263,8 @@ extern QEMUMachine ss5_machine, ss10_machine; /* iommu.c */ -void *iommu_init(target_phys_addr_t addr); +void *iommu_init(target_phys_addr_t addr, qemu_dma *parent_dma, + qemu_dma **dvma); void sparc_iommu_memory_rw(void *opaque, target_phys_addr_t addr, uint8_t *buf, int len, int is_write); static inline void sparc_iommu_memory_read(void *opaque,