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.
This commit is contained in:
Akash Bagdia 2014-12-09 10:42:08 +00:00
parent 3ee4957b49
commit 1c34ee20df
6 changed files with 45 additions and 2 deletions

View file

@ -64,6 +64,7 @@
#include "debug/SyscallVerbose.hh" #include "debug/SyscallVerbose.hh"
#include "mem/page_table.hh" #include "mem/page_table.hh"
#include "params/BaseCPU.hh" #include "params/BaseCPU.hh"
#include "sim/clocked_object.hh"
#include "sim/full_system.hh" #include "sim/full_system.hh"
#include "sim/process.hh" #include "sim/process.hh"
#include "sim/sim_events.hh" #include "sim/sim_events.hh"
@ -355,6 +356,11 @@ BaseCPU::startup()
if (params()->progress_interval) { if (params()->progress_interval) {
new CPUProgressEvent(this, 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 ProbePoints::PMUUPtr
@ -472,6 +478,27 @@ BaseCPU::findContext(ThreadContext *tc)
return 0; return 0;
} }
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 void
BaseCPU::switchOut() BaseCPU::switchOut()
{ {

View file

@ -279,10 +279,11 @@ class BaseCPU : public MemObject
Trace::InstTracer * getTracer() { return tracer; } Trace::InstTracer * getTracer() { return tracer; }
/// Notify the CPU that the indicated context is now active. /// 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. /// 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. /// Notify the CPU that the indicated context is now halted.
virtual void haltContext(ThreadID thread_num) {} virtual void haltContext(ThreadID thread_num) {}

View file

@ -287,6 +287,8 @@ MinorCPU::activateContext(ThreadID thread_id)
threads[thread_id]->activate(); threads[thread_id]->activate();
wakeupOnEvent(Minor::Pipeline::CPUStageId); wakeupOnEvent(Minor::Pipeline::CPUStageId);
pipeline->wakeupFetch(); pipeline->wakeupFetch();
BaseCPU::activateContext(thread_id);
} }
void void
@ -295,6 +297,8 @@ MinorCPU::suspendContext(ThreadID thread_id)
DPRINTF(MinorCPU, "SuspendContext %d\n", thread_id); DPRINTF(MinorCPU, "SuspendContext %d\n", thread_id);
threads[thread_id]->suspend(); threads[thread_id]->suspend();
BaseCPU::suspendContext(thread_id);
} }
void void

View file

@ -735,6 +735,8 @@ FullO3CPU<Impl>::activateContext(ThreadID tid)
lastActivatedCycle = curTick(); lastActivatedCycle = curTick();
_status = Running; _status = Running;
BaseCPU::activateContext(tid);
} }
} }
@ -755,6 +757,8 @@ FullO3CPU<Impl>::suspendContext(ThreadID tid)
} }
DPRINTF(Quiesce, "Suspending Context\n"); DPRINTF(Quiesce, "Suspending Context\n");
BaseCPU::suspendContext(tid);
} }
template <class Impl> template <class Impl>

View file

@ -247,6 +247,8 @@ AtomicSimpleCPU::activateContext(ThreadID thread_num)
== activeThreads.end()) { == activeThreads.end()) {
activeThreads.push_back(thread_num); activeThreads.push_back(thread_num);
} }
BaseCPU::activateContext(thread_num);
} }
@ -273,6 +275,7 @@ AtomicSimpleCPU::suspendContext(ThreadID thread_num)
} }
} }
BaseCPU::suspendContext(thread_num);
} }

View file

@ -218,6 +218,8 @@ TimingSimpleCPU::activateContext(ThreadID thread_num)
== activeThreads.end()) { == activeThreads.end()) {
activeThreads.push_back(thread_num); activeThreads.push_back(thread_num);
} }
BaseCPU::activateContext(thread_num);
} }
@ -243,6 +245,8 @@ TimingSimpleCPU::suspendContext(ThreadID thread_num)
deschedule(fetchEvent); deschedule(fetchEvent);
} }
} }
BaseCPU::suspendContext(thread_num);
} }
bool bool