X86: Hook the CMOS device to the I8259 PICs.
authorGabe Black <gblack@eecs.umich.edu>
Sat, 11 Oct 2008 08:31:32 +0000 (01:31 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Sat, 11 Oct 2008 08:31:32 +0000 (01:31 -0700)
src/dev/x86/Cmos.py
src/dev/x86/I8259.py
src/dev/x86/PC.py
src/dev/x86/cmos.cc
src/dev/x86/cmos.hh
src/dev/x86/i8259.cc
src/dev/x86/i8259.hh

index c786eda36a6fba5ddd63264b5247203e2b9c03c8..810432035c5960f64c30ac2bb3f797fd06bcf86b 100644 (file)
@@ -29,6 +29,7 @@
 from m5.params import *
 from m5.proxy import *
 from Device import BasicPioDevice
+from I8259 import I8259
 
 class Cmos(BasicPioDevice):
     type = 'Cmos'
@@ -36,3 +37,6 @@ class Cmos(BasicPioDevice):
     time = Param.Time('01/01/2009',
         "System time to use ('Now' for actual time)")
     pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
+    i8259 = Param.I8259('PIC to send RTC alarm interrupts to')
+    int_line = Param.Int(0,
+            'PIC relative interrupt line to use for alarm interrupts')
index a599a5b3ccbafa0805c2acdeaf290a139ff00e48..19670dde99c34c16e11c245b8b6937e78c23dd81 100644 (file)
@@ -34,4 +34,4 @@ class I8259(BasicPioDevice):
     type = 'I8259'
     cxx_class='X86ISA::I8259'
     pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
-    master = Param.Bool(True, 'If this PIC is the master or slave')
+    master = Param.I8259('The master PIC this PIC is cascaded with, if any')
index d0516ec13f9c13964a4ab35c41baa86c0fa000c8..d3d3118c61b02ae747c38dc103a68df5ab38ccee 100644 (file)
@@ -49,9 +49,9 @@ class PC(Platform):
     pciconfig = PciConfigAll()
 
     south_bridge = SouthBridge()
-    cmos = Cmos(pio_addr=x86IOAddress(0x70))
-    pic1 = I8259(pio_addr=x86IOAddress(0x20), master=True)
-    pic2 = I8259(pio_addr=x86IOAddress(0xA0), master=False)
+    pic1 = I8259(pio_addr=x86IOAddress(0x20))
+    pic2 = I8259(pio_addr=x86IOAddress(0xA0), master=pic1)
+    cmos = Cmos(pio_addr=x86IOAddress(0x70), i8259=pic2)
 
     # "Non-existant" port used for timing purposes by the linux kernel
     i_dont_exist = IsaFake(pio_addr=x86IOAddress(0x80), pio_size=1)
index 5bbded2605545f0c9ed02ddd3908e1ef7d5dfa32..d4ec58ddb3f57495015cf40c1dfc7e9d43541db8 100644 (file)
  */
 
 #include "dev/x86/cmos.hh"
+#include "dev/x86/i8259.hh"
 #include "mem/packet_access.hh"
 
+void
+X86ISA::Cmos::X86RTC::handleEvent()
+{
+    i8259->signalInterrupt(intLine);
+}
+
 Tick
 X86ISA::Cmos::read(PacketPtr pkt)
 {
index 04df9dd04374128b15552b4dc18a0c63b0360ad2..337fb8b020f2b6cb812dfadffdb0570c7744446b 100644 (file)
@@ -38,6 +38,8 @@
 namespace X86ISA
 {
 
+class I8259;
+
 class Cmos : public BasicPioDevice
 {
   protected:
@@ -54,24 +56,26 @@ class Cmos : public BasicPioDevice
 
     class X86RTC : public MC146818
     {
+      protected:
+        I8259 * i8259;
+        int intLine;
       public:
         X86RTC(EventManager *em, const std::string &n, const struct tm time,
-                bool bcd, Tick frequency) :
-            MC146818(em, n, time, bcd, frequency)
+                bool bcd, Tick frequency, I8259 *_i8259, int _intLine) :
+            MC146818(em, n, time, bcd, frequency),
+            i8259(_i8259), intLine(_intLine)
         {
         }
       protected:
-        void handleEvent()
-        {
-            return;
-        }
+        void handleEvent();
     } rtc;
 
   public:
     typedef CmosParams Params;
 
     Cmos(const Params *p) : BasicPioDevice(p), latency(p->pio_latency),
-        rtc(this, "rtc", p->time, true, ULL(5000000000))
+        rtc(this, "rtc", p->time, true, ULL(5000000000),
+                p->i8259, p->int_line)
     {
         pioSize = 2;
         memset(regs, 0, numRegs * sizeof(uint8_t));
index ed9b429c8342248ccd3a63c1db2939ffec2a29ed..2dd6caaff007280485db724fc95b1a5cbbf56809 100644 (file)
@@ -133,12 +133,13 @@ X86ISA::I8259::write(PacketPtr pkt)
             if (cascadeMode) {
                 initControlWord++;
             } else {
+                cascadeBits = 0;
                 initControlWord = 0;
             }
             break;
           case 0x2:
             DPRINTF(I8259, "Received initialization command word 3.\n");
-            if (master) {
+            if (master == NULL) {
                 DPRINTF(I8259, "Slaves attached to IRQs:%s%s%s%s%s%s%s%s\n",
                         bits(val, 0) ? " 0" : "",
                         bits(val, 1) ? " 1" : "",
@@ -148,8 +149,10 @@ X86ISA::I8259::write(PacketPtr pkt)
                         bits(val, 5) ? " 5" : "",
                         bits(val, 6) ? " 6" : "",
                         bits(val, 7) ? " 7" : "");
+                cascadeBits = val;
             } else {
                 DPRINTF(I8259, "Slave ID is %d.\n", val & mask(3));
+                cascadeBits = val & mask(3);
             }
             if (expectICW4)
                 initControlWord++;
@@ -181,6 +184,20 @@ X86ISA::I8259::write(PacketPtr pkt)
     return latency;
 }
 
+void
+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 (bits(IMR, line)) {
+        DPRINTF(I8259, "Interrupt %d was masked.\n", line);
+    } else if (master != NULL) {
+        DPRINTF(I8259, "Propogating interrupt to master.\n");
+        master->signalInterrupt(cascadeBits);
+    }
+}
+
 X86ISA::I8259 *
 I8259Params::create()
 {
index 131adc93f3e8dc6db0f0bd008e466202a834399a..c51ab1a6a69bd9df14dc2f89f8711d8560aa2037 100644 (file)
@@ -41,7 +41,7 @@ class I8259 : public BasicPioDevice
 {
   protected:
     Tick latency;
-    bool master;
+    I8259 *master;
 
     // Interrupt Request Register
     uint8_t IRR;
@@ -50,10 +50,16 @@ class I8259 : public BasicPioDevice
     // Interrupt Mask Register
     uint8_t IMR;
 
-    bool edgeTriggered;
     bool cascadeMode;
-    bool expectICW4;
+    // A bit vector of lines with slaves attached, or the slave id, depending
+    // on if this is a master or slave PIC.
+    uint8_t cascadeBits;
+
+    bool edgeTriggered;
     bool readIRR;
+
+    // State machine information for reading in initialization control words.
+    bool expectICW4;
     int initControlWord;
 
   public:
@@ -77,6 +83,8 @@ class I8259 : public BasicPioDevice
     Tick read(PacketPtr pkt);
 
     Tick write(PacketPtr pkt);
+
+    void signalInterrupt(int line);
 };
 
 }; // namespace X86ISA