timer_cpulocal.cc (12086:069c529a76fd) | timer_cpulocal.cc (13106:3af014b59080) |
---|---|
1/* | 1/* |
2 * Copyright (c) 2010-2013 ARM Limited | 2 * Copyright (c) 2010-2013,2018 ARM Limited |
3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated --- 24 unchanged lines hidden (view full) --- 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Ali Saidi 38 * Geoffrey Blake 39 */ 40 41#include "dev/arm/timer_cpulocal.hh" 42 | 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated --- 24 unchanged lines hidden (view full) --- 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Ali Saidi 38 * Geoffrey Blake 39 */ 40 41#include "dev/arm/timer_cpulocal.hh" 42 |
43#include "arch/arm/system.hh" |
|
43#include "base/intmath.hh" 44#include "base/trace.hh" 45#include "debug/Checkpoint.hh" 46#include "debug/Timer.hh" 47#include "dev/arm/base_gic.hh" 48#include "mem/packet.hh" 49#include "mem/packet_access.hh" 50 51CpuLocalTimer::CpuLocalTimer(Params *p) | 44#include "base/intmath.hh" 45#include "base/trace.hh" 46#include "debug/Checkpoint.hh" 47#include "debug/Timer.hh" 48#include "dev/arm/base_gic.hh" 49#include "mem/packet.hh" 50#include "mem/packet_access.hh" 51 52CpuLocalTimer::CpuLocalTimer(Params *p) |
52 : BasicPioDevice(p, 0x38), gic(p->gic) | 53 : BasicPioDevice(p, 0x38) |
53{ | 54{ |
55} 56 57void 58CpuLocalTimer::init() 59{ 60 auto p = params(); |
|
54 // Initialize the timer registers for each per cpu timer | 61 // Initialize the timer registers for each per cpu timer |
55 for (int i = 0; i < CPU_MAX; i++) { | 62 for (int i = 0; i < sys->numContexts(); i++) { 63 ThreadContext* tc = sys->getThreadContext(i); |
56 std::stringstream oss; 57 oss << name() << ".timer" << i; | 64 std::stringstream oss; 65 oss << name() << ".timer" << i; |
58 localTimer[i]._name = oss.str(); 59 localTimer[i].parent = this; 60 localTimer[i].intNumTimer = p->int_num_timer; 61 localTimer[i].intNumWatchdog = p->int_num_watchdog; 62 localTimer[i].cpuNum = i; | 66 67 localTimer.emplace_back( 68 new Timer(oss.str(), this, 69 p->int_timer->get(tc), 70 p->int_watchdog->get(tc))); |
63 } | 71 } |
72 73 BasicPioDevice::init(); |
|
64} 65 | 74} 75 |
66CpuLocalTimer::Timer::Timer() 67 : timerControl(0x0), watchdogControl(0x0), rawIntTimer(false), rawIntWatchdog(false), 68 rawResetWatchdog(false), watchdogDisableReg(0x0), pendingIntTimer(false), pendingIntWatchdog(false), | 76CpuLocalTimer::Timer::Timer(const std::string &timer_name, 77 CpuLocalTimer* _parent, 78 ArmInterruptPin* int_timer, 79 ArmInterruptPin* int_watchdog) 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), |
69 timerLoadValue(0x0), watchdogLoadValue(0x0), 70 timerZeroEvent([this]{ timerAtZero(); }, name()), 71 watchdogZeroEvent([this]{ watchdogAtZero(); }, name()) 72{ 73} 74 75Tick 76CpuLocalTimer::read(PacketPtr pkt) 77{ 78 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 79 assert(pkt->getSize() == 4); 80 Addr daddr = pkt->getAddr() - pioAddr; 81 ContextID cpu_id = pkt->req->contextId(); 82 DPRINTF(Timer, "Reading from CpuLocalTimer at offset: %#x\n", daddr); 83 assert(cpu_id >= 0); | 85 timerLoadValue(0x0), watchdogLoadValue(0x0), 86 timerZeroEvent([this]{ timerAtZero(); }, name()), 87 watchdogZeroEvent([this]{ watchdogAtZero(); }, name()) 88{ 89} 90 91Tick 92CpuLocalTimer::read(PacketPtr pkt) 93{ 94 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 95 assert(pkt->getSize() == 4); 96 Addr daddr = pkt->getAddr() - pioAddr; 97 ContextID cpu_id = pkt->req->contextId(); 98 DPRINTF(Timer, "Reading from CpuLocalTimer at offset: %#x\n", daddr); 99 assert(cpu_id >= 0); |
84 assert(cpu_id < CPU_MAX); | 100 assert(cpu_id < localTimer.size()); |
85 86 if (daddr < Timer::Size) | 101 102 if (daddr < Timer::Size) |
87 localTimer[cpu_id].read(pkt, daddr); | 103 localTimer[cpu_id]->read(pkt, daddr); |
88 else 89 panic("Tried to read CpuLocalTimer at offset %#x that doesn't exist\n", daddr); 90 pkt->makeAtomicResponse(); 91 return pioDelay; 92} 93 94 95void --- 58 unchanged lines hidden (view full) --- 154CpuLocalTimer::write(PacketPtr pkt) 155{ 156 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 157 assert(pkt->getSize() == 4); 158 Addr daddr = pkt->getAddr() - pioAddr; 159 ContextID cpu_id = pkt->req->contextId(); 160 DPRINTF(Timer, "Writing to CpuLocalTimer at offset: %#x\n", daddr); 161 assert(cpu_id >= 0); | 104 else 105 panic("Tried to read CpuLocalTimer at offset %#x that doesn't exist\n", daddr); 106 pkt->makeAtomicResponse(); 107 return pioDelay; 108} 109 110 111void --- 58 unchanged lines hidden (view full) --- 170CpuLocalTimer::write(PacketPtr pkt) 171{ 172 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 173 assert(pkt->getSize() == 4); 174 Addr daddr = pkt->getAddr() - pioAddr; 175 ContextID cpu_id = pkt->req->contextId(); 176 DPRINTF(Timer, "Writing to CpuLocalTimer at offset: %#x\n", daddr); 177 assert(cpu_id >= 0); |
162 assert(cpu_id < CPU_MAX); | 178 assert(cpu_id < localTimer.size()); |
163 164 if (daddr < Timer::Size) | 179 180 if (daddr < Timer::Size) |
165 localTimer[cpu_id].write(pkt, daddr); | 181 localTimer[cpu_id]->write(pkt, daddr); |
166 else 167 panic("Tried to write CpuLocalTimer at offset %#x that doesn't exist\n", daddr); 168 pkt->makeAtomicResponse(); 169 return pioDelay; 170} 171 172void 173CpuLocalTimer::Timer::write(PacketPtr pkt, Addr daddr) --- 118 unchanged lines hidden (view full) --- 292 DPRINTF(Timer, "Timer Counter reached zero\n"); 293 294 rawIntTimer = true; 295 bool old_pending = pendingIntTimer; 296 if (timerControl.intEnable) 297 pendingIntTimer = true; 298 if (pendingIntTimer && !old_pending) { 299 DPRINTF(Timer, "-- Causing interrupt\n"); | 182 else 183 panic("Tried to write CpuLocalTimer at offset %#x that doesn't exist\n", daddr); 184 pkt->makeAtomicResponse(); 185 return pioDelay; 186} 187 188void 189CpuLocalTimer::Timer::write(PacketPtr pkt, Addr daddr) --- 118 unchanged lines hidden (view full) --- 308 DPRINTF(Timer, "Timer Counter reached zero\n"); 309 310 rawIntTimer = true; 311 bool old_pending = pendingIntTimer; 312 if (timerControl.intEnable) 313 pendingIntTimer = true; 314 if (pendingIntTimer && !old_pending) { 315 DPRINTF(Timer, "-- Causing interrupt\n"); |
300 parent->gic->sendPPInt(intNumTimer, cpuNum); | 316 intTimer->raise(); |
301 } 302 303 if (!timerControl.autoReload) 304 return; 305 else 306 restartTimerCounter(timerLoadValue); 307} 308 --- 14 unchanged lines hidden (view full) --- 323 else if (watchdogControl.watchdogMode) { 324 rawResetWatchdog = true; 325 fatal("gem5 ARM Model does not support true watchdog operation!\n"); 326 //XXX: Should we ever support a true watchdog reset? 327 } 328 329 if (pendingIntWatchdog && !old_pending) { 330 DPRINTF(Timer, "-- Causing interrupt\n"); | 317 } 318 319 if (!timerControl.autoReload) 320 return; 321 else 322 restartTimerCounter(timerLoadValue); 323} 324 --- 14 unchanged lines hidden (view full) --- 339 else if (watchdogControl.watchdogMode) { 340 rawResetWatchdog = true; 341 fatal("gem5 ARM Model does not support true watchdog operation!\n"); 342 //XXX: Should we ever support a true watchdog reset? 343 } 344 345 if (pendingIntWatchdog && !old_pending) { 346 DPRINTF(Timer, "-- Causing interrupt\n"); |
331 parent->gic->sendPPInt(intNumWatchdog, cpuNum); | 347 intWatchdog->raise(); |
332 } 333 334 if (watchdogControl.watchdogMode) 335 return; 336 else if (watchdogControl.autoReload) 337 restartWatchdogCounter(watchdogLoadValue); 338} 339 340void 341CpuLocalTimer::Timer::serialize(CheckpointOut &cp) const 342{ 343 DPRINTF(Checkpoint, "Serializing Arm CpuLocalTimer\n"); | 348 } 349 350 if (watchdogControl.watchdogMode) 351 return; 352 else if (watchdogControl.autoReload) 353 restartWatchdogCounter(watchdogLoadValue); 354} 355 356void 357CpuLocalTimer::Timer::serialize(CheckpointOut &cp) const 358{ 359 DPRINTF(Checkpoint, "Serializing Arm CpuLocalTimer\n"); |
344 SERIALIZE_SCALAR(intNumTimer); 345 SERIALIZE_SCALAR(intNumWatchdog); | |
346 347 uint32_t timer_control_serial = timerControl; 348 uint32_t watchdog_control_serial = watchdogControl; 349 SERIALIZE_SCALAR(timer_control_serial); 350 SERIALIZE_SCALAR(watchdog_control_serial); 351 352 SERIALIZE_SCALAR(rawIntTimer); 353 SERIALIZE_SCALAR(rawIntWatchdog); --- 21 unchanged lines hidden (view full) --- 375 } 376} 377 378void 379CpuLocalTimer::Timer::unserialize(CheckpointIn &cp) 380{ 381 DPRINTF(Checkpoint, "Unserializing Arm CpuLocalTimer\n"); 382 | 360 361 uint32_t timer_control_serial = timerControl; 362 uint32_t watchdog_control_serial = watchdogControl; 363 SERIALIZE_SCALAR(timer_control_serial); 364 SERIALIZE_SCALAR(watchdog_control_serial); 365 366 SERIALIZE_SCALAR(rawIntTimer); 367 SERIALIZE_SCALAR(rawIntWatchdog); --- 21 unchanged lines hidden (view full) --- 389 } 390} 391 392void 393CpuLocalTimer::Timer::unserialize(CheckpointIn &cp) 394{ 395 DPRINTF(Checkpoint, "Unserializing Arm CpuLocalTimer\n"); 396 |
383 UNSERIALIZE_SCALAR(intNumTimer); 384 UNSERIALIZE_SCALAR(intNumWatchdog); 385 | |
386 uint32_t timer_control_serial; 387 UNSERIALIZE_SCALAR(timer_control_serial); 388 timerControl = timer_control_serial; 389 uint32_t watchdog_control_serial; 390 UNSERIALIZE_SCALAR(watchdog_control_serial); 391 watchdogControl = watchdog_control_serial; 392 393 UNSERIALIZE_SCALAR(rawIntTimer); --- 22 unchanged lines hidden (view full) --- 416 } 417} 418 419 420 421void 422CpuLocalTimer::serialize(CheckpointOut &cp) const 423{ | 397 uint32_t timer_control_serial; 398 UNSERIALIZE_SCALAR(timer_control_serial); 399 timerControl = timer_control_serial; 400 uint32_t watchdog_control_serial; 401 UNSERIALIZE_SCALAR(watchdog_control_serial); 402 watchdogControl = watchdog_control_serial; 403 404 UNSERIALIZE_SCALAR(rawIntTimer); --- 22 unchanged lines hidden (view full) --- 427 } 428} 429 430 431 432void 433CpuLocalTimer::serialize(CheckpointOut &cp) const 434{ |
424 for (int i = 0; i < CPU_MAX; i++) 425 localTimer[i].serializeSection(cp, csprintf("timer%d", i)); | 435 for (int i = 0; i < sys->numContexts(); i++) 436 localTimer[i]->serializeSection(cp, csprintf("timer%d", i)); |
426} 427 428void 429CpuLocalTimer::unserialize(CheckpointIn &cp) 430{ | 437} 438 439void 440CpuLocalTimer::unserialize(CheckpointIn &cp) 441{ |
431 for (int i = 0; i < CPU_MAX; i++) 432 localTimer[i].unserializeSection(cp, csprintf("timer%d", i)); | 442 for (int i = 0; i < sys->numContexts(); i++) 443 localTimer[i]->unserializeSection(cp, csprintf("timer%d", i)); |
433} 434 435CpuLocalTimer * 436CpuLocalTimerParams::create() 437{ 438 return new CpuLocalTimer(this); 439} | 444} 445 446CpuLocalTimer * 447CpuLocalTimerParams::create() 448{ 449 return new CpuLocalTimer(this); 450} |