Index: qemu/hw/pc.c =================================================================== --- qemu.orig/hw/pc.c 2007-08-22 19:29:57.000000000 +0000 +++ qemu/hw/pc.c 2007-08-22 19:42:13.000000000 +0000 @@ -601,6 +601,12 @@ cpu_reset(env); } +static void isa_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 const int ide_iobase[2] = { 0x1f0, 0x170 }; static const int ide_iobase2[2] = { 0x3f6, 0x376 }; static const int ide_irq[2] = { 14, 15 }; @@ -675,6 +681,7 @@ NICInfo *nd; qemu_irq *cpu_irq; qemu_irq *i8259; + qemu_dma *physical_dma, **isa_dma; linux_boot = (kernel_filename != NULL); @@ -779,7 +786,9 @@ /* map all the bios at the top of memory */ cpu_register_physical_memory((uint32_t)(-bios_size), bios_size, bios_offset | IO_MEM_ROM); - + + physical_dma = qemu_init_dma(isa_dma_memory_rw, NULL); + bochs_bios_init(); if (linux_boot) @@ -887,7 +896,7 @@ } i8042_init(i8259[1], i8259[12], 0x60); - DMA_init(0); + DMA_init(0, physical_dma, &isa_dma); #ifdef HAS_AUDIO audio_init(pci_enabled ? pci_bus : NULL, i8259); #endif Index: qemu/hw/dma.c =================================================================== --- qemu.orig/hw/dma.c 2007-08-22 19:29:57.000000000 +0000 +++ qemu/hw/dma.c 2007-08-22 19:44:23.000000000 +0000 @@ -48,6 +48,7 @@ uint8_t eop; DMA_transfer_handler transfer_handler; void *opaque; + qemu_dma *parent_dma; }; #define ADDR 0 @@ -380,16 +381,15 @@ r->opaque = opaque; } -int DMA_read_memory (int nchan, void *buf, int pos, int len) +static int dma_read_memory (struct dma_regs *r, 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]; if (r->mode & 0x20) { int i; uint8_t *p = buf; - cpu_physical_memory_read (addr - pos - len, buf, len); + dma_memory_read (r->parent_dma, addr - pos - len, buf, len); /* What about 16bit transfers? */ for (i = 0; i < len >> 1; i++) { uint8_t b = p[len - i - 1]; @@ -397,21 +397,20 @@ } } else - cpu_physical_memory_read (addr + pos, buf, len); + dma_memory_read (r->parent_dma, addr + pos, buf, len); return len; } -int DMA_write_memory (int nchan, void *buf, int pos, int len) +static int dma_write_memory (struct dma_regs *r, 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]; if (r->mode & 0x20) { int i; uint8_t *p = buf; - cpu_physical_memory_write (addr - pos - len, buf, len); + dma_memory_write (r->parent_dma, addr - pos - len, buf, len); /* What about 16bit transfers? */ for (i = 0; i < len; i++) { uint8_t b = p[len - i - 1]; @@ -419,11 +418,36 @@ } } else - cpu_physical_memory_write (addr + pos, buf, len); + dma_memory_write (r->parent_dma, addr + pos, buf, len); return len; } +static void DMA_memory_rw(void *opaque, target_phys_addr_t addr, + uint8_t *buf, int len, int is_write) +{ + struct dma_regs *r = (struct dma_regs *)opaque; + + if (is_write) + dma_write_memory(r, buf, 0, len); + else + dma_read_memory(r, buf, 0, len); +} + +int DMA_read_memory (int nchan, void *buf, int pos, int len) +{ + struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3]; + + return dma_read_memory(r, buf, pos, len); +} + +int DMA_write_memory (int nchan, void *buf, int pos, int len) +{ + struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3]; + + return dma_write_memory(r, buf, pos, len); +} + /* request the emulator to transfer a new DMA memory block ASAP */ void DMA_schedule(int nchan) { @@ -526,12 +550,22 @@ return 0; } -void DMA_init (int high_page_enable) +void DMA_init (int high_page_enable, qemu_dma *parent_dma, qemu_dma ***isa_dma) { + unsigned int i; + dma_init2(&dma_controllers[0], 0x00, 0, 0x80, high_page_enable ? 0x480 : -1); dma_init2(&dma_controllers[1], 0xc0, 1, 0x88, high_page_enable ? 0x488 : -1); + + *isa_dma = qemu_mallocz(sizeof(void *) * 8); + for (i = 0; i < 8; i++) { + *isa_dma[i] = qemu_init_dma(DMA_memory_rw, + &dma_controllers[i > 3].regs[i & 3]); + dma_controllers[i > 3].regs[i & 3].parent_dma = parent_dma; + } + register_savevm ("dma", 0, 1, dma_save, dma_load, &dma_controllers[0]); register_savevm ("dma", 1, 1, dma_save, dma_load, &dma_controllers[1]); } Index: qemu/vl.h =================================================================== --- qemu.orig/vl.h 2007-08-22 19:29:57.000000000 +0000 +++ qemu/vl.h 2007-08-22 19:42:54.000000000 +0000 @@ -1063,7 +1063,7 @@ void DMA_release_DREQ (int nchan); void DMA_schedule(int nchan); void DMA_run (void); -void DMA_init (int high_page_enable); +void DMA_init (int high_page_enable, qemu_dma *parent_dma, qemu_dma ***isa_dma); void DMA_register_channel (int nchan, DMA_transfer_handler transfer_handler, void *opaque); Index: qemu/hw/ppc_prep.c =================================================================== --- qemu.orig/hw/ppc_prep.c 2007-08-22 19:29:57.000000000 +0000 +++ qemu/hw/ppc_prep.c 2007-08-22 19:46:27.000000000 +0000 @@ -510,6 +510,12 @@ #define NVRAM_SIZE 0x2000 +static void ppc_isa_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); +} + /* PowerPC PREP hardware initialisation */ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device, DisplayState *ds, const char **fd_filename, @@ -528,6 +534,7 @@ ppc_def_t *def; PCIBus *pci_bus; qemu_irq *i8259; + qemu_dma *physical_dma, **isa_dma; sysctrl = qemu_mallocz(sizeof(sysctrl_t)); if (sysctrl == NULL) @@ -598,6 +605,8 @@ initrd_size = 0; } + physical_dma = qemu_init_dma(ppc_isa_dma_memory_rw, NULL); + isa_mem_base = 0xc0000000; if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) { cpu_abort(env, "Only 6xx bus is supported on PREP machine\n"); @@ -641,7 +650,7 @@ bs_table[2 * i], bs_table[2 * i + 1]); } i8042_init(i8259[1], i8259[12], 0x60); - DMA_init(1); + DMA_init(1, physical_dma, &isa_dma); // AUD_init(); // SB16_init();