From af0409f33f30475eec2ca7e5044a076f4c9c2b6b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Juha=20Riihim=C3=A4ki?= Date: Tue, 1 Sep 2009 18:07:12 +0300 Subject: [PATCH] add savevm support and fixes --- hw/soc_dma.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- hw/soc_dma.h | 4 +++- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/hw/soc_dma.c b/hw/soc_dma.c index e116e63..d004ce6 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 . */ +#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; -- 1.7.9.5