Patchwork [30/48] savevm and reset support for soc_dma

login
register
mail settings
Submitter Riku Voipio
Date March 26, 2010, 4:06 p.m.
Message ID <39ff11f959d78f5a574831ecbf097db9e55aba5f.1269617186.git.riku.voipio@nokia.com>
Download mbox | patch
Permalink /patch/48699/
State New
Headers show

Comments

Riku Voipio - March 26, 2010, 4:06 p.m.
From: Riku Voipio <riku.voipio@nokia.com>

Signed-Off-By: Riku Voipio <riku.voipio@nokia.com>

---
 hw/soc_dma.c |   72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 hw/soc_dma.h |    4 ++-
 2 files changed, 74 insertions(+), 2 deletions(-)

Patch

diff --git a/hw/soc_dma.c b/hw/soc_dma.c
index 8147ed5..280fe92 100644
--- a/hw/soc_dma.c
+++ b/hw/soc_dma.c
@@ -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;
 }
 
diff --git a/hw/soc_dma.h b/hw/soc_dma.h
index c0ebb8d..6bfd3a8 100644
--- a/hw/soc_dma.h
+++ b/hw/soc_dma.h
@@ -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;