From 1f4b0e1c2e16c46bfe7c3f35420f84d77a507bde Mon Sep 17 00:00:00 2001 From: Phanikiran Harithas Date: Sun, 10 Jun 2018 14:31:05 +0530 Subject: [PATCH] power: Add support for handling the Decrementer Interrupt This patch allows the programming of the decrementer device, which will count down to zero. As of now, the decrement happens after every instruction. When the decrementer value hits 0, the CPU is delivered a decrementer interrupt. [ego@linux.vnet.ibm.com: Fixed Conflicts in src/arch/power/interrupts.hh] Change-Id: I3a863a8e2bca434d5a8139df662429d3e83a8542 Signed-off-by: Phanikiran Harithas Signed-off-by: Venkatnarayan Kulkarni --- src/arch/power/faults.hh | 48 ++++++++++++++++++++++++++++++------ src/arch/power/interrupts.hh | 27 ++++++++++++++++---- src/arch/power/system.cc | 6 +++++ 3 files changed, 68 insertions(+), 13 deletions(-) diff --git a/src/arch/power/faults.hh b/src/arch/power/faults.hh index e20ef8eb5..9667639f2 100644 --- a/src/arch/power/faults.hh +++ b/src/arch/power/faults.hh @@ -30,17 +30,18 @@ #ifndef __ARCH_POWER_FAULTS_HH__ #define __ARCH_POWER_FAULTS_HH__ +#include "cpu/thread_context.hh" #include "sim/faults.hh" namespace PowerISA { -class PowerFault : public FaultBase +class PowerFaultBase : public FaultBase { protected: FaultName _name; - PowerFault(FaultName name) + PowerFaultBase(FaultName name) : _name(name) { } @@ -53,35 +54,66 @@ class PowerFault : public FaultBase }; -class UnimplementedOpcodeFault : public PowerFault +class UnimplementedOpcodeFault : public PowerFaultBase { public: UnimplementedOpcodeFault() - : PowerFault("Unimplemented Opcode") + : PowerFaultBase("Unimplemented Opcode") { } }; -class MachineCheckFault : public PowerFault +class MachineCheckFault : public PowerFaultBase { public: MachineCheckFault() - : PowerFault("Machine Check") + : PowerFaultBase("Machine Check") { } }; -class AlignmentFault : public PowerFault +class AlignmentFault : public PowerFaultBase { public: AlignmentFault() - : PowerFault("Alignment") + : PowerFaultBase("Alignment") { } }; + +class PowerInterrupt : public PowerFaultBase +{ + public: + PowerInterrupt() + : PowerFaultBase("Interrupt") + { + } +}; + + +class DecrementerInterrupt : public PowerInterrupt +{ + public: + DecrementerInterrupt() + { + } + virtual void invoke(ThreadContext * tc, const StaticInstPtr &inst = + StaticInst::nullStaticInstPtr) + { + Msr msr = tc->readIntReg(MISCREG_MSR); + // Refer Power ISA Manual v3.0B Book-III, section 6.5.11 + tc->setIntReg(INTREG_SRR0 , tc->instAddr()); + uint64_t srr1 = msr & 0xffffffff78fc0fff; + tc->setIntReg(INTREG_SRR1 , srr1); + msr = msr & 0xffffffffffff76cd; + tc->setIntReg(INTREG_MSR , msr); + tc->pcState(0x900); + } +}; + } // namespace PowerISA #endif // __ARCH_POWER_FAULTS_HH__ diff --git a/src/arch/power/interrupts.hh b/src/arch/power/interrupts.hh index 29e665cae..ead82dd70 100644 --- a/src/arch/power/interrupts.hh +++ b/src/arch/power/interrupts.hh @@ -30,6 +30,8 @@ #define __ARCH_POWER_INTERRUPT_HH__ #include "arch/generic/interrupts.hh" +#include "arch/power/faults.hh" +#include "arch/power/registers.hh" #include "base/logging.hh" #include "params/PowerInterrupts.hh" @@ -40,6 +42,10 @@ namespace PowerISA { class Interrupts : public BaseInterrupts { + private: + BaseCPU * cpu; + bool si = false; + public: typedef PowerInterruptsParams Params; @@ -70,22 +76,33 @@ class Interrupts : public BaseInterrupts } bool - checkInterrupts() const + checkInterrupts(ThreadContext *tc) { - panic("Interrupts::checkInterrupts not implemented.\n"); + //panic("Interrupts::checkInterrupts not implemented.\n"); + if ( tc->readIntReg(INTREG_DEC) == 0) { + si = true; + return true; + } + else { + tc->setIntReg(INTREG_DEC , tc->readIntReg(INTREG_DEC)-1); + return false; + } } Fault getInterrupt() { - assert(checkInterrupts()); - panic("Interrupts::getInterrupt not implemented.\n"); + assert(checkInterrupts(tc)); + if (si) + return std::make_shared(); + else return NoFault; } void updateIntrInfo() { - panic("Interrupts::updateIntrInfo not implemented.\n"); + tc->setIntReg(INTREG_DEC , 0xffffffffffffffff); + si = false; } }; diff --git a/src/arch/power/system.cc b/src/arch/power/system.cc index c1a3bee3e..46ff26f48 100644 --- a/src/arch/power/system.cc +++ b/src/arch/power/system.cc @@ -71,5 +71,11 @@ PowerSystem::initState() //Sixty Four, little endian,Hypervisor bits are enabled. // IR and DR bits are disabled. Msr msr = 0x9000000000000001; + tc->setIntReg(INTREG_DEC , 0xffffffffffffffff); + // This PVR is specific to power9 + tc->setIntReg(INTREG_PVR , 0x004e1100); tc->setIntReg(INTREG_MSR , msr); + //ArgumentReg0 is initialized with 0xc00000 because in linux/system.cc + //dtb is loaded at 0xc00000 + tc->setIntReg(ArgumentReg0, 0x1800000); } -- 2.30.2