X86: Keep track of what the initial count value was in the LAPIC timer.
This commit is contained in:
parent
18b3863127
commit
8b2ac20753
2 changed files with 38 additions and 10 deletions
|
@ -90,7 +90,7 @@ Intel8254Timer::unserialize(const string &base, Checkpoint *cp,
|
||||||
|
|
||||||
Intel8254Timer::Counter::Counter(Intel8254Timer *p,
|
Intel8254Timer::Counter::Counter(Intel8254Timer *p,
|
||||||
const string &name, unsigned int _num)
|
const string &name, unsigned int _num)
|
||||||
: _name(name), num(_num), event(this), count(0),
|
: _name(name), num(_num), event(this), initial_count(0),
|
||||||
latched_count(0), period(0), mode(0), output_high(false),
|
latched_count(0), period(0), mode(0), output_high(false),
|
||||||
latch_on(false), read_byte(LSB), write_byte(LSB), parent(p)
|
latch_on(false), read_byte(LSB), write_byte(LSB), parent(p)
|
||||||
{
|
{
|
||||||
|
@ -104,10 +104,24 @@ Intel8254Timer::Counter::latchCount()
|
||||||
if(!latch_on) {
|
if(!latch_on) {
|
||||||
latch_on = true;
|
latch_on = true;
|
||||||
read_byte = LSB;
|
read_byte = LSB;
|
||||||
latched_count = count;
|
latched_count = currentCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Intel8254Timer::Counter::currentCount()
|
||||||
|
{
|
||||||
|
int clocks = event.clocksLeft();
|
||||||
|
if (clocks == -1) {
|
||||||
|
warn_once("Reading current count from inactive timer.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (mode == RateGen || mode == SquareWave)
|
||||||
|
return clocks + 1;
|
||||||
|
else
|
||||||
|
return clocks;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
Intel8254Timer::Counter::read()
|
Intel8254Timer::Counter::read()
|
||||||
{
|
{
|
||||||
|
@ -126,6 +140,7 @@ Intel8254Timer::Counter::read()
|
||||||
panic("Shouldn't be here");
|
panic("Shouldn't be here");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
uint16_t count = currentCount();
|
||||||
switch (read_byte) {
|
switch (read_byte) {
|
||||||
case LSB:
|
case LSB:
|
||||||
read_byte = MSB;
|
read_byte = MSB;
|
||||||
|
@ -146,7 +161,7 @@ Intel8254Timer::Counter::write(const uint8_t data)
|
||||||
{
|
{
|
||||||
switch (write_byte) {
|
switch (write_byte) {
|
||||||
case LSB:
|
case LSB:
|
||||||
count = (count & 0xFF00) | data;
|
initial_count = (initial_count & 0xFF00) | data;
|
||||||
|
|
||||||
if (event.scheduled())
|
if (event.scheduled())
|
||||||
parent->deschedule(event);
|
parent->deschedule(event);
|
||||||
|
@ -155,13 +170,13 @@ Intel8254Timer::Counter::write(const uint8_t data)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSB:
|
case MSB:
|
||||||
count = (count & 0x00FF) | (data << 8);
|
initial_count = (initial_count & 0x00FF) | (data << 8);
|
||||||
// In the RateGen or SquareWave modes, the timer wraps around and
|
// In the RateGen or SquareWave modes, the timer wraps around and
|
||||||
// triggers on a value of 1, not 0.
|
// triggers on a value of 1, not 0.
|
||||||
if (mode == RateGen || mode == SquareWave)
|
if (mode == RateGen || mode == SquareWave)
|
||||||
period = count - 1;
|
period = initial_count - 1;
|
||||||
else
|
else
|
||||||
period = count;
|
period = initial_count;
|
||||||
|
|
||||||
if (period > 0)
|
if (period > 0)
|
||||||
event.setTo(period);
|
event.setTo(period);
|
||||||
|
@ -204,7 +219,7 @@ Intel8254Timer::Counter::outputHigh()
|
||||||
void
|
void
|
||||||
Intel8254Timer::Counter::serialize(const string &base, ostream &os)
|
Intel8254Timer::Counter::serialize(const string &base, ostream &os)
|
||||||
{
|
{
|
||||||
paramOut(os, base + ".count", count);
|
paramOut(os, base + ".initial_count", initial_count);
|
||||||
paramOut(os, base + ".latched_count", latched_count);
|
paramOut(os, base + ".latched_count", latched_count);
|
||||||
paramOut(os, base + ".period", period);
|
paramOut(os, base + ".period", period);
|
||||||
paramOut(os, base + ".mode", mode);
|
paramOut(os, base + ".mode", mode);
|
||||||
|
@ -223,7 +238,7 @@ void
|
||||||
Intel8254Timer::Counter::unserialize(const string &base, Checkpoint *cp,
|
Intel8254Timer::Counter::unserialize(const string &base, Checkpoint *cp,
|
||||||
const string §ion)
|
const string §ion)
|
||||||
{
|
{
|
||||||
paramIn(cp, section, base + ".count", count);
|
paramIn(cp, section, base + ".initial_count", initial_count);
|
||||||
paramIn(cp, section, base + ".latched_count", latched_count);
|
paramIn(cp, section, base + ".latched_count", latched_count);
|
||||||
paramIn(cp, section, base + ".period", period);
|
paramIn(cp, section, base + ".period", period);
|
||||||
paramIn(cp, section, base + ".mode", mode);
|
paramIn(cp, section, base + ".mode", mode);
|
||||||
|
@ -271,6 +286,14 @@ Intel8254Timer::Counter::CounterEvent::setTo(int clocks)
|
||||||
counter->parent->schedule(this, curTick + clocks * interval);
|
counter->parent->schedule(this, curTick + clocks * interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Intel8254Timer::Counter::CounterEvent::clocksLeft()
|
||||||
|
{
|
||||||
|
if (!scheduled())
|
||||||
|
return -1;
|
||||||
|
return (when() - curTick + interval - 1) / interval;
|
||||||
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
Intel8254Timer::Counter::CounterEvent::description() const
|
Intel8254Timer::Counter::CounterEvent::description() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -98,6 +98,8 @@ class Intel8254Timer : public EventManager
|
||||||
friend class Counter;
|
friend class Counter;
|
||||||
|
|
||||||
void setTo(int clocks);
|
void setTo(int clocks);
|
||||||
|
|
||||||
|
int clocksLeft();
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -108,8 +110,8 @@ class Intel8254Timer : public EventManager
|
||||||
|
|
||||||
CounterEvent event;
|
CounterEvent event;
|
||||||
|
|
||||||
/** Current count value */
|
/** Initial count value */
|
||||||
uint16_t count;
|
uint16_t initial_count;
|
||||||
|
|
||||||
/** Latched count */
|
/** Latched count */
|
||||||
uint16_t latched_count;
|
uint16_t latched_count;
|
||||||
|
@ -141,6 +143,9 @@ class Intel8254Timer : public EventManager
|
||||||
/** Latch the current count (if one is not already latched) */
|
/** Latch the current count (if one is not already latched) */
|
||||||
void latchCount();
|
void latchCount();
|
||||||
|
|
||||||
|
/** Get the current count for this counter */
|
||||||
|
int currentCount();
|
||||||
|
|
||||||
/** Set the read/write mode */
|
/** Set the read/write mode */
|
||||||
void setRW(int rw_val);
|
void setRW(int rw_val);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue