Fix problems with unCacheable addresses in timing-coherence
[gem5.git] / src / mem / cache / base_cache.hh
index 2e92e77300bfdcb9284115f0b3f1d848ffbc015e..563b1ca8ba44e1caa4e47058589f6dcfa35502f1 100644 (file)
@@ -72,6 +72,7 @@ enum RequestCause{
     Request_PF
 };
 
+class MSHR;
 /**
  * A basic cache interface. Implements some common functions for speed.
  */
@@ -111,7 +112,11 @@ class BaseCache : public MemObject
 
         bool isCpuSide;
 
+        bool waitingOnRetry;
+
         std::list<Packet *> drainList;
+
+        Packet *cshrRetry;
     };
 
     struct CacheEvent : public Event
@@ -156,7 +161,7 @@ class BaseCache : public MemObject
         if (status == Port::RangeChange){
             if (!isCpuSide) {
                 cpuSidePort->sendStatusChange(Port::RangeChange);
-                if (topLevelCache && !snoopRangesSent) {
+                if (!snoopRangesSent) {
                     snoopRangesSent = true;
                     memSidePort->sendStatusChange(Port::RangeChange);
                 }
@@ -177,7 +182,7 @@ class BaseCache : public MemObject
         fatal("No implementation");
     }
 
-    virtual void sendResult(Packet* &pkt, bool success)
+    virtual void sendResult(Packet* &pkt, MSHR* mshr, bool success)
     {
 
         fatal("No implementation");
@@ -389,11 +394,13 @@ class BaseCache : public MemObject
             blocked_causes[cause]++;
             blockedCycle = curTick;
         }
+        int old_state = blocked;
         if (!(blocked & flag)) {
             //Wasn't already blocked for this cause
             blocked |= flag;
             DPRINTF(Cache,"Blocking for cause %s\n", cause);
-            cpuSidePort->setBlocked();
+            if (!old_state)
+                cpuSidePort->setBlocked();
         }
     }
 
@@ -405,10 +412,12 @@ class BaseCache : public MemObject
     void setBlockedForSnoop(BlockedCause cause)
     {
         uint8_t flag = 1 << cause;
-        if (!(blocked & flag)) {
+        uint8_t old_state = blockedSnoop;
+        if (!(blockedSnoop & flag)) {
             //Wasn't already blocked for this cause
             blockedSnoop |= flag;
-            memSidePort->setBlocked();
+            if (!old_state)
+                memSidePort->setBlocked();
         }
     }
 
@@ -458,7 +467,7 @@ class BaseCache : public MemObject
      */
     void setMasterRequest(RequestCause cause, Tick time)
     {
-        if (!doMasterRequest())
+        if (!doMasterRequest() && !memSidePort->waitingOnRetry)
         {
             BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(memSidePort);
             reqCpu->schedule(time);
@@ -520,6 +529,10 @@ class BaseCache : public MemObject
             CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt);
             reqCpu->schedule(time);
         }
+        else {
+            if (pkt->cmd == Packet::Writeback) delete pkt->req;
+            delete pkt;
+        }
     }
 
     /**
@@ -536,6 +549,10 @@ class BaseCache : public MemObject
             CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt);
             reqCpu->schedule(time);
         }
+        else {
+            if (pkt->cmd == Packet::Writeback) delete pkt->req;
+            delete pkt;
+        }
     }
 
     /**
@@ -568,14 +585,14 @@ class BaseCache : public MemObject
         {
             //This is where snoops get updated
             AddrRangeList dummy;
-            if (!topLevelCache)
-            {
+//            if (!topLevelCache)
+//            {
                 cpuSidePort->getPeerAddressRanges(dummy, snoop);
-            }
-            else
-            {
-                snoop.push_back(RangeSize(0,-1));
-            }
+//            }
+//            else
+//            {
+//                snoop.push_back(RangeSize(0,-1));
+//            }
 
             return;
         }