dev-arm: Fix checkpointing for the GenericTimer
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Thu, 9 Apr 2020 09:48:13 +0000 (10:48 +0100)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Tue, 14 Apr 2020 15:01:19 +0000 (15:01 +0000)
The revamp of the GenericTimer was not taking into account:

* The name of the variable will be printed on the checkpoint to label the
data. It is not possible to use different variable names when
serializing/unserializing, and it is not possible to use the same
temporary variable to serialize/unserialize different values.

* the serializeSection is creating a new sub section in the
checkpoint. Doing the following:

void
GenericTimerFrame::serialize(CheckpointOut &cp) const
{
    physTimer.serializeSection(cp, "phys_timer");
    virtTimer.serializeSection(cp, "virt_timer");
    SERIALIZE_SCALAR(accessBits);
}

will serialize the accessBits under the virt_timer subsection
rather than the parent generic_timer_frame.

JIRA: https://gem5.atlassian.net/projects/GEM5/issues/GEM5-426

Change-Id: I7676309965a33156789d2ef13e966c7a4ad88a71
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Ciro Santilli <ciro.santilli@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/27708
Tested-by: kokoro <noreply+kokoro@google.com>
src/dev/arm/generic_timer.cc

index 6e19a3a25860e24f3722bbf85cf69bbcdf904e9c..7ba0374a4458d8c8a84077380ef161fb9b230136 100644 (file)
@@ -728,57 +728,65 @@ GenericTimer::CoreTimers::notify()
 void
 GenericTimer::CoreTimers::serialize(CheckpointOut &cp) const
 {
-    physS.serializeSection(cp, "phys_s_timer");
-    physNS.serializeSection(cp, "phys_ns_timer");
-    virt.serializeSection(cp, "virt_timer");
-    hyp.serializeSection(cp, "hyp_timer");
-
     SERIALIZE_SCALAR(cntfrq);
     SERIALIZE_SCALAR(cntkctl);
     SERIALIZE_SCALAR(cnthctl);
 
-    bool ev_scheduled = physEvStream.event.scheduled();
-    SERIALIZE_SCALAR(ev_scheduled);
-    if (ev_scheduled)
-        SERIALIZE_SCALAR(physEvStream.event.when());
+    const bool phys_ev_scheduled = physEvStream.event.scheduled();
+    SERIALIZE_SCALAR(phys_ev_scheduled);
+    if (phys_ev_scheduled) {
+        const Tick phys_ev_when = physEvStream.event.when();
+        SERIALIZE_SCALAR(phys_ev_when);
+    }
     SERIALIZE_SCALAR(physEvStream.transitionTo);
     SERIALIZE_SCALAR(physEvStream.transitionBit);
-    ev_scheduled = virtEvStream.event.scheduled();
-    SERIALIZE_SCALAR(ev_scheduled);
-    if (ev_scheduled)
-        SERIALIZE_SCALAR(virtEvStream.event.when());
+
+    const bool virt_ev_scheduled = virtEvStream.event.scheduled();
+    SERIALIZE_SCALAR(virt_ev_scheduled);
+    if (virt_ev_scheduled) {
+        const Tick virt_ev_when = virtEvStream.event.when();
+        SERIALIZE_SCALAR(virt_ev_when);
+    }
     SERIALIZE_SCALAR(virtEvStream.transitionTo);
     SERIALIZE_SCALAR(virtEvStream.transitionBit);
+
+    physS.serializeSection(cp, "phys_s_timer");
+    physNS.serializeSection(cp, "phys_ns_timer");
+    virt.serializeSection(cp, "virt_timer");
+    hyp.serializeSection(cp, "hyp_timer");
 }
 
 void
 GenericTimer::CoreTimers::unserialize(CheckpointIn &cp)
 {
-    physS.unserializeSection(cp, "phys_s_timer");
-    physNS.unserializeSection(cp, "phys_ns_timer");
-    virt.unserializeSection(cp, "virt_timer");
-    hyp.unserializeSection(cp, "hyp_timer");
-
     UNSERIALIZE_SCALAR(cntfrq);
     UNSERIALIZE_SCALAR(cntkctl);
     UNSERIALIZE_SCALAR(cnthctl);
 
-    bool ev_scheduled;
-    Tick when;
-    UNSERIALIZE_SCALAR(ev_scheduled);
-    if (ev_scheduled) {
-        UNSERIALIZE_SCALAR(when);
-        parent.reschedule(physEvStream.event, when, true);
+    bool phys_ev_scheduled;
+    UNSERIALIZE_SCALAR(phys_ev_scheduled);
+    if (phys_ev_scheduled) {
+        Tick phys_ev_when;
+        UNSERIALIZE_SCALAR(phys_ev_when);
+        parent.reschedule(physEvStream.event, phys_ev_when, true);
     }
     UNSERIALIZE_SCALAR(physEvStream.transitionTo);
     UNSERIALIZE_SCALAR(physEvStream.transitionBit);
-    UNSERIALIZE_SCALAR(ev_scheduled);
-    if (ev_scheduled) {
-        UNSERIALIZE_SCALAR(when);
-        parent.reschedule(virtEvStream.event, when, true);
+
+    bool virt_ev_scheduled;
+    UNSERIALIZE_SCALAR(virt_ev_scheduled);
+    if (virt_ev_scheduled) {
+        Tick virt_ev_when;
+        UNSERIALIZE_SCALAR(virt_ev_when);
+        parent.reschedule(virtEvStream.event, virt_ev_when, true);
     }
     UNSERIALIZE_SCALAR(virtEvStream.transitionTo);
     UNSERIALIZE_SCALAR(virtEvStream.transitionBit);
+
+    physS.unserializeSection(cp, "phys_s_timer");
+    physNS.unserializeSection(cp, "phys_ns_timer");
+    virt.unserializeSection(cp, "virt_timer");
+    hyp.unserializeSection(cp, "hyp_timer");
 }
 
 void
@@ -823,23 +831,25 @@ GenericTimerFrame::GenericTimerFrame(GenericTimerFrameParams *const p)
 void
 GenericTimerFrame::serialize(CheckpointOut &cp) const
 {
-    physTimer.serializeSection(cp, "phys_timer");
-    virtTimer.serializeSection(cp, "virt_timer");
     SERIALIZE_SCALAR(accessBits);
     if (hasEl0View())
         SERIALIZE_SCALAR(accessBitsEl0);
     SERIALIZE_SCALAR(nonSecureAccess);
+
+    physTimer.serializeSection(cp, "phys_timer");
+    virtTimer.serializeSection(cp, "virt_timer");
 }
 
 void
 GenericTimerFrame::unserialize(CheckpointIn &cp)
 {
-    physTimer.unserializeSection(cp, "phys_timer");
-    virtTimer.unserializeSection(cp, "virt_timer");
     UNSERIALIZE_SCALAR(accessBits);
     if (hasEl0View())
         UNSERIALIZE_SCALAR(accessBitsEl0);
     UNSERIALIZE_SCALAR(nonSecureAccess);
+
+    physTimer.unserializeSection(cp, "phys_timer");
+    virtTimer.unserializeSection(cp, "virt_timer");
 }
 
 uint64_t