diff options
Diffstat (limited to 'src/mem/cache/miss/mshr.cc')
-rw-r--r-- | src/mem/cache/miss/mshr.cc | 53 |
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, |