mshr.cc (11740:6e1cb0f750c0) | mshr.cc (11741:72916416d2e2) |
---|---|
1/* 2 * Copyright (c) 2012-2013, 2015-2016 ARM Limited 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 51 unchanged lines hidden (view full) --- 60#include "mem/cache/cache.hh" 61#include "sim/core.hh" 62 63using namespace std; 64 65MSHR::MSHR() : downstreamPending(false), 66 pendingModified(false), 67 postInvalidate(false), postDowngrade(false), | 1/* 2 * Copyright (c) 2012-2013, 2015-2016 ARM Limited 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 51 unchanged lines hidden (view full) --- 60#include "mem/cache/cache.hh" 61#include "sim/core.hh" 62 63using namespace std; 64 65MSHR::MSHR() : downstreamPending(false), 66 pendingModified(false), 67 postInvalidate(false), postDowngrade(false), |
68 isForward(false), allocOnFill(false) | 68 isForward(false) |
69{ 70} 71 72MSHR::TargetList::TargetList() | 69{ 70} 71 72MSHR::TargetList::TargetList() |
73 : needsWritable(false), hasUpgrade(false) | 73 : needsWritable(false), hasUpgrade(false), allocOnFill(false) |
74{} 75 76 77void | 74{} 75 76 77void |
78MSHR::TargetList::updateFlags(PacketPtr pkt, Target::Source source) | 78MSHR::TargetList::updateFlags(PacketPtr pkt, Target::Source source, 79 bool alloc_on_fill) |
79{ 80 if (source != Target::FromSnoop) { 81 if (pkt->needsWritable()) { 82 needsWritable = true; 83 } 84 85 // StoreCondReq is effectively an upgrade if it's in an MSHR 86 // since it would have been failed already if we didn't have a 87 // read-only copy 88 if (pkt->isUpgrade() || pkt->cmd == MemCmd::StoreCondReq) { 89 hasUpgrade = true; 90 } | 80{ 81 if (source != Target::FromSnoop) { 82 if (pkt->needsWritable()) { 83 needsWritable = true; 84 } 85 86 // StoreCondReq is effectively an upgrade if it's in an MSHR 87 // since it would have been failed already if we didn't have a 88 // read-only copy 89 if (pkt->isUpgrade() || pkt->cmd == MemCmd::StoreCondReq) { 90 hasUpgrade = true; 91 } |
92 93 // potentially re-evaluate whether we should allocate on a fill or 94 // not 95 allocOnFill = allocOnFill || alloc_on_fill; |
|
91 } 92} 93 94void 95MSHR::TargetList::populateFlags() 96{ 97 resetFlags(); 98 for (auto& t: *this) { | 96 } 97} 98 99void 100MSHR::TargetList::populateFlags() 101{ 102 resetFlags(); 103 for (auto& t: *this) { |
99 updateFlags(t.pkt, t.source); | 104 updateFlags(t.pkt, t.source, t.allocOnFill); |
100 } 101} 102 103inline void 104MSHR::TargetList::add(PacketPtr pkt, Tick readyTime, | 105 } 106} 107 108inline void 109MSHR::TargetList::add(PacketPtr pkt, Tick readyTime, |
105 Counter order, Target::Source source, bool markPending) | 110 Counter order, Target::Source source, bool markPending, 111 bool alloc_on_fill) |
106{ | 112{ |
107 updateFlags(pkt, source); | 113 updateFlags(pkt, source, alloc_on_fill); |
108 if (markPending) { 109 // Iterate over the SenderState stack and see if we find 110 // an MSHR entry. If we do, set the downstreamPending 111 // flag. Otherwise, do nothing. 112 MSHR *mshr = pkt->findNextSenderState<MSHR>(); 113 if (mshr != nullptr) { 114 assert(!mshr->downstreamPending); 115 mshr->downstreamPending = true; 116 } else { 117 // No need to clear downstreamPending later 118 markPending = false; 119 } 120 } 121 | 114 if (markPending) { 115 // Iterate over the SenderState stack and see if we find 116 // an MSHR entry. If we do, set the downstreamPending 117 // flag. Otherwise, do nothing. 118 MSHR *mshr = pkt->findNextSenderState<MSHR>(); 119 if (mshr != nullptr) { 120 assert(!mshr->downstreamPending); 121 mshr->downstreamPending = true; 122 } else { 123 // No need to clear downstreamPending later 124 markPending = false; 125 } 126 } 127 |
122 emplace_back(pkt, readyTime, order, source, markPending); | 128 emplace_back(pkt, readyTime, order, source, markPending, alloc_on_fill); |
123} 124 125 126static void 127replaceUpgrade(PacketPtr pkt) 128{ 129 // remember if the current packet has data allocated 130 bool has_data = pkt->hasData() || pkt->hasRespData(); --- 103 unchanged lines hidden (view full) --- 234{ 235 blkAddr = blk_addr; 236 blkSize = blk_size; 237 isSecure = target->isSecure(); 238 readyTime = when_ready; 239 order = _order; 240 assert(target); 241 isForward = false; | 129} 130 131 132static void 133replaceUpgrade(PacketPtr pkt) 134{ 135 // remember if the current packet has data allocated 136 bool has_data = pkt->hasData() || pkt->hasRespData(); --- 103 unchanged lines hidden (view full) --- 240{ 241 blkAddr = blk_addr; 242 blkSize = blk_size; 243 isSecure = target->isSecure(); 244 readyTime = when_ready; 245 order = _order; 246 assert(target); 247 isForward = false; |
242 allocOnFill = alloc_on_fill; | |
243 _isUncacheable = target->req->isUncacheable(); 244 inService = false; 245 downstreamPending = false; 246 assert(targets.isReset()); 247 // Don't know of a case where we would allocate a new MSHR for a 248 // snoop (mem-side request), so set source according to request here 249 Target::Source source = (target->cmd == MemCmd::HardPFReq) ? 250 Target::FromPrefetcher : Target::FromCPU; | 248 _isUncacheable = target->req->isUncacheable(); 249 inService = false; 250 downstreamPending = false; 251 assert(targets.isReset()); 252 // Don't know of a case where we would allocate a new MSHR for a 253 // snoop (mem-side request), so set source according to request here 254 Target::Source source = (target->cmd == MemCmd::HardPFReq) ? 255 Target::FromPrefetcher : Target::FromCPU; |
251 targets.add(target, when_ready, _order, source, true); | 256 targets.add(target, when_ready, _order, source, true, alloc_on_fill); |
252 assert(deferredTargets.isReset()); 253} 254 255 256void 257MSHR::clearDownstreamPending() 258{ 259 assert(downstreamPending); --- 40 unchanged lines hidden (view full) --- 300 // outstanding miss 301 assert(pkt->cmd != MemCmd::HardPFReq); 302 303 // uncacheable accesses always allocate a new MSHR, and cacheable 304 // accesses ignore any uncacheable MSHRs, thus we should never 305 // have targets addded if originally allocated uncacheable 306 assert(!_isUncacheable); 307 | 257 assert(deferredTargets.isReset()); 258} 259 260 261void 262MSHR::clearDownstreamPending() 263{ 264 assert(downstreamPending); --- 40 unchanged lines hidden (view full) --- 305 // outstanding miss 306 assert(pkt->cmd != MemCmd::HardPFReq); 307 308 // uncacheable accesses always allocate a new MSHR, and cacheable 309 // accesses ignore any uncacheable MSHRs, thus we should never 310 // have targets addded if originally allocated uncacheable 311 assert(!_isUncacheable); 312 |
308 // potentially re-evaluate whether we should allocate on a fill or 309 // not 310 allocOnFill = allocOnFill || alloc_on_fill; 311 | |
312 // if there's a request already in service for this MSHR, we will 313 // have to defer the new target until after the response if any of 314 // the following are true: 315 // - there are other targets already deferred 316 // - there's a pending invalidate to be applied after the response 317 // comes back (but before this target is processed) 318 // - this target requires a writable block and either we're not 319 // getting a writable block back or we have already snooped 320 // another read request that will downgrade our writable block 321 // to non-writable (Shared or Owned) 322 if (inService && 323 (!deferredTargets.empty() || hasPostInvalidate() || 324 (pkt->needsWritable() && 325 (!isPendingModified() || hasPostDowngrade() || isForward)))) { 326 // need to put on deferred list 327 if (hasPostInvalidate()) 328 replaceUpgrade(pkt); | 313 // if there's a request already in service for this MSHR, we will 314 // have to defer the new target until after the response if any of 315 // the following are true: 316 // - there are other targets already deferred 317 // - there's a pending invalidate to be applied after the response 318 // comes back (but before this target is processed) 319 // - this target requires a writable block and either we're not 320 // getting a writable block back or we have already snooped 321 // another read request that will downgrade our writable block 322 // to non-writable (Shared or Owned) 323 if (inService && 324 (!deferredTargets.empty() || hasPostInvalidate() || 325 (pkt->needsWritable() && 326 (!isPendingModified() || hasPostDowngrade() || isForward)))) { 327 // need to put on deferred list 328 if (hasPostInvalidate()) 329 replaceUpgrade(pkt); |
329 deferredTargets.add(pkt, whenReady, _order, Target::FromCPU, true); | 330 deferredTargets.add(pkt, whenReady, _order, Target::FromCPU, true, 331 alloc_on_fill); |
330 } else { 331 // No request outstanding, or still OK to append to 332 // outstanding request: append to regular target list. Only 333 // mark pending if current request hasn't been issued yet 334 // (isn't in service). | 332 } else { 333 // No request outstanding, or still OK to append to 334 // outstanding request: append to regular target list. Only 335 // mark pending if current request hasn't been issued yet 336 // (isn't in service). |
335 targets.add(pkt, whenReady, _order, Target::FromCPU, !inService); | 337 targets.add(pkt, whenReady, _order, Target::FromCPU, !inService, 338 alloc_on_fill); |
336 } 337} 338 339bool 340MSHR::handleSnoop(PacketPtr pkt, Counter _order) 341{ 342 DPRINTF(Cache, "%s for %s addr %#llx size %d\n", __func__, 343 pkt->cmdString(), pkt->getAddr(), pkt->getSize()); --- 82 unchanged lines hidden (view full) --- 426 // as Shared (and thus non-writable) 427 pkt->setResponderHadWritable(); 428 429 // in the case of an uncacheable request there is no need 430 // to set the responderHadWritable flag, but since the 431 // recipient does not care there is no harm in doing so 432 } 433 targets.add(cp_pkt, curTick(), _order, Target::FromSnoop, | 339 } 340} 341 342bool 343MSHR::handleSnoop(PacketPtr pkt, Counter _order) 344{ 345 DPRINTF(Cache, "%s for %s addr %#llx size %d\n", __func__, 346 pkt->cmdString(), pkt->getAddr(), pkt->getSize()); --- 82 unchanged lines hidden (view full) --- 429 // as Shared (and thus non-writable) 430 pkt->setResponderHadWritable(); 431 432 // in the case of an uncacheable request there is no need 433 // to set the responderHadWritable flag, but since the 434 // recipient does not care there is no harm in doing so 435 } 436 targets.add(cp_pkt, curTick(), _order, Target::FromSnoop, |
434 downstreamPending && targets.needsWritable); | 437 downstreamPending && targets.needsWritable, false); |
435 436 if (pkt->needsWritable()) { 437 // This transaction will take away our pending copy 438 postInvalidate = true; 439 } 440 } 441 442 if (!pkt->needsWritable() && !pkt->req->isUncacheable()) { --- 79 unchanged lines hidden (view full) --- 522 523void 524MSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const 525{ 526 ccprintf(os, "%s[%#llx:%#llx](%s) %s %s %s state: %s %s %s %s %s\n", 527 prefix, blkAddr, blkAddr + blkSize - 1, 528 isSecure ? "s" : "ns", 529 isForward ? "Forward" : "", | 438 439 if (pkt->needsWritable()) { 440 // This transaction will take away our pending copy 441 postInvalidate = true; 442 } 443 } 444 445 if (!pkt->needsWritable() && !pkt->req->isUncacheable()) { --- 79 unchanged lines hidden (view full) --- 525 526void 527MSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const 528{ 529 ccprintf(os, "%s[%#llx:%#llx](%s) %s %s %s state: %s %s %s %s %s\n", 530 prefix, blkAddr, blkAddr + blkSize - 1, 531 isSecure ? "s" : "ns", 532 isForward ? "Forward" : "", |
530 allocOnFill ? "AllocOnFill" : "", | 533 allocOnFill() ? "AllocOnFill" : "", |
531 needsWritable() ? "Wrtbl" : "", 532 _isUncacheable ? "Unc" : "", 533 inService ? "InSvc" : "", 534 downstreamPending ? "DwnPend" : "", 535 postInvalidate ? "PostInv" : "", 536 postDowngrade ? "PostDowngr" : ""); 537 538 if (!targets.empty()) { --- 16 unchanged lines hidden --- | 534 needsWritable() ? "Wrtbl" : "", 535 _isUncacheable ? "Unc" : "", 536 inService ? "InSvc" : "", 537 downstreamPending ? "DwnPend" : "", 538 postInvalidate ? "PostInv" : "", 539 postDowngrade ? "PostDowngr" : ""); 540 541 if (!targets.empty()) { --- 16 unchanged lines hidden --- |