X86: Tell the function that sends int messages who to send to instead of figuring it out itself.
This commit is contained in:
parent
88ab4bb257
commit
2f34a7eaeb
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue