base.cc (12127:4207df055b0d) base.cc (12276:22c220be30c5)
1/*
1/*
2 * Copyright (c) 2011-2012,2016 ARM Limited
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),
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)
139 syscallRetryLatency(p->syscallRetryLatency),
140 pwrGatingLatency(p->pwr_gating_latency),
141 enterPwrGatingEvent([this]{ enterPwrGating(); }, name())
140{
141 // if Python did not provide a valid ID, do it here
142 if (_cpuId == -1 ) {
143 _cpuId = cpuList.size();
144 }
145
146 // add self to global list of CPUs
147 cpuList.push_back(this);

--- 208 unchanged lines hidden (view full) ---

356 if (!params()->switched_out && profileEvent)
357 schedule(profileEvent, curTick());
358 }
359
360 if (params()->progress_interval) {
361 new CPUProgressEvent(this, params()->progress_interval);
362 }
363
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
364 // Assumption CPU start to operate instantaneously without any latency
365 if (ClockedObject::pwrState() == Enums::PwrState::UNDEFINED)
366 ClockedObject::pwrState(Enums::PwrState::ON);
367
368}
369
370ProbePoints::PMUUPtr
371BaseCPU::pmuProbePoint(const char *name)

--- 95 unchanged lines hidden (view full) ---

467 tc->setContextId(system->registerThreadContext(tc, _cpuId));
468 }
469
470 if (!FullSystem)
471 tc->getProcessPtr()->assignThreadContext(tc->contextId());
472 }
473}
474
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}
475
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
476int
477BaseCPU::findContext(ThreadContext *tc)
478{
479 ThreadID size = threadContexts.size();
480 for (ThreadID tid = 0; tid < size; ++tid) {
481 if (tc == threadContexts[tid])
482 return tid;
483 }
484 return 0;
485}
486
487void
488BaseCPU::activateContext(ThreadID thread_num)
489{
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
490 // For any active thread running, update CPU power state to active (ON)
491 ClockedObject::pwrState(Enums::PwrState::ON);
492}
493
494void
495BaseCPU::suspendContext(ThreadID thread_num)
496{
497 // Check if all threads are suspended
498 for (auto t : threadContexts) {
499 if (t->status() != ThreadContext::Suspended) {
500 return;
501 }
502 }
503
504 // All CPU threads suspended, enter lower power state for the CPU
505 ClockedObject::pwrState(Enums::PwrState::CLK_GATED);
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));
506}
507
508void
541}
542
543void
544BaseCPU::enterPwrGating(void)
545{
546 ClockedObject::pwrState(Enums::PwrState::OFF);
547}
548
549void
509BaseCPU::switchOut()
510{
511 assert(!_switchedOut);
512 _switchedOut = true;
513 if (profileEvent && profileEvent->scheduled())
514 deschedule(profileEvent);
515
516 // Flush all TLBs in the CPU to avoid having stale translations if
517 // it gets switched in later.
518 flushTLBs();
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);
519}
520
521void
522BaseCPU::takeOverFrom(BaseCPU *oldCPU)
523{
524 assert(threadContexts.size() == oldCPU->threadContexts.size());
525 assert(_cpuId == oldCPU->cpuId());
526 assert(_switchedOut);
527 assert(oldCPU != this);
528 _pid = oldCPU->getPid();
529 _taskId = oldCPU->taskId();
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());
530 _switchedOut = false;
531
532 ThreadID size = threadContexts.size();
533 for (ThreadID i = 0; i < size; ++i) {
534 ThreadContext *newTC = threadContexts[i];
535 ThreadContext *oldTC = oldCPU->threadContexts[i];
536
537 newTC->takeOverFrom(oldTC);

--- 250 unchanged lines hidden ---
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 ---