summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dev/alpha/tsunami_io.cc1
-rw-r--r--src/dev/intel_8254_timer.cc54
-rw-r--r--src/dev/intel_8254_timer.hh14
-rwxr-xr-xsrc/dev/mips/malta_io.cc1
-rw-r--r--src/dev/x86/i8254.cc6
-rw-r--r--src/dev/x86/i8254.hh1
6 files changed, 63 insertions, 14 deletions
diff --git a/src/dev/alpha/tsunami_io.cc b/src/dev/alpha/tsunami_io.cc
index a20cd8a88..2236546fc 100644
--- a/src/dev/alpha/tsunami_io.cc
+++ b/src/dev/alpha/tsunami_io.cc
@@ -288,6 +288,7 @@ void
TsunamiIO::startup()
{
rtc.startup();
+ pitimer.startup();
}
TsunamiIO *
diff --git a/src/dev/intel_8254_timer.cc b/src/dev/intel_8254_timer.cc
index 4aa3fec14..63bb6e8af 100644
--- a/src/dev/intel_8254_timer.cc
+++ b/src/dev/intel_8254_timer.cc
@@ -89,13 +89,22 @@ Intel8254Timer::unserialize(const string &base, Checkpoint *cp,
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 @@ Intel8254Timer::Counter::write(const uint8_t data)
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 @@ Intel8254Timer::Counter::serialize(const string &base, ostream &os)
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 @@ Intel8254Timer::Counter::unserialize(const string &base, Checkpoint *cp,
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 @@ Intel8254Timer::Counter::CounterEvent::description() const
{
return "Intel 8254 Interval timer";
}
+
+Tick
+Intel8254Timer::Counter::CounterEvent::getInterval()
+{
+ return interval;
+}
+
diff --git a/src/dev/intel_8254_timer.hh b/src/dev/intel_8254_timer.hh
index ad751447e..b2fd949f2 100644
--- a/src/dev/intel_8254_timer.hh
+++ b/src/dev/intel_8254_timer.hh
@@ -102,6 +102,8 @@ class Intel8254Timer : public EventManager
void setTo(int clocks);
int clocksLeft();
+
+ Tick getInterval();
};
private:
@@ -112,6 +114,9 @@ class Intel8254Timer : public EventManager
CounterEvent event;
+ /** True after startup is called. */
+ bool running;
+
/** Initial count value */
uint16_t initial_count;
@@ -121,6 +126,9 @@ class Intel8254Timer : public EventManager
/** Interrupt period */
uint16_t period;
+ /** When to start ticking */
+ Tick offset;
+
/** Current mode of operation */
uint8_t mode;
@@ -181,6 +189,9 @@ class Intel8254Timer : public EventManager
*/
void unserialize(const std::string &base, Checkpoint *cp,
const std::string &section);
+
+ /** Start ticking */
+ void startup();
};
protected:
@@ -246,6 +257,9 @@ class Intel8254Timer : public EventManager
*/
void unserialize(const std::string &base, Checkpoint *cp,
const std::string &section);
+
+ /** Start ticking */
+ void startup();
};
#endif // __DEV_8254_HH__
diff --git a/src/dev/mips/malta_io.cc b/src/dev/mips/malta_io.cc
index 6797a054c..d79e43260 100755
--- a/src/dev/mips/malta_io.cc
+++ b/src/dev/mips/malta_io.cc
@@ -146,6 +146,7 @@ void
MaltaIO::startup()
{
rtc.startup();
+ pitimer.startup();
}
MaltaIO *
diff --git a/src/dev/x86/i8254.cc b/src/dev/x86/i8254.cc
index f6af34a65..b80952237 100644
--- a/src/dev/x86/i8254.cc
+++ b/src/dev/x86/i8254.cc
@@ -89,6 +89,12 @@ X86ISA::I8254::unserialize(Checkpoint *cp, const std::string &section)
pit.unserialize("pit", cp, section);
}
+void
+X86ISA::I8254::startup()
+{
+ pit.startup();
+}
+
X86ISA::I8254 *
I8254Params::create()
{
diff --git a/src/dev/x86/i8254.hh b/src/dev/x86/i8254.hh
index 49ea271e9..76521e73e 100644
--- a/src/dev/x86/i8254.hh
+++ b/src/dev/x86/i8254.hh
@@ -111,6 +111,7 @@ class I8254 : public BasicPioDevice
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
+ virtual void startup();
};