summaryrefslogtreecommitdiff
path: root/src/mem/cache
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2014-02-18 05:50:58 -0500
committerAndreas Hansson <andreas.hansson@arm.com>2014-02-18 05:50:58 -0500
commit969b4362432659f436925c1d4266d8d4f6fae121 (patch)
treecbba278ff62c220accf228fa767d6f9a7e7c59b5 /src/mem/cache
parentbf2f178f85056fe518ce1ce9cb22c0dbc2e0b0ce (diff)
downloadgem5-969b4362432659f436925c1d4266d8d4f6fae121.tar.xz
mem: Filter cache snoops based on address ranges
This patch adds a filter to the cache to drop snoop requests that are not for a range covered by the cache. This fixes an issue observed when multiple caches are placed in parallel, covering different address ranges. Without this patch, all the caches will forward the snoop upwards, when only one should do so.
Diffstat (limited to 'src/mem/cache')
-rw-r--r--src/mem/cache/cache_impl.hh15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 76fb697c2..b482d6314 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -1475,10 +1475,23 @@ Cache<TagStore>::recvTimingSnoopReq(PacketPtr pkt)
// Snoops shouldn't happen when bypassing caches
assert(!system->bypassCaches());
+ // check if the packet is for an address range covered by this
+ // cache, partly to not waste time looking for it, but also to
+ // ensure that we only forward the snoop upwards if it is within
+ // our address ranges
+ bool in_range = false;
+ for (AddrRangeList::const_iterator r = addrRanges.begin();
+ r != addrRanges.end(); ++r) {
+ if (r->contains(pkt->getAddr())) {
+ in_range = true;
+ break;
+ }
+ }
+
// Note that some deferred snoops don't have requests, since the
// original access may have already completed
if ((pkt->req && pkt->req->isUncacheable()) ||
- pkt->cmd == MemCmd::Writeback) {
+ pkt->cmd == MemCmd::Writeback || !in_range) {
//Can't get a hit on an uncacheable address
//Revisit this for multi level coherence
return;