1/* |
2 * Copyright (c) 2011-2012,2016-2017 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 --- 120 unchanged lines hidden (view full) --- 131 _dataMasterId(p->system->getMasterId(name() + ".data")), 132 _taskId(ContextSwitchTaskId::Unknown), _pid(invldPid), 133 _switchedOut(p->switched_out), _cacheLineSize(p->system->cacheLineSize()), 134 interrupts(p->interrupts), profileEvent(NULL), 135 numThreads(p->numThreads), system(p->system), 136 functionTraceStream(nullptr), currentFunctionStart(0), 137 currentFunctionEnd(0), functionEntryTick(0), 138 addressMonitor(p->numThreads), |
139 syscallRetryLatency(p->syscallRetryLatency), 140 pwrGatingLatency(p->pwr_gating_latency), 141 enterPwrGatingEvent([this]{ enterPwrGating(); }, name()) |
142{ 143 // if Python did not provide a valid ID, do it here 144 if (_cpuId == -1 ) { 145 _cpuId = cpuList.size(); 146 } 147 148 // add self to global list of CPUs 149 cpuList.push_back(this); --- 208 unchanged lines hidden (view full) --- 358 if (!params()->switched_out && profileEvent) 359 schedule(profileEvent, curTick()); 360 } 361 362 if (params()->progress_interval) { 363 new CPUProgressEvent(this, params()->progress_interval); 364 } 365 |
366 if (_switchedOut) 367 ClockedObject::pwrState(Enums::PwrState::OFF); 368 |
369 // Assumption CPU start to operate instantaneously without any latency 370 if (ClockedObject::pwrState() == Enums::PwrState::UNDEFINED) 371 ClockedObject::pwrState(Enums::PwrState::ON); 372 373} 374 375ProbePoints::PMUUPtr 376BaseCPU::pmuProbePoint(const char *name) --- 95 unchanged lines hidden (view full) --- 472 tc->setContextId(system->registerThreadContext(tc, _cpuId)); 473 } 474 475 if (!FullSystem) 476 tc->getProcessPtr()->assignThreadContext(tc->contextId()); 477 } 478} 479 |
480void 481BaseCPU::deschedulePowerGatingEvent() 482{ 483 if (enterPwrGatingEvent.scheduled()){ 484 deschedule(enterPwrGatingEvent); 485 } 486} |
487 |
488void 489BaseCPU::schedulePowerGatingEvent() 490{ 491 for (auto tc : threadContexts) { 492 if (tc->status() == ThreadContext::Active) 493 return; 494 } 495 496 if (ClockedObject::pwrState() == Enums::PwrState::CLK_GATED) { 497 assert(!enterPwrGatingEvent.scheduled()); 498 // Schedule a power gating event when clock gated for the specified 499 // amount of time 500 schedule(enterPwrGatingEvent, clockEdge(pwrGatingLatency)); 501 } 502} 503 |
504int 505BaseCPU::findContext(ThreadContext *tc) 506{ 507 ThreadID size = threadContexts.size(); 508 for (ThreadID tid = 0; tid < size; ++tid) { 509 if (tc == threadContexts[tid]) 510 return tid; 511 } 512 return 0; 513} 514 515void 516BaseCPU::activateContext(ThreadID thread_num) 517{ |
518 // Squash enter power gating event while cpu gets activated 519 if (enterPwrGatingEvent.scheduled()) 520 deschedule(enterPwrGatingEvent); 521 |
522 // For any active thread running, update CPU power state to active (ON) 523 ClockedObject::pwrState(Enums::PwrState::ON); 524} 525 526void 527BaseCPU::suspendContext(ThreadID thread_num) 528{ 529 // Check if all threads are suspended 530 for (auto t : threadContexts) { 531 if (t->status() != ThreadContext::Suspended) { 532 return; 533 } 534 } 535 536 // All CPU threads suspended, enter lower power state for the CPU 537 ClockedObject::pwrState(Enums::PwrState::CLK_GATED); |
538 539 //Schedule power gating event when clock gated for a configurable cycles 540 schedule(enterPwrGatingEvent, clockEdge(pwrGatingLatency)); |
541} 542 543void |
544BaseCPU::enterPwrGating(void) 545{ 546 ClockedObject::pwrState(Enums::PwrState::OFF); 547} 548 549void |
550BaseCPU::switchOut() 551{ 552 assert(!_switchedOut); 553 _switchedOut = true; 554 if (profileEvent && profileEvent->scheduled()) 555 deschedule(profileEvent); 556 557 // Flush all TLBs in the CPU to avoid having stale translations if 558 // it gets switched in later. 559 flushTLBs(); |
560 561 // Go to the power gating state 562 ClockedObject::pwrState(Enums::PwrState::OFF); |
563} 564 565void 566BaseCPU::takeOverFrom(BaseCPU *oldCPU) 567{ 568 assert(threadContexts.size() == oldCPU->threadContexts.size()); 569 assert(_cpuId == oldCPU->cpuId()); 570 assert(_switchedOut); 571 assert(oldCPU != this); 572 _pid = oldCPU->getPid(); 573 _taskId = oldCPU->taskId(); |
574 // Take over the power state of the switchedOut CPU 575 ClockedObject::pwrState(oldCPU->pwrState()); |
576 _switchedOut = false; 577 578 ThreadID size = threadContexts.size(); 579 for (ThreadID i = 0; i < size; ++i) { 580 ThreadContext *newTC = threadContexts[i]; 581 ThreadContext *oldTC = oldCPU->threadContexts[i]; 582 583 newTC->takeOverFrom(oldTC); --- 250 unchanged lines hidden --- |