Fix functional access errors related to delayed respnoses in cachePort
authorRon Dreslinski <rdreslin@umich.edu>
Sun, 12 Nov 2006 11:35:39 +0000 (06:35 -0500)
committerRon Dreslinski <rdreslin@umich.edu>
Sun, 12 Nov 2006 11:35:39 +0000 (06:35 -0500)
src/mem/cache/base_cache.cc:
    On a delayed response, be sure to call the fixPacket wrapper to toggle hasData flag.
src/mem/packet.cc:
src/mem/packet.hh:
    Create a wrapper to toggle the hasData flag on delayed responses

--HG--
extra : convert_revision : 1ced8d4e3dc12a059fb7636d59e429cd3dd46901

src/mem/cache/base_cache.cc
src/mem/packet.cc
src/mem/packet.hh

index 489a24d4c18cfcb3e031f6c11984e665caa419d3..c16cb6945993f9d07cd8bb0867ba8a2ecf07e368 100644 (file)
@@ -114,6 +114,8 @@ BaseCache::CachePort::checkFunctional(PacketPtr pkt)
         // If the target contains data, and it overlaps the
         // probed request, need to update data
         if (target->intersect(pkt)) {
+            DPRINTF(Cache, "Functional %s access to blk_addr %x intersects a drain\n",
+                    pkt->cmdString(), pkt->getAddr() & ~(cache->getBlockSize() - 1));
             notDone = fixPacket(pkt, target);
         }
         i++;
@@ -126,8 +128,11 @@ BaseCache::CachePort::checkFunctional(PacketPtr pkt)
         PacketPtr target = j->second;
         // If the target contains data, and it overlaps the
         // probed request, need to update data
-        if (target->intersect(pkt))
-            notDone = fixPacket(pkt, target);
+        if (target->intersect(pkt)) {
+            DPRINTF(Cache, "Functional %s access to blk_addr %x intersects a response\n",
+                    pkt->cmdString(), pkt->getAddr() & ~(cache->getBlockSize() - 1));
+            notDone = fixDelayedResponsePacket(pkt, target);
+        }
         j++;
     }
     return notDone;
@@ -348,7 +353,7 @@ BaseCache::CacheEvent::process()
         }
         return;
     }
-    //Else it's a response Response
+    //Else it's a response
     assert(cachePort->transmitList.size());
     assert(cachePort->transmitList.front().first <= curTick);
     pkt = cachePort->transmitList.front().second;
index 938116ab548641c5869befcc4c92a18807456646..e2faf452732435872922332ce67d79b56ac13f82 100644 (file)
@@ -143,6 +143,24 @@ Packet::intersect(PacketPtr p)
     return !(s1 > e2 || e1 < s2);
 }
 
+bool
+fixDelayedResponsePacket(PacketPtr func, PacketPtr timing)
+{
+    bool result;
+
+    if (timing->isRead() || timing->isWrite()) {
+        timing->toggleData();
+        result = fixPacket(func, timing);
+        timing->toggleData();
+    }
+    else {
+        //Don't toggle if it isn't a read/write response
+        result = fixPacket(func, timing);
+    }
+
+    return result;
+}
+
 bool
 fixPacket(PacketPtr func, PacketPtr timing)
 {
index cb97dd0366c9ebb8ab9279fed851317cd9dc9a77..2bc51bf12e15fef417a52aaa95be8e4a185dff47 100644 (file)
@@ -344,6 +344,13 @@ class Packet
         srcValid = false;
     }
 
+
+    void toggleData() {
+        int icmd = (int)cmd;
+        icmd ^= HasData;
+        cmd = (Command)icmd;
+    }
+
     /**
      * Take a request packet and modify it in place to be suitable for
      * returning as a response to that request.
@@ -448,7 +455,6 @@ class Packet
     bool intersect(PacketPtr p);
 };
 
-
 /** This function given a functional packet and a timing packet either satisfies
  * the timing packet, or updates the timing packet to reflect the updated state
  * in the timing packet. It returns if the functional packet should continue to
@@ -456,6 +462,12 @@ class Packet
  */
 bool fixPacket(PacketPtr func, PacketPtr timing);
 
+/** This function is a wrapper for the fixPacket field that toggles the hasData bit
+ * it is used when a response is waiting in the caches, but hasn't been marked as a
+ * response yet (so the fixPacket needs to get the correct value for the hasData)
+ */
+bool fixDelayedResponsePacket(PacketPtr func, PacketPtr timing);
+
 std::ostream & operator<<(std::ostream &o, const Packet &p);
 
 #endif //__MEM_PACKET_HH