diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2009-04-19 03:56:24 -0700 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2009-04-19 03:56:24 -0700 |
commit | 4d32cd10ce5543fcec1ffb21d5e66c510d29e24d (patch) | |
tree | 205a0c82dfe1088338dc55026097cd42ea8eac71 /src/arch | |
parent | bdda224d4110dd8ebb6224bfa9bc2641957a8c57 (diff) | |
download | gem5-4d32cd10ce5543fcec1ffb21d5e66c510d29e24d.tar.xz |
X86: Use recvResponse to implement the idle bit in the Local APIC ICR.
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/x86/interrupts.cc | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index 9ac4b20ba..c247d9ebc 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -332,6 +332,22 @@ X86ISA::Interrupts::recvMessage(PacketPtr pkt) } +Tick +X86ISA::Interrupts::recvResponse(PacketPtr pkt) +{ + assert(!pkt->isError()); + assert(pkt->cmd == MemCmd::MessageResp); + InterruptCommandRegLow low = regs[APIC_INTERRUPT_COMMAND_LOW]; + // Record that the ICR is now idle. + low.deliveryStatus = 0; + regs[APIC_INTERRUPT_COMMAND_LOW] = low; + delete pkt->req; + delete pkt; + DPRINTF(LocalApic, "ICR is now idle.\n"); + return 0; +} + + void X86ISA::Interrupts::addressRanges(AddrRangeList &range_list) { @@ -475,9 +491,12 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val) message.level = low.level; message.trigger = low.trigger; bool timing = sys->getMemoryMode() == Enums::timing; + // Be careful no updates of the delivery status bit get lost. + regs[APIC_INTERRUPT_COMMAND_LOW] = low; switch (low.destShorthand) { case 0: intPort->sendMessage(message, timing); + newVal = regs[APIC_INTERRUPT_COMMAND_LOW]; break; case 1: panic("Self IPIs aren't implemented.\n"); |