32#include "debug/Intel8254Timer.hh"
41 {
this,
name +
".counter0", 0},
42 {
this,
name +
".counter1", 1},
43 {
this,
name +
".counter2", 2}
48Intel8254Timer::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);
77Intel8254Timer::serialize(
const std::string &base,
CheckpointOut &cp)
const
80 counters[0].serialize(
base +
".counter0", cp);
81 counters[1].serialize(
base +
".counter1", cp);
82 counters[2].serialize(
base +
".counter2", cp);
86Intel8254Timer::unserialize(
const std::string &base,
CheckpointIn &cp)
89 counters[0].unserialize(
base +
".counter0", cp);
90 counters[1].unserialize(
base +
".counter1", cp);
91 counters[2].unserialize(
base +
".counter2", cp);
95Intel8254Timer::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)
113Intel8254Timer::Counter::latchCount()
119 latched_count = currentCount();
124Intel8254Timer::Counter::currentCount()
126 int clocks =
event.clocksLeft();
128 warn_once(
"Reading current count from inactive timer.\n");
138Intel8254Timer::Counter::read()
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");
172Intel8254Timer::Counter::write(
const uint8_t
data)
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))
204Intel8254Timer::Counter::setRW(
int rw_val)
207 panic(
"Only LSB/MSB read/write is implemented.\n");
211Intel8254Timer::Counter::setMode(
int mode_val)
215 panic(
"PIT mode %#x is not implemented: \n", mode_val);
221Intel8254Timer::Counter::setBCD(
int bcd_val)
224 panic(
"PITimer does not implement BCD counts.\n");
228Intel8254Timer::Counter::outputHigh()
234Intel8254Timer::Counter::serialize(
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;
271Intel8254Timer::Counter::startup()
274 if ((period > 0) && (
offset > 0))
280Intel8254Timer::Counter::CounterEvent::CounterEvent(
Counter* c_ptr)
287Intel8254Timer::Counter::CounterEvent::process()
289 switch (counter->mode) {
295 setTo(counter->period);
298 panic(
"Unimplemented PITimer mode.\n");
300 counter->parent->counterInterrupt(counter->num);
304Intel8254Timer::Counter::CounterEvent::setTo(
int clocks)
307 panic(
"Timer can't be set to go off instantly.\n");
310 counter->parent->schedule(
this,
curTick() + clocks * interval);
314Intel8254Timer::Counter::CounterEvent::clocksLeft()
318 return (when() -
curTick() + interval - 1) / interval;
322Intel8254Timer::Counter::CounterEvent::description()
const
324 return "Intel 8254 Interval timer";
328Intel8254Timer::Counter::CounterEvent::getInterval()
uint16_t period
Interrupt period.
bool output_high
Output goes high when the counter reaches zero.
Tick offset
When to start ticking.
Programmable Interval Timer (Intel 8254)
const std::string & name() const
Intel8254Timer(EventManager *em, const std::string &name)
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.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Tick curTick()
The universal simulation clock.
std::ostream CheckpointOut
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
uint64_t Tick
Tick count type.
const std::string & name()