add savevm support and fixes
authorJuha Riihimäki <juha.riihimaki@nokia.com>
Tue, 1 Sep 2009 15:07:12 +0000 (18:07 +0300)
committerRiku Voipio <riku.voipio@nokia.com>
Wed, 9 Sep 2009 13:32:47 +0000 (16:32 +0300)
hw/soc_dma.c
hw/soc_dma.h

index e116e63..d004ce6 100644 (file)
@@ -20,6 +20,7 @@
 #include "qemu-common.h"
 #include "qemu-timer.h"
 #include "soc_dma.h"
+#include "hw.h"
 
 static void transfer_mem2mem(struct soc_dma_ch_s *ch)
 {
@@ -228,12 +229,79 @@ void soc_dma_reset(struct soc_dma_s *soc)
 {
     struct dma_s *s = (struct dma_s *) soc;
 
-    s->soc.drqbmp = 0;
+    memset(s->soc.drqst, 0, sizeof(s->soc.drqst));
     s->ch_enable_mask = 0;
     s->enabled_count = 0;
     soc_dma_ch_freq_update(s);
 }
 
+static void soc_dma_save_state(QEMUFile *f, void *opaque)
+{
+    struct dma_s *s = (struct dma_s *)opaque;
+    int i;
+    
+    qemu_put_buffer(f, s->soc.drqst, sizeof(s->soc.drqst));
+    qemu_put_sbe64(f, s->soc.freq);
+    qemu_put_be64(f, s->ch_enable_mask);
+    qemu_put_sbe64(f, s->channel_freq);
+    qemu_put_sbe32(f, s->enabled_count);
+    for (i = 0; i < s->chnum; i++) {
+        qemu_put_timer(f, s->ch[i].timer);
+        qemu_put_sbe32(f, s->ch[i].enable);
+        qemu_put_sbe32(f, s->ch[i].update);
+        qemu_put_sbe32(f, s->ch[i].bytes);
+        qemu_put_sbe32(f, s->ch[i].type[0]);
+        qemu_put_sbe32(f, s->ch[i].type[1]);
+#if TARGET_PHYS_ADDR_BITS == 32
+        qemu_put_be32(f, s->ch[i].vaddr[0]);
+        qemu_put_be32(f, s->ch[i].vaddr[1]);
+#elif TARGET_PHYS_ADDR_BITS == 64
+        qemu_put_be64(f, s->ch[i].vaddr[0]);
+        qemu_put_be64(f, s->ch[i].vaddr[1]);
+#else
+#error TARGET_PHYS_ADDR_BITS undefined
+#endif
+        qemu_put_sbe32(f, s->ch[i].running);
+    }
+}
+
+static int soc_dma_load_state(QEMUFile *f, void *opaque, int version_id)
+{
+    struct dma_s *s = (struct dma_s *)opaque;
+    int i;
+    
+    if (version_id)
+        return -EINVAL;
+    
+    qemu_get_buffer(f, s->soc.drqst, sizeof(s->soc.drqst));
+    s->soc.freq = qemu_get_sbe64(f);
+    s->ch_enable_mask = qemu_get_be64(f);
+    s->channel_freq = qemu_get_sbe64(f);
+    s->enabled_count = qemu_get_sbe32(f);
+    for (i = 0; i < s->chnum; i++) {
+        qemu_get_timer(f, s->ch[i].timer);
+        s->ch[i].enable = qemu_get_sbe32(f);
+        s->ch[i].update = qemu_get_sbe32(f);
+        s->ch[i].bytes = qemu_get_sbe32(f);
+        s->ch[i].type[0] = qemu_get_sbe32(f);
+        s->ch[i].type[1] = qemu_get_sbe32(f);
+#if TARGET_PHYS_ADDR_BITS == 32
+        s->ch[i].vaddr[0] = qemu_get_be32(f);
+        s->ch[i].vaddr[1] = qemu_get_be32(f);
+#elif TARGET_PHYS_ADDR_BITS == 64
+        s->ch[i].vaddr[0] = qemu_get_be64(f);
+        s->ch[i].vaddr[1] = qemu_get_be64(f);
+#else
+#error TARGET_PHYS_ADDR_BITS undefined
+#endif
+        s->ch[i].running = qemu_get_sbe32(f);
+        
+        soc_dma_ch_update(&s->ch[i]);
+    }
+    
+    return 0;
+}
+
 /* TODO: take a functional-clock argument */
 struct soc_dma_s *soc_dma_init(int n)
 {
@@ -251,6 +319,8 @@ struct soc_dma_s *soc_dma_init(int n)
     soc_dma_reset(&s->soc);
     fifo_size = 0;
 
+    register_savevm("soc_dma", -1, 0,
+                    soc_dma_save_state, soc_dma_load_state, s);
     return &s->soc;
 }
 
index c0ebb8d..6bfd3a8 100644 (file)
@@ -18,6 +18,8 @@
  * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#define DMA_MAX_DRQ 96
+
 struct soc_dma_s;
 struct soc_dma_ch_s;
 typedef void (*soc_dma_io_t)(void *opaque, uint8_t *buf, int len);
@@ -65,7 +67,7 @@ struct soc_dma_ch_s {
 struct soc_dma_s {
     /* Following fields are set by the SoC DMA module and can be used
      * by anybody.  */
-    uint64_t drqbmp;   /* Is zeroed by soc_dma_reset() */
+    uint8_t drqst[DMA_MAX_DRQ]; /* Is zeroed by soc_dma_reset() */
     qemu_irq *drq;
     void *opaque;
     int64_t freq;