diff options
-rw-r--r-- | hw/an5206.c | 4 | ||||
-rw-r--r-- | hw/dma.c | 30 | ||||
-rw-r--r-- | hw/etraxfs_dma.c | 18 | ||||
-rw-r--r-- | hw/integratorcp.c | 4 | ||||
-rw-r--r-- | hw/isa.h | 1 | ||||
-rw-r--r-- | hw/shix.c | 5 | ||||
-rw-r--r-- | hw/sun4m.c | 1 | ||||
-rw-r--r-- | hw/sun4u.c | 1 | ||||
-rw-r--r-- | vl.c | 2 |
9 files changed, 40 insertions, 26 deletions
diff --git a/hw/an5206.c b/hw/an5206.c index 2981263..9d315f3 100644 --- a/hw/an5206.c +++ b/hw/an5206.c @@ -24,10 +24,6 @@ void irq_info(void) { } -void DMA_run (void) -{ -} - /* Board init. */ static void an5206_init(ram_addr_t ram_size, int vga_ram_size, @@ -78,6 +78,8 @@ enum { }; +static void DMA_run (void); + static int channels[8] = {-1, 2, 3, 1, -1, -1, -1, 0}; static void write_page (void *opaque, uint32_t nport, uint32_t data) @@ -214,6 +216,7 @@ static void write_cont (void *opaque, uint32_t nport, uint32_t data) d->status &= ~(1 << (ichan + 4)); } d->status &= ~(1 << ichan); + DMA_run(); break; case 0x0a: /* single mask */ @@ -221,6 +224,7 @@ static void write_cont (void *opaque, uint32_t nport, uint32_t data) d->mask |= 1 << (data & 3); else d->mask &= ~(1 << (data & 3)); + DMA_run(); break; case 0x0b: /* mode */ @@ -255,10 +259,12 @@ static void write_cont (void *opaque, uint32_t nport, uint32_t data) case 0x0e: /* clear mask for all channels */ d->mask = 0; + DMA_run(); break; case 0x0f: /* write mask for all channels */ d->mask = data; + DMA_run(); break; default: @@ -310,6 +316,7 @@ void DMA_hold_DREQ (int nchan) ichan = nchan & 3; linfo ("held cont=%d chan=%d\n", ncont, ichan); dma_controllers[ncont].status |= 1 << (ichan + 4); + DMA_run(); } void DMA_release_DREQ (int nchan) @@ -320,6 +327,7 @@ void DMA_release_DREQ (int nchan) ichan = nchan & 3; linfo ("released cont=%d chan=%d\n", ncont, ichan); dma_controllers[ncont].status &= ~(1 << (ichan + 4)); + DMA_run(); } static void channel_run (int ncont, int ichan) @@ -347,10 +355,13 @@ static void channel_run (int ncont, int ichan) ldebug ("dma_pos %d size %d\n", n, (r->base[COUNT] + 1) << ncont); } -void DMA_run (void) +static QEMUBH *dma_bh; + +static void DMA_run (void) { struct dma_cont *d; int icont, ichan; + int rearm = 0; d = dma_controllers; @@ -360,10 +371,20 @@ void DMA_run (void) mask = 1 << ichan; - if ((0 == (d->mask & mask)) && (0 != (d->status & (mask << 4)))) + if ((0 == (d->mask & mask)) && (0 != (d->status & (mask << 4)))) { channel_run (icont, ichan); + rearm = 1; + } } } + + if (rearm) + qemu_bh_schedule_idle(dma_bh); +} + +static void DMA_run_bh(void *unused) +{ + DMA_run(); } void DMA_register_channel (int nchan, @@ -534,6 +555,9 @@ static int dma_load (QEMUFile *f, void *opaque, int version_id) qemu_get_8s (f, &r->dack); qemu_get_8s (f, &r->eop); } + + DMA_run(); + return 0; } @@ -545,4 +569,6 @@ void DMA_init (int high_page_enable) high_page_enable ? 0x488 : -1); register_savevm ("dma", 0, 1, dma_save, dma_load, &dma_controllers[0]); register_savevm ("dma", 1, 1, dma_save, dma_load, &dma_controllers[1]); + + dma_bh = qemu_bh_new(DMA_run_bh, NULL); } diff --git a/hw/etraxfs_dma.c b/hw/etraxfs_dma.c index a871b06..a7e547c 100644 --- a/hw/etraxfs_dma.c +++ b/hw/etraxfs_dma.c @@ -24,6 +24,8 @@ #include <stdio.h> #include <sys/time.h> #include "hw.h" +#include "qemu-common.h" +#include "sysemu.h" #include "etraxfs_dma.h" @@ -190,6 +192,8 @@ struct fs_dma_ctrl int nr_channels; struct fs_dma_channel *channels; + + QEMUBH *bh; }; static inline uint32_t channel_reg(struct fs_dma_ctrl *ctrl, int c, int reg) @@ -712,11 +716,12 @@ void etraxfs_dmac_connect_client(void *opaque, int c, } -static void *etraxfs_dmac; -void DMA_run(void) +static void DMA_run(void *opaque) { - if (etraxfs_dmac) - etraxfs_dmac_run(etraxfs_dmac); + struct fs_dma_ctrl *etraxfs_dmac = opaque; + if (vm_running) + etraxfs_dmac_run(etraxfs_dmac); + qemu_bh_schedule_idle(etraxfs_dmac->bh); } void *etraxfs_dmac_init(CPUState *env, @@ -729,6 +734,9 @@ void *etraxfs_dmac_init(CPUState *env, if (!ctrl) return NULL; + ctrl->bh = qemu_bh_new(DMA_run, ctrl); + qemu_bh_schedule_idle(ctrl->bh); + ctrl->base = base; ctrl->env = env; ctrl->nr_channels = nr_channels; @@ -747,8 +755,6 @@ void *etraxfs_dmac_init(CPUState *env, ctrl->channels[i].regmap); } - /* Hax, we only support one DMA controller at a time. */ - etraxfs_dmac = ctrl; return ctrl; err: qemu_free(ctrl->channels); diff --git a/hw/integratorcp.c b/hw/integratorcp.c index 779d46b..c0e2b66 100644 --- a/hw/integratorcp.c +++ b/hw/integratorcp.c @@ -15,10 +15,6 @@ #include "arm-misc.h" #include "net.h" -void DMA_run (void) -{ -} - typedef struct { uint32_t flash_offset; uint32_t cm_osc; @@ -19,7 +19,6 @@ 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_run (void); void DMA_init (int high_page_enable); void DMA_register_channel (int nchan, DMA_transfer_handler transfer_handler, @@ -35,11 +35,6 @@ #define BIOS_FILENAME "shix_bios.bin" #define BIOS_ADDRESS 0xA0000000 -void DMA_run(void) -{ - /* XXXXX */ -} - void irq_info(void) { /* XXXXX */ @@ -164,7 +164,6 @@ 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_run (void) {} void DMA_init (int high_page_enable) {} void DMA_register_channel (int nchan, DMA_transfer_handler transfer_handler, @@ -79,7 +79,6 @@ 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_run (void) {} void DMA_init (int high_page_enable) {} void DMA_register_channel (int nchan, DMA_transfer_handler transfer_handler, @@ -7983,8 +7983,6 @@ void main_loop_wait(int timeout) if (likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER))) qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], qemu_get_clock(vm_clock)); - /* run dma transfers, if any */ - DMA_run(); } /* real time timers */ |