summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/interrupts.cc36
-rw-r--r--src/arch/x86/interrupts.hh2
2 files changed, 18 insertions, 20 deletions
diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc
index 60ea6215b..dc4193f36 100644
--- a/src/arch/x86/interrupts.cc
+++ b/src/arch/x86/interrupts.cc
@@ -295,17 +295,21 @@ X86ISA::Interrupts::requestInterrupt(uint8_t vector,
void
X86ISA::Interrupts::setCPU(BaseCPU * newCPU)
{
+ assert(newCPU);
+ if (cpu != NULL && cpu->cpuId() != newCPU->cpuId()) {
+ panic("Local APICs can't be moved between CPUs"
+ " with different IDs.\n");
+ }
cpu = newCPU;
- assert(cpu);
- regs[APIC_ID] = (cpu->cpuId() << 24);
+ initialApicId = cpu->cpuId();
+ regs[APIC_ID] = (initialApicId << 24);
}
Tick
X86ISA::Interrupts::recvMessage(PacketPtr pkt)
{
- uint8_t id = (regs[APIC_ID] >> 24);
- Addr offset = pkt->getAddr() - x86InterruptAddress(id, 0);
+ Addr offset = pkt->getAddr() - x86InterruptAddress(initialApicId, 0);
assert(pkt->cmd == MemCmd::MessageReq);
switch(offset)
{
@@ -315,9 +319,6 @@ X86ISA::Interrupts::recvMessage(PacketPtr pkt)
DPRINTF(LocalApic,
"Got Trigger Interrupt message with vector %#x.\n",
message.vector);
- // Make sure we're really supposed to get this.
- assert((message.destMode == 0 && message.destination == id) ||
- (bits((int)message.destination, id)));
requestInterrupt(message.vector,
message.deliveryMode, message.trigger);
@@ -354,10 +355,10 @@ X86ISA::Interrupts::recvResponse(PacketPtr pkt)
void
X86ISA::Interrupts::addressRanges(AddrRangeList &range_list)
{
- uint8_t id = (regs[APIC_ID] >> 24);
range_list.clear();
- Range<Addr> range = RangeEx(x86LocalAPICAddress(id, 0),
- x86LocalAPICAddress(id, 0) + PageBytes);
+ Range<Addr> range = RangeEx(x86LocalAPICAddress(initialApicId, 0),
+ x86LocalAPICAddress(initialApicId, 0) +
+ PageBytes);
range_list.push_back(range);
pioAddr = range.start;
}
@@ -366,10 +367,10 @@ X86ISA::Interrupts::addressRanges(AddrRangeList &range_list)
void
X86ISA::Interrupts::getIntAddrRange(AddrRangeList &range_list)
{
- uint8_t id = (regs[APIC_ID] >> 24);
range_list.clear();
- range_list.push_back(RangeEx(x86InterruptAddress(id, 0),
- x86InterruptAddress(id, 0) + PhysAddrAPICRangeSize));
+ range_list.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
+ x86InterruptAddress(initialApicId, 0) +
+ PhysAddrAPICRangeSize));
}
@@ -515,14 +516,9 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
{
int numContexts = sys->numContexts();
pendingIPIs += (numContexts - 1);
- // We have no way to get at the thread context we're part
- // of, so we'll just have to go with the CPU for now.
- hack_once("Broadcast IPIs can't handle more than "
- "one context per CPU.\n");
- int myId = cpu->getContext(0)->contextId();
for (int i = 0; i < numContexts; i++) {
int thisId = sys->getThreadContext(i)->contextId();
- if (thisId != myId) {
+ if (thisId != initialApicId) {
PacketPtr pkt = buildIntRequest(thisId, message);
if (timing)
intPort->sendMessageTiming(pkt, latency);
@@ -589,7 +585,7 @@ X86ISA::Interrupts::Interrupts(Params * p) :
pendingInit(false), initVector(0),
pendingStartup(false), startupVector(0),
startedUp(false), pendingUnmaskableInt(false),
- pendingIPIs(0)
+ pendingIPIs(0), cpu(NULL)
{
pioSize = PageBytes;
memset(regs, 0, sizeof(regs));
diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh
index 72a852ada..33fafd941 100644
--- a/src/arch/x86/interrupts.hh
+++ b/src/arch/x86/interrupts.hh
@@ -191,6 +191,8 @@ class Interrupts : public BasicPioDevice, IntDev
BaseCPU *cpu;
+ int initialApicId;
+
public:
/*
* Params stuff.