diff options
author | Mitch Hayenga <mitch.hayenga@arm.com> | 2016-07-21 17:19:15 +0100 |
---|---|---|
committer | Mitch Hayenga <mitch.hayenga@arm.com> | 2016-07-21 17:19:15 +0100 |
commit | 8a476d387c84f037d0ccf3cc20dc88870ab45fec (patch) | |
tree | 341d4975740d91056a44b13bd43e10bf175d7166 /src/arch/sparc | |
parent | d25b58036a040d8ac733b824e2865e1f5fe43e00 (diff) | |
download | gem5-8a476d387c84f037d0ccf3cc20dc88870ab45fec.tar.xz |
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).
Diffstat (limited to 'src/arch/sparc')
-rw-r--r-- | src/arch/sparc/interrupts.hh | 56 |
1 files changed, 55 insertions, 1 deletions
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); |