#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)
{
}
};
-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__
#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"
class Interrupts : public BaseInterrupts
{
+ private:
+ BaseCPU * cpu;
+ bool si = false;
+
public:
typedef PowerInterruptsParams Params;
}
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<DecrementerInterrupt>();
+ else return NoFault;
}
void
updateIntrInfo()
{
- panic("Interrupts::updateIntrInfo not implemented.\n");
+ tc->setIntReg(INTREG_DEC , 0xffffffffffffffff);
+ si = false;
}
};
//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);
}