From 8a476d387c84f037d0ccf3cc20dc88870ab45fec Mon Sep 17 00:00:00 2001 From: Mitch Hayenga Date: Thu, 21 Jul 2016 17:19:15 +0100 Subject: isa: Modify get/check interrupt routines Make it so that getInterrupt *always* returns an interrupt if checkInterrupts() returns true. This fixes/simplifies handling of interrupts on the SMT FS CPUs (currently minor). --- src/arch/sparc/interrupts.hh | 56 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) (limited to 'src/arch/sparc') diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh index 8929759f3..e6c926676 100644 --- a/src/arch/sparc/interrupts.hh +++ b/src/arch/sparc/interrupts.hh @@ -121,12 +121,66 @@ class Interrupts : public SimObject 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); -- cgit v1.2.3