summaryrefslogtreecommitdiff
path: root/src/mem/cache/miss/mshr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/cache/miss/mshr.cc')
-rw-r--r--src/mem/cache/miss/mshr.cc53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/mem/cache/miss/mshr.cc b/src/mem/cache/miss/mshr.cc
index fc8d2175e..ca5e38601 100644
--- a/src/mem/cache/miss/mshr.cc
+++ b/src/mem/cache/miss/mshr.cc
@@ -75,6 +75,8 @@ MSHR::allocate(Addr _addr, int _size, PacketPtr target,
assert(deferredTargets.empty());
deferredNeedsExclusive = false;
pendingInvalidate = false;
+ replacedPendingUpgrade = false;
+ data = NULL;
}
void
@@ -171,6 +173,57 @@ MSHR::promoteDeferredTargets()
void
+MSHR::handleReplacement(CacheBlk *blk, int blkSize)
+{
+ // must be an outstanding upgrade request on block we're about to
+ // replace...
+ assert(!blk->isWritable());
+ assert(needsExclusive);
+ replacedPendingUpgrade = true;
+
+ // if it's dirty, just remember what happened and allow the
+ // writeback to continue. we'll reissue a ReadEx later whether
+ // the upgrade succeeds or not
+ if (blk->isDirty()) {
+ replacedPendingUpgradeDirty = true;
+ return;
+ }
+
+ // if not dirty, we need to save it off as it will be only valid
+ // copy in system if upgrade is successful (and may need to be
+ // written back then, as the current owner if any will be
+ // invalidating its block)
+ replacedPendingUpgradeDirty = false;
+ data = new uint8_t[blkSize];
+ std::memcpy(data, blk->data, blkSize);
+}
+
+
+bool
+MSHR::handleReplacedPendingUpgrade(Packet *pkt)
+{
+ // @TODO: if upgrade is nacked and replacedPendingUpgradeDirty is true, then we need to writeback the data (or rel
+ assert(pkt->cmd == MemCmd::UpgradeResp);
+ assert(replacedPendingUpgrade);
+ replacedPendingUpgrade = false; // reset
+ if (replacedPendingUpgradeDirty) {
+ // we wrote back the previous copy; just reissue as a ReadEx
+ return false;
+ }
+
+ // previous copy was not dirty, but we are now owner... fake out
+ // cache by taking saved data and converting UpgradeResp to
+ // ReadExResp
+ assert(data);
+ pkt->cmd = MemCmd::ReadExResp;
+ pkt->setData(data);
+ delete [] data;
+ data = NULL;
+ return true;
+}
+
+
+void
MSHR::dump()
{
ccprintf(cerr,