changeset 9d3b6e7dd205 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=9d3b6e7dd205
description:
        dev: prevent intel 8254 timer counter events firing before startup

        This change includes edits to Intel8254Timer to prevent counter events 
firing
        before startup to comply with SimObject initialization call sequence.

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

diffstat:

 src/dev/alpha/tsunami_io.cc |   1 +
 src/dev/intel_8254_timer.cc |  54 +++++++++++++++++++++++++++++++++-----------
 src/dev/intel_8254_timer.hh |  14 +++++++++++
 src/dev/mips/malta_io.cc    |   1 +
 src/dev/x86/i8254.cc        |   6 +++++
 src/dev/x86/i8254.hh        |   1 +
 6 files changed, 63 insertions(+), 14 deletions(-)

diffs (194 lines):

diff -r 04923a93f2b5 -r 9d3b6e7dd205 src/dev/alpha/tsunami_io.cc
--- a/src/dev/alpha/tsunami_io.cc       Wed Jan 07 00:34:40 2015 -0800
+++ b/src/dev/alpha/tsunami_io.cc       Tue Jan 06 15:10:22 2015 -0700
@@ -288,6 +288,7 @@
 TsunamiIO::startup()
 {
     rtc.startup();
+    pitimer.startup();
 }
 
 TsunamiIO *
diff -r 04923a93f2b5 -r 9d3b6e7dd205 src/dev/intel_8254_timer.cc
--- a/src/dev/intel_8254_timer.cc       Wed Jan 07 00:34:40 2015 -0800
+++ b/src/dev/intel_8254_timer.cc       Tue Jan 06 15:10:22 2015 -0700
@@ -89,13 +89,22 @@
     counter[2]->unserialize(base + ".counter2", cp, section);
 }
 
+void
+Intel8254Timer::startup()
+{
+    counter[0]->startup();
+    counter[1]->startup();
+    counter[2]->startup();
+}
+
 Intel8254Timer::Counter::Counter(Intel8254Timer *p,
         const string &name, unsigned int _num)
-    : _name(name), num(_num), event(this), initial_count(0),
-      latched_count(0), period(0), mode(0), output_high(false),
-      latch_on(false), read_byte(LSB), write_byte(LSB), parent(p)
+    : _name(name), num(_num), event(this), running(false),
+      initial_count(0), latched_count(0), period(0), mode(0),
+      output_high(false), latch_on(false), read_byte(LSB),
+      write_byte(LSB), parent(p)
 {
-
+    offset = period * event.getInterval();
 }
 
 void
@@ -179,7 +188,9 @@
         else
             period = initial_count;
 
-        if (period > 0)
+        offset = period * event.getInterval();
+
+        if (running && (period > 0))
             event.setTo(period);
 
         write_byte = LSB;
@@ -229,10 +240,10 @@
     paramOut(os, base + ".read_byte", read_byte);
     paramOut(os, base + ".write_byte", write_byte);
 
-    Tick event_tick = 0;
+    Tick event_tick_offset = 0;
     if (event.scheduled())
-        event_tick = event.when();
-    paramOut(os, base + ".event_tick", event_tick);
+        event_tick_offset = event.when() - curTick();
+    paramOut(os, base + ".event_tick_offset", event_tick_offset);
 }
 
 void
@@ -248,12 +259,20 @@
     paramIn(cp, section, base + ".read_byte", read_byte);
     paramIn(cp, section, base + ".write_byte", write_byte);
 
-    Tick event_tick = 0;
-    if (event.scheduled())
-        parent->deschedule(event);
-    paramIn(cp, section, base + ".event_tick", event_tick);
-    if (event_tick)
-        parent->schedule(event, event_tick);
+    Tick event_tick_offset = 0;
+    assert(!event.scheduled());
+    paramIn(cp, section, base + ".event_tick_offset", event_tick_offset);
+    offset = event_tick_offset;
+}
+
+void
+Intel8254Timer::Counter::startup()
+{
+    running = true;
+    if ((period > 0) && (offset > 0))
+    {
+        parent->schedule(event, curTick() + offset);
+    }
 }
 
 Intel8254Timer::Counter::CounterEvent::CounterEvent(Counter* c_ptr)
@@ -302,3 +321,10 @@
 {
     return "Intel 8254 Interval timer";
 }
+
+Tick
+Intel8254Timer::Counter::CounterEvent::getInterval()
+{
+    return interval;
+}
+
diff -r 04923a93f2b5 -r 9d3b6e7dd205 src/dev/intel_8254_timer.hh
--- a/src/dev/intel_8254_timer.hh       Wed Jan 07 00:34:40 2015 -0800
+++ b/src/dev/intel_8254_timer.hh       Tue Jan 06 15:10:22 2015 -0700
@@ -102,6 +102,8 @@
             void setTo(int clocks);
 
             int clocksLeft();
+
+            Tick getInterval();
         };
 
       private:
@@ -112,6 +114,9 @@
 
         CounterEvent event;
 
+        /** True after startup is called. */
+        bool running;
+
         /** Initial count value */
         uint16_t initial_count;
 
@@ -121,6 +126,9 @@
         /** Interrupt period */
         uint16_t period;
 
+        /** When to start ticking */
+        Tick offset;
+
         /** Current mode of operation */
         uint8_t mode;
 
@@ -181,6 +189,9 @@
          */
         void unserialize(const std::string &base, Checkpoint *cp,
                          const std::string &section);
+
+        /** Start ticking */
+        void startup();
     };
 
   protected:
@@ -246,6 +257,9 @@
      */
     void unserialize(const std::string &base, Checkpoint *cp,
                      const std::string &section);
+
+    /** Start ticking */
+    void startup();
 };
 
 #endif // __DEV_8254_HH__
diff -r 04923a93f2b5 -r 9d3b6e7dd205 src/dev/mips/malta_io.cc
--- a/src/dev/mips/malta_io.cc  Wed Jan 07 00:34:40 2015 -0800
+++ b/src/dev/mips/malta_io.cc  Tue Jan 06 15:10:22 2015 -0700
@@ -146,6 +146,7 @@
 MaltaIO::startup()
 {
     rtc.startup();
+    pitimer.startup();
 }
 
 MaltaIO *
diff -r 04923a93f2b5 -r 9d3b6e7dd205 src/dev/x86/i8254.cc
--- a/src/dev/x86/i8254.cc      Wed Jan 07 00:34:40 2015 -0800
+++ b/src/dev/x86/i8254.cc      Tue Jan 06 15:10:22 2015 -0700
@@ -89,6 +89,12 @@
     pit.unserialize("pit", cp, section);
 }
 
+void
+X86ISA::I8254::startup()
+{
+    pit.startup();
+}
+
 X86ISA::I8254 *
 I8254Params::create()
 {
diff -r 04923a93f2b5 -r 9d3b6e7dd205 src/dev/x86/i8254.hh
--- a/src/dev/x86/i8254.hh      Wed Jan 07 00:34:40 2015 -0800
+++ b/src/dev/x86/i8254.hh      Tue Jan 06 15:10:22 2015 -0700
@@ -111,6 +111,7 @@
 
     virtual void serialize(std::ostream &os);
     virtual void unserialize(Checkpoint *cp, const std::string &section);
+    virtual void startup();
 
 };
 
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to