diff options
author | cdirik <cdirik@micron.com> | 2015-01-06 15:10:22 -0700 |
---|---|---|
committer | cdirik <cdirik@micron.com> | 2015-01-06 15:10:22 -0700 |
commit | 1693e526d090f47323e378f0bd8546f28c2a97f7 (patch) | |
tree | bf026901c1b0fd644cef546fc1d69e252a46e789 /src/dev/intel_8254_timer.cc | |
parent | 1c1fb2c9886134c5ab4a877e2ac5baae8c2390a9 (diff) | |
download | gem5-1693e526d090f47323e378f0bd8546f28c2a97f7.tar.xz |
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 <nilay@cs.wisc.edu>
Diffstat (limited to 'src/dev/intel_8254_timer.cc')
-rw-r--r-- | src/dev/intel_8254_timer.cc | 54 |
1 files changed, 40 insertions, 14 deletions
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; +} + |