46 #include "debug/Checkpoint.hh"
47 #include "debug/Timer.hh"
67 std::stringstream oss;
68 oss <<
name() <<
".timer" <<
i;
71 new Timer(oss.str(),
this,
73 p.int_watchdog->get(tc)));
83 : _name(timer_name), parent(_parent), intTimer(int_timer),
84 intWatchdog(int_watchdog), timerControl(0x0), watchdogControl(0x0),
85 rawIntTimer(false), rawIntWatchdog(false),
86 rawResetWatchdog(false), watchdogDisableReg(0x0),
87 pendingIntTimer(false), pendingIntWatchdog(false),
88 timerLoadValue(0x0), watchdogLoadValue(0x0),
90 watchdogZeroEvent([
this]{ watchdogAtZero(); },
name())
101 DPRINTF(
Timer,
"Reading from CpuLocalTimer at offset: %#x\n", daddr);
108 panic(
"Tried to read CpuLocalTimer at offset %#x that doesn't exist\n", daddr);
117 DPRINTF(
Timer,
"Reading from CpuLocalTimer at offset: %#x\n", daddr);
122 pkt->
setLE<uint32_t>(timerLoadValue);
124 case TimerCounterReg:
125 DPRINTF(
Timer,
"Event schedule for timer %d, clock=%d, prescale=%d\n",
126 timerZeroEvent.when(), parent->clockPeriod(),
128 time = timerZeroEvent.when() -
curTick();
129 time = (time / parent->clockPeriod()) >> (4 * timerControl.prescalar);
131 pkt->
setLE<uint32_t>(time);
133 case TimerControlReg:
134 pkt->
setLE<uint32_t>(timerControl);
136 case TimerIntStatusReg:
137 pkt->
setLE<uint32_t>(rawIntTimer);
139 case WatchdogLoadReg:
140 pkt->
setLE<uint32_t>(watchdogLoadValue);
142 case WatchdogCounterReg:
144 "Event schedule for watchdog %d, clock=%d, prescale=%d\n",
145 watchdogZeroEvent.when(), parent->clockPeriod(),
147 time = watchdogZeroEvent.when() -
curTick();
148 time = (time / parent->clockPeriod()) >>
149 (4 * watchdogControl.prescalar);
151 pkt->
setLE<uint32_t>(time);
153 case WatchdogControlReg:
154 pkt->
setLE<uint32_t>(watchdogControl);
156 case WatchdogIntStatusReg:
157 pkt->
setLE<uint32_t>(rawIntWatchdog);
159 case WatchdogResetStatusReg:
160 pkt->
setLE<uint32_t>(rawResetWatchdog);
162 case WatchdogDisableReg:
163 panic(
"Tried to read from WatchdogDisableRegister\n");
166 panic(
"Tried to read CpuLocalTimer at offset %#x\n", daddr);
178 DPRINTF(
Timer,
"Writing to CpuLocalTimer at offset: %#x\n", daddr);
185 panic(
"Tried to write CpuLocalTimer at offset %#x that doesn't exist\n", daddr);
193 DPRINTF(
Timer,
"Writing to CpuLocalTimer at offset: %#x\n", daddr);
202 timerLoadValue = pkt->
getLE<uint32_t>();
203 restartTimerCounter(timerLoadValue);
205 case TimerCounterReg:
207 restartTimerCounter(pkt->
getLE<uint32_t>());
209 case TimerControlReg:
210 old_enable = timerControl.enable;
211 timerControl = pkt->
getLE<uint32_t>();
212 if ((old_enable == 0) && timerControl.enable)
213 restartTimerCounter(timerLoadValue);
215 case TimerIntStatusReg:
217 if (pendingIntTimer) {
218 pendingIntTimer =
false;
222 case WatchdogLoadReg:
223 watchdogLoadValue = pkt->
getLE<uint32_t>();
224 restartWatchdogCounter(watchdogLoadValue);
226 case WatchdogCounterReg:
228 if (!watchdogControl.watchdogMode) {
229 restartWatchdogCounter(pkt->
getLE<uint32_t>());
232 case WatchdogControlReg:
233 old_enable = watchdogControl.enable;
234 old_wd_mode = watchdogControl.watchdogMode;
235 watchdogControl = pkt->
getLE<uint32_t>();
236 if ((old_enable == 0) && watchdogControl.enable)
237 restartWatchdogCounter(watchdogLoadValue);
239 if ((old_wd_mode == 1) && watchdogControl.watchdogMode == 0)
240 watchdogControl.watchdogMode = 1;
242 case WatchdogIntStatusReg:
243 rawIntWatchdog =
false;
244 if (pendingIntWatchdog) {
245 pendingIntWatchdog =
false;
249 case WatchdogResetStatusReg:
250 rawResetWatchdog =
false;
253 case WatchdogDisableReg:
254 old_val = watchdogDisableReg;
255 watchdogDisableReg = pkt->
getLE<uint32_t>();
257 if (old_val == 0x12345678 && watchdogDisableReg == 0x87654321)
258 watchdogControl.watchdogMode = 0;
261 panic(
"Tried to write CpuLocalTimer timer at offset %#x\n", daddr);
271 if (!timerControl.enable)
274 Tick time = parent->clockPeriod() << (4 * timerControl.prescalar);
277 if (timerZeroEvent.scheduled()) {
278 DPRINTF(
Timer,
"-- Event was already schedule, de-scheduling\n");
279 parent->deschedule(timerZeroEvent);
281 parent->schedule(timerZeroEvent,
curTick() + time);
289 if (!watchdogControl.enable)
292 Tick time = parent->clockPeriod() << (4 * watchdogControl.prescalar);
295 if (watchdogZeroEvent.scheduled()) {
296 DPRINTF(
Timer,
"-- Event was already schedule, de-scheduling\n");
297 parent->deschedule(watchdogZeroEvent);
299 parent->schedule(watchdogZeroEvent,
curTick() + time);
307 if (!timerControl.enable)
313 bool old_pending = pendingIntTimer;
314 if (timerControl.intEnable)
315 pendingIntTimer =
true;
316 if (pendingIntTimer && !old_pending) {
321 if (!timerControl.autoReload)
324 restartTimerCounter(timerLoadValue);
330 if (!watchdogControl.enable)
335 rawIntWatchdog =
true;
336 bool old_pending = pendingIntWatchdog;
339 if (watchdogControl.intEnable && !watchdogControl.watchdogMode)
340 pendingIntWatchdog =
true;
341 else if (watchdogControl.watchdogMode) {
342 rawResetWatchdog =
true;
343 fatal(
"gem5 ARM Model does not support true watchdog operation!\n");
347 if (pendingIntWatchdog && !old_pending) {
349 intWatchdog->raise();
352 if (watchdogControl.watchdogMode)
354 else if (watchdogControl.autoReload)
355 restartWatchdogCounter(watchdogLoadValue);
361 DPRINTF(Checkpoint,
"Serializing Arm CpuLocalTimer\n");
363 uint32_t timer_control_serial = timerControl;
364 uint32_t watchdog_control_serial = watchdogControl;
377 bool timer_is_in_event = timerZeroEvent.scheduled();
379 bool watchdog_is_in_event = watchdogZeroEvent.scheduled();
382 Tick timer_event_time;
383 if (timer_is_in_event){
384 timer_event_time = timerZeroEvent.when();
387 Tick watchdog_event_time;
388 if (watchdog_is_in_event){
389 watchdog_event_time = watchdogZeroEvent.when();
397 DPRINTF(Checkpoint,
"Unserializing Arm CpuLocalTimer\n");
399 uint32_t timer_control_serial;
401 timerControl = timer_control_serial;
402 uint32_t watchdog_control_serial;
404 watchdogControl = watchdog_control_serial;
415 bool timer_is_in_event;
417 bool watchdog_is_in_event;
420 Tick timer_event_time;
421 if (timer_is_in_event){
423 parent->schedule(timerZeroEvent, timer_event_time);
425 Tick watchdog_event_time;
426 if (watchdog_is_in_event) {
428 parent->schedule(watchdogZeroEvent, watchdog_event_time);