summaryrefslogtreecommitdiff
path: root/src/mem/cache/cache_impl.hh
diff options
context:
space:
mode:
authorSteve Reinhardt <stever@eecs.umich.edu>2007-07-26 17:04:17 -0700
committerSteve Reinhardt <stever@eecs.umich.edu>2007-07-26 17:04:17 -0700
commitc3bf59dcb9dddd64d5ad603f7af6589b87e7afad (patch)
treeae51979714aa372d996d64c1841892e20a68fd9c /src/mem/cache/cache_impl.hh
parentf1b5c8fb57ee656df3a1b9d021de723279f66b2f (diff)
downloadgem5-c3bf59dcb9dddd64d5ad603f7af6589b87e7afad.tar.xz
Add downward express snoops for invalidations.
--HG-- extra : convert_revision : 4916fa9721d727d8416ad8c07df3a8171d02b2b4
Diffstat (limited to 'src/mem/cache/cache_impl.hh')
-rw-r--r--src/mem/cache/cache_impl.hh15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 6db40b609..2ead54ba6 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -371,6 +371,17 @@ Cache<TagStore>::timingAccess(PacketPtr pkt)
DPRINTF(Cache, "mem inhibited on 0x%x: not responding\n",
pkt->getAddr());
assert(!pkt->req->isUncacheable());
+ // Special tweak for multilevel coherence: snoop downward here
+ // on invalidates since there may be other caches below here
+ // that have shared copies. Not necessary if we know that
+ // supplier had exclusive copy to begin with.
+ if (pkt->needsExclusive() && !pkt->isSupplyExclusive()) {
+ Packet *snoopPkt = new Packet(pkt, true); // clear flags
+ snoopPkt->setExpressSnoop();
+ snoopPkt->assertMemInhibit();
+ memSidePort->sendTiming(snoopPkt);
+ // main memory will delete snoopPkt
+ }
return true;
}
@@ -966,6 +977,7 @@ Cache<TagStore>::handleSnoop(PacketPtr pkt, BlkType *blk,
// we respond in atomic mode), so just figure out what to do now
// and then do it later
bool supply = blk->isDirty() && pkt->isRead() && !upperSupply;
+ bool have_exclusive = blk->isWritable();
bool invalidate = pkt->isInvalidate();
if (pkt->isRead() && !pkt->isInvalidate()) {
@@ -985,6 +997,9 @@ Cache<TagStore>::handleSnoop(PacketPtr pkt, BlkType *blk,
if (supply) {
assert(!pkt->memInhibitAsserted());
pkt->assertMemInhibit();
+ if (have_exclusive) {
+ pkt->setSupplyExclusive();
+ }
if (is_timing) {
doTimingSupplyResponse(pkt, blk->data, is_deferred);
} else {