summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkash Bagdia <akash.bagdia@ARM.com>2014-12-09 10:42:08 +0000
committerAkash Bagdia <akash.bagdia@ARM.com>2014-12-09 10:42:08 +0000
commit1c34ee20dfbbd557e394d61825232b10c0f3d37f (patch)
treeb3a6cedf9cb10fec3c0722df7301bc1c5cca1507
parent3ee4957b4930a252c0185a6bc71bdf1c6ebc5ed9 (diff)
downloadgem5-1c34ee20dfbbd557e394d61825232b10c0f3d37f.tar.xz
power: Low-power idle power state for idle CPUs
Add functionality to the BaseCPU that will put the entire CPU into a low-power idle state whenever all threads in it are idle.
-rw-r--r--src/cpu/base.cc27
-rw-r--r--src/cpu/base.hh5
-rw-r--r--src/cpu/minor/cpu.cc4
-rw-r--r--src/cpu/o3/cpu.cc4
-rw-r--r--src/cpu/simple/atomic.cc3
-rw-r--r--src/cpu/simple/timing.cc4
6 files changed, 45 insertions, 2 deletions
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 624843f42..0f9fe49ea 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -64,6 +64,7 @@
#include "debug/SyscallVerbose.hh"
#include "mem/page_table.hh"
#include "params/BaseCPU.hh"
+#include "sim/clocked_object.hh"
#include "sim/full_system.hh"
#include "sim/process.hh"
#include "sim/sim_events.hh"
@@ -355,6 +356,11 @@ BaseCPU::startup()
if (params()->progress_interval) {
new CPUProgressEvent(this, params()->progress_interval);
}
+
+ // Assumption CPU start to operate instantaneously without any latency
+ if (ClockedObject::pwrState() == Enums::PwrState::UNDEFINED)
+ ClockedObject::pwrState(Enums::PwrState::ON);
+
}
ProbePoints::PMUUPtr
@@ -473,6 +479,27 @@ BaseCPU::findContext(ThreadContext *tc)
}
void
+BaseCPU::activateContext(ThreadID thread_num)
+{
+ // For any active thread running, update CPU power state to active (ON)
+ ClockedObject::pwrState(Enums::PwrState::ON);
+}
+
+void
+BaseCPU::suspendContext(ThreadID thread_num)
+{
+ // Check if all threads are suspended
+ for (auto t : threadContexts) {
+ if (t->status() != ThreadContext::Suspended) {
+ return;
+ }
+ }
+
+ // All CPU threads suspended, enter lower power state for the CPU
+ ClockedObject::pwrState(Enums::PwrState::CLK_GATED);
+}
+
+void
BaseCPU::switchOut()
{
assert(!_switchedOut);
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index 438c38812..f01aa71f3 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -279,10 +279,11 @@ class BaseCPU : public MemObject
Trace::InstTracer * getTracer() { return tracer; }
/// Notify the CPU that the indicated context is now active.
- virtual void activateContext(ThreadID thread_num) {}
+ virtual void activateContext(ThreadID thread_num);
/// Notify the CPU that the indicated context is now suspended.
- virtual void suspendContext(ThreadID thread_num) {}
+ /// Check if possible to enter a lower power state
+ virtual void suspendContext(ThreadID thread_num);
/// Notify the CPU that the indicated context is now halted.
virtual void haltContext(ThreadID thread_num) {}
diff --git a/src/cpu/minor/cpu.cc b/src/cpu/minor/cpu.cc
index cd39a8b93..a707c6045 100644
--- a/src/cpu/minor/cpu.cc
+++ b/src/cpu/minor/cpu.cc
@@ -287,6 +287,8 @@ MinorCPU::activateContext(ThreadID thread_id)
threads[thread_id]->activate();
wakeupOnEvent(Minor::Pipeline::CPUStageId);
pipeline->wakeupFetch();
+
+ BaseCPU::activateContext(thread_id);
}
void
@@ -295,6 +297,8 @@ MinorCPU::suspendContext(ThreadID thread_id)
DPRINTF(MinorCPU, "SuspendContext %d\n", thread_id);
threads[thread_id]->suspend();
+
+ BaseCPU::suspendContext(thread_id);
}
void
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index 79ad705bf..73174e4a9 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -735,6 +735,8 @@ FullO3CPU<Impl>::activateContext(ThreadID tid)
lastActivatedCycle = curTick();
_status = Running;
+
+ BaseCPU::activateContext(tid);
}
}
@@ -755,6 +757,8 @@ FullO3CPU<Impl>::suspendContext(ThreadID tid)
}
DPRINTF(Quiesce, "Suspending Context\n");
+
+ BaseCPU::suspendContext(tid);
}
template <class Impl>
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index f3e14d401..3cd6c1666 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -247,6 +247,8 @@ AtomicSimpleCPU::activateContext(ThreadID thread_num)
== activeThreads.end()) {
activeThreads.push_back(thread_num);
}
+
+ BaseCPU::activateContext(thread_num);
}
@@ -273,6 +275,7 @@ AtomicSimpleCPU::suspendContext(ThreadID thread_num)
}
}
+ BaseCPU::suspendContext(thread_num);
}
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index 43f4eb9f4..c99f9c475 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -218,6 +218,8 @@ TimingSimpleCPU::activateContext(ThreadID thread_num)
== activeThreads.end()) {
activeThreads.push_back(thread_num);
}
+
+ BaseCPU::activateContext(thread_num);
}
@@ -243,6 +245,8 @@ TimingSimpleCPU::suspendContext(ThreadID thread_num)
deschedule(fetchEvent);
}
}
+
+ BaseCPU::suspendContext(thread_num);
}
bool