Add support for PIC interrupts in IO, and DIRx interrupts in CChip
authorRon Dreslinski <rdreslin@umich.edu>
Thu, 29 Jan 2004 00:18:29 +0000 (19:18 -0500)
committerRon Dreslinski <rdreslin@umich.edu>
Thu, 29 Jan 2004 00:18:29 +0000 (19:18 -0500)
dev/tsunami_cchip.cc:
dev/tsunami_cchip.hh:
    Add Interrupt capabilities for DIRx, added postDRIR and clearDRIR
    functions
dev/tsunami_io.cc:
    Add PIC interrupts, and post/clearPIC functions
dev/tsunami_io.hh:
    Add support for PIC interrupts, added post/clearPIC functions

--HG--
extra : convert_revision : b705568670b157c1a4496c365226526fa96e21e0

dev/tsunami_cchip.cc
dev/tsunami_cchip.hh
dev/tsunami_io.cc
dev/tsunami_io.hh

index ffde4da98890d195aa16295d30550c56e95854d0..9c14bc3b099a3b91353f1bfc546afe6a8d0bbc91 100644 (file)
@@ -31,6 +31,7 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t,
     for(int i=0; i < Tsunami::Max_CPUs; i++) {
         dim[i] = 0;
         dir[i] = 0;
+        dirInterrupting[i] = false;
     }
 
     drir = 0;
@@ -163,15 +164,47 @@ TsunamiCChip::write(MemReqPtr req, const uint8_t *data)
                   return No_Fault;
               case TSDEV_CC_DIM0:
                    dim[0] = *(uint64_t*)data;
+                   if (dim[0] & drir) {
+                       dir[0] = dim[0] & drir;
+                       if (!dirInterrupting[0]) {
+                           dirInterrupting[0] = true;
+                           tsunami->intrctrl->post(0, TheISA::INTLEVEL_IRQ1, 0);
+                           DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n");
+                       }
+                   }
                   return No_Fault;
               case TSDEV_CC_DIM1:
                   dim[1] = *(uint64_t*)data;
+                  if (dim[1] & drir) {
+                       dir[1] = dim[1] & drir;
+                       if (!dirInterrupting[1]) {
+                           dirInterrupting[1] = true;
+                           tsunami->intrctrl->post(1, TheISA::INTLEVEL_IRQ1, 0);
+                           DPRINTF(Tsunami, "posting dir interrupt to cpu 1\n");
+                       }
+                  }
                   return No_Fault;
               case TSDEV_CC_DIM2:
                   dim[2] = *(uint64_t*)data;
+                  if (dim[2] & drir) {
+                       dir[2] = dim[2] & drir;
+                       if (!dirInterrupting[2]) {
+                           dirInterrupting[2] = true;
+                           tsunami->intrctrl->post(2, TheISA::INTLEVEL_IRQ1, 0);
+                           DPRINTF(Tsunami, "posting dir interrupt to cpu 2\n");
+                       }
+                  }
                   return No_Fault;
               case TSDEV_CC_DIM3:
                   dim[3] = *(uint64_t*)data;
+                  if ((dim[3] & drir) /*And Not Already Int*/) {
+                       dir[3] = dim[3] & drir;
+                       if (!dirInterrupting[3]) {
+                           dirInterrupting[3] = true;
+                           tsunami->intrctrl->post(3, TheISA::INTLEVEL_IRQ1, 0);
+                           DPRINTF(Tsunami, "posting dir interrupt to cpu 3\n");
+                       }
+                  }
                   return No_Fault;
               case TSDEV_CC_DIR0:
               case TSDEV_CC_DIR1:
@@ -214,6 +247,37 @@ TsunamiCChip::write(MemReqPtr req, const uint8_t *data)
     return No_Fault;
 }
 
+void
+TsunamiCChip::postDRIR(uint64_t bitvector)
+{
+    drir |= bitvector;
+    for(int i=0; i < Tsunami::Max_CPUs; i++) {
+        if (bitvector & dim[i]) {
+            dir[i] |= bitvector;
+            if (!dirInterrupting[i]) {
+                dirInterrupting[i] = true;
+                tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, 0);
+                DPRINTF(Tsunami, "posting dir interrupt to cpu %d\n",i);
+            }
+        }
+    }
+}
+
+void
+TsunamiCChip::clearDRIR(uint64_t bitvector)
+{
+    drir &= ~bitvector;
+    for(int i=0; i < Tsunami::Max_CPUs; i++) {
+        dir[i] &= ~bitvector;
+        if (!dir[i]) {
+            dirInterrupting[i] = false;
+            tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, 0);
+            DPRINTF(Tsunami, "clearing dir interrupt to cpu %d\n", i);
+
+        }
+    }
+}
+
 void
 TsunamiCChip::serialize(std::ostream &os)
 {
index 287fbdf7058c6ee18b554f9abf96aee505ec3602..c1c196d184687be245555d68d03e6e42363356c6 100644 (file)
@@ -47,6 +47,7 @@ class TsunamiCChip : public MmapDevice
     Tsunami *tsunami;
     uint64_t dim[Tsunami::Max_CPUs];
     uint64_t dir[Tsunami::Max_CPUs];
+    bool dirInterrupting[Tsunami::Max_CPUs];
     uint64_t drir;
 
   public:
@@ -56,6 +57,9 @@ class TsunamiCChip : public MmapDevice
     virtual Fault read(MemReqPtr req, uint8_t *data);
     virtual Fault write(MemReqPtr req, const uint8_t *data);
 
+    void postDRIR(uint64_t bitvector);
+    void clearDRIR(uint64_t bitvector);
+
     virtual void serialize(std::ostream &os);
     virtual void unserialize(Checkpoint *cp, const std::string &section);
 
index 87f997e9ed30e9f0111158dd51d5badad75d0d9e..cfa91a67d7ee5fce0d057cd6b4dfaf76a3dc1788 100644 (file)
@@ -109,6 +109,8 @@ TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time,
     timerData = 0;
     set_time(init_time == 0 ? time(NULL) : init_time);
     uip = 1;
+    picr = 0;
+    picInterrupting = false;
 }
 
 void
@@ -202,9 +204,15 @@ TsunamiIO::write(MemReqPtr req, const uint8_t *data)
             switch(daddr) {
                 case TSDEV_PIC1_MASK:
                     mask1 = *(uint8_t*)data;
+                    if ((picr & mask1) && !picInterrupting) {
+                        picInterrupting = true;
+                        tsunami->cchip->postDRIR(uint64_t(1) << 55);
+                        DPRINTF(Tsunami, "posting pic interrupt to cchip\n");
+                    }
                     return No_Fault;
                 case TSDEV_PIC2_MASK:
                     mask2 = *(uint8_t*)data;
+                    //PIC2 Not implemented to interrupt
                     return No_Fault;
                 case TSDEV_DMA1_RESET:
                     return No_Fault;
@@ -279,6 +287,30 @@ TsunamiIO::write(MemReqPtr req, const uint8_t *data)
     return No_Fault;
 }
 
+void
+TsunamiIO::postPIC(uint8_t bitvector)
+{
+    //PIC2 Is not implemented, because nothing of interest there
+    picr |= bitvector;
+    if ((picr & mask1) && !picInterrupting) {
+        picInterrupting = true;
+        tsunami->cchip->postDRIR(uint64_t(1) << 55);
+        DPRINTF(Tsunami, "posting pic interrupt to cchip\n");
+    }
+}
+
+void
+TsunamiIO::clearPIC(uint8_t bitvector)
+{
+    //PIC2 Is not implemented, because nothing of interest there
+    picr &= ~bitvector;
+    if (!(picr & mask1)) {
+        picInterrupting = false;
+        tsunami->cchip->clearDRIR(uint64_t(1) << 55);
+        DPRINTF(Tsunami, "clearing pic interrupt to cchip\n");
+    }
+}
+
 void
 TsunamiIO::serialize(std::ostream &os)
 {
index 9706dea2532061ce774601e3d60662858cd993c8..97589e5f060512589ee72ea38e096489ec32f959 100644 (file)
@@ -90,6 +90,9 @@ class TsunamiIO : public MmapDevice
       uint8_t mode1;
       uint8_t mode2;
 
+    uint8_t picr; //Raw PIC interrput register, before masking
+    bool picInterrupting;
+
     Tsunami *tsunami;
 
       /* This timer is initilized, but after I wrote the code
@@ -121,6 +124,9 @@ class TsunamiIO : public MmapDevice
     virtual Fault read(MemReqPtr req, uint8_t *data);
     virtual Fault write(MemReqPtr req, const uint8_t *data);
 
+    void postPIC(uint8_t bitvector);
+    void clearPIC(uint8_t bitvector);
+
     virtual void serialize(std::ostream &os);
     virtual void unserialize(Checkpoint *cp, const std::string &section);
 };