46 #include "debug/Checkpoint.hh"
47 #include "debug/Timer.hh"
64 std::stringstream oss;
65 oss <<
name() <<
".timer" <<
i;
68 new Timer(oss.str(),
this,
70 p.int_watchdog->get(tc)));
80 : _name(timer_name), parent(_parent), intTimer(int_timer),
81 intWatchdog(int_watchdog), timerControl(0x0), watchdogControl(0x0),
82 rawIntTimer(false), rawIntWatchdog(false),
83 rawResetWatchdog(false), watchdogDisableReg(0x0),
84 pendingIntTimer(false), pendingIntWatchdog(false),
85 timerLoadValue(0x0), watchdogLoadValue(0x0),
87 watchdogZeroEvent([
this]{ watchdogAtZero(); },
name())
98 DPRINTF(
Timer,
"Reading from CpuLocalTimer at offset: %#x\n", daddr);
105 panic(
"Tried to read CpuLocalTimer at offset %#x that doesn't exist\n", daddr);
114 DPRINTF(
Timer,
"Reading from CpuLocalTimer at offset: %#x\n", daddr);
119 pkt->
setLE<uint32_t>(timerLoadValue);
121 case TimerCounterReg:
122 DPRINTF(
Timer,
"Event schedule for timer %d, clock=%d, prescale=%d\n",
123 timerZeroEvent.when(), parent->clockPeriod(),
125 time = timerZeroEvent.when() -
curTick();
126 time = time / parent->clockPeriod() /
127 power(16, timerControl.prescalar);
129 pkt->
setLE<uint32_t>(time);
131 case TimerControlReg:
132 pkt->
setLE<uint32_t>(timerControl);
134 case TimerIntStatusReg:
135 pkt->
setLE<uint32_t>(rawIntTimer);
137 case WatchdogLoadReg:
138 pkt->
setLE<uint32_t>(watchdogLoadValue);
140 case WatchdogCounterReg:
142 "Event schedule for watchdog %d, clock=%d, prescale=%d\n",
143 watchdogZeroEvent.when(), parent->clockPeriod(),
145 time = watchdogZeroEvent.when() -
curTick();
146 time = time / parent->clockPeriod() /
147 power(16, watchdogControl.prescalar);
149 pkt->
setLE<uint32_t>(time);
151 case WatchdogControlReg:
152 pkt->
setLE<uint32_t>(watchdogControl);
154 case WatchdogIntStatusReg:
155 pkt->
setLE<uint32_t>(rawIntWatchdog);
157 case WatchdogResetStatusReg:
158 pkt->
setLE<uint32_t>(rawResetWatchdog);
160 case WatchdogDisableReg:
161 panic(
"Tried to read from WatchdogDisableRegister\n");
164 panic(
"Tried to read CpuLocalTimer at offset %#x\n", daddr);
176 DPRINTF(
Timer,
"Writing to CpuLocalTimer at offset: %#x\n", daddr);
183 panic(
"Tried to write CpuLocalTimer at offset %#x that doesn't exist\n", daddr);
191 DPRINTF(
Timer,
"Writing to CpuLocalTimer at offset: %#x\n", daddr);
200 timerLoadValue = pkt->
getLE<uint32_t>();
201 restartTimerCounter(timerLoadValue);
203 case TimerCounterReg:
205 restartTimerCounter(pkt->
getLE<uint32_t>());
207 case TimerControlReg:
208 old_enable = timerControl.enable;
209 timerControl = pkt->
getLE<uint32_t>();
210 if ((old_enable == 0) && timerControl.enable)
211 restartTimerCounter(timerLoadValue);
213 case TimerIntStatusReg:
215 if (pendingIntTimer) {
216 pendingIntTimer =
false;
220 case WatchdogLoadReg:
221 watchdogLoadValue = pkt->
getLE<uint32_t>();
222 restartWatchdogCounter(watchdogLoadValue);
224 case WatchdogCounterReg:
226 if (!watchdogControl.watchdogMode) {
227 restartWatchdogCounter(pkt->
getLE<uint32_t>());
230 case WatchdogControlReg:
231 old_enable = watchdogControl.enable;
232 old_wd_mode = watchdogControl.watchdogMode;
233 watchdogControl = pkt->
getLE<uint32_t>();
234 if ((old_enable == 0) && watchdogControl.enable)
235 restartWatchdogCounter(watchdogLoadValue);
237 if ((old_wd_mode == 1) && watchdogControl.watchdogMode == 0)
238 watchdogControl.watchdogMode = 1;
240 case WatchdogIntStatusReg:
241 rawIntWatchdog =
false;
242 if (pendingIntWatchdog) {
243 pendingIntWatchdog =
false;
247 case WatchdogResetStatusReg:
248 rawResetWatchdog =
false;
251 case WatchdogDisableReg:
252 old_val = watchdogDisableReg;
253 watchdogDisableReg = pkt->
getLE<uint32_t>();
255 if (old_val == 0x12345678 && watchdogDisableReg == 0x87654321)
256 watchdogControl.watchdogMode = 0;
259 panic(
"Tried to write CpuLocalTimer timer at offset %#x\n", daddr);
269 if (!timerControl.enable)
272 Tick time = parent->clockPeriod() *
power(16, timerControl.prescalar);
275 if (timerZeroEvent.scheduled()) {
276 DPRINTF(
Timer,
"-- Event was already schedule, de-scheduling\n");
277 parent->deschedule(timerZeroEvent);
279 parent->schedule(timerZeroEvent,
curTick() + time);
287 if (!watchdogControl.enable)
290 Tick time = parent->clockPeriod() *
power(16, watchdogControl.prescalar);
293 if (watchdogZeroEvent.scheduled()) {
294 DPRINTF(
Timer,
"-- Event was already schedule, de-scheduling\n");
295 parent->deschedule(watchdogZeroEvent);
297 parent->schedule(watchdogZeroEvent,
curTick() + time);
305 if (!timerControl.enable)
311 bool old_pending = pendingIntTimer;
312 if (timerControl.intEnable)
313 pendingIntTimer =
true;
314 if (pendingIntTimer && !old_pending) {
319 if (!timerControl.autoReload)
322 restartTimerCounter(timerLoadValue);
328 if (!watchdogControl.enable)
333 rawIntWatchdog =
true;
334 bool old_pending = pendingIntWatchdog;
337 if (watchdogControl.intEnable && !watchdogControl.watchdogMode)
338 pendingIntWatchdog =
true;
339 else if (watchdogControl.watchdogMode) {
340 rawResetWatchdog =
true;
341 fatal(
"gem5 ARM Model does not support true watchdog operation!\n");
345 if (pendingIntWatchdog && !old_pending) {
347 intWatchdog->raise();
350 if (watchdogControl.watchdogMode)
352 else if (watchdogControl.autoReload)
353 restartWatchdogCounter(watchdogLoadValue);
359 DPRINTF(Checkpoint,
"Serializing Arm CpuLocalTimer\n");
361 uint32_t timer_control_serial = timerControl;
362 uint32_t watchdog_control_serial = watchdogControl;
375 bool timer_is_in_event = timerZeroEvent.scheduled();
377 bool watchdog_is_in_event = watchdogZeroEvent.scheduled();
380 Tick timer_event_time;
381 if (timer_is_in_event){
382 timer_event_time = timerZeroEvent.when();
385 Tick watchdog_event_time;
386 if (watchdog_is_in_event){
387 watchdog_event_time = watchdogZeroEvent.when();
395 DPRINTF(Checkpoint,
"Unserializing Arm CpuLocalTimer\n");
397 uint32_t timer_control_serial;
399 timerControl = timer_control_serial;
400 uint32_t watchdog_control_serial;
402 watchdogControl = watchdog_control_serial;
413 bool timer_is_in_event;
415 bool watchdog_is_in_event;
418 Tick timer_event_time;
419 if (timer_is_in_event){
421 parent->schedule(timerZeroEvent, timer_event_time);
423 Tick watchdog_event_time;
424 if (watchdog_is_in_event) {
426 parent->schedule(watchdogZeroEvent, watchdog_event_time);