summaryrefslogtreecommitdiff
path: root/src/mem/cache/cache_impl.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/cache/cache_impl.hh')
-rw-r--r--src/mem/cache/cache_impl.hh36
1 files changed, 26 insertions, 10 deletions
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 0dd158afe..9ec0250e1 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -256,11 +256,9 @@ Cache<TagStore>::satisfyCpuSideRequest(PacketPtr pkt, BlkType *blk,
template<class TagStore>
void
-Cache<TagStore>::markInService(MSHR *mshr, PacketPtr pkt)
+Cache<TagStore>::markInService(MSHR *mshr, bool pending_dirty_resp)
{
- // packet can be either a request or response
-
- markInServiceInternal(mshr, pkt);
+ markInServiceInternal(mshr, pending_dirty_resp);
#if 0
if (mshr->originalCmd == MemCmd::HardPFReq) {
DPRINTF(HWPrefetch, "%s:Marking a HW_PF in service\n",
@@ -1745,7 +1743,7 @@ Cache<TagStore>::recvTimingSnoopReq(PacketPtr pkt)
if (pkt->isInvalidate()) {
// Invalidation trumps our writeback... discard here
- markInService(mshr);
+ markInService(mshr, false);
delete wb_pkt;
}
} // writebacks.size()
@@ -1910,9 +1908,10 @@ Cache<TagStore>::getTimingPacket()
snoop_pkt.senderState = mshr;
cpuSidePort->sendTimingSnoopReq(&snoop_pkt);
- // Check to see if the prefetch was squashed by an upper cache
- // Or if a writeback arrived between the time the prefetch was
- // placed in the MSHRs and when it was selected to send.
+ // Check to see if the prefetch was squashed by an upper
+ // cache (to prevent us from grabbing the line) or if a
+ // writeback arrived between the time the prefetch was
+ // placed in the MSHRs and when it was selected to be sent.
if (snoop_pkt.prefetchSquashed() || blk != NULL) {
DPRINTF(Cache, "Prefetch squashed by cache. "
"Deallocating mshr target %#x.\n", mshr->addr);
@@ -1926,8 +1925,13 @@ Cache<TagStore>::getTimingPacket()
return NULL;
}
+ // Check if the prefetch hit a writeback in an upper cache
+ // and if so we will eventually get a HardPFResp from
+ // above
if (snoop_pkt.memInhibitAsserted()) {
- markInService(mshr, &snoop_pkt);
+ // If we are getting a non-shared response it is dirty
+ bool pending_dirty_resp = !snoop_pkt.sharedAsserted();
+ markInService(mshr, pending_dirty_resp);
DPRINTF(Cache, "Upward snoop of prefetch for addr"
" %#x (%s) hit\n",
tgt_pkt->getAddr(), tgt_pkt->isSecure()? "s": "ns");
@@ -2148,7 +2152,19 @@ Cache<TagStore>::MemSidePacketQueue::sendDeferredPacket()
// care about this packet and might override it before
// it gets retried
} else {
- cache.markInService(mshr, pkt);
+ // As part of the call to sendTimingReq the packet is
+ // forwarded to all neighbouring caches (and any
+ // caches above them) as a snoop. The packet is also
+ // sent to any potential cache below as the
+ // interconnect is not allowed to buffer the
+ // packet. Thus at this point we know if any of the
+ // neighbouring, or the downstream cache is
+ // responding, and if so, if it is with a dirty line
+ // or not.
+ bool pending_dirty_resp = !pkt->sharedAsserted() &&
+ pkt->memInhibitAsserted();
+
+ cache.markInService(mshr, pending_dirty_resp);
}
}
}