From 7df680b6d31af485c34f160103f6c5f9c161463e Mon Sep 17 00:00:00 2001 From: Kajol Jain Date: Wed, 12 Jun 2019 14:40:51 +0530 Subject: [PATCH] arch-power: Added support for SMT This adds support for SMT (simultaneous multi-threading). * Enable multithreading for power architecture. * Make number of threads 2. * Added support for post and clear interrupt. * Added interrupt array support for external interrupts so that it will check any pending interrupt request in every tick. * Initialize PIR for second thread. * Initialize PC state for second thread so that it will loop until first thread try to wake up secondary threads. * Initialize register r3 for second thread. Change-Id: I5825e62a94b50aaa213eb64335973129addf2e4c Signed-off-by: Kajol Jain --- configs/common/FSConfig.py | 2 + src/arch/power/interrupts.hh | 73 ++++++++++++++++++++++++++---------- src/arch/power/system.cc | 5 +++ src/cpu/BaseCPU.py | 2 +- src/cpu/base.cc | 3 +- src/sim/system.cc | 5 ++- 6 files changed, 66 insertions(+), 24 deletions(-) diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py index e725d3101..47c79184c 100644 --- a/configs/common/FSConfig.py +++ b/configs/common/FSConfig.py @@ -705,6 +705,8 @@ def makeLinuxPowerSystem(mem_mode, numCPUs=1, mdesc=None, cmdline=None): self.boot_osflags = fillInCmdline(mdesc, cmdline) self.kernel = binary('vmlinux') self.dtb_filename = binary('gem5-power9-fs.dtb') + self.multi_thread = True; + self._num_cpus = 2; return self diff --git a/src/arch/power/interrupts.hh b/src/arch/power/interrupts.hh index d4bfd876e..81045d294 100644 --- a/src/arch/power/interrupts.hh +++ b/src/arch/power/interrupts.hh @@ -37,6 +37,17 @@ #include "params/PowerInterrupts.hh" #include "sim/sim_object.hh" +#define NumInterruptLevels 8 + +#define SystemReset 0 //System Reset Interrupt(Highest Priority) +#define MachineCheck 1 //Machine Check Interrupt +#define DirectExt 2 //Direct External Interrupt +#define MediatedExt 3 //Mediated External Interrupt +#define Decrementer 4 //Decrementer Interrupt +#define PerfMoniter 5 //Performance Monitor Interrupt +#define DirPriDoorbell 6 //Directed Privileged Doorbell Interrupt +#define DirHypDoorbell 7 //Directed Hypervisor Doorbell Interrupt + class BaseCPU; class ThreadContext; @@ -46,7 +57,9 @@ class Interrupts : public SimObject { private: BaseCPU * cpu; - bool si = false; + + protected: + bool interrupts[NumInterruptLevels]; public: typedef PowerInterruptsParams Params; @@ -58,7 +71,9 @@ class Interrupts : public SimObject } Interrupts(Params * p) : SimObject(p), cpu(NULL) - {} + { + memset(interrupts, 0, sizeof(interrupts)); + } void setCPU(BaseCPU * _cpu) @@ -69,45 +84,64 @@ class Interrupts : public SimObject void post(int int_num, int index) { - panic("Interrupts::post not implemented.\n"); + DPRINTF(Interrupt, "Interrupt %d: posted\n", int_num); + if (int_num < 0 || int_num >= NumInterruptLevels) + panic("int_num out of bounds for fun POST%d\n",int_num); + interrupts[int_num] = 1; } void clear(int int_num, int index) { - panic("Interrupts::clear not implemented.\n"); + DPRINTF(Interrupt, "Interrupt %d:\n", int_num); + if (int_num < 0 || int_num >= NumInterruptLevels) + panic("int_num out of bounds for fun CLEAR%d\n",int_num); + interrupts[int_num] = 0; } void clearAll() { - panic("Interrupts::clearAll not implemented.\n"); + memset(interrupts, 0, sizeof(interrupts)); } bool checkInterrupts(ThreadContext *tc) { - //panic("Interrupts::checkInterrupts not implemented.\n"); - Msr msr = tc->readIntReg(INTREG_MSR); - tc->setIntReg(INTREG_TB , tc->readIntReg(INTREG_TB)+1); - if ( tc->readIntReg(INTREG_DEC) == 0 && msr.ee) { - si = true; - return true; - } - else if (tc->readIntReg(INTREG_DEC) == 0 && !msr.ee) { + Msr msr = tc->readIntReg(INTREG_MSR); + tc->setIntReg(INTREG_TB , tc->readIntReg(INTREG_TB)+1); + if (tc->readIntReg(INTREG_DEC) != 0) + tc->setIntReg(INTREG_DEC , tc->readIntReg(INTREG_DEC)-1); + else + interrupts[Decrementer] = 1; + if (msr.ee) + { + for (int i = 0; i < NumInterruptLevels; i++) { + if (interrupts[i] == 1) + return true; + } + } + if (interrupts[DirHypDoorbell] && (!msr.hv || msr.pr)) + return true; return false; - } else { - tc->setIntReg(INTREG_DEC , tc->readIntReg(INTREG_DEC)-1); - return false; - } } Fault getInterrupt(ThreadContext *tc) { assert(checkInterrupts(tc)); - if (si) - return std::make_shared(); + if (interrupts[Decrementer]) { + clear(Decrementer,0); + return std::make_shared(); + } + else if (interrupts[DirPriDoorbell]) { + clear(DirPriDoorbell,0); + return std::make_shared(); + } + else if (interrupts[DirHypDoorbell]) { + clear(DirHypDoorbell,0); + return std::make_shared(); + } else return NoFault; } @@ -115,7 +149,6 @@ class Interrupts : public SimObject updateIntrInfo(ThreadContext *tc) { tc->setIntReg(INTREG_DEC , 0xffffffffffffffff); - si = false; } }; diff --git a/src/arch/power/system.cc b/src/arch/power/system.cc index 1df07a506..b54d3c4ec 100644 --- a/src/arch/power/system.cc +++ b/src/arch/power/system.cc @@ -80,4 +80,9 @@ PowerSystem::initState() //ArgumentReg0 is initialized with 0xc00000 because in linux/system.cc //dtb is loaded at 0xc00000 tc->setIntReg(ArgumentReg0, 0x1800000); + ThreadID tid = 1; + ThreadContext *tc1 = threadContexts[tid]; + tc1->pcState(0xc00000000000a840); + tc1->setIntReg(ArgumentReg0, 0x1); + tc1->setIntReg(INTREG_PIR,0x1); } diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py index 9a2506778..3c7f233f1 100644 --- a/src/cpu/BaseCPU.py +++ b/src/cpu/BaseCPU.py @@ -141,7 +141,7 @@ class BaseCPU(MemObject): system = Param.System(Parent.any, "system object") cpu_id = Param.Int(-1, "CPU identifier") socket_id = Param.Unsigned(0, "Physical Socket identifier") - numThreads = Param.Unsigned(1, "number of HW thread contexts") + numThreads = Param.Unsigned(2, "number of HW thread contexts") pwr_gating_latency = Param.Cycles(300, "Latency to enter power gating state when all contexts are suspended") diff --git a/src/cpu/base.cc b/src/cpu/base.cc index c576f1def..2d6e4765f 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -467,7 +467,8 @@ void BaseCPU::registerThreadContexts() { assert(system->multiThread || numThreads == 1); - + printf("System in multithread: %d\n",system->multiThread ); + printf("NumThreads:: %d\n",numThreads ); ThreadID size = threadContexts.size(); for (ThreadID tid = 0; tid < size; ++tid) { ThreadContext *tc = threadContexts[tid]; diff --git a/src/sim/system.cc b/src/sim/system.cc index 74bc94ee8..dc4d3f7c3 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -300,8 +300,9 @@ void System::initState() { if (FullSystem) { - for (int i = 0; i < threadContexts.size(); i++) - TheISA::startupCPU(threadContexts[i], i); + for (int i = 0; i < threadContexts.size(); i++){ + printf("[LOG]: Starting CPU with id %d\n",i); + TheISA::startupCPU(threadContexts[i], i);} // Moved from the constructor to here since it relies on the // address map being resolved in the interconnect /** -- 2.30.2