summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dev/intel_8254_timer.cc27
-rw-r--r--src/dev/intel_8254_timer.hh2
2 files changed, 23 insertions, 6 deletions
diff --git a/src/dev/intel_8254_timer.cc b/src/dev/intel_8254_timer.cc
index 16d09f582..802dd44f5 100644
--- a/src/dev/intel_8254_timer.cc
+++ b/src/dev/intel_8254_timer.cc
@@ -147,13 +147,16 @@ Intel8254Timer::Counter::write(const uint8_t data)
case MSB:
count = (count & 0x00FF) | (data << 8);
- period = count;
+ // In the RateGen or SquareWave modes, the timer wraps around and
+ // triggers on a value of 1, not 0.
+ if (mode == RateGen || mode == SquareWave)
+ period = count - 1;
+ else
+ period = count;
+
+ if (period > 0)
+ event.setTo(period);
- if (period > 0) {
- DPRINTF(Intel8254Timer, "Timer set to curTick + %d\n",
- count * event.interval);
- event.schedule(curTick + count * event.interval);
- }
write_byte = LSB;
break;
}
@@ -240,14 +243,26 @@ Intel8254Timer::Counter::CounterEvent::process()
switch (counter->mode) {
case InitTc:
counter->output_high = true;
+ break;
case RateGen:
case SquareWave:
+ setTo(counter->period);
break;
default:
panic("Unimplemented PITimer mode.\n");
}
}
+void
+Intel8254Timer::Counter::CounterEvent::setTo(int clocks)
+{
+ if (clocks == 0)
+ panic("Timer can't be set to go off instantly.\n");
+ DPRINTF(Intel8254Timer, "Timer set to curTick + %d\n",
+ clocks * interval);
+ schedule(curTick + clocks * interval);
+}
+
const char *
Intel8254Timer::Counter::CounterEvent::description() const
{
diff --git a/src/dev/intel_8254_timer.hh b/src/dev/intel_8254_timer.hh
index c7c2b1591..23596a687 100644
--- a/src/dev/intel_8254_timer.hh
+++ b/src/dev/intel_8254_timer.hh
@@ -95,6 +95,8 @@ class Intel8254Timer
virtual const char *description() const;
friend class Counter;
+
+ void setTo(int clocks);
};
private: