summaryrefslogtreecommitdiff
path: root/src/dev/x86/i82094aa.cc
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-04-26 02:09:54 -0700
committerGabe Black <gblack@eecs.umich.edu>2009-04-26 02:09:54 -0700
commit06b3e3c303599e4227212638fa4778d115842eea (patch)
treefa55d4cc4058d9ddc87630603ef137856fe2a0c8 /src/dev/x86/i82094aa.cc
parent2f34a7eaeb6d82b745fbd57fa4cc31d874ed202c (diff)
downloadgem5-06b3e3c303599e4227212638fa4778d115842eea.tar.xz
X86: Implement lowest priority interrupts more correctly.
Lowest priority interrupts are now delivered based on a rotating offset into the list of potential recipients. There could be parasitic cases were a processor gets picked on and ends up at that rotating offset all the time, but it's much more likely that the group will stay consistent and the pain will be distributed evenly.
Diffstat (limited to 'src/dev/x86/i82094aa.cc')
-rw-r--r--src/dev/x86/i82094aa.cc20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/dev/x86/i82094aa.cc b/src/dev/x86/i82094aa.cc
index ad9b29dd0..ed936d0cb 100644
--- a/src/dev/x86/i82094aa.cc
+++ b/src/dev/x86/i82094aa.cc
@@ -38,7 +38,7 @@
X86ISA::I82094AA::I82094AA(Params *p) : PioDevice(p), IntDev(this),
latency(p->pio_latency), pioAddr(p->pio_addr),
- extIntPic(p->external_int_pic)
+ extIntPic(p->external_int_pic), lowestPriorityOffset(0)
{
// This assumes there's only one I/O APIC in the system
initialApicId = id = p->apic_id;
@@ -189,8 +189,22 @@ X86ISA::I82094AA::signalInterrupt(int line)
apics.push_back(localApicIt->first);
}
}
- if (message.deliveryMode == DeliveryMode::LowestPriority) {
- panic("Lowest priority delivery mode is not implemented.\n");
+ if (message.deliveryMode == DeliveryMode::LowestPriority &&
+ apics.size()) {
+ // The manual seems to suggest that the chipset just does
+ // something reasonable for these instead of actually using
+ // state from the local APIC. We'll just rotate an offset
+ // through the set of APICs selected above.
+ uint64_t modOffset = lowestPriorityOffset % apics.size();
+ lowestPriorityOffset++;
+ ApicList::iterator apicIt = apics.begin();
+ while (modOffset--) {
+ apicIt++;
+ assert(apicIt != apics.end());
+ }
+ int selected = *apicIt;
+ apics.clear();
+ apics.push_back(selected);
}
}
intPort->sendMessage(apics, message,