diff options
Diffstat (limited to 'src/mem/cache/cache_impl.hh')
-rw-r--r-- | src/mem/cache/cache_impl.hh | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index e8e1876a0..00ba0d24f 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -1394,6 +1394,12 @@ Cache<TagStore>::handleSnoop(PacketPtr pkt, BlkType *blk, if (snoopPkt.sharedAsserted()) { pkt->assertShared(); } + // If this request is a prefetch and an + // upper level squashes the prefetch request, + // make sure to propogate the squash to the requester. + if (snoopPkt.prefetchSquashed()) { + pkt->setPrefetchSquashed(); + } } else { cpuSidePort->sendAtomicSnoop(pkt); if (!alreadyResponded && pkt->memInhibitAsserted()) { @@ -1420,6 +1426,17 @@ Cache<TagStore>::handleSnoop(PacketPtr pkt, BlkType *blk, bool respond = blk->isDirty() && pkt->needsResponse(); bool have_exclusive = blk->isWritable(); + // Invalidate any prefetch's from below that would strip write permissions + // MemCmd::HardPFReq is only observed by upstream caches. After missing + // above and in it's own cache, a new MemCmd::ReadReq is created that + // downstream caches observe. + if (pkt->cmd == MemCmd::HardPFReq) { + DPRINTF(Cache, "Squashing prefetch from lower cache %#x\n", + pkt->getAddr()); + pkt->setPrefetchSquashed(); + return; + } + if (pkt->isRead() && !invalidate) { assert(!needs_exclusive); pkt->assertShared(); @@ -1503,6 +1520,14 @@ Cache<TagStore>::recvTimingSnoopReq(PacketPtr pkt) Addr blk_addr = blockAlign(pkt->getAddr()); MSHR *mshr = mshrQueue.findMatch(blk_addr, is_secure); + // Squash any prefetch requests from below on MSHR hits + if (mshr && pkt->cmd == MemCmd::HardPFReq) { + DPRINTF(Cache, "Squashing prefetch from lower cache on mshr hit %#x\n", + pkt->getAddr()); + pkt->setPrefetchSquashed(); + return; + } + // Let the MSHR itself track the snoop and decide whether we want // to go ahead and do the regular cache snoop if (mshr && mshr->handleSnoop(pkt, order++)) { @@ -1730,6 +1755,20 @@ Cache<TagStore>::getTimingPacket() snoop_pkt.senderState = mshr; cpuSidePort->sendTimingSnoopReq(&snoop_pkt); + // Check to see if the prefetch was squashed by an upper cache + if (snoop_pkt.prefetchSquashed()) { + DPRINTF(Cache, "Prefetch squashed by upper cache. " + "Deallocating mshr target %#x.\n", mshr->addr); + + // Deallocate the mshr target + if (mshr->queue->forceDeallocateTarget(mshr)) { + // Clear block if this deallocation resulted freed an + // mshr when all had previously been utilized + clearBlocked((BlockedCause)(mshr->queue->index)); + } + return NULL; + } + if (snoop_pkt.memInhibitAsserted()) { markInService(mshr, &snoop_pkt); DPRINTF(Cache, "Upward snoop of prefetch for addr" |