43 #include "debug/Checkpoint.hh"
44 #include "debug/Timer.hh"
61 std::stringstream oss;
62 oss <<
name() <<
".timer" <<
i;
65 new Timer(oss.str(),
this,
66 p->int_timer->get(tc),
67 p->int_watchdog->get(tc)));
77 : _name(timer_name), parent(_parent), intTimer(int_timer),
78 intWatchdog(int_watchdog), timerControl(0x0), watchdogControl(0x0),
79 rawIntTimer(false), rawIntWatchdog(false),
80 rawResetWatchdog(false), watchdogDisableReg(0x0),
81 pendingIntTimer(false), pendingIntWatchdog(false),
82 timerLoadValue(0x0), watchdogLoadValue(0x0),
84 watchdogZeroEvent([
this]{ watchdogAtZero(); },
name())
95 DPRINTF(
Timer,
"Reading from CpuLocalTimer at offset: %#x\n", daddr);
102 panic(
"Tried to read CpuLocalTimer at offset %#x that doesn't exist\n", daddr);
111 DPRINTF(
Timer,
"Reading from CpuLocalTimer at offset: %#x\n", daddr);
116 pkt->
setLE<uint32_t>(timerLoadValue);
118 case TimerCounterReg:
119 DPRINTF(
Timer,
"Event schedule for timer %d, clock=%d, prescale=%d\n",
120 timerZeroEvent.when(), parent->clockPeriod(),
122 time = timerZeroEvent.when() -
curTick();
123 time = time / parent->clockPeriod() /
124 power(16, timerControl.prescalar);
126 pkt->
setLE<uint32_t>(time);
128 case TimerControlReg:
129 pkt->
setLE<uint32_t>(timerControl);
131 case TimerIntStatusReg:
132 pkt->
setLE<uint32_t>(rawIntTimer);
134 case WatchdogLoadReg:
135 pkt->
setLE<uint32_t>(watchdogLoadValue);
137 case WatchdogCounterReg:
139 "Event schedule for watchdog %d, clock=%d, prescale=%d\n",
140 watchdogZeroEvent.when(), parent->clockPeriod(),
142 time = watchdogZeroEvent.when() -
curTick();
143 time = time / parent->clockPeriod() /
144 power(16, watchdogControl.prescalar);
146 pkt->
setLE<uint32_t>(time);
148 case WatchdogControlReg:
149 pkt->
setLE<uint32_t>(watchdogControl);
151 case WatchdogIntStatusReg:
152 pkt->
setLE<uint32_t>(rawIntWatchdog);
154 case WatchdogResetStatusReg:
155 pkt->
setLE<uint32_t>(rawResetWatchdog);
157 case WatchdogDisableReg:
158 panic(
"Tried to read from WatchdogDisableRegister\n");
161 panic(
"Tried to read CpuLocalTimer at offset %#x\n", daddr);
173 DPRINTF(
Timer,
"Writing to CpuLocalTimer at offset: %#x\n", daddr);
180 panic(
"Tried to write CpuLocalTimer at offset %#x that doesn't exist\n", daddr);
188 DPRINTF(
Timer,
"Writing to CpuLocalTimer at offset: %#x\n", daddr);
197 timerLoadValue = pkt->
getLE<uint32_t>();
198 restartTimerCounter(timerLoadValue);
200 case TimerCounterReg:
202 restartTimerCounter(pkt->
getLE<uint32_t>());
204 case TimerControlReg:
205 old_enable = timerControl.enable;
206 timerControl = pkt->
getLE<uint32_t>();
207 if ((old_enable == 0) && timerControl.enable)
208 restartTimerCounter(timerLoadValue);
210 case TimerIntStatusReg:
212 if (pendingIntTimer) {
213 pendingIntTimer =
false;
217 case WatchdogLoadReg:
218 watchdogLoadValue = pkt->
getLE<uint32_t>();
219 restartWatchdogCounter(watchdogLoadValue);
221 case WatchdogCounterReg:
223 if (!watchdogControl.watchdogMode) {
224 restartWatchdogCounter(pkt->
getLE<uint32_t>());
227 case WatchdogControlReg:
228 old_enable = watchdogControl.enable;
229 old_wd_mode = watchdogControl.watchdogMode;
230 watchdogControl = pkt->
getLE<uint32_t>();
231 if ((old_enable == 0) && watchdogControl.enable)
232 restartWatchdogCounter(watchdogLoadValue);
234 if ((old_wd_mode == 1) && watchdogControl.watchdogMode == 0)
235 watchdogControl.watchdogMode = 1;
237 case WatchdogIntStatusReg:
238 rawIntWatchdog =
false;
239 if (pendingIntWatchdog) {
240 pendingIntWatchdog =
false;
244 case WatchdogResetStatusReg:
245 rawResetWatchdog =
false;
248 case WatchdogDisableReg:
249 old_val = watchdogDisableReg;
250 watchdogDisableReg = pkt->
getLE<uint32_t>();
252 if (old_val == 0x12345678 && watchdogDisableReg == 0x87654321)
253 watchdogControl.watchdogMode = 0;
256 panic(
"Tried to write CpuLocalTimer timer at offset %#x\n", daddr);
266 if (!timerControl.enable)
269 Tick time = parent->clockPeriod() *
power(16, timerControl.prescalar);
272 if (timerZeroEvent.scheduled()) {
273 DPRINTF(
Timer,
"-- Event was already schedule, de-scheduling\n");
274 parent->deschedule(timerZeroEvent);
276 parent->schedule(timerZeroEvent,
curTick() + time);
284 if (!watchdogControl.enable)
287 Tick time = parent->clockPeriod() *
power(16, watchdogControl.prescalar);
290 if (watchdogZeroEvent.scheduled()) {
291 DPRINTF(
Timer,
"-- Event was already schedule, de-scheduling\n");
292 parent->deschedule(watchdogZeroEvent);
294 parent->schedule(watchdogZeroEvent,
curTick() + time);
302 if (!timerControl.enable)
308 bool old_pending = pendingIntTimer;
309 if (timerControl.intEnable)
310 pendingIntTimer =
true;
311 if (pendingIntTimer && !old_pending) {
316 if (!timerControl.autoReload)
319 restartTimerCounter(timerLoadValue);
325 if (!watchdogControl.enable)
330 rawIntWatchdog =
true;
331 bool old_pending = pendingIntWatchdog;
334 if (watchdogControl.intEnable && !watchdogControl.watchdogMode)
335 pendingIntWatchdog =
true;
336 else if (watchdogControl.watchdogMode) {
337 rawResetWatchdog =
true;
338 fatal(
"gem5 ARM Model does not support true watchdog operation!\n");
342 if (pendingIntWatchdog && !old_pending) {
344 intWatchdog->raise();
347 if (watchdogControl.watchdogMode)
349 else if (watchdogControl.autoReload)
350 restartWatchdogCounter(watchdogLoadValue);
356 DPRINTF(Checkpoint,
"Serializing Arm CpuLocalTimer\n");
358 uint32_t timer_control_serial = timerControl;
359 uint32_t watchdog_control_serial = watchdogControl;
372 bool timer_is_in_event = timerZeroEvent.scheduled();
374 bool watchdog_is_in_event = watchdogZeroEvent.scheduled();
377 Tick timer_event_time;
378 if (timer_is_in_event){
379 timer_event_time = timerZeroEvent.when();
382 Tick watchdog_event_time;
383 if (watchdog_is_in_event){
384 watchdog_event_time = watchdogZeroEvent.when();
392 DPRINTF(Checkpoint,
"Unserializing Arm CpuLocalTimer\n");
394 uint32_t timer_control_serial;
396 timerControl = timer_control_serial;
397 uint32_t watchdog_control_serial;
399 watchdogControl = watchdog_control_serial;
410 bool timer_is_in_event;
412 bool watchdog_is_in_event;
415 Tick timer_event_time;
416 if (timer_is_in_event){
418 parent->schedule(timerZeroEvent, timer_event_time);
420 Tick watchdog_event_time;
421 if (watchdog_is_in_event) {
423 parent->schedule(watchdogZeroEvent, watchdog_event_time);
444 CpuLocalTimerParams::create()