32 #include "debug/Intel8254Timer.hh"
41 {
this,
name +
".counter0", 0},
42 {
this,
name +
".counter1", 1},
43 {
this,
name +
".counter2", 2}
48 Intel8254Timer::writeControl(
const CtrlReg
data)
52 if (
sel == ReadBackCommand) {
53 ReadBackCommandVal rb_val =
static_cast<uint8_t
>(
data);
56 "Latching the PIT status byte is not implemented.");
59 for (
auto &counter: counters) {
60 if (
bits((uint8_t)rb_val.select, counter.index()))
67 if (
data.rw == LatchCommand) {
68 counters[
sel].latchCount();
71 counters[
sel].setMode(
data.mode);
80 counters[0].serialize(
base +
".counter0", cp);
81 counters[1].serialize(
base +
".counter1", cp);
82 counters[2].serialize(
base +
".counter2", cp);
89 counters[0].unserialize(
base +
".counter0", cp);
90 counters[1].unserialize(
base +
".counter1", cp);
91 counters[2].unserialize(
base +
".counter2", cp);
95 Intel8254Timer::startup()
97 counters[0].startup();
98 counters[1].startup();
99 counters[2].startup();
103 const std::string &
name,
unsigned int _num)
104 : _name(
name), num(_num),
event(this), running(false),
105 initial_count(0), latched_count(0), period(0),
mode(0),
106 output_high(false), latch_on(false), read_byte(LSB),
107 write_byte(LSB), parent(
p)
119 latched_count = currentCount();
126 int clocks =
event.clocksLeft();
128 warn_once(
"Reading current count from inactive timer.\n");
144 return (uint8_t)latched_count;
149 return latched_count >> 8;
152 panic(
"Shouldn't be here");
155 uint16_t
count = currentCount();
159 return (uint8_t)
count;
166 panic(
"Shouldn't be here");
174 switch (write_byte) {
176 initial_count = (initial_count & 0xFF00) |
data;
178 if (
event.scheduled())
179 parent->deschedule(
event);
185 initial_count = (initial_count & 0x00FF) | (
data << 8);
189 period = initial_count - 1;
191 period = initial_count;
193 offset = period *
event.getInterval();
195 if (running && (period > 0))
207 panic(
"Only LSB/MSB read/write is implemented.\n");
215 panic(
"PIT mode %#x is not implemented: \n", mode_val);
224 panic(
"PITimer does not implement BCD counts.\n");
246 Tick event_tick_offset = 0;
247 if (
event.scheduled())
248 event_tick_offset =
event.when() -
curTick();
249 paramOut(cp,
base +
".event_tick_offset", event_tick_offset);
255 paramIn(cp,
base +
".initial_count", initial_count);
256 paramIn(cp,
base +
".latched_count", latched_count);
264 Tick event_tick_offset = 0;
265 assert(!
event.scheduled());
266 paramIn(cp,
base +
".event_tick_offset", event_tick_offset);
267 offset = event_tick_offset;
274 if ((period > 0) && (
offset > 0))
289 switch (counter->mode) {
291 counter->output_high =
true;
295 setTo(counter->period);
298 panic(
"Unimplemented PITimer mode.\n");
300 counter->parent->counterInterrupt(counter->num);
307 panic(
"Timer can't be set to go off instantly.\n");
310 counter->parent->schedule(
this,
curTick() + clocks * interval);
318 return (when() -
curTick() + interval - 1) / interval;
324 return "Intel 8254 Interval timer";
virtual const char * description() const
Event description.
void process()
Event process.
uint8_t read()
Read a count byte.
void setMode(int mode_val)
Set operational mode.
void serialize(const std::string &base, CheckpointOut &cp) const
Serialize this object to the given output stream.
uint16_t period
Interrupt period.
void unserialize(const std::string &base, CheckpointIn &cp)
Reconstruct the state of this object from a checkpoint.
void setBCD(int bcd_val)
Set count encoding.
void startup()
Start ticking.
void latchCount()
Latch the current count (if one is not already latched)
bool outputHigh()
Is the output high?
Tick offset
When to start ticking.
int currentCount()
Get the current count for this counter.
void setRW(int rw_val)
Set the read/write mode.
void write(const uint8_t data)
Write a count byte.
Programmable Interval Timer (Intel 8254)
Intel8254Timer(EventManager *em, const std::string &name)
const std::string & name() const
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
#define panic(...)
This implements a cprintf based panic() function.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
double s
These variables equal the number of ticks in the unit of time they're named after in a double.
double Counter
All counters are of 64-bit values.
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Tick curTick()
The universal simulation clock.
std::ostream CheckpointOut
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
void unserialize(ThreadContext &tc, CheckpointIn &cp)
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
uint64_t Tick
Tick count type.
void serialize(const ThreadContext &tc, CheckpointOut &cp)
Thread context serialization helpers.
const std::string & name()