* Miguel J. Serrano
*/
-#include "base/misc.hh"
#include "dev/intel_8254_timer.hh"
-#include "sim/sim_object.hh"
+
+#include "base/logging.hh"
+#include "debug/Intel8254Timer.hh"
using namespace std;
}
}
-unsigned int
-Intel8254Timer::drain(Event *de)
+void
+Intel8254Timer::serialize(const string &base, CheckpointOut &cp) const
{
- unsigned int count = 0;
- count += counter[0]->drain(de);
- count += counter[1]->drain(de);
- count += counter[2]->drain(de);
- assert(count == 0);
- return count;
+ // serialize the counters
+ counter[0]->serialize(base + ".counter0", cp);
+ counter[1]->serialize(base + ".counter1", cp);
+ counter[2]->serialize(base + ".counter2", cp);
}
void
-Intel8254Timer::serialize(const string &base, ostream &os)
+Intel8254Timer::unserialize(const string &base, CheckpointIn &cp)
{
- // serialize the counters
- counter[0]->serialize(base + ".counter0", os);
- counter[1]->serialize(base + ".counter1", os);
- counter[2]->serialize(base + ".counter2", os);
+ // unserialze the counters
+ counter[0]->unserialize(base + ".counter0", cp);
+ counter[1]->unserialize(base + ".counter1", cp);
+ counter[2]->unserialize(base + ".counter2", cp);
}
void
-Intel8254Timer::unserialize(const string &base, Checkpoint *cp,
- const string §ion)
+Intel8254Timer::startup()
{
- // unserialze the counters
- counter[0]->unserialize(base + ".counter0", cp, section);
- counter[1]->unserialize(base + ".counter1", cp, section);
- counter[2]->unserialize(base + ".counter2", cp, section);
+ 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
Intel8254Timer::Counter::latchCount()
{
// behave like a real latch
- if(!latch_on) {
+ if (!latch_on) {
latch_on = true;
read_byte = LSB;
latched_count = currentCount();
else
period = initial_count;
- if (period > 0)
+ offset = period * event.getInterval();
+
+ if (running && (period > 0))
event.setTo(period);
write_byte = LSB;
void
Intel8254Timer::Counter::setMode(int mode_val)
{
- if(mode_val != InitTc && mode_val != RateGen &&
+ if (mode_val != InitTc && mode_val != RateGen &&
mode_val != SquareWave)
panic("PIT mode %#x is not implemented: \n", mode_val);
return output_high;
}
-unsigned int
-Intel8254Timer::Counter::drain(Event *de)
+void
+Intel8254Timer::Counter::serialize(const string &base, CheckpointOut &cp) const
{
- if (event.scheduled()) {
- event_tick = event.when();
- parent->deschedule(event);
- } else {
- event_tick = 0;
- }
- return 0;
+ paramOut(cp, base + ".initial_count", initial_count);
+ paramOut(cp, base + ".latched_count", latched_count);
+ paramOut(cp, base + ".period", period);
+ paramOut(cp, base + ".mode", mode);
+ paramOut(cp, base + ".output_high", output_high);
+ paramOut(cp, base + ".latch_on", latch_on);
+ paramOut(cp, base + ".read_byte", read_byte);
+ paramOut(cp, base + ".write_byte", write_byte);
+
+ Tick event_tick_offset = 0;
+ if (event.scheduled())
+ event_tick_offset = event.when() - curTick();
+ paramOut(cp, base + ".event_tick_offset", event_tick_offset);
}
void
-Intel8254Timer::Counter::serialize(const string &base, ostream &os)
+Intel8254Timer::Counter::unserialize(const string &base, CheckpointIn &cp)
{
- paramOut(os, base + ".initial_count", initial_count);
- paramOut(os, base + ".latched_count", latched_count);
- paramOut(os, base + ".period", period);
- paramOut(os, base + ".mode", mode);
- paramOut(os, base + ".output_high", output_high);
- paramOut(os, base + ".latch_on", latch_on);
- paramOut(os, base + ".read_byte", read_byte);
- paramOut(os, base + ".write_byte", write_byte);
- paramOut(os, base + ".event_tick", event_tick);
+ paramIn(cp, base + ".initial_count", initial_count);
+ paramIn(cp, base + ".latched_count", latched_count);
+ paramIn(cp, base + ".period", period);
+ paramIn(cp, base + ".mode", mode);
+ paramIn(cp, base + ".output_high", output_high);
+ paramIn(cp, base + ".latch_on", latch_on);
+ paramIn(cp, base + ".read_byte", read_byte);
+ paramIn(cp, base + ".write_byte", write_byte);
+
+ Tick event_tick_offset = 0;
+ assert(!event.scheduled());
+ paramIn(cp, base + ".event_tick_offset", event_tick_offset);
+ offset = event_tick_offset;
}
void
-Intel8254Timer::Counter::unserialize(const string &base, Checkpoint *cp,
- const string §ion)
+Intel8254Timer::Counter::startup()
{
- paramIn(cp, section, base + ".initial_count", initial_count);
- paramIn(cp, section, base + ".latched_count", latched_count);
- paramIn(cp, section, base + ".period", period);
- paramIn(cp, section, base + ".mode", mode);
- paramIn(cp, section, base + ".output_high", output_high);
- paramIn(cp, section, base + ".latch_on", latch_on);
- paramIn(cp, section, base + ".read_byte", read_byte);
- paramIn(cp, section, base + ".write_byte", write_byte);
-
- paramIn(cp, section, base + ".event_tick", event_tick);
- if (event_tick)
- parent->schedule(event, event_tick);
+ running = true;
+ if ((period > 0) && (offset > 0))
+ {
+ parent->schedule(event, curTick() + offset);
+ }
}
Intel8254Timer::Counter::CounterEvent::CounterEvent(Counter* c_ptr)
{
if (clocks == 0)
panic("Timer can't be set to go off instantly.\n");
- DPRINTF(Intel8254Timer, "Timer set to curTick + %d\n",
+ DPRINTF(Intel8254Timer, "Timer set to curTick() + %d\n",
clocks * interval);
- counter->parent->schedule(this, curTick + clocks * interval);
+ counter->parent->schedule(this, curTick() + clocks * interval);
}
int
{
if (!scheduled())
return -1;
- return (when() - curTick + interval - 1) / interval;
+ return (when() - curTick() + interval - 1) / interval;
}
const char *
{
return "Intel 8254 Interval timer";
}
+
+Tick
+Intel8254Timer::Counter::CounterEvent::getInterval()
+{
+ return interval;
+}
+