summaryrefslogtreecommitdiff
path: root/src/mem/cache/mshr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/cache/mshr.cc')
-rw-r--r--src/mem/cache/mshr.cc46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/mem/cache/mshr.cc b/src/mem/cache/mshr.cc
index 4241fa375..1b21546aa 100644
--- a/src/mem/cache/mshr.cc
+++ b/src/mem/cache/mshr.cc
@@ -111,6 +111,52 @@ MSHR::TargetList::populateFlags()
}
}
+void
+MSHR::TargetList::updateWriteFlags(PacketPtr pkt)
+{
+ if (isWholeLineWrite()) {
+ // if we have already seen writes for the full block
+ // stop here, this might be a full line write followed
+ // by other compatible requests (e.g., reads)
+ return;
+ }
+
+ if (canMergeWrites) {
+ if (!pkt->isWrite()) {
+ // We won't allow further merging if this hasn't
+ // been a write
+ canMergeWrites = false;
+ return;
+ }
+
+ // Avoid merging requests with special flags (e.g.,
+ // strictly ordered)
+ const Request::FlagsType no_merge_flags =
+ Request::UNCACHEABLE | Request::STRICT_ORDER |
+ Request::MMAPPED_IPR | Request::PRIVILEGED |
+ Request::LLSC | Request::MEM_SWAP |
+ Request::MEM_SWAP_COND | Request::SECURE;
+ const auto &req_flags = pkt->req->getFlags();
+ bool compat_write = !req_flags.isSet(no_merge_flags);
+
+ // if this is the first write, it might be a whole
+ // line write and even if we can't merge any
+ // subsequent write requests, we still need to service
+ // it as a whole line write (e.g., SECURE whole line
+ // write)
+ bool first_write = empty();
+ if (first_write || compat_write) {
+ auto offset = pkt->getOffset(blkSize);
+ auto begin = writesBitmap.begin() + offset;
+ std::fill(begin, begin + pkt->getSize(), true);
+ }
+
+ // We won't allow further merging if this has been a
+ // special write
+ canMergeWrites &= compat_write;
+ }
+}
+
inline void
MSHR::TargetList::add(PacketPtr pkt, Tick readyTime,
Counter order, Target::Source source, bool markPending,