X86: Tell the function that sends int messages who to send to instead of figuring...
authorGabe Black <gblack@eecs.umich.edu>
Sun, 26 Apr 2009 09:09:27 +0000 (02:09 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Sun, 26 Apr 2009 09:09:27 +0000 (02:09 -0700)
src/arch/x86/interrupts.cc
src/dev/x86/i82094aa.cc
src/dev/x86/intdev.cc
src/dev/x86/intdev.hh

index 88d200b80a29a130a76316b232cb74484749ba16..1b7933036a87ac99439a1125355de55fc46cfda0 100644 (file)
@@ -510,11 +510,41 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
             bool timing = sys->getMemoryMode() == Enums::timing;
             // Be careful no updates of the delivery status bit get lost.
             regs[APIC_INTERRUPT_COMMAND_LOW] = low;
+            ApicList apics;
+            int numContexts = sys->numContexts();
             switch (low.destShorthand) {
               case 0:
-                pendingIPIs++;
-                intPort->sendMessage(message, timing);
-                newVal = regs[APIC_INTERRUPT_COMMAND_LOW];
+                if (message.deliveryMode == DeliveryMode::LowestPriority) {
+                    panic("Lowest priority delivery mode "
+                            "IPIs aren't implemented.\n");
+                }
+                if (message.destMode == 1) {
+                    int dest = message.destination;
+                    hack_once("Assuming logical destinations are 1 << id.\n");
+                    for (int i = 0; i < numContexts; i++) {
+                        if (dest & 0x1)
+                            apics.push_back(i);
+                        dest = dest >> 1;
+                    }
+                } else {
+                    if (message.destination == 0xFF) {
+                        for (int i = 0; i < numContexts; i++) {
+                            if (i == initialApicId) {
+                                requestInterrupt(message.vector,
+                                        message.deliveryMode, message.trigger);
+                            } else {
+                                apics.push_back(i);
+                            }
+                        }
+                    } else {
+                        if (message.destination == initialApicId) {
+                            requestInterrupt(message.vector,
+                                    message.deliveryMode, message.trigger);
+                        } else {
+                            apics.push_back(message.destination);
+                        }
+                    }
+                }
                 break;
               case 1:
                 newVal = val;
@@ -527,22 +557,17 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
                 // Fall through
               case 3:
                 {
-                    int numContexts = sys->numContexts();
-                    pendingIPIs += (numContexts - 1);
                     for (int i = 0; i < numContexts; i++) {
-                        int thisId = sys->getThreadContext(i)->contextId();
-                        if (thisId != initialApicId) {
-                            PacketPtr pkt = buildIntRequest(thisId, message);
-                            if (timing)
-                                intPort->sendMessageTiming(pkt, latency);
-                            else
-                                intPort->sendMessageAtomic(pkt);
+                        if (i != initialApicId) {
+                            apics.push_back(i);
                         }
                     }
                 }
-                newVal = regs[APIC_INTERRUPT_COMMAND_LOW];
                 break;
             }
+            pendingIPIs += apics.size();
+            intPort->sendMessage(apics, message, timing);
+            newVal = regs[APIC_INTERRUPT_COMMAND_LOW];
         }
         break;
       case APIC_LVT_TIMER:
index 3f0ed9e9610cd11a757ae5a0592ed674823eb2ce..ad9b29dd05cade9fa95b06facb73e0631e68dc12 100644 (file)
@@ -28,6 +28,7 @@
  * Authors: Gabe Black
  */
 
+#include "arch/x86/interrupts.hh"
 #include "arch/x86/intmessage.hh"
 #include "dev/x86/i82094aa.hh"
 #include "dev/x86/i8259.hh"
@@ -162,7 +163,38 @@ X86ISA::I82094AA::signalInterrupt(int line)
         message.destMode = entry.destMode;
         message.level = entry.polarity;
         message.trigger = entry.trigger;
-        intPort->sendMessage(message, sys->getMemoryMode() == Enums::timing);
+        ApicList apics;
+        int numContexts = sys->numContexts();
+        if (message.destMode == 0) {
+            if (message.deliveryMode == DeliveryMode::LowestPriority) {
+                panic("Lowest priority delivery mode from the "
+                        "IO APIC aren't supported in physical "
+                        "destination mode.\n");
+            }
+            if (message.destination == 0xFF) {
+                for (int i = 0; i < numContexts; i++) {
+                    apics.push_back(i);
+                }
+            } else {
+                apics.push_back(message.destination);
+            }
+        } else {
+            for (int i = 0; i < numContexts; i++) {
+                std::map<int, Interrupts *>::iterator localApicIt =
+                    localApics.find(i);
+                assert(localApicIt != localApics.end());
+                Interrupts *localApic = localApicIt->second;
+                if ((localApic->readReg(APIC_LOGICAL_DESTINATION) >> 24) &
+                        message.destination) {
+                    apics.push_back(localApicIt->first);
+                }
+            }
+            if (message.deliveryMode == DeliveryMode::LowestPriority) {
+                panic("Lowest priority delivery mode is not implemented.\n");
+            }
+        }
+        intPort->sendMessage(apics, message,
+                sys->getMemoryMode() == Enums::timing);
     }
 }
 
index 10e50c13ed32b4bbc19d9842ec4d9545dde05d11..5bc6065f5b66f5600d4081e1ab2c5c6812e63c02 100644 (file)
 #include "dev/x86/intdev.hh"
 
 void
-X86ISA::IntDev::IntPort::sendMessage(TriggerIntMessage message, bool timing)
+X86ISA::IntDev::IntPort::sendMessage(ApicList apics,
+        TriggerIntMessage message, bool timing)
 {
-    if (DeliveryMode::isReserved(message.deliveryMode)) {
-        fatal("Tried to use reserved delivery mode %d\n",
-                message.deliveryMode);
-    } else if (DTRACE(IntDev)) {
-        DPRINTF(IntDev, "Delivery mode is: %s.\n",
-                DeliveryMode::names[message.deliveryMode]);
-        DPRINTF(IntDev, "Vector is %#x.\n", message.vector);
-    }
-    if (message.destMode == 0) {
-        DPRINTF(IntDev,
-                "Sending interrupt to APIC ID %d.\n", message.destination);
-        PacketPtr pkt = buildIntRequest(message.destination, message);
-        if (timing) {
+    ApicList::iterator apicIt;
+    for (apicIt = apics.begin(); apicIt != apics.end(); apicIt++) {
+        PacketPtr pkt = buildIntRequest(*apicIt, message);
+        if (timing)
             sendMessageTiming(pkt, latency);
-        } else {
+        else
             sendMessageAtomic(pkt);
-        }
-    } else {
-        DPRINTF(IntDev, "Sending interrupts to APIC IDs:"
-                "%s%s%s%s%s%s%s%s\n",
-                bits((int)message.destination, 0) ? " 0": "",
-                bits((int)message.destination, 1) ? " 1": "",
-                bits((int)message.destination, 2) ? " 2": "",
-                bits((int)message.destination, 3) ? " 3": "",
-                bits((int)message.destination, 4) ? " 4": "",
-                bits((int)message.destination, 5) ? " 5": "",
-                bits((int)message.destination, 6) ? " 6": "",
-                bits((int)message.destination, 7) ? " 7": ""
-                );
-        uint8_t dests = message.destination;
-        uint8_t id = 0;
-        while(dests) {
-            if (dests & 0x1) {
-                PacketPtr pkt = buildIntRequest(id, message);
-                if (timing)
-                    sendMessageTiming(pkt, latency);
-                else
-                    sendMessageAtomic(pkt);
-            }
-            dests >>= 1;
-            id++;
-        }
     }
 }
 
index 3a99783f78287f53f7724e88fc4a676861fe4b4a..c2c8057b98bd13e72ab1e59ac9be5f0fa26c2760 100644 (file)
 #include "params/X86IntSinkPin.hh"
 #include "params/X86IntLine.hh"
 
+#include <list>
+
 namespace X86ISA {
 
+typedef std::list<int> ApicList;
+
 class IntDev
 {
   protected:
@@ -78,7 +82,8 @@ class IntDev
 
         // This is x86 focused, so if this class becomes generic, this would
         // need to be moved into a subclass.
-        void sendMessage(TriggerIntMessage message, bool timing);
+        void sendMessage(ApicList apics,
+                TriggerIntMessage message, bool timing);
 
         void recvStatusChange(Status status)
         {