X86: Make the I8259 PIC accept a specific EOI command.
authorGabe Black <gblack@eecs.umich.edu>
Mon, 13 Oct 2008 06:22:58 +0000 (23:22 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Mon, 13 Oct 2008 06:22:58 +0000 (23:22 -0700)
src/dev/x86/i8259.cc
src/dev/x86/i8259.hh

index be0bfbe4d3919162f12db47663cc6c5f4a618174..3b0053ee9c0dfe465363f85cd66c30a6c679a2c8 100644 (file)
@@ -107,8 +107,12 @@ X86ISA::I8259::write(PacketPtr pkt)
                 DPRINTF(I8259, "Subcommand: No operation.\n");
                 break;
               case 0x3:
-                DPRINTF(I8259, "Subcommand: Specific EIO.");
-                DPRINTF(I8259, "Reset In-Service bit %d.\n", bits(val, 2, 0));
+                {
+                    int line = bits(val, 2, 0);
+                    DPRINTF(I8259, "Subcommand: Specific EIO on line %d.\n",
+                            line);
+                    handleEOI(line);
+                }
                 break;
               case 0x4:
                 DPRINTF(I8259, "Subcommand: Rotate in auto-EOI mode (set).\n");
@@ -205,6 +209,30 @@ X86ISA::I8259::write(PacketPtr pkt)
     return latency;
 }
 
+void
+X86ISA::I8259::handleEOI(int line)
+{
+    ISR &= ~(1 << line);
+    // There may be an interrupt that was waiting which can
+    // now be sent.
+    if (IRR)
+        requestInterrupt(findMsbSet(IRR));
+}
+
+void
+X86ISA::I8259::requestInterrupt(int 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");
+        }
+    }
+}
+
 void
 X86ISA::I8259::signalInterrupt(int line)
 {
@@ -216,15 +244,7 @@ X86ISA::I8259::signalInterrupt(int line)
         DPRINTF(I8259, "Interrupt %d was masked.\n", line);
     } else {
         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");
-            }
-        }
+        requestInterrupt(line);
     }
 }
 
index 371a27874c7d4a80718ff799006c56e4ff984611..6f6d3f038daf8e57a42f15e3b3765e648e02476d 100644 (file)
@@ -73,6 +73,9 @@ class I8259 : public BasicPioDevice, public IntDev
     bool expectICW4;
     int initControlWord;
 
+    void requestInterrupt(int line);
+    void handleEOI(int line);
+
   public:
     typedef I8259Params Params;