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:
Yu-Cheng Chang
2024-07-10 17:36:37 +08:00
committed by GitHub
parent d54dcac393
commit ce8db85867
3 changed files with 29 additions and 0 deletions

View File

@@ -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")

View File

@@ -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) {

View File

@@ -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: