dev: prevent RTC events firing before startup
authorCagdas Dirik <cdirik@micron.com>
Sat, 3 Jan 2015 23:51:48 +0000 (17:51 -0600)
committerCagdas Dirik <cdirik@micron.com>
Sat, 3 Jan 2015 23:51:48 +0000 (17:51 -0600)
This change includes edits to MC146818 timer to prevent RTC events
firing before startup to comply with SimObject initialization call sequence.

Committed by: Nilay Vaish <nilay@cs.wisc.edu>

src/dev/alpha/tsunami_io.cc
src/dev/alpha/tsunami_io.hh
src/dev/arm/rtc_pl031.cc
src/dev/mc146818.cc
src/dev/mc146818.hh
src/dev/mips/malta_io.cc
src/dev/mips/malta_io.hh
src/dev/x86/cmos.cc
src/dev/x86/cmos.hh

index 2c503880ff07a600aea37b588bdbaaeb54a1bbbc..a20cd8a88145c8f38b22617a9cb8d3a3d6cae6fd 100644 (file)
@@ -284,6 +284,12 @@ TsunamiIO::unserialize(Checkpoint *cp, const string &section)
     rtc.unserialize("rtc", cp, section);
 }
 
+void
+TsunamiIO::startup()
+{
+    rtc.startup();
+}
+
 TsunamiIO *
 TsunamiIOParams::create()
 {
index 684295551ba1f14565c850613cb93756eec14ed8..f242c9e2ac21cc974e75165e3bf9ce5cad91bb9a 100644 (file)
@@ -151,6 +151,11 @@ class TsunamiIO : public BasicPioDevice
      */
     virtual void unserialize(Checkpoint *cp, const std::string &section);
 
+    /**
+     * Start running.
+     */
+    virtual void startup();
+
 };
 
 #endif // __DEV_TSUNAMI_IO_HH__
index a43ac6271683edb83dd5543fbc6200b8ac9baabf..e619045c2aff4bbc43aca9e8e9f5cc9c07f82222 100644 (file)
@@ -44,7 +44,6 @@
 #include "debug/Timer.hh"
 #include "dev/arm/amba_device.hh"
 #include "dev/arm/rtc_pl031.hh"
-#include "dev/mc146818.hh"
 #include "mem/packet.hh"
 #include "mem/packet_access.hh"
 
index 81366b774919098fe098b3aa13f0a8b5104bdc0a..fa83507609c0b46687a3100454ad6e63b1a446d8 100644 (file)
@@ -122,6 +122,15 @@ MC146818::rega_dv_disabled(const RtcRegA &reg)
         reg.dv == RTCA_DV_DISABLED1;
 }
 
+void
+MC146818::startup()
+{
+    assert(!event.scheduled());
+    assert(!tickEvent.scheduled());
+    schedule(event, curTick() + event.offset);
+    schedule(tickEvent, curTick() + tickEvent.offset);
+}
+
 void
 MC146818::writeData(const uint8_t addr, const uint8_t data)
 {
@@ -291,17 +300,16 @@ MC146818::unserialize(const string &base, Checkpoint *cp,
     //
     Tick rtcTimerInterruptTickOffset;
     UNSERIALIZE_SCALAR(rtcTimerInterruptTickOffset);
-    reschedule(event, curTick() + rtcTimerInterruptTickOffset);
+    event.offset = rtcTimerInterruptTickOffset;
     Tick rtcClockTickOffset;
     UNSERIALIZE_SCALAR(rtcClockTickOffset);
-    reschedule(tickEvent, curTick() + rtcClockTickOffset);
+    tickEvent.offset = rtcClockTickOffset;
 }
 
 MC146818::RTCEvent::RTCEvent(MC146818 * _parent, Tick i)
-    : parent(_parent), interval(i)
+    : parent(_parent), interval(i), offset(i)
 {
     DPRINTF(MC146818, "RTC Event Initilizing\n");
-    parent->schedule(this, curTick() + interval);
 }
 
 void
index 76cd40c37abca2313c498d77910e0d1e53f903f0..936f597d04272669a7b4656086dc53c198907243 100644 (file)
@@ -51,6 +51,7 @@ class MC146818 : public EventManager
     {
         MC146818 * parent;
         Tick interval;
+        Tick offset;
 
         RTCEvent(MC146818 * _parent, Tick i);
 
@@ -68,11 +69,11 @@ class MC146818 : public EventManager
     struct RTCTickEvent : public Event
     {
         MC146818 * parent;
+        Tick offset;
 
-        RTCTickEvent(MC146818 * _parent) : parent(_parent)
-        {
-            parent->schedule(this, curTick() + SimClock::Int::s);
-        }
+        RTCTickEvent(MC146818 * _parent) :
+            parent(_parent), offset(SimClock::Int::s)
+        {}
 
         /** Event process to occur at interrupt*/
         void process();
@@ -153,6 +154,9 @@ class MC146818 : public EventManager
             bool bcd, Tick frequency);
     virtual ~MC146818();
 
+    /** Start ticking */
+    virtual void startup();
+
     /** RTC write data */
     void writeData(const uint8_t addr, const uint8_t data);
 
index d769b1112f9b1439ae6ea40ed55fcd2240d0fd15..6797a054ce7e1dbea0c72ea8dea9e1710665ae6e 100755 (executable)
@@ -142,6 +142,12 @@ MaltaIO::unserialize(Checkpoint *cp, const string &section)
     rtc.unserialize("rtc", cp, section);
 }
 
+void
+MaltaIO::startup()
+{
+    rtc.startup();
+}
+
 MaltaIO *
 MaltaIOParams::create()
 {
index f74d42da42fadb7904e6d6dc4b598caad5cb488d..dd035aea2652fd9018bf9b245f9a1c43f0fe129e 100755 (executable)
@@ -143,6 +143,11 @@ class MaltaIO : public BasicPioDevice
      */
     virtual void unserialize(Checkpoint *cp, const std::string &section);
 
+    /**
+     * Start running.
+     */
+    virtual void startup();
+
 };
 
 #endif // __DEV_MALTA_IO_HH__
index d7107deb74cbe252c6828b732fe155d3a161a93e..6a778b7589493fe1aeae62d52344712f4fc9f4c9 100644 (file)
@@ -112,6 +112,12 @@ X86ISA::Cmos::writeRegister(uint8_t reg, uint8_t val)
     }
 }
 
+void
+X86ISA::Cmos::startup()
+{
+    rtc.startup();
+}
+
 void
 X86ISA::Cmos::serialize(std::ostream &os)
 {
index 7957e5304123ccc1ca24374e6ceb5c99d87ca190..fa5865c0a17fce7ca30d9c131607dcb5865d8273 100644 (file)
@@ -82,6 +82,7 @@ class Cmos : public BasicPioDevice
 
     Tick write(PacketPtr pkt);
 
+    virtual void startup();
     virtual void serialize(std::ostream &os);
     virtual void unserialize(Checkpoint *cp, const std::string &section);