45 #include "debug/Checkpoint.hh"
46 #include "debug/Timer.hh"
56 std::stringstream oss;
57 oss <<
name() <<
".timer" <<
i;
67 : timerControl(0x0), watchdogControl(0x0), rawIntTimer(false), rawIntWatchdog(false),
68 rawResetWatchdog(false), watchdogDisableReg(0x0), pendingIntTimer(false), pendingIntWatchdog(false),
69 timerLoadValue(0x0), watchdogLoadValue(0x0), timerZeroEvent(this), watchdogZeroEvent(this)
80 DPRINTF(
Timer,
"Reading from CpuLocalTimer at offset: %#x\n", daddr);
87 panic(
"Tried to read CpuLocalTimer at offset %#x that doesn't exist\n", daddr);
96 DPRINTF(
Timer,
"Reading from CpuLocalTimer at offset: %#x\n", daddr);
101 pkt->
set<uint32_t>(timerLoadValue);
103 case TimerCounterReg:
104 DPRINTF(
Timer,
"Event schedule for timer %d, clock=%d, prescale=%d\n",
105 timerZeroEvent.when(), parent->clockPeriod(),
107 time = timerZeroEvent.when() -
curTick();
108 time = time / parent->clockPeriod() /
109 power(16, timerControl.prescalar);
111 pkt->
set<uint32_t>(time);
113 case TimerControlReg:
114 pkt->
set<uint32_t>(timerControl);
116 case TimerIntStatusReg:
117 pkt->
set<uint32_t>(rawIntTimer);
119 case WatchdogLoadReg:
120 pkt->
set<uint32_t>(watchdogLoadValue);
122 case WatchdogCounterReg:
124 "Event schedule for watchdog %d, clock=%d, prescale=%d\n",
125 watchdogZeroEvent.when(), parent->clockPeriod(),
127 time = watchdogZeroEvent.when() -
curTick();
128 time = time / parent->clockPeriod() /
129 power(16, watchdogControl.prescalar);
131 pkt->
set<uint32_t>(time);
133 case WatchdogControlReg:
134 pkt->
set<uint32_t>(watchdogControl);
136 case WatchdogIntStatusReg:
137 pkt->
set<uint32_t>(rawIntWatchdog);
139 case WatchdogResetStatusReg:
140 pkt->
set<uint32_t>(rawResetWatchdog);
142 case WatchdogDisableReg:
143 panic(
"Tried to read from WatchdogDisableRegister\n");
146 panic(
"Tried to read CpuLocalTimer at offset %#x\n", daddr);
158 DPRINTF(
Timer,
"Writing to CpuLocalTimer at offset: %#x\n", daddr);
165 panic(
"Tried to write CpuLocalTimer at offset %#x that doesn't exist\n", daddr);
173 DPRINTF(
Timer,
"Writing to CpuLocalTimer at offset: %#x\n", daddr);
182 timerLoadValue = pkt->
get<uint32_t>();
183 restartTimerCounter(timerLoadValue);
185 case TimerCounterReg:
187 restartTimerCounter(pkt->
get<uint32_t>());
189 case TimerControlReg:
190 old_enable = timerControl.enable;
191 timerControl = pkt->
get<uint32_t>();
192 if ((old_enable == 0) && timerControl.enable)
193 restartTimerCounter(timerLoadValue);
195 case TimerIntStatusReg:
197 if (pendingIntTimer) {
198 pendingIntTimer =
false;
202 case WatchdogLoadReg:
203 watchdogLoadValue = pkt->
get<uint32_t>();
204 restartWatchdogCounter(watchdogLoadValue);
206 case WatchdogCounterReg:
208 if (!watchdogControl.watchdogMode) {
209 restartWatchdogCounter(pkt->
get<uint32_t>());
212 case WatchdogControlReg:
213 old_enable = watchdogControl.enable;
214 old_wd_mode = watchdogControl.watchdogMode;
215 watchdogControl = pkt->
get<uint32_t>();
216 if ((old_enable == 0) && watchdogControl.enable)
217 restartWatchdogCounter(watchdogLoadValue);
219 if ((old_wd_mode == 1) && watchdogControl.watchdogMode == 0)
220 watchdogControl.watchdogMode = 1;
222 case WatchdogIntStatusReg:
223 rawIntWatchdog =
false;
224 if (pendingIntWatchdog) {
225 pendingIntWatchdog =
false;
229 case WatchdogResetStatusReg:
230 rawResetWatchdog =
false;
233 case WatchdogDisableReg:
234 old_val = watchdogDisableReg;
235 watchdogDisableReg = pkt->
get<uint32_t>();
237 if (old_val == 0x12345678 && watchdogDisableReg == 0x87654321)
238 watchdogControl.watchdogMode = 0;
241 panic(
"Tried to write CpuLocalTimer timer at offset %#x\n", daddr);
250 DPRINTF(
Timer,
"Resetting timer counter with value %#x\n", val);
251 if (!timerControl.enable)
254 Tick time = parent->clockPeriod() *
power(16, timerControl.prescalar);
257 if (timerZeroEvent.scheduled()) {
258 DPRINTF(
Timer,
"-- Event was already schedule, de-scheduling\n");
259 parent->deschedule(timerZeroEvent);
261 parent->schedule(timerZeroEvent,
curTick() + time);
268 DPRINTF(
Timer,
"Resetting watchdog counter with value %#x\n", val);
269 if (!watchdogControl.enable)
272 Tick time = parent->clockPeriod() *
power(16, watchdogControl.prescalar);
275 if (watchdogZeroEvent.scheduled()) {
276 DPRINTF(
Timer,
"-- Event was already schedule, de-scheduling\n");
277 parent->deschedule(watchdogZeroEvent);
279 parent->schedule(watchdogZeroEvent,
curTick() + time);
287 if (!timerControl.enable)
293 bool old_pending = pendingIntTimer;
294 if (timerControl.intEnable)
295 pendingIntTimer =
true;
296 if (pendingIntTimer && !old_pending) {
298 parent->gic->sendPPInt(intNumTimer,
cpuNum);
301 if (!timerControl.autoReload)
304 restartTimerCounter(timerLoadValue);
310 if (!watchdogControl.enable)
315 rawIntWatchdog =
true;
316 bool old_pending = pendingIntWatchdog;
319 if (watchdogControl.intEnable && !watchdogControl.watchdogMode)
320 pendingIntWatchdog =
true;
321 else if (watchdogControl.watchdogMode) {
322 rawResetWatchdog =
true;
323 fatal(
"gem5 ARM Model does not support true watchdog operation!\n");
327 if (pendingIntWatchdog && !old_pending) {
329 parent->gic->sendPPInt(intNumWatchdog,
cpuNum);
332 if (watchdogControl.watchdogMode)
334 else if (watchdogControl.autoReload)
335 restartWatchdogCounter(watchdogLoadValue);
341 DPRINTF(Checkpoint,
"Serializing Arm CpuLocalTimer\n");
345 uint32_t timer_control_serial = timerControl;
346 uint32_t watchdog_control_serial = watchdogControl;
359 bool timer_is_in_event = timerZeroEvent.scheduled();
361 bool watchdog_is_in_event = watchdogZeroEvent.scheduled();
364 Tick timer_event_time;
365 if (timer_is_in_event){
366 timer_event_time = timerZeroEvent.when();
369 Tick watchdog_event_time;
370 if (watchdog_is_in_event){
371 watchdog_event_time = watchdogZeroEvent.when();
379 DPRINTF(Checkpoint,
"Unserializing Arm CpuLocalTimer\n");
384 uint32_t timer_control_serial;
386 timerControl = timer_control_serial;
387 uint32_t watchdog_control_serial;
389 watchdogControl = watchdog_control_serial;
400 bool timer_is_in_event;
402 bool watchdog_is_in_event;
405 Tick timer_event_time;
406 if (timer_is_in_event){
408 parent->schedule(timerZeroEvent, timer_event_time);
410 Tick watchdog_event_time;
411 if (watchdog_is_in_event) {
413 parent->schedule(watchdogZeroEvent, watchdog_event_time);
434 CpuLocalTimerParams::create()
Tick write(PacketPtr pkt) override
Handle a write to the device.
void set(T v, ByteOrder endian)
Set the value in the data pointer to v using the specified endianness.
Timer localTimer[CPU_MAX]
Timers that do the actual work.
void read(PacketPtr pkt, Addr daddr)
Handle read for a single timer.
ContextID contextId() const
Accessor function for context ID.
void restartTimerCounter(uint32_t val)
Restart the counter ticking at val.
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
uint32_t intNumTimer
Number of interrupt to cause/clear.
EndBitUnion(WatchdogCtrl) protected CpuLocalTimer * parent
Pointer to parent class.
T get(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness.
void serialize(CheckpointOut &cp) const override
Serialize an object.
CpuLocalTimerParams Params
#define UNSERIALIZE_SCALAR(scalar)
Tick curTick()
The current simulated tick.
std::string csprintf(const char *format, const Args &...args)
Addr pioSize
Size that the device's address range.
void serialize(CheckpointOut &cp) const override
Serialize an object.
void makeAtomicResponse()
uint64_t Tick
Tick count type.
uint64_t power(uint32_t n, uint32_t e)
uint32_t cpuNum
Cpu this timer is attached to.
void write(PacketPtr pkt, Addr daddr)
Handle write for a single timer.
Bitfield< 15, 8 > prescalar
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
const RequestPtr req
A pointer to the original request.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
This implements the cpu local timer from the Cortex-A9 MPCore Technical Reference Manual rev r2p2 (AR...
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
void restartWatchdogCounter(uint32_t val)
void timerAtZero()
Called when the counter reaches 0.
#define SERIALIZE_SCALAR(scalar)
virtual const std::string name() const
Base class for ARM GIC implementations.
Declaration of the Packet class.
std::ostream CheckpointOut
Tick read(PacketPtr pkt) override
Handle a read to the device.
Tick pioDelay
Delay that the device experinces on an access.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Addr pioAddr
Address that the device listens to.
CpuLocalTimer(Params *p)
The constructor for RealView just registers itself with the MMU.
int ContextID
Globally unique thread context ID.
if(it_gpu==gpuTypeMap.end())