summary refs log tree commit diff stats
path: root/hw/arm_gic.c
diff options
context:
space:
mode:
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2008-07-02 16:48:32 +0000
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2008-07-02 16:48:32 +0000
commit23e39294034e13d29a0707483542bab850d601b4 (patch)
treebf8c1fa3e39234083a06bd7b579476f870853b06 /hw/arm_gic.c
parentab19b0ecfddf94ae2053b973cea5a58c8dac0363 (diff)
downloadfocaccia-qemu-23e39294034e13d29a0707483542bab850d601b4.tar.gz
focaccia-qemu-23e39294034e13d29a0707483542bab850d601b4.zip
Save/restore for stellaris boards.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4824 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/arm_gic.c')
-rw-r--r--hw/arm_gic.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 7f67c5276d..54e99f4d66 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -650,6 +650,79 @@ static void gic_reset(gic_state *s)
 #endif
 }
 
+static void gic_save(QEMUFile *f, void *opaque)
+{
+    gic_state *s = (gic_state *)opaque;
+    int i;
+    int j;
+
+    qemu_put_be32(f, s->enabled);
+    for (i = 0; i < NCPU; i++) {
+        qemu_put_be32(f, s->cpu_enabled[i]);
+#ifndef NVIC
+        qemu_put_be32(f, s->irq_target[i]);
+#endif
+        for (j = 0; j < 32; j++)
+            qemu_put_be32(f, s->priority1[j][i]);
+        for (j = 0; j < GIC_NIRQ; j++)
+            qemu_put_be32(f, s->last_active[j][i]);
+        qemu_put_be32(f, s->priority_mask[i]);
+        qemu_put_be32(f, s->running_irq[i]);
+        qemu_put_be32(f, s->running_priority[i]);
+        qemu_put_be32(f, s->current_pending[i]);
+    }
+    for (i = 0; i < GIC_NIRQ - 32; i++) {
+        qemu_put_be32(f, s->priority2[i]);
+    }
+    for (i = 0; i < GIC_NIRQ; i++) {
+        qemu_put_byte(f, s->irq_state[i].enabled);
+        qemu_put_byte(f, s->irq_state[i].pending);
+        qemu_put_byte(f, s->irq_state[i].active);
+        qemu_put_byte(f, s->irq_state[i].level);
+        qemu_put_byte(f, s->irq_state[i].model);
+        qemu_put_byte(f, s->irq_state[i].trigger);
+    }
+}
+
+static int gic_load(QEMUFile *f, void *opaque, int version_id)
+{
+    gic_state *s = (gic_state *)opaque;
+    int i;
+    int j;
+
+    if (version_id != 1)
+        return -EINVAL;
+
+    s->enabled = qemu_get_be32(f);
+    for (i = 0; i < NCPU; i++) {
+        s->cpu_enabled[i] = qemu_get_be32(f);
+#ifndef NVIC
+        s->irq_target[i] = qemu_get_be32(f);
+#endif
+        for (j = 0; j < 32; j++)
+            s->priority1[j][i] = qemu_get_be32(f);
+        for (j = 0; j < GIC_NIRQ; j++)
+            s->last_active[j][i] = qemu_get_be32(f);
+        s->priority_mask[i] = qemu_get_be32(f);
+        s->running_irq[i] = qemu_get_be32(f);
+        s->running_priority[i] = qemu_get_be32(f);
+        s->current_pending[i] = qemu_get_be32(f);
+    }
+    for (i = 0; i < GIC_NIRQ - 32; i++) {
+        s->priority2[i] = qemu_get_be32(f);
+    }
+    for (i = 0; i < GIC_NIRQ; i++) {
+        s->irq_state[i].enabled = qemu_get_byte(f);
+        s->irq_state[i].pending = qemu_get_byte(f);
+        s->irq_state[i].active = qemu_get_byte(f);
+        s->irq_state[i].level = qemu_get_byte(f);
+        s->irq_state[i].model = qemu_get_byte(f);
+        s->irq_state[i].trigger = qemu_get_byte(f);
+    }
+
+    return 0;
+}
+
 static gic_state *gic_init(uint32_t base, qemu_irq *parent_irq)
 {
     gic_state *s;
@@ -669,5 +742,6 @@ static gic_state *gic_init(uint32_t base, qemu_irq *parent_irq)
                                  iomemtype);
     s->base = base;
     gic_reset(s);
+    register_savevm("arm_gic", -1, 1, gic_save, gic_load, s);
     return s;
 }