X86: Tell the function that sends int messages who to send to instead of figuring it out itself.

This commit is contained in:
Gabe Black 2009-04-26 02:09:27 -07:00
parent 88ab4bb257
commit 2f34a7eaeb
4 changed files with 84 additions and 56 deletions

View file

@ -510,11 +510,41 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
bool timing = sys->getMemoryMode() == Enums::timing; bool timing = sys->getMemoryMode() == Enums::timing;
// Be careful no updates of the delivery status bit get lost. // Be careful no updates of the delivery status bit get lost.
regs[APIC_INTERRUPT_COMMAND_LOW] = low; regs[APIC_INTERRUPT_COMMAND_LOW] = low;
ApicList apics;
int numContexts = sys->numContexts();
switch (low.destShorthand) { switch (low.destShorthand) {
case 0: case 0:
pendingIPIs++; if (message.deliveryMode == DeliveryMode::LowestPriority) {
intPort->sendMessage(message, timing); panic("Lowest priority delivery mode "
newVal = regs[APIC_INTERRUPT_COMMAND_LOW]; "IPIs aren't implemented.\n");
}
if (message.destMode == 1) {
int dest = message.destination;
hack_once("Assuming logical destinations are 1 << id.\n");
for (int i = 0; i < numContexts; i++) {
if (dest & 0x1)
apics.push_back(i);
dest = dest >> 1;
}
} else {
if (message.destination == 0xFF) {
for (int i = 0; i < numContexts; i++) {
if (i == initialApicId) {
requestInterrupt(message.vector,
message.deliveryMode, message.trigger);
} else {
apics.push_back(i);
}
}
} else {
if (message.destination == initialApicId) {
requestInterrupt(message.vector,
message.deliveryMode, message.trigger);
} else {
apics.push_back(message.destination);
}
}
}
break; break;
case 1: case 1:
newVal = val; newVal = val;
@ -527,22 +557,17 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
// Fall through // Fall through
case 3: case 3:
{ {
int numContexts = sys->numContexts();
pendingIPIs += (numContexts - 1);
for (int i = 0; i < numContexts; i++) { for (int i = 0; i < numContexts; i++) {
int thisId = sys->getThreadContext(i)->contextId(); if (i != initialApicId) {
if (thisId != initialApicId) { apics.push_back(i);
PacketPtr pkt = buildIntRequest(thisId, message);
if (timing)
intPort->sendMessageTiming(pkt, latency);
else
intPort->sendMessageAtomic(pkt);
} }
} }
} }
newVal = regs[APIC_INTERRUPT_COMMAND_LOW];
break; break;
} }
pendingIPIs += apics.size();
intPort->sendMessage(apics, message, timing);
newVal = regs[APIC_INTERRUPT_COMMAND_LOW];
} }
break; break;
case APIC_LVT_TIMER: case APIC_LVT_TIMER:

View file

@ -28,6 +28,7 @@
* Authors: Gabe Black * Authors: Gabe Black
*/ */
#include "arch/x86/interrupts.hh"
#include "arch/x86/intmessage.hh" #include "arch/x86/intmessage.hh"
#include "dev/x86/i82094aa.hh" #include "dev/x86/i82094aa.hh"
#include "dev/x86/i8259.hh" #include "dev/x86/i8259.hh"
@ -162,7 +163,38 @@ X86ISA::I82094AA::signalInterrupt(int line)
message.destMode = entry.destMode; message.destMode = entry.destMode;
message.level = entry.polarity; message.level = entry.polarity;
message.trigger = entry.trigger; message.trigger = entry.trigger;
intPort->sendMessage(message, sys->getMemoryMode() == Enums::timing); ApicList apics;
int numContexts = sys->numContexts();
if (message.destMode == 0) {
if (message.deliveryMode == DeliveryMode::LowestPriority) {
panic("Lowest priority delivery mode from the "
"IO APIC aren't supported in physical "
"destination mode.\n");
}
if (message.destination == 0xFF) {
for (int i = 0; i < numContexts; i++) {
apics.push_back(i);
}
} else {
apics.push_back(message.destination);
}
} else {
for (int i = 0; i < numContexts; i++) {
std::map<int, Interrupts *>::iterator localApicIt =
localApics.find(i);
assert(localApicIt != localApics.end());
Interrupts *localApic = localApicIt->second;
if ((localApic->readReg(APIC_LOGICAL_DESTINATION) >> 24) &
message.destination) {
apics.push_back(localApicIt->first);
}
}
if (message.deliveryMode == DeliveryMode::LowestPriority) {
panic("Lowest priority delivery mode is not implemented.\n");
}
}
intPort->sendMessage(apics, message,
sys->getMemoryMode() == Enums::timing);
} }
} }

View file

@ -31,50 +31,16 @@
#include "dev/x86/intdev.hh" #include "dev/x86/intdev.hh"
void void
X86ISA::IntDev::IntPort::sendMessage(TriggerIntMessage message, bool timing) X86ISA::IntDev::IntPort::sendMessage(ApicList apics,
TriggerIntMessage message, bool timing)
{ {
if (DeliveryMode::isReserved(message.deliveryMode)) { ApicList::iterator apicIt;
fatal("Tried to use reserved delivery mode %d\n", for (apicIt = apics.begin(); apicIt != apics.end(); apicIt++) {
message.deliveryMode); PacketPtr pkt = buildIntRequest(*apicIt, message);
} else if (DTRACE(IntDev)) { if (timing)
DPRINTF(IntDev, "Delivery mode is: %s.\n",
DeliveryMode::names[message.deliveryMode]);
DPRINTF(IntDev, "Vector is %#x.\n", message.vector);
}
if (message.destMode == 0) {
DPRINTF(IntDev,
"Sending interrupt to APIC ID %d.\n", message.destination);
PacketPtr pkt = buildIntRequest(message.destination, message);
if (timing) {
sendMessageTiming(pkt, latency); sendMessageTiming(pkt, latency);
} else { else
sendMessageAtomic(pkt); sendMessageAtomic(pkt);
}
} else {
DPRINTF(IntDev, "Sending interrupts to APIC IDs:"
"%s%s%s%s%s%s%s%s\n",
bits((int)message.destination, 0) ? " 0": "",
bits((int)message.destination, 1) ? " 1": "",
bits((int)message.destination, 2) ? " 2": "",
bits((int)message.destination, 3) ? " 3": "",
bits((int)message.destination, 4) ? " 4": "",
bits((int)message.destination, 5) ? " 5": "",
bits((int)message.destination, 6) ? " 6": "",
bits((int)message.destination, 7) ? " 7": ""
);
uint8_t dests = message.destination;
uint8_t id = 0;
while(dests) {
if (dests & 0x1) {
PacketPtr pkt = buildIntRequest(id, message);
if (timing)
sendMessageTiming(pkt, latency);
else
sendMessageAtomic(pkt);
}
dests >>= 1;
id++;
}
} }
} }

View file

@ -43,8 +43,12 @@
#include "params/X86IntSinkPin.hh" #include "params/X86IntSinkPin.hh"
#include "params/X86IntLine.hh" #include "params/X86IntLine.hh"
#include <list>
namespace X86ISA { namespace X86ISA {
typedef std::list<int> ApicList;
class IntDev class IntDev
{ {
protected: protected:
@ -78,7 +82,8 @@ class IntDev
// This is x86 focused, so if this class becomes generic, this would // This is x86 focused, so if this class becomes generic, this would
// need to be moved into a subclass. // need to be moved into a subclass.
void sendMessage(TriggerIntMessage message, bool timing); void sendMessage(ApicList apics,
TriggerIntMessage message, bool timing);
void recvStatusChange(Status status) void recvStatusChange(Status status)
{ {