Index: qemu/hw/sparc32_dma.c =================================================================== --- qemu.orig/hw/sparc32_dma.c 2007-08-22 20:03:09.000000000 +0000 +++ qemu/hw/sparc32_dma.c 2007-08-22 20:03:47.000000000 +0000 @@ -58,62 +58,10 @@ struct DMAState { uint32_t dmaregs[DMA_REGS]; qemu_irq irq; - void *iommu; qemu_irq dev_reset; + qemu_dma *dma; }; -/* Note: on sparc, the lance 16 bit bus is swapped */ -void ledma_memory_read(void *opaque, target_phys_addr_t addr, - uint8_t *buf, int len, int do_bswap) -{ - DMAState *s = opaque; - int i; - - DPRINTF("DMA write, direction: %c, addr 0x%8.8x\n", - s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]); - addr |= s->dmaregs[3]; - if (do_bswap) { - sparc_iommu_memory_read(s->iommu, addr, buf, len); - } else { - addr &= ~1; - len &= ~1; - sparc_iommu_memory_read(s->iommu, addr, buf, len); - for(i = 0; i < len; i += 2) { - bswap16s((uint16_t *)(buf + i)); - } - } -} - -void ledma_memory_write(void *opaque, target_phys_addr_t addr, - uint8_t *buf, int len, int do_bswap) -{ - DMAState *s = opaque; - int l, i; - uint16_t tmp_buf[32]; - - DPRINTF("DMA read, direction: %c, addr 0x%8.8x\n", - s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]); - addr |= s->dmaregs[3]; - if (do_bswap) { - sparc_iommu_memory_write(s->iommu, addr, buf, len); - } else { - addr &= ~1; - len &= ~1; - while (len > 0) { - l = len; - if (l > sizeof(tmp_buf)) - l = sizeof(tmp_buf); - for(i = 0; i < l; i += 2) { - tmp_buf[i >> 1] = bswap16(*(uint16_t *)(buf + i)); - } - sparc_iommu_memory_write(s->iommu, addr, (uint8_t *)tmp_buf, l); - len -= l; - buf += l; - addr += l; - } - } -} - static void dma_set_irq(void *opaque, int irq, int level) { DMAState *s = opaque; @@ -128,24 +76,29 @@ } } -void espdma_memory_read(void *opaque, uint8_t *buf, int len) +static void ledma_memory_rw(void *opaque, target_phys_addr_t addr, + uint8_t *buf, int len, int is_write) { DMAState *s = opaque; - DPRINTF("DMA read, direction: %c, addr 0x%8.8x\n", - s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]); - sparc_iommu_memory_read(s->iommu, s->dmaregs[1], buf, len); - s->dmaregs[0] |= DMA_INTR; - s->dmaregs[1] += len; + DPRINTF("DMA %s, direction: %c, addr 0x%8.8x\n", + is_write ? "write" : "read", + s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', addr); + addr |= s->dmaregs[3]; + addr &= ~1; + len &= ~1; + dma_memory_rw(s->dma, addr, buf, len, is_write); } -void espdma_memory_write(void *opaque, uint8_t *buf, int len) +static void espdma_memory_rw(void *opaque, target_phys_addr_t addr, + uint8_t *buf, int len, int is_write) { DMAState *s = opaque; - DPRINTF("DMA write, direction: %c, addr 0x%8.8x\n", + DPRINTF("DMA %s, direction: %c, addr 0x%8.8x\n", + is_write ? "write" : "read", s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]); - sparc_iommu_memory_write(s->iommu, s->dmaregs[1], buf, len); + dma_memory_rw(s->dma, s->dmaregs[1], buf, len, is_write); s->dmaregs[0] |= DMA_INTR; s->dmaregs[1] += len; } @@ -238,7 +191,8 @@ } void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq parent_irq, - void *iommu, qemu_irq **dev_irq, qemu_irq **reset) + qemu_irq **dev_irq, qemu_dma *parent_dma, + qemu_dma **dev_dma, int is_espdma, qemu_irq **reset) { DMAState *s; int dma_io_memory; @@ -248,7 +202,7 @@ return NULL; s->irq = parent_irq; - s->iommu = iommu; + s->dma = parent_dma; dma_io_memory = cpu_register_io_memory(0, dma_mem_read, dma_mem_write, s); cpu_register_physical_memory(daddr, DMA_SIZE, dma_io_memory); @@ -259,5 +213,10 @@ *reset = &s->dev_reset; + if (is_espdma) + *dev_dma = qemu_init_dma(espdma_memory_rw, s); + else + *dev_dma = qemu_init_dma(ledma_memory_rw, s); + return s; } Index: qemu/hw/sun4m.c =================================================================== --- qemu.orig/hw/sun4m.c 2007-08-22 20:03:28.000000000 +0000 +++ qemu/hw/sun4m.c 2007-08-22 20:03:47.000000000 +0000 @@ -318,7 +318,7 @@ qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq, *espdma_irq, *ledma_irq; qemu_irq *esp_reset, *le_reset; - qemu_dma *physical_dma, *dummy_dma, *dvma; + qemu_dma *physical_dma, *dummy_dma, *dvma, *esp_dvma, *le_dvma; /* init CPUs */ sparc_find_by_name(cpu_model, &def); @@ -360,11 +360,11 @@ hwdef->clock_irq); espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq], - iommu, &espdma_irq, &esp_reset); + &espdma_irq, dvma, &esp_dvma, 1, &esp_reset); ledma = sparc32_dma_init(hwdef->dma_base + 16ULL, - slavio_irq[hwdef->le_irq], iommu, &ledma_irq, - &le_reset); + slavio_irq[hwdef->le_irq], &ledma_irq, dvma, + &le_dvma, 0, &le_reset); if (graphic_depth != 8 && graphic_depth != 24) { fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth); @@ -375,7 +375,7 @@ if (nd_table[0].model == NULL || strcmp(nd_table[0].model, "lance") == 0) { - lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset); + lance_init(&nd_table[0], hwdef->le_base, *ledma_irq, le_dvma, le_reset); } else if (strcmp(nd_table[0].model, "?") == 0) { fprintf(stderr, "qemu: Supported NICs: lance\n"); exit (1); @@ -401,7 +401,7 @@ fdctrl_init(slavio_irq[hwdef->fd_irq], 0, 1, hwdef->fd_base, fd_table, dummy_dma); - main_esp = esp_init(bs_table, hwdef->esp_base, espdma, *espdma_irq, + main_esp = esp_init(bs_table, hwdef->esp_base, *espdma_irq, esp_dvma, esp_reset); for (i = 0; i < MAX_DISKS; i++) { Index: qemu/vl.h =================================================================== --- qemu.orig/vl.h 2007-08-22 20:03:09.000000000 +0000 +++ qemu/vl.h 2007-08-22 20:03:47.000000000 +0000 @@ -1097,8 +1097,8 @@ /* pcnet.c */ void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn); -void lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque, - qemu_irq irq, qemu_irq *reset); +void lance_init(NICInfo *nd, target_phys_addr_t leaddr, qemu_irq irq, + qemu_dma *parent_dma, qemu_irq *reset); /* vmmouse.c */ void *vmmouse_init(void *m); @@ -1265,21 +1265,6 @@ /* iommu.c */ 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, - target_phys_addr_t addr, - uint8_t *buf, int len) -{ - sparc_iommu_memory_rw(opaque, addr, buf, len, 0); -} - -static inline void sparc_iommu_memory_write(void *opaque, - target_phys_addr_t addr, - uint8_t *buf, int len) -{ - sparc_iommu_memory_rw(opaque, addr, buf, len, 1); -} /* tcx.c */ void tcx_init(DisplayState *ds, target_phys_addr_t addr, uint8_t *vram_base, @@ -1318,17 +1303,12 @@ /* esp.c */ void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id); void *esp_init(BlockDriverState **bd, target_phys_addr_t espaddr, - void *dma_opaque, qemu_irq irq, qemu_irq *reset); + qemu_irq irq, qemu_dma *parent_dma, qemu_irq *reset); /* sparc32_dma.c */ void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq parent_irq, - void *iommu, qemu_irq **dev_irq, qemu_irq **reset); -void ledma_memory_read(void *opaque, target_phys_addr_t addr, - uint8_t *buf, int len, int do_bswap); -void ledma_memory_write(void *opaque, target_phys_addr_t addr, - uint8_t *buf, int len, int do_bswap); -void espdma_memory_read(void *opaque, uint8_t *buf, int len); -void espdma_memory_write(void *opaque, uint8_t *buf, int len); + qemu_irq **dev_irq, qemu_dma *parent_dma, + qemu_dma **dev_dma, int is_espdma, qemu_irq **reset); /* cs4231.c */ void cs_init(target_phys_addr_t base, int irq, void *intctl); Index: qemu/hw/esp.c =================================================================== --- qemu.orig/hw/esp.c 2007-08-22 20:03:09.000000000 +0000 +++ qemu/hw/esp.c 2007-08-22 20:03:47.000000000 +0000 @@ -52,6 +52,7 @@ struct ESPState { qemu_irq irq; + qemu_dma *parent_dma; BlockDriverState **bd; uint8_t rregs[ESP_REGS]; uint8_t wregs[ESP_REGS]; @@ -73,7 +74,6 @@ uint32_t dma_counter; uint8_t *async_buf; uint32_t async_len; - void *dma_opaque; }; #define STAT_DO 0x00 @@ -105,7 +105,7 @@ target = s->wregs[4] & 7; DPRINTF("get_cmd: len %d target %d\n", dmalen, target); if (s->dma) { - espdma_memory_read(s->dma_opaque, buf, dmalen); + dma_memory_read(s->parent_dma, 0, buf, dmalen); } else { buf[0] = 0; memcpy(&buf[1], s->ti_buf, dmalen); @@ -189,7 +189,7 @@ s->ti_buf[0] = s->sense; s->ti_buf[1] = 0; if (s->dma) { - espdma_memory_write(s->dma_opaque, s->ti_buf, 2); + dma_memory_write(s->parent_dma, 0, s->ti_buf, 2); s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; s->rregs[5] = INTR_BS | INTR_FC; s->rregs[6] = SEQ_CD; @@ -222,7 +222,7 @@ len = s->dma_left; if (s->do_cmd) { DPRINTF("command len %d + %d\n", s->cmdlen, len); - espdma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len); + dma_memory_read(s->parent_dma, 0, &s->cmdbuf[s->cmdlen], len); s->ti_size = 0; s->cmdlen = 0; s->do_cmd = 0; @@ -237,9 +237,9 @@ len = s->async_len; } if (to_device) { - espdma_memory_read(s->dma_opaque, s->async_buf, len); + dma_memory_read(s->parent_dma, 0, s->async_buf, len); } else { - espdma_memory_write(s->dma_opaque, s->async_buf, len); + dma_memory_write(s->parent_dma, 0, s->async_buf, len); } s->dma_left -= len; s->async_buf += len; @@ -575,7 +575,7 @@ } void *esp_init(BlockDriverState **bd, target_phys_addr_t espaddr, - void *dma_opaque, qemu_irq irq, qemu_irq *reset) + qemu_irq irq, qemu_dma *parent_dma, qemu_irq *reset) { ESPState *s; int esp_io_memory; @@ -586,7 +586,7 @@ s->bd = bd; s->irq = irq; - s->dma_opaque = dma_opaque; + s->parent_dma = parent_dma; esp_io_memory = cpu_register_io_memory(0, esp_mem_read, esp_mem_write, s); cpu_register_physical_memory(espaddr, ESP_SIZE, esp_io_memory); Index: qemu/hw/pcnet.c =================================================================== --- qemu.orig/hw/pcnet.c 2007-08-22 20:03:09.000000000 +0000 +++ qemu/hw/pcnet.c 2007-08-22 20:03:47.000000000 +0000 @@ -73,6 +73,7 @@ void (*phys_mem_write)(void *dma_opaque, target_phys_addr_t addr, uint8_t *buf, int len, int do_bswap); void *dma_opaque; + qemu_dma *parent_dma; }; struct qemu_ether_header { @@ -2015,6 +2016,46 @@ pcnet_h_reset(opaque); } +/* Note: on sparc, the lance 16 bit bus is swapped */ +static void ledma_memory_read(void *opaque, target_phys_addr_t addr, + uint8_t *buf, int len, int do_bswap) +{ + int i; + + if (do_bswap) { + dma_memory_read(opaque, addr, buf, len); + } else { + dma_memory_read(opaque, addr, buf, len); + for(i = 0; i < len; i += 2) { + bswap16s((uint16_t *)(buf + i)); + } + } +} + +static void ledma_memory_write(void *opaque, target_phys_addr_t addr, + uint8_t *buf, int len, int do_bswap) +{ + int l, i; + uint16_t tmp_buf[32]; + + if (do_bswap) { + dma_memory_write(opaque, addr, buf, len); + } else { + while (len > 0) { + l = len; + if (l > sizeof(tmp_buf)) + l = sizeof(tmp_buf); + for(i = 0; i < l; i += 2) { + tmp_buf[i >> 1] = bswap16(*(uint16_t *)(buf + i)); + } + dma_memory_write(opaque, addr, (uint8_t *)tmp_buf, l); + len -= l; + buf += l; + addr += l; + } + } +} + static void lance_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val) { @@ -2050,8 +2091,8 @@ lance_mem_writew, }; -void lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque, - qemu_irq irq, qemu_irq *reset) +void lance_init(NICInfo *nd, target_phys_addr_t leaddr, qemu_irq irq, + qemu_dma *parent_dma, qemu_irq *reset) { PCNetState *d; int lance_io_memory; @@ -2063,7 +2104,7 @@ lance_io_memory = cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d); - d->dma_opaque = dma_opaque; + d->dma_opaque = parent_dma; *reset = *qemu_allocate_irqs(parent_lance_reset, d, 1);