summaryrefslogtreecommitdiff
path: root/src/cpu/base.cc
diff options
context:
space:
mode:
authorAnouk Van Laer <anouk.vanlaer@arm.com>2017-03-17 12:02:00 +0000
committerAndreas Sandberg <andreas.sandberg@arm.com>2017-11-20 11:03:03 +0000
commitc0d613adb4eca09c32aca1cc90f04c29574f69c6 (patch)
tree1c2a0d26778d8b8ca3f0b359f990dc695156bf8f /src/cpu/base.cc
parentd626f4f7aaa4d2c9f7ae1afc35577fa025b4de38 (diff)
downloadgem5-c0d613adb4eca09c32aca1cc90f04c29574f69c6.tar.xz
pwr: Adds logic to enter power gating for the cpu model
If the CPU has been clock gated for a sufficient amount of time (configurable via pwrGatingLatency), the CPU will go into the OFF power state. This does not model hardware, just behaviour. Change-Id: Ib3681d1ffa6ad25eba60f47b4020325f63472d43 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/3969 Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Diffstat (limited to 'src/cpu/base.cc')
-rw-r--r--src/cpu/base.cc50
1 files changed, 48 insertions, 2 deletions
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 6f76b8c6f..78cf4196c 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2012,2016 ARM Limited
+ * Copyright (c) 2011-2012,2016-2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -136,7 +136,9 @@ BaseCPU::BaseCPU(Params *p, bool is_checker)
functionTraceStream(nullptr), currentFunctionStart(0),
currentFunctionEnd(0), functionEntryTick(0),
addressMonitor(p->numThreads),
- syscallRetryLatency(p->syscallRetryLatency)
+ syscallRetryLatency(p->syscallRetryLatency),
+ pwrGatingLatency(p->pwr_gating_latency),
+ enterPwrGatingEvent([this]{ enterPwrGating(); }, name())
{
// if Python did not provide a valid ID, do it here
if (_cpuId == -1 ) {
@@ -361,6 +363,9 @@ BaseCPU::startup()
new CPUProgressEvent(this, params()->progress_interval);
}
+ if (_switchedOut)
+ ClockedObject::pwrState(Enums::PwrState::OFF);
+
// Assumption CPU start to operate instantaneously without any latency
if (ClockedObject::pwrState() == Enums::PwrState::UNDEFINED)
ClockedObject::pwrState(Enums::PwrState::ON);
@@ -472,6 +477,29 @@ BaseCPU::registerThreadContexts()
}
}
+void
+BaseCPU::deschedulePowerGatingEvent()
+{
+ if (enterPwrGatingEvent.scheduled()){
+ deschedule(enterPwrGatingEvent);
+ }
+}
+
+void
+BaseCPU::schedulePowerGatingEvent()
+{
+ for (auto tc : threadContexts) {
+ if (tc->status() == ThreadContext::Active)
+ return;
+ }
+
+ if (ClockedObject::pwrState() == Enums::PwrState::CLK_GATED) {
+ assert(!enterPwrGatingEvent.scheduled());
+ // Schedule a power gating event when clock gated for the specified
+ // amount of time
+ schedule(enterPwrGatingEvent, clockEdge(pwrGatingLatency));
+ }
+}
int
BaseCPU::findContext(ThreadContext *tc)
@@ -487,6 +515,10 @@ BaseCPU::findContext(ThreadContext *tc)
void
BaseCPU::activateContext(ThreadID thread_num)
{
+ // Squash enter power gating event while cpu gets activated
+ if (enterPwrGatingEvent.scheduled())
+ deschedule(enterPwrGatingEvent);
+
// For any active thread running, update CPU power state to active (ON)
ClockedObject::pwrState(Enums::PwrState::ON);
}
@@ -503,6 +535,15 @@ BaseCPU::suspendContext(ThreadID thread_num)
// All CPU threads suspended, enter lower power state for the CPU
ClockedObject::pwrState(Enums::PwrState::CLK_GATED);
+
+ //Schedule power gating event when clock gated for a configurable cycles
+ schedule(enterPwrGatingEvent, clockEdge(pwrGatingLatency));
+}
+
+void
+BaseCPU::enterPwrGating(void)
+{
+ ClockedObject::pwrState(Enums::PwrState::OFF);
}
void
@@ -516,6 +557,9 @@ BaseCPU::switchOut()
// Flush all TLBs in the CPU to avoid having stale translations if
// it gets switched in later.
flushTLBs();
+
+ // Go to the power gating state
+ ClockedObject::pwrState(Enums::PwrState::OFF);
}
void
@@ -527,6 +571,8 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
assert(oldCPU != this);
_pid = oldCPU->getPid();
_taskId = oldCPU->taskId();
+ // Take over the power state of the switchedOut CPU
+ ClockedObject::pwrState(oldCPU->pwrState());
_switchedOut = false;
ThreadID size = threadContexts.size();