Patchwork [10/15] pseries: savevm support for XICS interrupt controller

login
register
mail settings
Submitter David Gibson
Date Oct. 15, 2012, 12:24 a.m.
Message ID <1350260682-21428-11-git-send-email-david@gibson.dropbear.id.au>
Download mbox | patch
Permalink /patch/191445/
State New
Headers show

Comments

David Gibson - Oct. 15, 2012, 12:24 a.m.
This patch adds the necessary VMStateDescription information to allow
savevm/loadvm for the XICS interrupt controller.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/xics.c |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 53 insertions(+), 4 deletions(-)

Patch

diff --git a/hw/xics.c b/hw/xics.c
index 5e20f0f..c4dcde5 100644
--- a/hw/xics.c
+++ b/hw/xics.c
@@ -50,7 +50,7 @@  struct icp_server_state {
 struct ics_state;
 
 struct icp_state {
-    long nr_servers;
+    uint32_t nr_servers;
     struct icp_server_state *ss;
     struct ics_state *ics;
 };
@@ -171,7 +171,7 @@  static void icp_irq(struct icp_state *icp, int server, int nr, uint8_t priority)
  */
 
 struct ics_irq_state {
-    int server;
+    uint32_t server;
     uint8_t priority;
     uint8_t saved_priority;
 #define XICS_STATUS_ASSERTED           0x1
@@ -182,8 +182,8 @@  struct ics_irq_state {
 };
 
 struct ics_state {
-    int nr_irqs;
-    int offset;
+    uint32_t nr_irqs;
+    uint32_t offset;
     qemu_irq *qirqs;
     bool *islsi;
     struct ics_irq_state *irqs;
@@ -519,6 +519,48 @@  static void xics_reset(void *opaque)
     }
 }
 
+static const VMStateDescription vmstate_icp_server = {
+    .name = "icp/server",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        /* Sanity check */
+        VMSTATE_UINT32(xirr, struct icp_server_state),
+        VMSTATE_UINT8(pending_priority, struct icp_server_state),
+        VMSTATE_UINT8(mfrr, struct icp_server_state),
+        VMSTATE_END_OF_LIST()
+    },
+};
+
+static const VMStateDescription vmstate_ics_irq = {
+    .name = "ics/irq",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT32(server, struct ics_irq_state),
+        VMSTATE_UINT8(priority, struct ics_irq_state),
+        VMSTATE_UINT8(saved_priority, struct ics_irq_state),
+        VMSTATE_UINT8(status, struct ics_irq_state),
+        VMSTATE_END_OF_LIST()
+    },
+};
+
+static const VMStateDescription vmstate_ics = {
+    .name = "ics",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        /* Sanity check */
+        VMSTATE_UINT32_EQUAL(nr_irqs, struct ics_state),
+
+        VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, struct ics_state, nr_irqs, vmstate_ics_irq, struct ics_irq_state),
+        VMSTATE_END_OF_LIST()
+    },
+};
+
 void xics_cpu_setup(struct icp_state *icp, CPUPPCState *env)
 {
     struct icp_server_state *ss = &icp->ss[env->cpu_index];
@@ -539,6 +581,8 @@  void xics_cpu_setup(struct icp_state *icp, CPUPPCState *env)
                 "bus model\n");
         abort();
     }
+
+    vmstate_register(NULL, env->cpu_index, &vmstate_icp_server, ss);
 }
 
 struct icp_state *xics_system_init(int nr_servers, int nr_irqs)
@@ -573,5 +617,10 @@  struct icp_state *xics_system_init(int nr_servers, int nr_irqs)
 
     qemu_register_reset(xics_reset, icp);
 
+    /* We use each the ICS's offset into the global irq number space
+     * as an instance id.  This means we can extend to multiple ICS
+     * instances without needing to change the savevm format */
+    vmstate_register(NULL, ics->offset, &vmstate_ics, ics);
+
     return icp;
 }