#include "arch/sparc/faults.hh"
#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/registers.hh"
#include "cpu/thread_context.hh"
+#include "debug/Interrupt.hh"
#include "params/SparcInterrupts.hh"
#include "sim/sim_object.hh"
namespace SparcISA
{
+enum InterruptTypes
+{
+ IT_TRAP_LEVEL_ZERO,
+ IT_HINTP,
+ IT_INT_VEC,
+ IT_CPU_MONDO,
+ IT_DEV_MONDO,
+ IT_RES_ERROR,
+ IT_SOFT_INT,
+ NumInterruptTypes
+};
+
class Interrupts : public SimObject
{
private:
bool
checkInterrupts(ThreadContext *tc) const
{
- return intStatus;
+ if (!intStatus)
+ return false;
+
+ HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
+ PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
+
+ // THESE ARE IN ORDER OF PRIORITY
+ // since there are early returns, and the highest
+ // priority interrupts should get serviced,
+ // it is v. important that new interrupts are inserted
+ // in the right order of processing
+ if (hpstate.hpriv) {
+ if (pstate.ie) {
+ if (interrupts[IT_HINTP]) {
+ // This will be cleaned by a HINTP write
+ return true;
+ }
+ if (interrupts[IT_INT_VEC]) {
+ // this will be cleared by an ASI read (or write)
+ return true;
+ }
+ }
+ } else {
+ if (interrupts[IT_TRAP_LEVEL_ZERO]) {
+ // this is cleared by deasserting HPSTATE::tlz
+ return true;
+ }
+ // HStick matches always happen in priv mode (ie doesn't matter)
+ if (interrupts[IT_HINTP]) {
+ return true;
+ }
+ if (interrupts[IT_INT_VEC]) {
+ // this will be cleared by an ASI read (or write)
+ return true;
+ }
+ if (pstate.ie) {
+ if (interrupts[IT_CPU_MONDO]) {
+ return true;
+ }
+ if (interrupts[IT_DEV_MONDO]) {
+ return true;
+ }
+ if (interrupts[IT_SOFT_INT]) {
+ return true;
+ }
+
+ if (interrupts[IT_RES_ERROR]) {
+ return true;
+ }
+ } // !hpriv && pstate.ie
+ } // !hpriv
+
+ return false;
}
Fault
getInterrupt(ThreadContext *tc)
{
- int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
- int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
- bool ie = pstate & PSTATE::ie;
+ assert(checkInterrupts(tc));
+
+ HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
+ PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
// THESE ARE IN ORDER OF PRIORITY
// since there are early returns, and the highest
// priority interrupts should get serviced,
// it is v. important that new interrupts are inserted
// in the right order of processing
- if (hpstate & HPSTATE::hpriv) {
- if (ie) {
+ if (hpstate.hpriv) {
+ if (pstate.ie) {
if (interrupts[IT_HINTP]) {
// This will be cleaned by a HINTP write
- return new HstickMatch;
+ return std::make_shared<HstickMatch>();
}
if (interrupts[IT_INT_VEC]) {
// this will be cleared by an ASI read (or write)
- return new InterruptVector;
+ return std::make_shared<InterruptVector>();
}
}
} else {
if (interrupts[IT_TRAP_LEVEL_ZERO]) {
// this is cleared by deasserting HPSTATE::tlz
- return new TrapLevelZero;
+ return std::make_shared<TrapLevelZero>();
}
// HStick matches always happen in priv mode (ie doesn't matter)
if (interrupts[IT_HINTP]) {
- return new HstickMatch;
+ return std::make_shared<HstickMatch>();
}
if (interrupts[IT_INT_VEC]) {
// this will be cleared by an ASI read (or write)
- return new InterruptVector;
+ return std::make_shared<InterruptVector>();
}
- if (ie) {
+ if (pstate.ie) {
if (interrupts[IT_CPU_MONDO]) {
- return new CpuMondo;
+ return std::make_shared<CpuMondo>();
}
if (interrupts[IT_DEV_MONDO]) {
- return new DevMondo;
+ return std::make_shared<DevMondo>();
}
if (interrupts[IT_SOFT_INT]) {
int level = InterruptLevel(interrupts[IT_SOFT_INT]);
- return new InterruptLevelN(level);
+ return std::make_shared<InterruptLevelN>(level);
}
if (interrupts[IT_RES_ERROR]) {
- return new ResumableError;
+ return std::make_shared<ResumableError>();
}
- } // !hpriv && ie
+ } // !hpriv && pstate.ie
} // !hpriv
return NoFault;
}
void
updateIntrInfo(ThreadContext *tc)
- {
-
- }
+ {}
uint64_t
get_vec(int int_num)
}
void
- serialize(std::ostream &os)
+ serialize(CheckpointOut &cp) const override
{
SERIALIZE_ARRAY(interrupts,NumInterruptTypes);
SERIALIZE_SCALAR(intStatus);
}
void
- unserialize(Checkpoint *cp, const std::string §ion)
+ unserialize(CheckpointIn &cp) override
{
UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes);
UNSERIALIZE_SCALAR(intStatus);