summaryrefslogtreecommitdiff
path: root/src/arch/alpha
diff options
context:
space:
mode:
authorMitch Hayenga <mitch.hayenga@arm.com>2016-07-21 17:19:15 +0100
committerMitch Hayenga <mitch.hayenga@arm.com>2016-07-21 17:19:15 +0100
commit8a476d387c84f037d0ccf3cc20dc88870ab45fec (patch)
tree341d4975740d91056a44b13bd43e10bf175d7166 /src/arch/alpha
parentd25b58036a040d8ac733b824e2865e1f5fe43e00 (diff)
downloadgem5-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/alpha')
-rw-r--r--src/arch/alpha/interrupts.hh68
1 files changed, 46 insertions, 22 deletions
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<InterruptFault>();
- } 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<InterruptFault>();
}
void