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/alpha/interrupts.hh | 68 ++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 22 deletions(-) (limited to 'src/arch/alpha') diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh index 1e67f54b5..61ac6c968 100644 --- a/src/arch/alpha/interrupts.hh +++ b/src/arch/alpha/interrupts.hh @@ -137,18 +137,18 @@ class Interrupts : public SimObject bool checkInterrupts(ThreadContext *tc) const { - return (intstatus != 0) && !(tc->pcState().pc() & 0x3); - } + if (intstatus == 0) + return false; - Fault - getInterrupt(ThreadContext *tc) - { - uint64_t ipl = 0; - uint64_t summary = 0; + if (tc->pcState().pc() & 0x3) + return false; if (tc->readMiscRegNoEffect(IPR_ASTRR)) panic("asynchronous traps not implemented\n"); + uint64_t ipl = 0; + uint64_t summary = 0; + if (tc->readMiscRegNoEffect(IPR_SIRR)) { for (uint64_t i = INTLEVEL_SOFTWARE_MIN; i < INTLEVEL_SOFTWARE_MAX; i++) { @@ -160,28 +160,52 @@ class Interrupts : public SimObject } } - if (intstatus) { - for (uint64_t i = INTLEVEL_EXTERNAL_MIN; - i < INTLEVEL_EXTERNAL_MAX; i++) { - if (intstatus & (ULL(1) << i)) { + for (uint64_t i = INTLEVEL_EXTERNAL_MIN; i < INTLEVEL_EXTERNAL_MAX; + i++) { + if (intstatus & (ULL(1) << i)) { + // See table 4-19 of 21164 hardware reference + ipl = i; + summary |= (ULL(1) << i); + } + } + + return ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR); + } + + Fault + getInterrupt(ThreadContext *tc) + { + assert(checkInterrupts(tc)); + + uint64_t ipl = 0; + uint64_t summary = 0; + if (tc->readMiscRegNoEffect(IPR_SIRR)) { + for (uint64_t i = INTLEVEL_SOFTWARE_MIN; + i < INTLEVEL_SOFTWARE_MAX; i++) { + if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) { // See table 4-19 of 21164 hardware reference - ipl = i; + ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; summary |= (ULL(1) << i); } } } - if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) { - newIpl = ipl; - newSummary = summary; - newInfoSet = true; - DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary); - - return std::make_shared(); - } else { - return NoFault; + for (uint64_t i = INTLEVEL_EXTERNAL_MIN; i < INTLEVEL_EXTERNAL_MAX; + i++) { + if (intstatus & (ULL(1) << i)) { + // See table 4-19 of 21164 hardware reference + ipl = i; + summary |= (ULL(1) << i); + } } + + newIpl = ipl; + newSummary = summary; + newInfoSet = true; + DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", + tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary); + + return std::make_shared(); } void -- cgit v1.2.3