summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mem/cache/base_cache.hh4
-rw-r--r--src/mem/cache/cache_impl.hh41
-rw-r--r--src/mem/cache/coherence/simple_coherence.hh6
-rw-r--r--src/mem/cache/coherence/uni_coherence.cc36
-rw-r--r--src/mem/cache/coherence/uni_coherence.hh2
5 files changed, 60 insertions, 29 deletions
diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh
index 93830b04f..60d7029ac 100644
--- a/src/mem/cache/base_cache.hh
+++ b/src/mem/cache/base_cache.hh
@@ -128,8 +128,10 @@ class BaseCache : public MemObject
const char *description();
};
- protected:
+ public: //Made public so coherence can get at it.
CachePort *cpuSidePort;
+
+ protected:
CachePort *memSidePort;
bool snoopRangesSent;
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index b5d7e1960..18f56b1ba 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -373,10 +373,15 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
//Revisit this for multi level coherence
return;
}
+
+ //Send a timing (true) invalidate up if the protocol calls for it
+ coherence->propogateInvalidate(pkt, true);
+
Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
BlkType *blk = tags->findBlock(pkt);
MSHR *mshr = missQueue->findMSHR(blk_addr);
- if (coherence->hasProtocol()) { //@todo Move this into handle bus req
+ if (coherence->hasProtocol() || pkt->isInvalidate()) {
+ //@todo Move this into handle bus req
//If we find an mshr, and it is in service, we need to NACK or
//invalidate
if (mshr) {
@@ -626,6 +631,7 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update,
}
}
+ return 0;
} else if (!blk) {
// update the cache state and statistics
if (mshr || !writes.empty()){
@@ -713,24 +719,27 @@ template<class TagStore, class Buffering, class Coherence>
Tick
Cache<TagStore,Buffering,Coherence>::snoopProbe(PacketPtr &pkt)
{
- Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
- BlkType *blk = tags->findBlock(pkt);
- MSHR *mshr = missQueue->findMSHR(blk_addr);
- CacheBlk::State new_state = 0;
- bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state);
- if (satisfy) {
- DPRINTF(Cache, "Cache snooped a %s request for addr %x and "
- "now supplying data, new state is %i\n",
- pkt->cmdString(), blk_addr, new_state);
+ //Send a atomic (false) invalidate up if the protocol calls for it
+ coherence->propogateInvalidate(pkt, true);
+
+ Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
+ BlkType *blk = tags->findBlock(pkt);
+ MSHR *mshr = missQueue->findMSHR(blk_addr);
+ CacheBlk::State new_state = 0;
+ bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state);
+ if (satisfy) {
+ DPRINTF(Cache, "Cache snooped a %s request for addr %x and "
+ "now supplying data, new state is %i\n",
+ pkt->cmdString(), blk_addr, new_state);
tags->handleSnoop(blk, new_state, pkt);
return hitLatency;
- }
- if (blk)
- DPRINTF(Cache, "Cache snooped a %s request for addr %x, "
- "new state is %i\n",
+ }
+ if (blk)
+ DPRINTF(Cache, "Cache snooped a %s request for addr %x, "
+ "new state is %i\n",
pkt->cmdString(), blk_addr, new_state);
- tags->handleSnoop(blk, new_state);
- return 0;
+ tags->handleSnoop(blk, new_state);
+ return 0;
}
diff --git a/src/mem/cache/coherence/simple_coherence.hh b/src/mem/cache/coherence/simple_coherence.hh
index a356b3ecc..5a0127c01 100644
--- a/src/mem/cache/coherence/simple_coherence.hh
+++ b/src/mem/cache/coherence/simple_coherence.hh
@@ -160,6 +160,12 @@ class SimpleCoherence
bool allowFastWrites() { return false; }
bool hasProtocol() { return true; }
+
+ void propogateInvalidate(Packet *pkt, bool isTiming)
+ {
+ //For now we do nothing, asssumes simple coherence is top level of cache
+ return;
+ }
};
#endif //__SIMPLE_COHERENCE_HH__
diff --git a/src/mem/cache/coherence/uni_coherence.cc b/src/mem/cache/coherence/uni_coherence.cc
index 464266a29..4ebb2664c 100644
--- a/src/mem/cache/coherence/uni_coherence.cc
+++ b/src/mem/cache/coherence/uni_coherence.cc
@@ -76,19 +76,31 @@ UniCoherence::handleBusRequest(Packet * &pkt, CacheBlk *blk, MSHR *mshr,
{
new_state = 0;
if (pkt->isInvalidate()) {
- DPRINTF(Cache, "snoop inval on blk %x (blk ptr %x)\n",
- pkt->getAddr(), blk);
- // Forward to other caches
- Packet * tmp = new Packet(pkt->req, Packet::InvalidateReq, -1);
- cshrs.allocate(tmp);
- cache->setSlaveRequest(Request_Coherence, curTick);
- if (cshrs.isFull()) {
- cache->setBlockedForSnoop(Blocked_Coherence);
+ DPRINTF(Cache, "snoop inval on blk %x (blk ptr %x)\n",
+ pkt->getAddr(), blk);
+ }
+ else if (blk) {
+ new_state = blk->status;
+ }
+ return false;
+}
+
+void
+UniCoherence::propogateInvalidate(Packet *pkt, bool isTiming)
+{
+ if (pkt->isInvalidate()) {
+ if (isTiming) {
+ // Forward to other caches
+ Packet * tmp = new Packet(pkt->req, Packet::InvalidateReq, -1);
+ cshrs.allocate(tmp);
+ cache->setSlaveRequest(Request_Coherence, curTick);
+ if (cshrs.isFull())
+ cache->setBlockedForSnoop(Blocked_Coherence);
}
- } else {
- if (blk) {
- new_state = blk->status;
+ else {
+ Packet * tmp = new Packet(pkt->req, Packet::InvalidateReq, -1);
+ cache->cpuSidePort->sendAtomic(tmp);
+ delete tmp;
}
}
- return false;
}
diff --git a/src/mem/cache/coherence/uni_coherence.hh b/src/mem/cache/coherence/uni_coherence.hh
index 60da7a36e..4f69d52e2 100644
--- a/src/mem/cache/coherence/uni_coherence.hh
+++ b/src/mem/cache/coherence/uni_coherence.hh
@@ -139,6 +139,8 @@ class UniCoherence
bool allowFastWrites() { return true; }
bool hasProtocol() { return false; }
+
+ void propogateInvalidate(Packet *pkt, bool isTiming);
};
#endif //__UNI_COHERENCE_HH__