diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2009-04-26 02:06:21 -0700 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2009-04-26 02:06:21 -0700 |
commit | c5e2cf841d2502479a8f00c20ab70ab9ae325d69 (patch) | |
tree | cddec849e22944583155adb0400511c1773346e3 /src/arch/x86/interrupts.cc | |
parent | 8d84f81e7041bd26320b0795800100f2aa298965 (diff) | |
download | gem5-c5e2cf841d2502479a8f00c20ab70ab9ae325d69.tar.xz |
X86: Record the initial APIC ID which identifies an APIC in M5.
The ID as exposed to software can be changed. Tracking those changes in M5
would be cumbersome, especially since there's no guarantee the IDs will remain
unique.
Diffstat (limited to 'src/arch/x86/interrupts.cc')
-rw-r--r-- | src/arch/x86/interrupts.cc | 36 |
1 files changed, 16 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)); |