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) |
69{ 70} 71 72MSHR::TargetList::TargetList() |
73 : needsWritable(false), hasUpgrade(false), allocOnFill(false) |
74{} 75 76 77void |
78MSHR::TargetList::updateFlags(PacketPtr pkt, Target::Source source, 79 bool alloc_on_fill) |
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; |
96 } 97} 98 99void 100MSHR::TargetList::populateFlags() 101{ 102 resetFlags(); 103 for (auto& t: *this) { |
104 updateFlags(t.pkt, t.source, t.allocOnFill); |
105 } 106} 107 108inline void 109MSHR::TargetList::add(PacketPtr pkt, Tick readyTime, |
110 Counter order, Target::Source source, bool markPending, 111 bool alloc_on_fill) |
112{ |
113 updateFlags(pkt, source, alloc_on_fill); |
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 |
128 emplace_back(pkt, readyTime, order, source, markPending, alloc_on_fill); |
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; |
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; |
256 targets.add(target, when_ready, _order, source, true, alloc_on_fill); |
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 |
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); |
330 deferredTargets.add(pkt, whenReady, _order, Target::FromCPU, true, 331 alloc_on_fill); |
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). |
337 targets.add(pkt, whenReady, _order, Target::FromCPU, !inService, 338 alloc_on_fill); |
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, |
437 downstreamPending && targets.needsWritable, false); |
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" : "", |
533 allocOnFill() ? "AllocOnFill" : "", |
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 --- |