43 #include "debug/Checkpoint.hh"
44 #include "debug/Timer.hh"
51 global_timer(
name() +
".globaltimer", this,
p->int_num)
57 : _name(__name), parent(_parent), intNum(int_num), control(0x0),
58 rawInt(false), pendingInt(false), autoIncValue(0x0), cmpValEvent(this)
72 panic(
"Tried to read A9GlobalTimer at offset %#x that doesn't exist\n",
81 return ticks / parent->clockPeriod() / (control.prescalar + 1) - 1;
87 DPRINTF(
Timer,
"Reading from A9GlobalTimer at offset: %#x\n", daddr);
92 time = getTimeCounterFromTicks(
curTick());
93 DPRINTF(
Timer,
"-- returning lower 32-bits of counter: %u\n", time);
94 pkt->
setLE<uint32_t>(time);
96 case CounterRegHigh32:
97 time = getTimeCounterFromTicks(
curTick());
99 DPRINTF(
Timer,
"-- returning upper 32-bits of counter: %u\n", time);
100 pkt->
setLE<uint32_t>(time);
103 pkt->
setLE<uint32_t>(control);
106 pkt->
setLE<uint32_t>(rawInt);
109 DPRINTF(
Timer,
"Event schedule for %d, clock=%d, prescale=%d\n",
110 cmpValEvent.when(), parent->clockPeriod(), control.
prescalar);
111 if (cmpValEvent.scheduled()) {
112 time = getTimeCounterFromTicks(cmpValEvent.when() -
curTick());
116 DPRINTF(
Timer,
"-- returning lower 32-bits of comparator: %u\n", time);
117 pkt->
setLE<uint32_t>(time);
119 case CmpValRegHigh32:
120 DPRINTF(
Timer,
"Event schedule for %d, clock=%d, prescale=%d\n",
121 cmpValEvent.when(), parent->clockPeriod(), control.
prescalar);
122 if (cmpValEvent.scheduled()) {
123 time = getTimeCounterFromTicks(cmpValEvent.when() -
curTick());
128 DPRINTF(
Timer,
"-- returning upper 32-bits of comparator: %u\n", time);
129 pkt->
setLE<uint32_t>(time);
131 case AutoIncrementReg:
132 pkt->
setLE<uint32_t>(autoIncValue);
135 panic(
"Tried to read A9GlobalTimer at offset %#x\n", daddr);
138 DPRINTF(
Timer,
"Reading %#x from A9GlobalTimer at offset: %#x\n",
139 pkt->
getLE<uint32_t>(), daddr);
148 DPRINTF(
Timer,
"Writing to A9GlobalTimer at offset: %#x\n", daddr);
150 warn_once(
"A9 Global Timer doesn't support banked per-cpu registers\n");
155 panic(
"Tried to write A9GlobalTimer at offset %#x doesn't exist\n",
164 DPRINTF(
Timer,
"Writing %#x to A9GlobalTimer at offset: %#x\n",
165 pkt->
getLE<uint32_t>(), daddr);
167 case CounterRegLow32:
168 case CounterRegHigh32:
169 DPRINTF(
Timer,
"Ignoring unsupported write to Global Timer Counter\n");
174 old_enable = control.enable;
175 old_cmpEnable = control.cmpEnable;
176 control = pkt->
getLE<uint32_t>();
177 if ((old_enable == 0) && control.enable)
179 if ((old_cmpEnable == 0) && control.cmpEnable)
188 parent->gic->clearInt(intNum);
192 cmpVal &= 0xFFFFFFFF00000000
ULL;
193 cmpVal |= (uint64_t)pkt->
getLE<uint32_t>();
195 case CmpValRegHigh32:
196 cmpVal &= 0x00000000FFFFFFFF
ULL;
197 cmpVal |= ((uint64_t)pkt->
getLE<uint32_t>() << 32);
199 case AutoIncrementReg:
200 autoIncValue = pkt->
getLE<uint32_t>();
203 panic(
"Tried to write A9GlobalTimer at offset %#x\n", daddr);
213 DPRINTF(
Timer,
"Restarting counter with value %#x\n", cmpVal);
215 Tick time = parent->clockPeriod() * (control.prescalar + 1) * (cmpVal + 1);
221 if (cmpValEvent.scheduled()) {
222 DPRINTF(
Timer,
"-- Event was already schedule, de-scheduling\n");
223 parent->deschedule(cmpValEvent);
225 parent->schedule(cmpValEvent, time);
226 DPRINTF(
Timer,
"-- Scheduling new event for: %d\n", time);
238 bool old_pending = pendingInt;
239 if (control.intEnable)
241 if (pendingInt && !old_pending) {
243 parent->gic->sendPPInt(intNum, 0);
246 if (control.autoIncrement == 0)
249 cmpVal += (uint64_t)autoIncValue;
256 DPRINTF(Checkpoint,
"Serializing Arm A9GlobalTimer\n");
258 uint32_t control_serial = control;
266 bool is_in_event = cmpValEvent.scheduled();
271 event_time = cmpValEvent.when();
279 DPRINTF(Checkpoint,
"Unserializing Arm A9GlobalTimer\n");
281 uint32_t control_serial;
283 control = control_serial;
296 parent->schedule(cmpValEvent, event_time);
313 A9GlobalTimerParams::create()