aboutsummaryrefslogtreecommitdiff
path: root/hw/etraxfs_dma.c
diff options
context:
space:
mode:
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2008-10-31 17:25:56 +0000
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2008-10-31 17:25:56 +0000
commit492c30af2567a59413c064f88eb81e1691865195 (patch)
tree6f95d3dacabf2f99be4d0b60e41ad855385ee055 /hw/etraxfs_dma.c
parent1b435b10324fe9937f254bb00718f78d5e50837a (diff)
downloadqemu-492c30af2567a59413c064f88eb81e1691865195.zip
qemu-492c30af2567a59413c064f88eb81e1691865195.tar.gz
qemu-492c30af2567a59413c064f88eb81e1691865195.tar.bz2
Make DMA bottom-half driven (v2)
The current DMA routines are driven by a call in main_loop_wait() after every select. This patch converts the DMA code to be driven by a constantly rescheduled bottom half. The advantage of using a scheduled bottom half is that we can stop scheduling the bottom half when there no DMA channels are runnable. This means we can potentially detect this case and sleep longer in the main loop. The only two architectures implementing DMA_run() are cris and i386. For cris, I converted it to a simple repeating bottom half. I've only compile tested this as cris does not seem to work on a 64-bit host. It should be functionally identical to the previous implementation so I expect it to work. For x86, I've made sure to only fire the DMA bottom half if there is a DMA channel that is runnable. The effect of this is that unless you're using sb16 or a floppy disk, the DMA bottom half never fires. You probably should test this malc. My own benchmarks actually show slight improvement by it's possible the change in timing could affect your demos. Since v1, I've changed the code to use a BH instead of a timer. cris at least seems to depend on faster than 10ms polling. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5573 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/etraxfs_dma.c')
-rw-r--r--hw/etraxfs_dma.c18
1 files changed, 12 insertions, 6 deletions
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);