From 4d32cd10ce5543fcec1ffb21d5e66c510d29e24d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 19 Apr 2009 03:56:24 -0700 Subject: [PATCH] X86: Use recvResponse to implement the idle bit in the Local APIC ICR. --- src/arch/x86/interrupts.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) 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");