The device had no VMStateDescription, so none of its register or PHY
state was saved or migrated.

The MAC register block and the PHY registers are structs that contain
nothing but uint32_t (MAC) or uint16_t (PHY) fields. Overlay each with
an array of the same element type, in an anonymous union, so that the
rest of the code keeps its s->regs.foo style access, and migrate each
block as an array of that type. Unlike describing them as byte
buffers, this is correct when migrating between hosts of different
endianness.

The interrupt outputs are derived from the registers and need no
handling after load: the device at the other end of each line
migrates its own state.

Signed-off-by: Marcelo Manzo <[email protected]>
---
 hw/net/bcm2838_genet.c         | 23 +++++++++++++++++++++++
 include/hw/net/bcm2838_genet.h | 22 +++++++++++++++++++---
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/hw/net/bcm2838_genet.c b/hw/net/bcm2838_genet.c
index 840a1bc72b..53bba99b38 100644
--- a/hw/net/bcm2838_genet.c
+++ b/hw/net/bcm2838_genet.c
@@ -17,6 +17,7 @@
 #include "system/dma.h"
 #include "hw/core/registerfields.h"
 #include "hw/core/resettable.h"
+#include "migration/vmstate.h"
 #include "hw/net/bcm2838_genet.h"
 #include "trace.h"
 
@@ -1135,6 +1136,27 @@ static const Property genet_properties[] = {
     DEFINE_NIC_PROPERTIES(BCM2838GenetState, nic_conf),
 };
 
+static const VMStateDescription vmstate_bcm2838_genet = {
+    .name = "bcm2838-genet",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (const VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(regs_u32, BCM2838GenetState,
+                             sizeof(BCM2838GenetRegs) / sizeof(uint32_t)),
+        VMSTATE_UINT16_ARRAY(phy_regs_u16, BCM2838GenetState,
+                             sizeof(BCM2838GenetPhyRegs) / sizeof(uint16_t)),
+        VMSTATE_UINT16_ARRAY(phy_shd_regs_u16, BCM2838GenetState,
+                             sizeof(BCM2838GenetPhyShdRegs)
+                             / sizeof(uint16_t)),
+        VMSTATE_UINT16_ARRAY(phy_aux_ctl_shd_regs.regs, BCM2838GenetState,
+                             BCM2838_GENET_PHY_AUX_CTL_REGS_SIZE),
+        VMSTATE_UINT16_2DARRAY(phy_exp_shd_regs.regs, BCM2838GenetState,
+                               BCM2838_GENET_PHY_EXP_SHD_BLOCKS_CNT,
+                               BCM2838_GENET_PHY_EXP_SHD_REGS_CNT),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static void bcm2838_genet_class_init(ObjectClass *class, const void *data)
 {
     static ResettablePhases unused_parent_phases;
@@ -1142,6 +1164,7 @@ static void bcm2838_genet_class_init(ObjectClass *class, 
const void *data)
     ResettableClass *rc = RESETTABLE_CLASS(class);
 
     dc->realize = bcm2838_genet_realize;
+    dc->vmsd = &vmstate_bcm2838_genet;
     resettable_class_set_parent_phases(rc, NULL, bcm2838_genet_reset, NULL,
                                        &unused_parent_phases);
     device_class_set_props(dc, genet_properties);
diff --git a/include/hw/net/bcm2838_genet.h b/include/hw/net/bcm2838_genet.h
index 87a59941ec..2420711a29 100644
--- a/include/hw/net/bcm2838_genet.h
+++ b/include/hw/net/bcm2838_genet.h
@@ -409,9 +409,25 @@ struct BCM2838GenetState {
     MemoryRegion regs_mr;
     AddressSpace dma_as;
 
-    BCM2838GenetRegs regs;
-    BCM2838GenetPhyRegs phy_regs;
-    BCM2838GenetPhyShdRegs phy_shd_regs;
+    /*
+     * The register blocks are named structs that contain nothing but
+     * uint32_t (MAC) or uint16_t (PHY) fields. Overlay each with an array
+     * of the same element type so that the whole block can be migrated
+     * with a single VMSTATE_UINT32_ARRAY()/VMSTATE_UINT16_ARRAY().
+     */
+    union {
+        BCM2838GenetRegs regs;
+        uint32_t regs_u32[sizeof(BCM2838GenetRegs) / sizeof(uint32_t)];
+    };
+    union {
+        BCM2838GenetPhyRegs phy_regs;
+        uint16_t phy_regs_u16[sizeof(BCM2838GenetPhyRegs) / sizeof(uint16_t)];
+    };
+    union {
+        BCM2838GenetPhyShdRegs phy_shd_regs;
+        uint16_t phy_shd_regs_u16[sizeof(BCM2838GenetPhyShdRegs)
+                                  / sizeof(uint16_t)];
+    };
     BCM2838GenetPhyAuxShdRegs phy_aux_ctl_shd_regs;
     BCM2838GenetPhyExpShdRegs phy_exp_shd_regs;
 
-- 
2.55.0


Reply via email to