cpu: Add cpuIdlePins to indicate the threadContext of CPU is idle (#1285)
If the threacContext of CPU enters the suspend mode, raise the threadID of threadContext cpu_idle_pins with the high signal to target. If the threadContext of CPU enters the activate mode, lower the threadID of thread cpu_idle_pins with low signal to target.
This commit is contained in:
@@ -45,6 +45,7 @@ from m5.objects.ClockDomain import *
|
||||
from m5.objects.ClockedObject import ClockedObject
|
||||
from m5.objects.CPUTracers import ExeTracer
|
||||
from m5.objects.InstTracer import InstTracer
|
||||
from m5.objects.IntPin import VectorIntSourcePin
|
||||
from m5.objects.Platform import Platform
|
||||
from m5.objects.ResetPort import ResetResponsePort
|
||||
from m5.objects.SubSystem import SubSystem
|
||||
@@ -155,6 +156,13 @@ class BaseCPU(ClockedObject):
|
||||
|
||||
model_reset = ResetResponsePort("Generic reset for the CPU")
|
||||
|
||||
cpu_idle_pins = VectorIntSourcePin(
|
||||
"This signal indicates the thread context of CPU is idle. Should be "
|
||||
"equal to the numThreads or keep empty to ignore idle signals. If the "
|
||||
"user specifies cpu_idle_pins less than numThreads. The ContextId "
|
||||
"greater than the size of cpu_idle_pins will be ignored."
|
||||
)
|
||||
|
||||
tracer = Param.InstTracer(default_tracer, "Instruction tracer")
|
||||
|
||||
icache_port = RequestPort("Instruction Port")
|
||||
|
||||
@@ -191,6 +191,12 @@ BaseCPU::BaseCPU(const Params &p, bool is_checker)
|
||||
modelResetPort.onChange([this](const bool &new_val) {
|
||||
setReset(new_val);
|
||||
});
|
||||
|
||||
for (int i = 0; i < params().port_cpu_idle_pins_connection_count; i++) {
|
||||
cpuIdlePins.emplace_back(new IntSourcePin<BaseCPU>(
|
||||
csprintf("%s.cpu_idle_pins[%d]", name(), i), i, this));
|
||||
}
|
||||
|
||||
// create a stat group object for each thread on this core
|
||||
fetchStats.reserve(numThreads);
|
||||
executeStats.reserve(numThreads);
|
||||
@@ -463,6 +469,8 @@ BaseCPU::getPort(const std::string &if_name, PortID idx)
|
||||
return getInstPort();
|
||||
else if (if_name == "model_reset")
|
||||
return modelResetPort;
|
||||
else if (if_name == "cpu_idle_pins")
|
||||
return *cpuIdlePins[idx];
|
||||
else
|
||||
return ClockedObject::getPort(if_name, idx);
|
||||
}
|
||||
@@ -537,6 +545,11 @@ BaseCPU::activateContext(ThreadID thread_num)
|
||||
|
||||
DPRINTF(Thread, "activate contextId %d\n",
|
||||
threadContexts[thread_num]->contextId());
|
||||
|
||||
if (thread_num < cpuIdlePins.size()) {
|
||||
cpuIdlePins[thread_num]->lower();
|
||||
}
|
||||
|
||||
// Squash enter power gating event while cpu gets activated
|
||||
if (enterPwrGatingEvent.scheduled())
|
||||
deschedule(enterPwrGatingEvent);
|
||||
@@ -551,6 +564,11 @@ BaseCPU::suspendContext(ThreadID thread_num)
|
||||
{
|
||||
DPRINTF(Thread, "suspend contextId %d\n",
|
||||
threadContexts[thread_num]->contextId());
|
||||
|
||||
if (thread_num < cpuIdlePins.size()) {
|
||||
cpuIdlePins[thread_num]->raise();
|
||||
}
|
||||
|
||||
// Check if all threads are suspended
|
||||
for (auto t : threadContexts) {
|
||||
if (t->status() != ThreadContext::Suspended) {
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "arch/generic/interrupts.hh"
|
||||
#include "base/statistics.hh"
|
||||
#include "debug/Mwait.hh"
|
||||
#include "dev/intpin.hh"
|
||||
#include "mem/htm.hh"
|
||||
#include "mem/port_proxy.hh"
|
||||
#include "sim/clocked_object.hh"
|
||||
@@ -259,6 +260,8 @@ class BaseCPU : public ClockedObject
|
||||
protected:
|
||||
std::vector<ThreadContext *> threadContexts;
|
||||
|
||||
std::vector<std::unique_ptr<IntSourcePin<BaseCPU>>> cpuIdlePins;
|
||||
|
||||
trace::InstTracer * tracer;
|
||||
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user