341,344c341,346
< InterruptCommandRegLow low = regs[APIC_INTERRUPT_COMMAND_LOW];
< // Record that the ICR is now idle.
< low.deliveryStatus = 0;
< regs[APIC_INTERRUPT_COMMAND_LOW] = low;
---
> if (--pendingIPIs == 0) {
> InterruptCommandRegLow low = regs[APIC_INTERRUPT_COMMAND_LOW];
> // Record that the ICR is now idle.
> low.deliveryStatus = 0;
> regs[APIC_INTERRUPT_COMMAND_LOW] = low;
> }
498a501
> pendingIPIs++;
503c506,508
< panic("Self IPIs aren't implemented.\n");
---
> newVal = val;
> requestInterrupt(message.vector,
> message.deliveryMode, message.trigger);
506,507c511,513
< panic("Broadcast including self IPIs aren't implemented.\n");
< break;
---
> requestInterrupt(message.vector,
> message.deliveryMode, message.trigger);
> // Fall through
509c515,534
< panic("Broadcast excluding self IPIs aren't implemented.\n");
---
> {
> 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) {
> PacketPtr pkt = buildIntRequest(thisId, message);
> if (timing)
> intPort->sendMessageTiming(pkt, latency);
> else
> intPort->sendMessageAtomic(pkt);
> }
> }
> }
> newVal = regs[APIC_INTERRUPT_COMMAND_LOW];
566c591,592
< startedUp(false), pendingUnmaskableInt(false)
---
> startedUp(false), pendingUnmaskableInt(false),
> pendingIPIs(0)