summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-04-26 02:09:13 -0700
committerGabe Black <gblack@eecs.umich.edu>2009-04-26 02:09:13 -0700
commit88ab4bb257265cee555baafb940cee42c12f159a (patch)
tree93c5bd57602f49fbddcdd7fc1d0430d93dcd21fa /src
parentc5e2cf841d2502479a8f00c20ab70ab9ae325d69 (diff)
downloadgem5-88ab4bb257265cee555baafb940cee42c12f159a.tar.xz
X86: Make the local APICs register themselves with the IO APIC.
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.
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86/interrupts.cc13
-rw-r--r--src/arch/x86/interrupts.hh5
-rw-r--r--src/dev/x86/i82094aa.cc7
-rw-r--r--src/dev/x86/i82094aa.hh6
4 files changed, 31 insertions, 0 deletions
diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc
index dc4193f36..88d200b80 100644
--- a/src/arch/x86/interrupts.cc
+++ b/src/arch/x86/interrupts.cc
@@ -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)
{
diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh
index 33fafd941..e1bd676db 100644
--- a/src/arch/x86/interrupts.hh
+++ b/src/arch/x86/interrupts.hh
@@ -214,6 +214,11 @@ class Interrupts : public BasicPioDevice, IntDev
}
/*
+ * Initialize this object by registering it with the IO APIC.
+ */
+ void init();
+
+ /*
* Functions to interact with the interrupt port from IntDev.
*/
Tick read(PacketPtr pkt);
diff --git a/src/dev/x86/i82094aa.cc b/src/dev/x86/i82094aa.cc
index e55f1ec87..3f0ed9e96 100644
--- a/src/dev/x86/i82094aa.cc
+++ b/src/dev/x86/i82094aa.cc
@@ -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()
{
diff --git a/src/dev/x86/i82094aa.hh b/src/dev/x86/i82094aa.hh
index 7501259c1..e81d85fa9 100644
--- a/src/dev/x86/i82094aa.hh
+++ b/src/dev/x86/i82094aa.hh
@@ -37,10 +37,13 @@
#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