changeset 7539092b28ac in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=7539092b28ac
description:
        X86: Create a mechanism for the IO APIC to access I8259 vectors.

diffstat:

5 files changed, 16 insertions(+)
src/dev/x86/i82094aa.cc |    1 +
src/dev/x86/i82094aa.hh |    1 +
src/dev/x86/i8259.cc    |    9 +++++++++
src/dev/x86/i8259.hh    |    2 ++
src/dev/x86/intdev.hh   |    3 +++

diffs (242 lines):

diff -r f548d22a2f71 -r 7539092b28ac src/dev/x86/i82094aa.cc
--- a/src/dev/x86/i82094aa.cc   Sun Oct 12 13:51:48 2008 -0700
+++ b/src/dev/x86/i82094aa.cc   Sun Oct 12 13:54:57 2008 -0700
@@ -30,12 +30,13 @@
 
 #include "arch/x86/intmessage.hh"
 #include "dev/x86/i82094aa.hh"
+#include "dev/x86/i8259.hh"
 #include "mem/packet.hh"
 #include "mem/packet_access.hh"
 #include "sim/system.hh"
 
 X86ISA::I82094AA::I82094AA(Params *p) : PioDevice(p), IntDev(this),
-   latency(p->pio_latency), pioAddr(p->pio_addr)
+   latency(p->pio_latency), pioAddr(p->pio_addr), extIntPic(NULL)
 {
     // This assumes there's only one I/O APIC in the system
     id = sys->getNumCPUs();
@@ -145,24 +146,27 @@
         DPRINTF(I82094AA, "Entry was masked.\n");
         return;
     } else {
-        if (DTRACE(I82094AA)) {
-            if (DeliveryMode::isReserved(entry.deliveryMode)) {
-                fatal("Tried to use reserved delivery mode "
-                        "for IO APIC entry %d.\n", line);
-            } else {
-                DPRINTF(I82094AA, "Delivery mode is: %s.\n",
-                        DeliveryMode::names[entry.deliveryMode]);
-            }
-            DPRINTF(I82094AA, "Vector is %#x.\n", entry.vector);
-        }
-
         TriggerIntMessage message;
         message.destination = entry.dest;
-        message.vector = entry.vector;
+        if (entry.deliveryMode == DeliveryMode::ExtInt) {
+            assert(extIntPic);
+            message.vector = extIntPic->getVector();
+        } else {
+            message.vector = entry.vector;
+        }
         message.deliveryMode = entry.deliveryMode;
         message.destMode = entry.destMode;
         message.level = entry.polarity;
         message.trigger = entry.trigger;
+
+        if (DeliveryMode::isReserved(entry.deliveryMode)) {
+            fatal("Tried to use reserved delivery mode "
+                    "for IO APIC entry %d.\n", line);
+        } else if (DTRACE(I82094AA)) {
+            DPRINTF(I82094AA, "Delivery mode is: %s.\n",
+                    DeliveryMode::names[entry.deliveryMode]);
+            DPRINTF(I82094AA, "Vector is %#x.\n", message.vector);
+        }
 
         if (entry.destMode == 0) {
             DPRINTF(I82094AA,
diff -r f548d22a2f71 -r 7539092b28ac src/dev/x86/i82094aa.hh
--- a/src/dev/x86/i82094aa.hh   Sun Oct 12 13:51:48 2008 -0700
+++ b/src/dev/x86/i82094aa.hh   Sun Oct 12 13:54:57 2008 -0700
@@ -40,6 +40,8 @@
 namespace X86ISA
 {
 
+class I8259;
+
 class I82094AA : public PioDevice, public IntDev
 {
   public:
@@ -60,9 +62,10 @@
     EndBitUnion(RedirTableEntry)
 
   protected:
-    System * system;
     Tick latency;
     Addr pioAddr;
+
+    I8259 * extIntPic;
 
     uint8_t regSel;
     uint8_t id;
@@ -85,6 +88,12 @@
     }
 
     I82094AA(Params *p);
+
+    void
+    setExtIntPic(I8259 * pic)
+    {
+        extIntPic = pic;
+    }
 
     Tick read(PacketPtr pkt);
     Tick write(PacketPtr pkt);
diff -r f548d22a2f71 -r 7539092b28ac src/dev/x86/i8259.cc
--- a/src/dev/x86/i8259.cc      Sun Oct 12 13:51:48 2008 -0700
+++ b/src/dev/x86/i8259.cc      Sun Oct 12 13:54:57 2008 -0700
@@ -29,7 +29,27 @@
  */
 
 #include "base/bitfield.hh"
+#include "dev/x86/i82094aa.hh"
 #include "dev/x86/i8259.hh"
+
+X86ISA::I8259::I8259(Params * p) : BasicPioDevice(p), IntDev(this),
+                    latency(p->pio_latency), output(p->output),
+                    mode(p->mode), slave(NULL),
+                    IRR(0), ISR(0), IMR(0),
+                    readIRR(true), initControlWord(0)
+{
+    if (output) {
+        I8259 * master;
+        master = dynamic_cast<I8259 *>(output->getDevice());
+        if (master)
+            master->setSlave(this);
+        I82094AA * ioApic;
+        ioApic = dynamic_cast<I82094AA *>(output->getDevice());
+        if (ioApic)
+            ioApic->setExtIntPic(this);
+    }
+    pioSize = 2;
+}
 
 Tick
 X86ISA::I8259::read(PacketPtr pkt)
@@ -189,19 +209,44 @@
 X86ISA::I8259::signalInterrupt(int line)
 {
     DPRINTF(I8259, "Interrupt raised on line %d.\n", line);
-    if (line > 7)
-        fatal("Line number %d doesn't exist. The max is 7.\n");
+    if (line >= NumLines)
+        fatal("Line number %d doesn't exist. The max is %d.\n",
+                line, NumLines - 1);
     if (bits(IMR, line)) {
         DPRINTF(I8259, "Interrupt %d was masked.\n", line);
     } else {
-        if (output) {
-            DPRINTF(I8259, "Propogating interrupt.\n");
-            output->signalInterrupt();
-        } else {
-            warn("Received interrupt but didn't have "
-                    "anyone to tell about it.\n");
+        IRR |= 1 << line;
+        if (bits(ISR, 7, line) == 0) {
+            if (output) {
+                DPRINTF(I8259, "Propogating interrupt.\n");
+                output->signalInterrupt();
+            } else {
+                warn("Received interrupt but didn't have "
+                        "anyone to tell about it.\n");
+            }
         }
     }
+}
+
+int
+X86ISA::I8259::getVector()
+{
+    /*
+     * This code only handles one slave. Since that's how the PC platform
+     * always uses the 8259 PIC, there shouldn't be any need for more. If
+     * there -is- a need for more for some reason, "slave" can become a
+     * vector of slaves.
+     */
+    int line = findMsbSet(IRR);
+    IRR &= ~(1 << line);
+    DPRINTF(I8259, "Interrupt %d was accepted.\n", line);
+    ISR |= 1 << line;
+    if (slave && bits(cascadeBits, line)) {
+        DPRINTF(I8259, "Interrupt was from slave who will "
+                "provide the vector.\n");
+        return slave->getVector();
+    }
+    return line | vectorOffset;
 }
 
 X86ISA::I8259 *
diff -r f548d22a2f71 -r 7539092b28ac src/dev/x86/i8259.hh
--- a/src/dev/x86/i8259.hh      Sun Oct 12 13:51:48 2008 -0700
+++ b/src/dev/x86/i8259.hh      Sun Oct 12 13:54:57 2008 -0700
@@ -39,12 +39,17 @@
 namespace X86ISA
 {
 
+class I82094AA;
+
 class I8259 : public BasicPioDevice, public IntDev
 {
   protected:
+    static const int NumLines = 8;
+
     Tick latency;
     IntPin *output;
     Enums::X86I8259CascadeMode mode;
+    I8259 * slave;
 
     // Interrupt Request Register
     uint8_t IRR;
@@ -77,19 +82,19 @@
         return dynamic_cast<const Params *>(_params);
     }
 
-    I8259(Params * p) : BasicPioDevice(p), IntDev(this),
-                        latency(p->pio_latency), output(p->output),
-                        mode(p->mode), IRR(0), ISR(0), IMR(0),
-                        vectorOffset(0), readIRR(true), initControlWord(0)
+    I8259(Params * p);
+
+    void
+    setSlave(I8259 * _slave)
     {
-        pioSize = 2;
+        slave = _slave;
     }
 
     Tick read(PacketPtr pkt);
-
     Tick write(PacketPtr pkt);
 
     void signalInterrupt(int line);
+    int getVector();
 };
 
 }; // namespace X86ISA
diff -r f548d22a2f71 -r 7539092b28ac src/dev/x86/intdev.hh
--- a/src/dev/x86/intdev.hh     Sun Oct 12 13:51:48 2008 -0700
+++ b/src/dev/x86/intdev.hh     Sun Oct 12 13:54:57 2008 -0700
@@ -122,6 +122,12 @@
   public:
     typedef X86IntPinParams Params;
 
+    IntDev *
+    getDevice() const
+    {
+        return device;
+    }
+
     const Params *
     params() const
     {
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to