Rewrote interrupt code to handle masking correctly and changed every
authorAli Saidi <saidi@eecs.umich.edu>
Mon, 16 Feb 2004 04:56:44 +0000 (23:56 -0500)
committerAli Saidi <saidi@eecs.umich.edu>
Mon, 16 Feb 2004 04:56:44 +0000 (23:56 -0500)
interrupt to use a different subnumber since both devices could
interrupt at the same time and we don't want to loose one.

dev/tsunami_cchip.cc:
    rewrote interrupt code to handle interrupt mask clearing correctly
dev/tsunami_cchip.hh:
    changed (post/clear)DRIR to use a interrupt number rather than a vecotr
dev/tsunami_io.cc:
    updated for new post/clearDRIR calls

--HG--
extra : convert_revision : 5b39f5e15a66d5eb6e689e6ece62f99b5fa735ab

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

index 2d8113491d3c63b9f77ddb605cf30785a0c77f35..375664be039da43603a22d7003cef73ac7066ebc 100644 (file)
@@ -134,6 +134,7 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
             req->vaddr, req->size);
 
     Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6;
+    uint64_t olddim;
 
     switch (req->size) {
 
@@ -161,47 +162,47 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
                   panic("TSDEV_CC_AARx write not implemeted\n");
                   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");
-                       }
+                  int number;
+                  if(daddr == TSDEV_CC_DIM0)
+                      number = 0;
+                  else if(daddr == TSDEV_CC_DIM1)
+                      number = 1;
+                  else if(daddr == TSDEV_CC_DIM2)
+                      number = 2;
+                  else
+                      number = 3;
+
+                  olddim = dim[number];
+                  dim[number] = *(uint64_t*)data;
+                  dir[number] = dim[number] & drir;
+                  uint64_t bitvector;
+                  for(int x = 0; x < 64; x++)
+                  {
+                      bitvector = 1 << x;
+                      // Figure out which bits have changed
+                      if ((dim[number] & bitvector) != (olddim & bitvector))
+                      {
+                          // The bit is now set and it wasn't before (set)
+                          if((dim[number] & bitvector) && (dir[number] & bitvector))
+                          {
+                              tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x);
+                              DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n");
+                          }
+                          else if (!(dir[number] & bitvector))
+                          {
+                              // The bit was set and now its now clear and
+                              // we were interrupting on that bit before
+                              tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x);
+                              DPRINTF(Tsunami, "dim write resulting in clear"
+                                      "dir interrupt to cpu 0\n");
+
+                          }
+
+
+                      }
                   }
                   return No_Fault;
               case TSDEV_CC_DIR0:
@@ -209,25 +210,20 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
               case TSDEV_CC_DIR2:
               case TSDEV_CC_DIR3:
                   panic("TSDEV_CC_DIR write not implemented\n");
-                  return No_Fault;
               case TSDEV_CC_DRIR:
                   panic("TSDEV_CC_DRIR write not implemented\n");
-                  return No_Fault;
               case TSDEV_CC_PRBEN:
                   panic("TSDEV_CC_PRBEN write not implemented\n");
-                  return No_Fault;
               case TSDEV_CC_IIC0:
               case TSDEV_CC_IIC1:
               case TSDEV_CC_IIC2:
               case TSDEV_CC_IIC3:
                   panic("TSDEV_CC_IICx write not implemented\n");
-                  return No_Fault;
               case TSDEV_CC_MPR0:
               case TSDEV_CC_MPR1:
               case TSDEV_CC_MPR2:
               case TSDEV_CC_MPR3:
                   panic("TSDEV_CC_MPRx write not implemented\n");
-                  return No_Fault;
               default:
                   panic("default in cchip read reached, accessing 0x%x\n");
           }
@@ -246,34 +242,39 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
 }
 
 void
-TsunamiCChip::postDRIR(uint64_t bitvector)
+TsunamiCChip::postDRIR(uint32_t interrupt)
 {
+    uint64_t bitvector = 0x1 << interrupt;
     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);
-            }
+        dir[i] = dim[i] & drir;
+        if (dim[i] & bitvector) {
+                tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, interrupt);
+                DPRINTF(Tsunami, "posting dir interrupt to cpu %d,"
+                        "interrupt %d\n",i, interrupt);
         }
     }
 }
 
 void
-TsunamiCChip::clearDRIR(uint64_t bitvector)
+TsunamiCChip::clearDRIR(uint32_t interrupt)
 {
-    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);
+    uint64_t bitvector = 0x1 << interrupt;
+    if (drir & bitvector)
+    {
+        drir &= ~bitvector;
+        for(int i=0; i < Tsunami::Max_CPUs; i++) {
+            if (dir[i] & bitvector) {
+                tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, interrupt);
+                DPRINTF(Tsunami, "clearing dir interrupt to cpu %d,"
+                    "interrupt %d\n",i, interrupt);
 
+            }
+            dir[i] = dim[i] & drir;
         }
     }
+    else
+        DPRINTF(Tsunami, "Spurrious clear? interrupt %d\n", interrupt);
 }
 
 void
index 8c8ed4d206bae65b8bc7707d32f8931bf2667c70..75214c52794c6079ff8f9854292be726b83d68fa 100644 (file)
@@ -79,8 +79,8 @@ class TsunamiCChip : public FunctionalMemory
     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);
+    void postDRIR(uint32_t interrupt);
+    void clearDRIR(uint32_t interrupt);
 
     virtual void serialize(std::ostream &os);
     virtual void unserialize(Checkpoint *cp, const std::string &section);
index ccf0bc2daf5d5f32bbb9daca52222d3c74710a93..fa87a72c41ff69738eb67c32a1c7b21384fa5b59 100644 (file)
@@ -237,7 +237,7 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
             mask1 = *(uint8_t*)data;
             if ((picr & mask1) && !picInterrupting) {
                 picInterrupting = true;
-                tsunami->cchip->postDRIR(uint64_t(1) << 55);
+                tsunami->cchip->postDRIR(55);
                 DPRINTF(Tsunami, "posting pic interrupt to cchip\n");
             }
             return No_Fault;
@@ -326,7 +326,7 @@ TsunamiIO::postPIC(uint8_t bitvector)
     picr |= bitvector;
     if ((picr & mask1) && !picInterrupting) {
         picInterrupting = true;
-        tsunami->cchip->postDRIR(uint64_t(1) << 55);
+        tsunami->cchip->postDRIR(55);
         DPRINTF(Tsunami, "posting pic interrupt to cchip\n");
     }
 }
@@ -338,7 +338,7 @@ TsunamiIO::clearPIC(uint8_t bitvector)
     picr &= ~bitvector;
     if (!(picr & mask1)) {
         picInterrupting = false;
-        tsunami->cchip->clearDRIR(uint64_t(1) << 55);
+        tsunami->cchip->clearDRIR(55);
         DPRINTF(Tsunami, "clearing pic interrupt to cchip\n");
     }
 }