summary refs log tree commit diff stats
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,