summaryrefslogtreecommitdiff
path: root/src/mem/cache/base_cache.cc
diff options
context:
space:
mode:
authorRon Dreslinski <rdreslin@umich.edu>2006-08-16 15:54:02 -0400
committerRon Dreslinski <rdreslin@umich.edu>2006-08-16 15:54:02 -0400
commit8a82553aec48029a7752f7192ca1c65236192cce (patch)
tree1b00f5f6ce755d4fb70ae7f33791f85b1bd38d7f /src/mem/cache/base_cache.cc
parent890f0fc782b939a72c907ebf49866c634cfa3454 (diff)
downloadgem5-8a82553aec48029a7752f7192ca1c65236192cce.tar.xz
Fixes for blocking in the caches that needed to be pulled
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
Diffstat (limited to 'src/mem/cache/base_cache.cc')
-rw-r--r--src/mem/cache/base_cache.cc56
1 files changed, 54 insertions, 2 deletions
diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc
index 9b1034577..8978fef02 100644
--- a/src/mem/cache/base_cache.cc
+++ b/src/mem/cache/base_cache.cc
@@ -73,6 +73,7 @@ BaseCache::CachePort::recvTiming(Packet *pkt)
{
if (blocked)
{
+ DPRINTF(Cache,"Scheduling a retry while blocked\n");
mustSendRetry = true;
return false;
}
@@ -92,20 +93,62 @@ BaseCache::CachePort::recvFunctional(Packet *pkt)
}
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);