# HG changeset patch # User cdirik # Date 1420582222 25200 # Tue Jan 06 15:10:22 2015 -0700 # Node ID 3c6d7d09724ab1992e4a04dfd29e543662e67051 # Parent 9ac724889705defdbecad4103da7fdc649d263e1 Preventing intel 8254 timer counter events firing before startup diff -r 9ac724889705 -r 3c6d7d09724a src/dev/alpha/tsunami_io.cc --- a/src/dev/alpha/tsunami_io.cc Sun Jan 04 13:02:12 2015 -0600 +++ 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 9ac724889705 -r 3c6d7d09724a src/dev/intel_8254_timer.hh --- a/src/dev/intel_8254_timer.hh Sun Jan 04 13:02:12 2015 -0600 +++ 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 §ion); + + /** Start ticking */ + void startup(); }; protected: @@ -246,6 +257,9 @@ */ void unserialize(const std::string &base, Checkpoint *cp, const std::string §ion); + + /** Start ticking */ + void startup(); }; #endif // __DEV_8254_HH__ diff -r 9ac724889705 -r 3c6d7d09724a src/dev/intel_8254_timer.cc --- a/src/dev/intel_8254_timer.cc Sun Jan 04 13:02:12 2015 -0600 +++ 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 9ac724889705 -r 3c6d7d09724a src/dev/mips/malta_io.cc --- a/src/dev/mips/malta_io.cc Sun Jan 04 13:02:12 2015 -0600 +++ 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 9ac724889705 -r 3c6d7d09724a src/dev/x86/i8254.hh --- a/src/dev/x86/i8254.hh Sun Jan 04 13:02:12 2015 -0600 +++ 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 §ion); + virtual void startup(); }; diff -r 9ac724889705 -r 3c6d7d09724a src/dev/x86/i8254.cc --- a/src/dev/x86/i8254.cc Sun Jan 04 13:02:12 2015 -0600 +++ 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() {