From 19d2b5e6ff7202c2bf45c547efa85ae6c2d76bbd Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 16 Feb 2015 14:08:22 +0100 Subject: i8257: rewrite DMA_schedule to avoid hooking into the CPU loop The i8257 DMA controller uses an idle bottom half, which by default does not cause the main loop to exit. Therefore, the DMA_schedule function is there to ensure that the CPU relinquishes the iothread mutex to the iothread. However, this is not enough since the iothread will call aio_compute_timeout() and go to sleep again. In the iothread world, forcing execution of the idle bottom half is much simpler, and only requires a call to qemu_notify_event(). Do it, removing the need for the "cpu_request_exit" pseudo-irq. The next patch will remove it. Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- hw/dma/i8257.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'hw/dma/i8257.c') diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index a414029bea..409ba7d01f 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -358,6 +358,7 @@ static void channel_run (int ncont, int ichan) } static QEMUBH *dma_bh; +static bool dma_bh_scheduled; static void DMA_run (void) { @@ -390,12 +391,15 @@ static void DMA_run (void) running = 0; out: - if (rearm) + if (rearm) { qemu_bh_schedule_idle(dma_bh); + dma_bh_scheduled = true; + } } static void DMA_run_bh(void *unused) { + dma_bh_scheduled = false; DMA_run(); } @@ -458,12 +462,14 @@ int DMA_write_memory (int nchan, void *buf, int pos, int len) return len; } -/* request the emulator to transfer a new DMA memory block ASAP */ -void DMA_schedule(int nchan) +/* request the emulator to transfer a new DMA memory block ASAP (even + * if the idle bottom half would not have exited the iothread yet). + */ +void DMA_schedule(void) { - struct dma_cont *d = &dma_controllers[nchan > 3]; - - qemu_irq_pulse(*d->cpu_request_exit); + if (dma_bh_scheduled) { + qemu_notify_event(); + } } static void dma_reset(void *opaque) -- cgit v1.2.3 From 5039d6e23586fe6bbedc5e4fe302b48a66890ade Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 16 Feb 2015 14:13:11 +0100 Subject: i8257: remove cpu_request_exit irq This is unused. cpu_exit now is almost exclusively an internal function to the CPU execution loop. In a few patches, we'll change the remaining occurrences to qemu_cpu_kick, making it truly internal. Reviewed-by: Richard henderson Signed-off-by: Paolo Bonzini --- hw/dma/i8257.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'hw/dma/i8257.c') diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index 409ba7d01f..13984244a6 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -59,7 +59,6 @@ static struct dma_cont { uint8_t flip_flop; int dshift; struct dma_regs regs[4]; - qemu_irq *cpu_request_exit; MemoryRegion channel_io; MemoryRegion cont_io; } dma_controllers[2]; @@ -521,13 +520,11 @@ static const MemoryRegionOps cont_io_ops = { /* 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, - qemu_irq *cpu_request_exit) + int page_base, int pageh_base) { int i; d->dshift = dshift; - d->cpu_request_exit = cpu_request_exit; memory_region_init_io(&d->channel_io, NULL, &channel_io_ops, d, "dma-chan", 8 << d->dshift); @@ -591,12 +588,10 @@ static const VMStateDescription vmstate_dma = { } }; -void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit) +void DMA_init(int high_page_enable) { - dma_init2(&dma_controllers[0], 0x00, 0, 0x80, - high_page_enable ? 0x480 : -1, cpu_request_exit); - dma_init2(&dma_controllers[1], 0xc0, 1, 0x88, - high_page_enable ? 0x488 : -1, cpu_request_exit); + 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); vmstate_register (NULL, 0, &vmstate_dma, &dma_controllers[0]); vmstate_register (NULL, 1, &vmstate_dma, &dma_controllers[1]); -- cgit v1.2.3