summaryrefslogtreecommitdiff
path: root/src/mem/cache/mshr.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/cache/mshr.hh')
-rw-r--r--src/mem/cache/mshr.hh103
1 files changed, 100 insertions, 3 deletions
diff --git a/src/mem/cache/mshr.hh b/src/mem/cache/mshr.hh
index 218de9244..56b81b6b2 100644
--- a/src/mem/cache/mshr.hh
+++ b/src/mem/cache/mshr.hh
@@ -38,6 +38,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Erik Hallnor
+ * Nikos Nikoleris
*/
/**
@@ -52,11 +53,13 @@
#include <iosfwd>
#include <list>
#include <string>
+#include <vector>
#include "base/printable.hh"
#include "base/types.hh"
#include "mem/cache/queue_entry.hh"
#include "mem/packet.hh"
+#include "mem/request.hh"
#include "sim/core.hh"
class BaseCache;
@@ -115,6 +118,9 @@ class MSHR : public QueueEntry, public Printable
public:
+ /** Track if we sent this as a whole line write or not */
+ bool wasWholeLineWrite;
+
/** True if the entry is just a simple forward from an upper level */
bool isForward;
@@ -187,7 +193,24 @@ class MSHR : public QueueEntry, public Printable
void updateFlags(PacketPtr pkt, Target::Source source,
bool alloc_on_fill);
+ /**
+ * Reset state
+ *
+ * @param blk_addr Address of the cache block
+ * @param blk_size Size of the cache block
+ */
+ void init(Addr blk_addr, Addr blk_size) {
+ blkAddr = blk_addr;
+ blkSize = blk_size;
+ writesBitmap.resize(blk_size);
+
+ resetFlags();
+ }
+
void resetFlags() {
+ onlyWrites = true;
+ std::fill(writesBitmap.begin(), writesBitmap.end(), false);
+
needsWritable = false;
hasUpgrade = false;
allocOnFill = false;
@@ -203,12 +226,44 @@ class MSHR : public QueueEntry, public Printable
void populateFlags();
/**
+ * Add the specified packet in the TargetList. This function
+ * stores information related to the added packet and updates
+ * accordingly the flags.
+ *
+ * @param pkt Packet considered for adding
+ */
+ void updateWriteFlags(PacketPtr pkt) {
+ const Request::FlagsType noMergeFlags =
+ Request::UNCACHEABLE |
+ Request::STRICT_ORDER | Request::MMAPPED_IPR |
+ Request::PRIVILEGED | Request::LLSC |
+ Request::MEM_SWAP | Request::MEM_SWAP_COND |
+ Request::SECURE;
+
+ // 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)
+ if (!isWholeLineWrite()) {
+ bool can_merge_write = pkt->isWrite() &&
+ ((pkt->req->getFlags() & noMergeFlags) == 0);
+ onlyWrites &= can_merge_write;
+ if (onlyWrites) {
+ auto offset = pkt->getOffset(blkSize);
+ auto begin = writesBitmap.begin() + offset;
+ std::fill(begin, begin + pkt->getSize(), true);
+ }
+ }
+ }
+
+ /**
* Tests if the flags of this TargetList have their default
* values.
+ *
+ * @return True if the TargetList are reset, false otherwise.
*/
bool isReset() const {
return !needsWritable && !hasUpgrade && !allocOnFill &&
- !hasFromCache;
+ !hasFromCache && onlyWrites;
}
/**
@@ -224,8 +279,7 @@ class MSHR : public QueueEntry, public Printable
* @param alloc_on_fill Whether it should allocate on a fill
*/
void add(PacketPtr pkt, Tick readyTime, Counter order,
- Target::Source source, bool markPending,
- bool alloc_on_fill);
+ Target::Source source, bool markPending, bool alloc_on_fill);
/**
* Convert upgrades to the equivalent request if the cache line they
@@ -238,6 +292,39 @@ class MSHR : public QueueEntry, public Printable
bool trySatisfyFunctional(PacketPtr pkt);
void print(std::ostream &os, int verbosity,
const std::string &prefix) const;
+
+ /**
+ * Check if this list contains only compatible writes, and if they
+ * span the entire cache line. This is used as part of the
+ * miss-packet creation. Note that new requests may arrive after a
+ * miss-packet has been created, and for the fill we therefore use
+ * the wasWholeLineWrite field.
+ */
+ bool isWholeLineWrite() const
+ {
+ return onlyWrites &&
+ std::all_of(writesBitmap.begin(),
+ writesBitmap.end(), [](bool i) { return i; });
+ }
+
+ private:
+ /** Address of the cache block for this list of targets. */
+ Addr blkAddr;
+
+ /** Size of the cache block. */
+ Addr blkSize;
+
+ /** Are we only dealing with writes. */
+ bool onlyWrites;
+
+ // NOTE: std::vector<bool> might not meet satisfy the
+ // ForwardIterator requirement and therefore cannot be used
+ // for writesBitmap.
+ /**
+ * Track which bytes are written by requests in this target
+ * list.
+ */
+ std::vector<char> writesBitmap;
};
/** A list of MSHRs. */
@@ -315,6 +402,16 @@ class MSHR : public QueueEntry, public Printable
TargetList deferredTargets;
public:
+ /**
+ * Check if this MSHR contains only compatible writes, and if they
+ * span the entire cache line. This is used as part of the
+ * miss-packet creation. Note that new requests may arrive after a
+ * miss-packet has been created, and for the fill we therefore use
+ * the wasWholeLineWrite field.
+ */
+ bool isWholeLineWrite() const {
+ return targets.isWholeLineWrite();
+ }
/**
* Allocate a miss to this MSHR.