diff options
-rw-r--r-- | src/dev/alpha/tsunami_io.cc | 1 | ||||
-rw-r--r-- | src/dev/intel_8254_timer.cc | 54 | ||||
-rw-r--r-- | src/dev/intel_8254_timer.hh | 14 | ||||
-rwxr-xr-x | src/dev/mips/malta_io.cc | 1 | ||||
-rw-r--r-- | src/dev/x86/i8254.cc | 6 | ||||
-rw-r--r-- | src/dev/x86/i8254.hh | 1 |
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 §ion); + + /** Start ticking */ + void startup(); }; protected: @@ -246,6 +257,9 @@ class Intel8254Timer : public EventManager */ void unserialize(const std::string &base, Checkpoint *cp, const std::string §ion); + + /** 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 §ion) 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 §ion); + virtual void startup(); }; |