Fixes for blocking in the caches that needed to be pulled
authorRon Dreslinski <rdreslin@umich.edu>
Wed, 16 Aug 2006 19:54:02 +0000 (15:54 -0400)
committerRon Dreslinski <rdreslin@umich.edu>
Wed, 16 Aug 2006 19:54:02 +0000 (15:54 -0400)
src/mem/cache/base_cache.cc:
    Add in retry path for blocking with multi-level caches
src/mem/cache/base_cache.hh:
    Pull more of the blocking fixes into head
src/mem/packet.hh:
    Fix typo

--HG--
extra : convert_revision : d4d149adfa414136ebd2c4789b739bb065710f7a

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

index 9b103457744f21a2ba9d55c1aa3f3280b5422bbb..8978fef02253ad70b3f7e5fabe9411f4fe3ad58a 100644 (file)
@@ -73,6 +73,7 @@ BaseCache::CachePort::recvTiming(Packet *pkt)
 {
     if (blocked)
     {
+        DPRINTF(Cache,"Scheduling a retry while blocked\n");
         mustSendRetry = true;
         return false;
     }
@@ -91,21 +92,63 @@ BaseCache::CachePort::recvFunctional(Packet *pkt)
     cache->doFunctionalAccess(pkt, isCpuSide);
 }
 
+void
+BaseCache::CachePort::recvRetry()
+{
+    Packet *pkt;
+
+    if (!isCpuSide)
+    {
+        pkt = cache->getPacket();
+        bool success = sendTiming(pkt);
+        DPRINTF(Cache, "Address %x was %s in sending the timing request\n",
+                pkt->getAddr(), success ? "succesful" : "unsuccesful");
+        cache->sendResult(pkt, success);
+        if (success && cache->doMasterRequest())
+        {
+            //Still more to issue, rerequest in 1 cycle
+            pkt = NULL;
+            BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this);
+            reqCpu->schedule(curTick + 1);
+        }
+    }
+    else
+    {
+        pkt = cache->getCoherencePacket();
+        bool success = sendTiming(pkt);
+        if (success && cache->doSlaveRequest())
+        {
+            //Still more to issue, rerequest in 1 cycle
+            pkt = NULL;
+            BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this);
+            reqCpu->schedule(curTick + 1);
+        }
+
+    }
+    return;
+}
 void
 BaseCache::CachePort::setBlocked()
 {
+    assert(!blocked);
+    DPRINTF(Cache, "Cache Blocking\n");
     blocked = true;
+    //Clear the retry flag
+    mustSendRetry = false;
 }
 
 void
 BaseCache::CachePort::clearBlocked()
 {
+    assert(blocked);
+    DPRINTF(Cache, "Cache Unblocking\n");
+    blocked = false;
     if (mustSendRetry)
     {
+        DPRINTF(Cache, "Cache Sending Retry\n");
         mustSendRetry = false;
         sendRetry();
     }
-    blocked = false;
 }
 
 BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort)
@@ -128,6 +171,7 @@ BaseCache::CacheEvent::process()
     {
         if (!cachePort->isCpuSide)
         {
+            //MSHR
             pkt = cachePort->cache->getPacket();
             bool success = cachePort->sendTiming(pkt);
             DPRINTF(Cache, "Address %x was %s in sending the timing request\n",
@@ -142,11 +186,19 @@ BaseCache::CacheEvent::process()
         }
         else
         {
+            //CSHR
             pkt = cachePort->cache->getCoherencePacket();
-            cachePort->sendTiming(pkt);
+            bool success = cachePort->sendTiming(pkt);
+            if (success && cachePort->cache->doSlaveRequest())
+            {
+                //Still more to issue, rerequest in 1 cycle
+                pkt = NULL;
+                this->schedule(curTick+1);
+            }
         }
         return;
     }
+    //Response
     //Know the packet to send, no need to mark in service (must succed)
     bool success = cachePort->sendTiming(pkt);
     assert(success);
index 9fb790ceefdf9f873c7dbb991a0195d8b5a64561..069dbab5864fa17cbbe5fadc9bea4e71c61a73b4 100644 (file)
@@ -98,6 +98,8 @@ class BaseCache : public MemObject
 
         virtual int deviceBlockSize();
 
+        virtual void recvRetry();
+
       public:
         void setBlocked();
 
@@ -407,17 +409,23 @@ class BaseCache : public MemObject
     void clearBlocked(BlockedCause cause)
     {
         uint8_t flag = 1 << cause;
-        blocked &= ~flag;
-        blockedSnoop &= ~flag;
         DPRINTF(Cache,"Unblocking for cause %s, causes left=%i\n",
                 cause, blocked);
-        if (!isBlocked()) {
-            blocked_cycles[cause] += curTick - blockedCycle;
-            DPRINTF(Cache,"Unblocking from all causes\n");
-            cpuSidePort->clearBlocked();
+        if (blocked & flag)
+        {
+            blocked &= ~flag;
+            if (!isBlocked()) {
+                blocked_cycles[cause] += curTick - blockedCycle;
+                DPRINTF(Cache,"Unblocking from all causes\n");
+                cpuSidePort->clearBlocked();
+            }
         }
-        if (!isBlockedForSnoop()) {
-           memSidePort->clearBlocked();
+        if (blockedSnoop & flag)
+        {
+            blockedSnoop &= ~flag;
+            if (!isBlockedForSnoop()) {
+                memSidePort->clearBlocked();
+            }
         }
     }
 
index 83b4006e2806200fcb6f4339e1b54ba8c41fa363..9511d43b5a6a3193510a50abc843aa6490289597 100644 (file)
@@ -216,7 +216,7 @@ class Packet
     bool isRequest()    { return (cmd & IsRequest)  != 0; }
     bool isResponse()   { return (cmd & IsResponse) != 0; }
     bool needsResponse() { return (cmd & NeedsResponse) != 0; }
-    bool isInvalidate()  { return (cmd * IsInvalidate) != 0; }
+    bool isInvalidate()  { return (cmd & IsInvalidate) != 0; }
 
     bool isCacheFill() { return (flags & CACHE_LINE_FILL) != 0; }
     bool isNoAllocate() { return (flags & NO_ALLOCATE) != 0; }