diff --git a/Makefile.objs b/Makefile.objs index 1a33d4eb4a..15851010ca 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -156,6 +156,7 @@ hw-obj-$(CONFIG_USB_UHCI) += usb-uhci.o hw-obj-$(CONFIG_FDC) += fdc.o hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o +hw-obj-$(CONFIG_DMA) += dma.o # PPC devices hw-obj-$(CONFIG_OPENPIC) += openpic.o diff --git a/Makefile.target b/Makefile.target index ba5147fbc4..fda5bf3c73 100644 --- a/Makefile.target +++ b/Makefile.target @@ -188,7 +188,6 @@ obj-y += rtl8139.o obj-y += e1000.o # Hardware support -obj-i386-y = dma.o obj-i386-y += vga.o obj-i386-y += mc146818rtc.o i8259.o pc.o obj-i386-y += cirrus_vga.o apic.o ioapic.o piix_pci.o @@ -199,7 +198,7 @@ obj-i386-y += pc_piix.o # shared objects obj-ppc-y = ppc.o -obj-ppc-y += vga.o dma.o +obj-ppc-y += vga.o # PREP target obj-ppc-y += i8259.o mc146818rtc.o obj-ppc-y += ppc_prep.o @@ -217,7 +216,7 @@ obj-ppc-$(CONFIG_FDT) += device_tree.o obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o obj-mips-y += mips_addr.o mips_timer.o mips_int.o -obj-mips-y += dma.o vga.o i8259.o +obj-mips-y += vga.o i8259.o obj-mips-y += g364fb.o jazz_led.o obj-mips-y += gt64xxx.o mc146818rtc.o obj-mips-y += piix4.o cirrus_vga.o diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 852e298016..ed00471da2 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -13,6 +13,7 @@ CONFIG_USB_UHCI=y CONFIG_FDC=y CONFIG_ACPI=y CONFIG_APM=y +CONFIG_DMA=y CONFIG_IDE_CORE=y CONFIG_IDE_QDEV=y CONFIG_IDE_PCI=y diff --git a/default-configs/mips-softmmu.mak b/default-configs/mips-softmmu.mak index 850f226d0d..29be52eb1d 100644 --- a/default-configs/mips-softmmu.mak +++ b/default-configs/mips-softmmu.mak @@ -15,6 +15,7 @@ CONFIG_USB_UHCI=y CONFIG_FDC=y CONFIG_ACPI=y CONFIG_APM=y +CONFIG_DMA=y CONFIG_IDE_CORE=y CONFIG_IDE_QDEV=y CONFIG_IDE_PCI=y diff --git a/default-configs/mips64-softmmu.mak b/default-configs/mips64-softmmu.mak index 21338ffc72..9bae8a7bc2 100644 --- a/default-configs/mips64-softmmu.mak +++ b/default-configs/mips64-softmmu.mak @@ -15,6 +15,7 @@ CONFIG_USB_UHCI=y CONFIG_FDC=y CONFIG_ACPI=y CONFIG_APM=y +CONFIG_DMA=y CONFIG_IDE_CORE=y CONFIG_IDE_QDEV=y CONFIG_IDE_PCI=y diff --git a/default-configs/mips64el-softmmu.mak b/default-configs/mips64el-softmmu.mak index 4aa88efe7c..b372c1dfa1 100644 --- a/default-configs/mips64el-softmmu.mak +++ b/default-configs/mips64el-softmmu.mak @@ -15,6 +15,7 @@ CONFIG_USB_UHCI=y CONFIG_FDC=y CONFIG_ACPI=y CONFIG_APM=y +CONFIG_DMA=y CONFIG_IDE_CORE=y CONFIG_IDE_QDEV=y CONFIG_IDE_PCI=y diff --git a/default-configs/mipsel-softmmu.mak b/default-configs/mipsel-softmmu.mak index a8de1eb67f..10ef483799 100644 --- a/default-configs/mipsel-softmmu.mak +++ b/default-configs/mipsel-softmmu.mak @@ -15,6 +15,7 @@ CONFIG_USB_UHCI=y CONFIG_FDC=y CONFIG_ACPI=y CONFIG_APM=y +CONFIG_DMA=y CONFIG_IDE_CORE=y CONFIG_IDE_QDEV=y CONFIG_IDE_PCI=y diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak index 03cc20f359..c026bbb00e 100644 --- a/default-configs/ppc-softmmu.mak +++ b/default-configs/ppc-softmmu.mak @@ -10,6 +10,7 @@ CONFIG_SERIAL=y CONFIG_I8254=y CONFIG_PCKBD=y CONFIG_FDC=y +CONFIG_DMA=y CONFIG_OPENPIC=y CONFIG_PREP_PCI=y CONFIG_MACIO=y diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak index 8c771330b3..0101a283e3 100644 --- a/default-configs/ppc64-softmmu.mak +++ b/default-configs/ppc64-softmmu.mak @@ -10,6 +10,7 @@ CONFIG_SERIAL=y CONFIG_I8254=y CONFIG_PCKBD=y CONFIG_FDC=y +CONFIG_DMA=y CONFIG_OPENPIC=y CONFIG_PREP_PCI=y CONFIG_MACIO=y diff --git a/default-configs/ppcemb-softmmu.mak b/default-configs/ppcemb-softmmu.mak index 2a0210da6b..8ba9ac179f 100644 --- a/default-configs/ppcemb-softmmu.mak +++ b/default-configs/ppcemb-softmmu.mak @@ -10,6 +10,7 @@ CONFIG_SERIAL=y CONFIG_I8254=y CONFIG_PCKBD=y CONFIG_FDC=y +CONFIG_DMA=y CONFIG_OPENPIC=y CONFIG_PREP_PCI=y CONFIG_MACIO=y diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak index 3db8c0c366..518320377f 100644 --- a/default-configs/x86_64-softmmu.mak +++ b/default-configs/x86_64-softmmu.mak @@ -13,6 +13,7 @@ CONFIG_USB_UHCI=y CONFIG_FDC=y CONFIG_ACPI=y CONFIG_APM=y +CONFIG_DMA=y CONFIG_IDE_CORE=y CONFIG_IDE_QDEV=y CONFIG_IDE_PCI=y diff --git a/hw/dma.c b/hw/dma.c index e5f7af7a88..5b215211e1 100644 --- a/hw/dma.c +++ b/hw/dma.c @@ -57,6 +57,7 @@ static struct dma_cont { uint8_t flip_flop; int dshift; struct dma_regs regs[4]; + qemu_irq *cpu_request_exit; } dma_controllers[2]; enum { @@ -444,9 +445,9 @@ int DMA_write_memory (int nchan, void *buf, int pos, int len) /* request the emulator to transfer a new DMA memory block ASAP */ void DMA_schedule(int nchan) { - CPUState *env = cpu_single_env; - if (env) - cpu_exit(env); + struct dma_cont *d = &dma_controllers[nchan > 3]; + + qemu_irq_pulse(*d->cpu_request_exit); } static void dma_reset(void *opaque) @@ -464,12 +465,14 @@ static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len) /* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */ static void dma_init2(struct dma_cont *d, int base, int dshift, - int page_base, int pageh_base) + int page_base, int pageh_base, + qemu_irq *cpu_request_exit) { static const int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 }; int i; d->dshift = dshift; + d->cpu_request_exit = cpu_request_exit; for (i = 0; i < 8; i++) { register_ioport_write (base + (i << dshift), 1, 1, write_chan, d); register_ioport_read (base + (i << dshift), 1, 1, read_chan, d); @@ -539,12 +542,12 @@ static const VMStateDescription vmstate_dma = { } }; -void DMA_init (int high_page_enable) +void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit) { dma_init2(&dma_controllers[0], 0x00, 0, 0x80, - high_page_enable ? 0x480 : -1); + high_page_enable ? 0x480 : -1, cpu_request_exit); dma_init2(&dma_controllers[1], 0xc0, 1, 0x88, - high_page_enable ? 0x488 : -1); + high_page_enable ? 0x488 : -1, cpu_request_exit); vmstate_register (0, &vmstate_dma, &dma_controllers[0]); vmstate_register (1, &vmstate_dma, &dma_controllers[1]); diff --git a/hw/isa.h b/hw/isa.h index 97f69a25cb..aaf0272c25 100644 --- a/hw/isa.h +++ b/hw/isa.h @@ -41,7 +41,7 @@ int DMA_write_memory (int nchan, void *buf, int pos, int size); void DMA_hold_DREQ (int nchan); void DMA_release_DREQ (int nchan); void DMA_schedule(int nchan); -void DMA_init (int high_page_enable); +void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit); void DMA_register_channel (int nchan, DMA_transfer_handler transfer_handler, void *opaque); diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c index 6e0ec8fd36..ead3a00c3d 100644 --- a/hw/mips_jazz.c +++ b/hw/mips_jazz.c @@ -114,6 +114,15 @@ static void audio_init(qemu_irq *pic) #define MAGNUM_BIOS_SIZE_MAX 0x7e000 #define MAGNUM_BIOS_SIZE (BIOS_SIZE < MAGNUM_BIOS_SIZE_MAX ? BIOS_SIZE : MAGNUM_BIOS_SIZE_MAX) +static void cpu_request_exit(void *opaque, int irq, int level) +{ + CPUState *env = cpu_single_env; + + if (env && level) { + cpu_exit(env); + } +} + static void mips_jazz_init (ram_addr_t ram_size, const char *cpu_model, @@ -130,6 +139,7 @@ void mips_jazz_init (ram_addr_t ram_size, PITState *pit; DriveInfo *fds[MAX_FD]; qemu_irq esp_reset; + qemu_irq *cpu_exit_irq; ram_addr_t ram_offset; ram_addr_t bios_offset; @@ -189,7 +199,8 @@ void mips_jazz_init (ram_addr_t ram_size, i8259 = i8259_init(env->irq[4]); isa_bus_new(NULL); isa_bus_irqs(i8259); - DMA_init(0); + cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); + DMA_init(0, cpu_exit_irq); pit = pit_init(0x40, i8259[0]); pcspk_init(pit); diff --git a/hw/mips_malta.c b/hw/mips_malta.c index 792709bf5a..a8f9d152dd 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -763,6 +763,15 @@ static void main_cpu_reset(void *opaque) } } +static void cpu_request_exit(void *opaque, int irq, int level) +{ + CPUState *env = cpu_single_env; + + if (env && level) { + cpu_exit(env); + } +} + static void mips_malta_init (ram_addr_t ram_size, const char *boot_device, @@ -781,6 +790,7 @@ void mips_malta_init (ram_addr_t ram_size, FDCtrl *floppy_controller; MaltaFPGAState *malta_fpga; qemu_irq *i8259; + qemu_irq *cpu_exit_irq; int piix4_devfn; uint8_t *eeprom_buf; i2c_bus *smbus; @@ -943,7 +953,8 @@ void mips_malta_init (ram_addr_t ram_size, qdev_init_nofail(eeprom); } pit = pit_init(0x40, isa_reserve_irq(0)); - DMA_init(0); + cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); + DMA_init(0, cpu_exit_irq); /* Super I/O */ isa_dev = isa_create_simple("i8042"); diff --git a/hw/pc.c b/hw/pc.c index d2fb9be778..e7f31d3848 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -914,6 +914,15 @@ void pc_vga_init(PCIBus *pci_bus) } } +static void cpu_request_exit(void *opaque, int irq, int level) +{ + CPUState *env = cpu_single_env; + + if (env && level) { + cpu_exit(env); + } +} + void pc_basic_device_init(qemu_irq *isa_irq, FDCtrl **floppy_controller, ISADevice **rtc_state) @@ -923,6 +932,7 @@ void pc_basic_device_init(qemu_irq *isa_irq, PITState *pit; qemu_irq *a20_line; ISADevice *i8042; + qemu_irq *cpu_exit_irq; register_ioport_write(0x80, 1, 1, ioport80_write, NULL); @@ -955,7 +965,8 @@ void pc_basic_device_init(qemu_irq *isa_irq, i8042_setup_a20_line(i8042, a20_line); vmmouse_init(i8042); - DMA_init(0); + cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); + DMA_init(0, cpu_exit_irq); for(i = 0; i < MAX_FD; i++) { fd[i] = drive_get(IF_FLOPPY, 0, i); diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c index 09a98819d1..16c9950740 100644 --- a/hw/ppc_prep.c +++ b/hw/ppc_prep.c @@ -547,6 +547,15 @@ static CPUReadMemoryFunc * const PPC_prep_io_read[] = { #define NVRAM_SIZE 0x2000 +static void cpu_request_exit(void *opaque, int irq, int level) +{ + CPUState *env = cpu_single_env; + + if (env && level) { + cpu_exit(env); + } +} + /* PowerPC PREP hardware initialisation */ static void ppc_prep_init (ram_addr_t ram_size, const char *boot_device, @@ -565,6 +574,7 @@ static void ppc_prep_init (ram_addr_t ram_size, uint32_t kernel_base, kernel_size, initrd_base, initrd_size; PCIBus *pci_bus; qemu_irq *i8259; + qemu_irq *cpu_exit_irq; int ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; DriveInfo *fd[MAX_FD]; @@ -719,7 +729,10 @@ static void ppc_prep_init (ram_addr_t ram_size, hd[2 * i + 1]); } isa_create_simple("i8042"); - DMA_init(1); + + cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); + DMA_init(1, cpu_exit_irq); + // SB16_init(); for(i = 0; i < MAX_FD; i++) { diff --git a/hw/sun4m.c b/hw/sun4m.c index 9a79120b1d..7ba0f763bc 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -152,7 +152,11 @@ int DMA_write_memory (int nchan, void *buf, int pos, int size) void DMA_hold_DREQ (int nchan) {} void DMA_release_DREQ (int nchan) {} void DMA_schedule(int nchan) {} -void DMA_init (int high_page_enable) {} + +void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit) +{ +} + void DMA_register_channel (int nchan, DMA_transfer_handler transfer_handler, void *opaque) diff --git a/hw/sun4u.c b/hw/sun4u.c index 24ea367d1a..e9a1e231e9 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -105,7 +105,11 @@ int DMA_write_memory (int nchan, void *buf, int pos, int size) void DMA_hold_DREQ (int nchan) {} void DMA_release_DREQ (int nchan) {} void DMA_schedule(int nchan) {} -void DMA_init (int high_page_enable) {} + +void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit) +{ +} + void DMA_register_channel (int nchan, DMA_transfer_handler transfer_handler, void *opaque)