summary refs log tree commit diff stats
path: root/hw/core/clock-vmstate.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/core/clock-vmstate.c')
-rw-r--r--hw/core/clock-vmstate.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/hw/core/clock-vmstate.c b/hw/core/clock-vmstate.c
index 260b13fc2c..9d9174ffbd 100644
--- a/hw/core/clock-vmstate.c
+++ b/hw/core/clock-vmstate.c
@@ -14,12 +14,50 @@
 #include "migration/vmstate.h"
 #include "hw/clock.h"
 
+static bool muldiv_needed(void *opaque)
+{
+    Clock *clk = opaque;
+
+    return clk->multiplier != 1 || clk->divider != 1;
+}
+
+static int clock_pre_load(void *opaque)
+{
+    Clock *clk = opaque;
+    /*
+     * The initial out-of-reset settings of the Clock might have been
+     * configured by the device to be different from what we set
+     * in clock_initfn(), so we must here set the default values to
+     * be used if they are not in the inbound migration state.
+     */
+    clk->multiplier = 1;
+    clk->divider = 1;
+
+    return 0;
+}
+
+const VMStateDescription vmstate_muldiv = {
+    .name = "clock/muldiv",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = muldiv_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(multiplier, Clock),
+        VMSTATE_UINT32(divider, Clock),
+    },
+};
+
 const VMStateDescription vmstate_clock = {
     .name = "clock",
     .version_id = 0,
     .minimum_version_id = 0,
+    .pre_load = clock_pre_load,
     .fields = (VMStateField[]) {
         VMSTATE_UINT64(period, Clock),
         VMSTATE_END_OF_LIST()
-    }
+    },
+    .subsections = (const VMStateDescription*[]) {
+        &vmstate_muldiv,
+        NULL
+    },
 };