aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/an5206.c4
-rw-r--r--hw/dma.c30
-rw-r--r--hw/etraxfs_dma.c18
-rw-r--r--hw/integratorcp.c4
-rw-r--r--hw/isa.h1
-rw-r--r--hw/shix.c5
-rw-r--r--hw/sun4m.c1
-rw-r--r--hw/sun4u.c1
8 files changed, 40 insertions, 24 deletions
diff --git a/hw/an5206.c b/hw/an5206.c
index 29812631e7..9d315f3aa4 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,
diff --git a/hw/dma.c b/hw/dma.c
index 00c6332b4f..b247a0cd89 100644
--- a/hw/dma.c
+++ b/hw/dma.c
@@ -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 a871b0630e..a7e547c08a 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 779d46b70e..c0e2b66bc3 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;
diff --git a/hw/isa.h b/hw/isa.h
index 222e4f347b..a8c1a56a45 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -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,
diff --git a/hw/shix.c b/hw/shix.c
index 140efe90a5..eb53ee59d0 100644
--- a/hw/shix.c
+++ b/hw/shix.c
@@ -35,11 +35,6 @@
#define BIOS_FILENAME "shix_bios.bin"
#define BIOS_ADDRESS 0xA0000000
-void DMA_run(void)
-{
- /* XXXXX */
-}
-
void irq_info(void)
{
/* XXXXX */
diff --git a/hw/sun4m.c b/hw/sun4m.c
index d1c5b94e9f..f3c6501fb1 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -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,
diff --git a/hw/sun4u.c b/hw/sun4u.c
index a70ad201ab..057d598d7f 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -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,