summaryrefslogtreecommitdiff
path: root/src/cpu/minor/cpu.cc
diff options
context:
space:
mode:
authorMitch Hayenga <mitch.hayenga@arm.com>2016-07-21 17:19:16 +0100
committerMitch Hayenga <mitch.hayenga@arm.com>2016-07-21 17:19:16 +0100
commitff4009ac005be0347015f8ba5a8e37a3aa930e69 (patch)
treeb80cfa7c70c0e39f54c8c3d78527722cb6658510 /src/cpu/minor/cpu.cc
parent8a476d387c84f037d0ccf3cc20dc88870ab45fec (diff)
downloadgem5-ff4009ac005be0347015f8ba5a8e37a3aa930e69.tar.xz
cpu: Add SMT support to MinorCPU
This patch adds SMT support to the MinorCPU. Currently RoundRobin or Random thread scheduling are supported. Change-Id: I91faf39ff881af5918cca05051829fc6261f20e3
Diffstat (limited to 'src/cpu/minor/cpu.cc')
-rw-r--r--src/cpu/minor/cpu.cc59
1 files changed, 26 insertions, 33 deletions
diff --git a/src/cpu/minor/cpu.cc b/src/cpu/minor/cpu.cc
index 79807a2a7..016a60f47 100644
--- a/src/cpu/minor/cpu.cc
+++ b/src/cpu/minor/cpu.cc
@@ -47,32 +47,33 @@
#include "debug/Quiesce.hh"
MinorCPU::MinorCPU(MinorCPUParams *params) :
- BaseCPU(params)
+ BaseCPU(params),
+ threadPolicy(params->threadPolicy)
{
/* This is only written for one thread at the moment */
Minor::MinorThread *thread;
- if (FullSystem) {
- thread = new Minor::MinorThread(this, 0, params->system, params->itb,
- params->dtb, params->isa[0]);
- } else {
- /* thread_id 0 */
- thread = new Minor::MinorThread(this, 0, params->system,
- params->workload[0], params->itb, params->dtb, params->isa[0]);
- }
-
- threads.push_back(thread);
+ for (ThreadID i = 0; i < numThreads; i++) {
+ if (FullSystem) {
+ thread = new Minor::MinorThread(this, i, params->system,
+ params->itb, params->dtb, params->isa[i]);
+ thread->setStatus(ThreadContext::Halted);
+ } else {
+ thread = new Minor::MinorThread(this, i, params->system,
+ params->workload[i], params->itb, params->dtb,
+ params->isa[i]);
+ }
- thread->setStatus(ThreadContext::Halted);
+ threads.push_back(thread);
+ ThreadContext *tc = thread->getTC();
+ threadContexts.push_back(tc);
+ }
- ThreadContext *tc = thread->getTC();
if (params->checker) {
fatal("The Minor model doesn't support checking (yet)\n");
}
- threadContexts.push_back(tc);
-
Minor::MinorDynInst::init();
pipeline = new Minor::Pipeline(*this, *params);
@@ -137,9 +138,6 @@ MinorCPU::serializeThread(CheckpointOut &cp, ThreadID thread_id) const
void
MinorCPU::unserializeThread(CheckpointIn &cp, ThreadID thread_id)
{
- if (thread_id != 0)
- fatal("Trying to load more than one thread into a MinorCPU\n");
-
threads[thread_id]->unserialize(cp);
}
@@ -170,11 +168,11 @@ void
MinorCPU::wakeup(ThreadID tid)
{
DPRINTF(Drain, "[tid:%d] MinorCPU wakeup\n", tid);
+ assert(tid < numThreads);
- if (threads[tid]->status() == ThreadContext::Suspended)
+ if (threads[tid]->status() == ThreadContext::Suspended) {
threads[tid]->activate();
-
- DPRINTF(Drain,"Suspended Processor awoke\n");
+ }
}
void
@@ -187,13 +185,10 @@ MinorCPU::startup()
for (auto i = threads.begin(); i != threads.end(); i ++)
(*i)->startup();
- /* Workaround cases in SE mode where a thread is activated with an
- * incorrect PC that is updated after the call to activate. This
- * causes problems for Minor since it instantiates a virtual
- * branch instruction when activateContext() is called which ends
- * up pointing to an illegal address. */
- if (threads[0]->status() == ThreadContext::Active)
- activateContext(0);
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ threads[tid]->startup();
+ pipeline->wakeupFetch(tid);
+ }
}
DrainState
@@ -246,6 +241,7 @@ MinorCPU::drainResume()
for (ThreadID tid = 0; tid < numThreads; tid++)
wakeup(tid);
+
pipeline->drainResume();
}
@@ -278,7 +274,7 @@ MinorCPU::takeOverFrom(BaseCPU *old_cpu)
void
MinorCPU::activateContext(ThreadID thread_id)
{
- DPRINTF(MinorCPU, "ActivateContext thread: %d", thread_id);
+ DPRINTF(MinorCPU, "ActivateContext thread: %d\n", thread_id);
/* Do some cycle accounting. lastStopped is reset to stop the
* wakeup call on the pipeline from adding the quiesce period
@@ -289,7 +285,7 @@ MinorCPU::activateContext(ThreadID thread_id)
/* Wake up the thread, wakeup the pipeline tick */
threads[thread_id]->activate();
wakeupOnEvent(Minor::Pipeline::CPUStageId);
- pipeline->wakeupFetch();
+ pipeline->wakeupFetch(thread_id);
BaseCPU::activateContext(thread_id);
}
@@ -317,9 +313,6 @@ MinorCPU::wakeupOnEvent(unsigned int stage_id)
MinorCPU *
MinorCPUParams::create()
{
- numThreads = 1;
- if (!FullSystem && workload.size() != 1)
- panic("only one workload allowed");
return new MinorCPU(this);
}