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)
{
+ assert(checkInterrupts(tc));
+
HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
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 (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 && pstate.ie
} // !hpriv
}
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);