From 6e8a1f853dc5ae6f5389efaa583a8a37a3bcb99e 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 | 22 ++++++++++++++--- src/arch/power/system.cc | 6 +++++ 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/src/arch/power/faults.hh b/src/arch/power/faults.hh index a99ae7b30..bfb4dd00f 100644 --- a/src/arch/power/faults.hh +++ b/src/arch/power/faults.hh @@ -33,17 +33,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) { } @@ -56,35 +57,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 f89959863..40f5c3fce 100644 --- a/src/arch/power/interrupts.hh +++ b/src/arch/power/interrupts.hh @@ -31,6 +31,8 @@ #ifndef __ARCH_POWER_INTERRUPT_HH__ #define __ARCH_POWER_INTERRUPT_HH__ +#include "arch/power/faults.hh" +#include "arch/power/registers.hh" #include "base/logging.hh" #include "params/PowerInterrupts.hh" #include "sim/sim_object.hh" @@ -44,6 +46,7 @@ class Interrupts : public SimObject { private: BaseCPU * cpu; + bool si = false; public: typedef PowerInterruptsParams Params; @@ -82,22 +85,33 @@ class Interrupts : public SimObject } bool - checkInterrupts(ThreadContext *tc) 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(ThreadContext *tc) { assert(checkInterrupts(tc)); - panic("Interrupts::getInterrupt not implemented.\n"); + if (si) + return std::make_shared(); + else return NoFault; } void updateIntrInfo(ThreadContext *tc) { - 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