X86: Make the local APICs register themselves with the IO APIC.
authorGabe Black <gblack@eecs.umich.edu>
Sun, 26 Apr 2009 09:09:13 +0000 (02:09 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Sun, 26 Apr 2009 09:09:13 +0000 (02:09 -0700)
This is a hack so that the IO APIC can figure out information about the local
APICs. The local APICs still have no way to find out about each other.
Ideally, when the local APICs update state that's relevant to somebody else,
they'd send an update to everyone. Without being able to do a broadcast, that
would still require knowing who else there is to notify. Other broadcasts are
implemented using assumptions that may not always be true.

src/arch/x86/interrupts.cc
src/arch/x86/interrupts.hh
src/dev/x86/i82094aa.cc
src/dev/x86/i82094aa.hh

index dc4193f363169e786b69201905bafe90d4e418ac..88d200b80a29a130a76316b232cb74484749ba16 100644 (file)
@@ -59,6 +59,9 @@
 #include "arch/x86/interrupts.hh"
 #include "arch/x86/intmessage.hh"
 #include "cpu/base.hh"
+#include "dev/x86/i82094aa.hh"
+#include "dev/x86/pc.hh"
+#include "dev/x86/south_bridge.hh"
 #include "mem/packet_access.hh"
 #include "sim/system.hh"
 
@@ -306,6 +309,16 @@ X86ISA::Interrupts::setCPU(BaseCPU * newCPU)
 }
 
 
+void
+X86ISA::Interrupts::init()
+{
+    BasicPioDevice::init();
+    Pc * pc = dynamic_cast<Pc *>(platform);
+    assert(pc);
+    pc->southBridge->ioApic->registerLocalApic(initialApicId, this);
+}
+
+
 Tick
 X86ISA::Interrupts::recvMessage(PacketPtr pkt)
 {
index 33fafd9415a147dffc4c1ae811669e2219d63b78..e1bd676dbfa705f2eb56bac5aa33a2e7aa183db0 100644 (file)
@@ -213,6 +213,11 @@ class Interrupts : public BasicPioDevice, IntDev
         return dynamic_cast<const Params *>(_params);
     }
 
+    /*
+     * Initialize this object by registering it with the IO APIC.
+     */
+    void init();
+
     /*
      * Functions to interact with the interrupt port from IntDev.
      */
index e55f1ec87fb329010caf530f0ce0e4be324ecd2e..3f0ed9e9610cd11a757ae5a0592ed674823eb2ce 100644 (file)
@@ -182,6 +182,13 @@ X86ISA::I82094AA::lowerInterruptPin(int number)
     pinStates[number] = false;
 }
 
+void
+X86ISA::I82094AA::registerLocalApic(int initialId, Interrupts *localApic)
+{
+    assert(localApic);
+    localApics[initialId] = localApic;
+}
+
 X86ISA::I82094AA *
 I82094AAParams::create()
 {
index 7501259c12bacfe44a418b87e4b0ce1d0a9b59e9..e81d85fa9c9ef765e3585df123eb4a7cc1225fb8 100644 (file)
 #include "dev/x86/intdev.hh"
 #include "params/I82094AA.hh"
 
+#include <map>
+
 namespace X86ISA
 {
 
 class I8259;
+class Interrupts;
 
 class I82094AA : public PioDevice, public IntDev
 {
@@ -67,6 +70,8 @@ class I82094AA : public PioDevice, public IntDev
 
     I8259 * extIntPic;
 
+    std::map<int, Interrupts *> localApics;
+
     uint8_t regSel;
     uint8_t initialApicId;
     uint8_t id;
@@ -122,6 +127,7 @@ class I82094AA : public PioDevice, public IntDev
     void signalInterrupt(int line);
     void raiseInterruptPin(int number);
     void lowerInterruptPin(int number);
+    void registerLocalApic(int id, Interrupts *localApic);
 };
 
 }; // namespace X86ISA