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 ---