cache.cc (11278:18411ccc4f3c) cache.cc (11284:b3926db25371)
1/*
2 * Copyright (c) 2010-2015 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

--- 143 unchanged lines hidden (view full) ---

152
153 assert(blk && blk->isValid());
154 // Occasionally this is not true... if we are a lower-level cache
155 // satisfying a string of Read and ReadEx requests from
156 // upper-level caches, a Read will mark the block as shared but we
157 // can satisfy a following ReadEx anyway since we can rely on the
158 // Read requester(s) to have buffered the ReadEx snoop and to
159 // invalidate their blocks after receiving them.
1/*
2 * Copyright (c) 2010-2015 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

--- 143 unchanged lines hidden (view full) ---

152
153 assert(blk && blk->isValid());
154 // Occasionally this is not true... if we are a lower-level cache
155 // satisfying a string of Read and ReadEx requests from
156 // upper-level caches, a Read will mark the block as shared but we
157 // can satisfy a following ReadEx anyway since we can rely on the
158 // Read requester(s) to have buffered the ReadEx snoop and to
159 // invalidate their blocks after receiving them.
160 // assert(!pkt->needsExclusive() || blk->isWritable());
160 // assert(!pkt->needsWritable() || blk->isWritable());
161 assert(pkt->getOffset(blkSize) + pkt->getSize() <= blkSize);
162
163 // Check RMW operations first since both isRead() and
164 // isWrite() will be true for them
165 if (pkt->cmd == MemCmd::SwapReq) {
166 cmpAndSwap(blk, pkt);
167 } else if (pkt->isWrite()) {
161 assert(pkt->getOffset(blkSize) + pkt->getSize() <= blkSize);
162
163 // Check RMW operations first since both isRead() and
164 // isWrite() will be true for them
165 if (pkt->cmd == MemCmd::SwapReq) {
166 cmpAndSwap(blk, pkt);
167 } else if (pkt->isWrite()) {
168 // we have the block in a writable state and can go ahead,
169 // note that the line may be also be considered writable in
170 // downstream caches along the path to memory, but always
171 // Exclusive, and never Modified
168 assert(blk->isWritable());
172 assert(blk->isWritable());
169 // Write or WriteLine at the first cache with block in Exclusive
173 // Write or WriteLine at the first cache with block in writable state
170 if (blk->checkWrite(pkt)) {
171 pkt->writeDataToBlock(blk->data, blkSize);
172 }
174 if (blk->checkWrite(pkt)) {
175 pkt->writeDataToBlock(blk->data, blkSize);
176 }
173 // Always mark the line as dirty even if we are a failed
174 // StoreCond so we supply data to any snoops that have
175 // appended themselves to this cache before knowing the store
176 // will fail.
177 // Always mark the line as dirty (and thus transition to the
178 // Modified state) even if we are a failed StoreCond so we
179 // supply data to any snoops that have appended themselves to
180 // this cache before knowing the store will fail.
177 blk->status |= BlkDirty;
178 DPRINTF(Cache, "%s for %s addr %#llx size %d (write)\n", __func__,
179 pkt->cmdString(), pkt->getAddr(), pkt->getSize());
180 } else if (pkt->isRead()) {
181 if (pkt->isLLSC()) {
182 blk->trackLoadLocked(pkt);
183 }
184 pkt->setDataFromBlock(blk->data, blkSize);
185 // determine if this read is from a (coherent) cache, or not
186 // by looking at the command type; we could potentially add a
187 // packet attribute such as 'FromCache' to make this check a
188 // bit cleaner
189 if (pkt->cmd == MemCmd::ReadExReq ||
190 pkt->cmd == MemCmd::ReadSharedReq ||
191 pkt->cmd == MemCmd::ReadCleanReq ||
192 pkt->cmd == MemCmd::SCUpgradeFailReq) {
193 assert(pkt->getSize() == blkSize);
194 // special handling for coherent block requests from
195 // upper-level caches
181 blk->status |= BlkDirty;
182 DPRINTF(Cache, "%s for %s addr %#llx size %d (write)\n", __func__,
183 pkt->cmdString(), pkt->getAddr(), pkt->getSize());
184 } else if (pkt->isRead()) {
185 if (pkt->isLLSC()) {
186 blk->trackLoadLocked(pkt);
187 }
188 pkt->setDataFromBlock(blk->data, blkSize);
189 // determine if this read is from a (coherent) cache, or not
190 // by looking at the command type; we could potentially add a
191 // packet attribute such as 'FromCache' to make this check a
192 // bit cleaner
193 if (pkt->cmd == MemCmd::ReadExReq ||
194 pkt->cmd == MemCmd::ReadSharedReq ||
195 pkt->cmd == MemCmd::ReadCleanReq ||
196 pkt->cmd == MemCmd::SCUpgradeFailReq) {
197 assert(pkt->getSize() == blkSize);
198 // special handling for coherent block requests from
199 // upper-level caches
196 if (pkt->needsExclusive()) {
200 if (pkt->needsWritable()) {
197 // sanity check
198 assert(pkt->cmd == MemCmd::ReadExReq ||
199 pkt->cmd == MemCmd::SCUpgradeFailReq);
200
201 // if we have a dirty copy, make sure the recipient
201 // sanity check
202 assert(pkt->cmd == MemCmd::ReadExReq ||
203 pkt->cmd == MemCmd::SCUpgradeFailReq);
204
205 // if we have a dirty copy, make sure the recipient
202 // keeps it marked dirty
206 // keeps it marked dirty (in the modified state)
203 if (blk->isDirty()) {
207 if (blk->isDirty()) {
204 pkt->assertMemInhibit();
208 pkt->setCacheResponding();
205 }
206 // on ReadExReq we give up our copy unconditionally,
207 // even if this cache is mostly inclusive, we may want
208 // to revisit this
209 invalidateBlock(blk);
210 } else if (blk->isWritable() && !pending_downgrade &&
209 }
210 // on ReadExReq we give up our copy unconditionally,
211 // even if this cache is mostly inclusive, we may want
212 // to revisit this
213 invalidateBlock(blk);
214 } else if (blk->isWritable() && !pending_downgrade &&
211 !pkt->sharedAsserted() &&
215 !pkt->hasSharers() &&
212 pkt->cmd != MemCmd::ReadCleanReq) {
216 pkt->cmd != MemCmd::ReadCleanReq) {
213 // we can give the requester an exclusive copy (by not
214 // asserting shared line) on a read request if:
215 // - we have an exclusive copy at this level (& below)
217 // we can give the requester a writable copy on a read
218 // request if:
219 // - we have a writable copy at this level (& below)
216 // - we don't have a pending snoop from below
217 // signaling another read request
218 // - no other cache above has a copy (otherwise it
220 // - we don't have a pending snoop from below
221 // signaling another read request
222 // - no other cache above has a copy (otherwise it
219 // would have asseretd shared line on request)
220 // - we are not satisfying an instruction fetch (this
221 // prevents dirty data in the i-cache)
222
223 // would have set hasSharers flag when
224 // snooping the packet)
225 // - the read has explicitly asked for a clean
226 // copy of the line
223 if (blk->isDirty()) {
224 // special considerations if we're owner:
225 if (!deferred_response) {
227 if (blk->isDirty()) {
228 // special considerations if we're owner:
229 if (!deferred_response) {
226 // if we are responding immediately and can
227 // signal that we're transferring ownership
228 // (inhibit set) along with exclusivity
229 // (shared not set), do so
230 pkt->assertMemInhibit();
230 // respond with the line in Modified state
231 // (cacheResponding set, hasSharers not set)
232 pkt->setCacheResponding();
231
233
232 // if this cache is mostly inclusive, we keep
233 // the block as writable (exclusive), and pass
234 // it upwards as writable and dirty
235 // (modified), hence we have multiple caches
236 // considering the same block writable,
237 // something that we get away with due to the
238 // fact that: 1) this cache has been
239 // considered the ordering points and
240 // responded to all snoops up till now, and 2)
241 // we always snoop upwards before consulting
242 // the local cache, both on a normal request
243 // (snooping done by the crossbar), and on a
244 // snoop
245 blk->status &= ~BlkDirty;
246
247 // if this cache is mostly exclusive with
248 // respect to the cache above, drop the block
249 if (clusivity == Enums::mostly_excl) {
234 if (clusivity == Enums::mostly_excl) {
235 // if this cache is mostly exclusive with
236 // respect to the cache above, drop the
237 // block, no need to first unset the dirty
238 // bit
250 invalidateBlock(blk);
239 invalidateBlock(blk);
240 } else {
241 // if this cache is mostly inclusive, we
242 // keep the block in the Exclusive state,
243 // and pass it upwards as Modified
244 // (writable and dirty), hence we have
245 // multiple caches, all on the same path
246 // towards memory, all considering the
247 // same block writable, but only one
248 // considering it Modified
249
250 // we get away with multiple caches (on
251 // the same path to memory) considering
252 // the block writeable as we always enter
253 // the cache hierarchy through a cache,
254 // and first snoop upwards in all other
255 // branches
256 blk->status &= ~BlkDirty;
251 }
252 } else {
253 // if we're responding after our own miss,
254 // there's a window where the recipient didn't
255 // know it was getting ownership and may not
256 // have responded to snoops correctly, so we
257 }
258 } else {
259 // if we're responding after our own miss,
260 // there's a window where the recipient didn't
261 // know it was getting ownership and may not
262 // have responded to snoops correctly, so we
257 // can't pass off ownership *or* exclusivity
258 pkt->assertShared();
263 // have to respond with a shared line
264 pkt->setHasSharers();
259 }
260 }
261 } else {
262 // otherwise only respond with a shared copy
265 }
266 }
267 } else {
268 // otherwise only respond with a shared copy
263 pkt->assertShared();
269 pkt->setHasSharers();
264 }
265 }
266 } else {
270 }
271 }
272 } else {
267 // Upgrade or Invalidate, since we have it Exclusively (E or
268 // M), we ack then invalidate.
273 // Upgrade or Invalidate
269 assert(pkt->isUpgrade() || pkt->isInvalidate());
270
271 // for invalidations we could be looking at the temp block
272 // (for upgrades we always allocate)
273 invalidateBlock(blk);
274 DPRINTF(Cache, "%s for %s addr %#llx size %d (invalidation)\n",
275 __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize());
276 }
277}
278
279
280/////////////////////////////////////////////////////
281//
282// MSHR helper functions
283//
284/////////////////////////////////////////////////////
285
286
287void
274 assert(pkt->isUpgrade() || pkt->isInvalidate());
275
276 // for invalidations we could be looking at the temp block
277 // (for upgrades we always allocate)
278 invalidateBlock(blk);
279 DPRINTF(Cache, "%s for %s addr %#llx size %d (invalidation)\n",
280 __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize());
281 }
282}
283
284
285/////////////////////////////////////////////////////
286//
287// MSHR helper functions
288//
289/////////////////////////////////////////////////////
290
291
292void
288Cache::markInService(MSHR *mshr, bool pending_dirty_resp)
293Cache::markInService(MSHR *mshr, bool pending_modified_resp)
289{
294{
290 markInServiceInternal(mshr, pending_dirty_resp);
295 markInServiceInternal(mshr, pending_modified_resp);
291}
292
293/////////////////////////////////////////////////////
294//
295// Access path: requests coming in from the CPU side
296//
297/////////////////////////////////////////////////////
298

--- 116 unchanged lines hidden (view full) ---

415 blk->status |= BlkSecure;
416 }
417 }
418 // only mark the block dirty if we got a writeback command,
419 // and leave it as is for a clean writeback
420 if (pkt->cmd == MemCmd::WritebackDirty) {
421 blk->status |= BlkDirty;
422 }
296}
297
298/////////////////////////////////////////////////////
299//
300// Access path: requests coming in from the CPU side
301//
302/////////////////////////////////////////////////////
303

--- 116 unchanged lines hidden (view full) ---

420 blk->status |= BlkSecure;
421 }
422 }
423 // only mark the block dirty if we got a writeback command,
424 // and leave it as is for a clean writeback
425 if (pkt->cmd == MemCmd::WritebackDirty) {
426 blk->status |= BlkDirty;
427 }
423 // if shared is not asserted we got the writeback in modified
424 // state, if it is asserted we are in the owned state
425 if (!pkt->sharedAsserted()) {
428 // if the packet does not have sharers, it is passing
429 // writable, and we got the writeback in Modified or Exclusive
430 // state, if not we are in the Owned or Shared state
431 if (!pkt->hasSharers()) {
426 blk->status |= BlkWritable;
427 }
428 // nothing else to do; writeback doesn't expect response
429 assert(!pkt->needsResponse());
430 std::memcpy(blk->data, pkt->getConstPtr<uint8_t>(), blkSize);
431 DPRINTF(Cache, "%s new state is %s\n", __func__, blk->print());
432 incHitCount(pkt);
433 return true;

--- 6 unchanged lines hidden (view full) ---

440 return true;
441 }
442 // We didn't find the block here, propagate the CleanEvict further
443 // down the memory hierarchy. Returning false will treat the CleanEvict
444 // like a Writeback which could not find a replaceable block so has to
445 // go to next level.
446 return false;
447 } else if ((blk != NULL) &&
432 blk->status |= BlkWritable;
433 }
434 // nothing else to do; writeback doesn't expect response
435 assert(!pkt->needsResponse());
436 std::memcpy(blk->data, pkt->getConstPtr<uint8_t>(), blkSize);
437 DPRINTF(Cache, "%s new state is %s\n", __func__, blk->print());
438 incHitCount(pkt);
439 return true;

--- 6 unchanged lines hidden (view full) ---

446 return true;
447 }
448 // We didn't find the block here, propagate the CleanEvict further
449 // down the memory hierarchy. Returning false will treat the CleanEvict
450 // like a Writeback which could not find a replaceable block so has to
451 // go to next level.
452 return false;
453 } else if ((blk != NULL) &&
448 (pkt->needsExclusive() ? blk->isWritable()
449 : blk->isReadable())) {
454 (pkt->needsWritable() ? blk->isWritable() : blk->isReadable())) {
450 // OK to satisfy access
451 incHitCount(pkt);
452 satisfyCpuSideRequest(pkt, blk);
453 return true;
454 }
455
456 // Can't satisfy access normally... either no block (blk == NULL)
455 // OK to satisfy access
456 incHitCount(pkt);
457 satisfyCpuSideRequest(pkt, blk);
458 return true;
459 }
460
461 // Can't satisfy access normally... either no block (blk == NULL)
457 // or have block but need exclusive & only have shared.
462 // or have block but need writable
458
459 incMissCount(pkt);
460
461 if (blk == NULL && pkt->isLLSC() && pkt->isWrite()) {
462 // complete miss on store conditional... just give up now
463 pkt->req->setExtraData(0);
464 return true;
465 }

--- 136 unchanged lines hidden (view full) ---

602 // @todo This should really enqueue the packet rather
603 bool M5_VAR_USED success = memSidePort->sendTimingReq(pkt);
604 assert(success);
605 return true;
606 }
607
608 promoteWholeLineWrites(pkt);
609
463
464 incMissCount(pkt);
465
466 if (blk == NULL && pkt->isLLSC() && pkt->isWrite()) {
467 // complete miss on store conditional... just give up now
468 pkt->req->setExtraData(0);
469 return true;
470 }

--- 136 unchanged lines hidden (view full) ---

607 // @todo This should really enqueue the packet rather
608 bool M5_VAR_USED success = memSidePort->sendTimingReq(pkt);
609 assert(success);
610 return true;
611 }
612
613 promoteWholeLineWrites(pkt);
614
610 if (pkt->memInhibitAsserted()) {
615 if (pkt->cacheResponding()) {
611 // a cache above us (but not where the packet came from) is
616 // a cache above us (but not where the packet came from) is
612 // responding to the request
613 DPRINTF(Cache, "mem inhibited on addr %#llx (%s): not responding\n",
617 // responding to the request, in other words it has the line
618 // in Modified or Owned state
619 DPRINTF(Cache, "Cache above responding to %#llx (%s): "
620 "not responding\n",
614 pkt->getAddr(), pkt->isSecure() ? "s" : "ns");
615
621 pkt->getAddr(), pkt->isSecure() ? "s" : "ns");
622
616 // if the packet needs exclusive, and the cache that has
617 // promised to respond (setting the inhibit flag) is not
618 // providing exclusive (it is in O vs M state), we know that
619 // there may be other shared copies in the system; go out and
620 // invalidate them all
621 if (pkt->needsExclusive() && !pkt->isSupplyExclusive()) {
623 // if the packet needs the block to be writable, and the cache
624 // that has promised to respond (setting the cache responding
625 // flag) is not providing writable (it is in Owned rather than
626 // the Modified state), we know that there may be other Shared
627 // copies in the system; go out and invalidate them all
628 if (pkt->needsWritable() && !pkt->responderHadWritable()) {
629 // an upstream cache that had the line in Owned state
630 // (dirty, but not writable), is responding and thus
631 // transferring the dirty line from one branch of the
632 // cache hierarchy to another
633
634 // send out an express snoop and invalidate all other
635 // copies (snooping a packet that needs writable is the
636 // same as an invalidation), thus turning the Owned line
637 // into a Modified line, note that we don't invalidate the
638 // block in the current cache or any other cache on the
639 // path to memory
640
622 // create a downstream express snoop with cleared packet
623 // flags, there is no need to allocate any data as the
624 // packet is merely used to co-ordinate state transitions
625 Packet *snoop_pkt = new Packet(pkt, true, false);
626
627 // also reset the bus time that the original packet has
628 // not yet paid for
629 snoop_pkt->headerDelay = snoop_pkt->payloadDelay = 0;
630
631 // make this an instantaneous express snoop, and let the
641 // create a downstream express snoop with cleared packet
642 // flags, there is no need to allocate any data as the
643 // packet is merely used to co-ordinate state transitions
644 Packet *snoop_pkt = new Packet(pkt, true, false);
645
646 // also reset the bus time that the original packet has
647 // not yet paid for
648 snoop_pkt->headerDelay = snoop_pkt->payloadDelay = 0;
649
650 // make this an instantaneous express snoop, and let the
632 // other caches in the system know that the packet is
633 // inhibited, because we have found the authorative copy
634 // (O) that will supply the right data
651 // other caches in the system know that the another cache
652 // is responding, because we have found the authorative
653 // copy (Modified or Owned) that will supply the right
654 // data
635 snoop_pkt->setExpressSnoop();
655 snoop_pkt->setExpressSnoop();
636 snoop_pkt->assertMemInhibit();
656 snoop_pkt->setCacheResponding();
637
638 // this express snoop travels towards the memory, and at
639 // every crossbar it is snooped upwards thus reaching
640 // every cache in the system
641 bool M5_VAR_USED success = memSidePort->sendTimingReq(snoop_pkt);
642 // express snoops always succeed
643 assert(success);
644
657
658 // this express snoop travels towards the memory, and at
659 // every crossbar it is snooped upwards thus reaching
660 // every cache in the system
661 bool M5_VAR_USED success = memSidePort->sendTimingReq(snoop_pkt);
662 // express snoops always succeed
663 assert(success);
664
645 // main memory will delete the packet
665 // main memory will delete the snoop packet
646 }
647
666 }
667
648 // queue for deletion, as the sending cache is still relying
649 // on the packet
668 // queue for deletion, as opposed to immediate deletion, as
669 // the sending cache is still relying on the packet
650 pendingDelete.reset(pkt);
651
670 pendingDelete.reset(pkt);
671
652 // no need to take any action in this particular cache as the
653 // caches along the path to memory are allowed to keep lines
654 // in a shared state, and a cache above us already committed
655 // to responding
672 // no need to take any action in this particular cache as an
673 // upstream cache has already committed to responding, and
674 // either the packet does not need writable (and we can let
675 // the cache that set the cache responding flag pass on the
676 // line without any need for intervention), or if the packet
677 // needs writable it is provided, or we have already sent out
678 // any express snoops in the section above
656 return true;
657 }
658
659 // anything that is merely forwarded pays for the forward latency and
660 // the delay provided by the crossbar
661 Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay;
662
663 // We use lookupLatency here because it is used to specify the latency

--- 203 unchanged lines hidden (view full) ---

867 // that yet. Note that we do need to leave the
868 // block valid so that it stays in the cache, in
869 // case we get an upgrade response (and hence no
870 // new data) when the write miss completes.
871 // As long as CPUs do proper store/load forwarding
872 // internally, and have a sufficiently weak memory
873 // model, this is probably unnecessary, but at some
874 // point it must have seemed like we needed it...
679 return true;
680 }
681
682 // anything that is merely forwarded pays for the forward latency and
683 // the delay provided by the crossbar
684 Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay;
685
686 // We use lookupLatency here because it is used to specify the latency

--- 203 unchanged lines hidden (view full) ---

890 // that yet. Note that we do need to leave the
891 // block valid so that it stays in the cache, in
892 // case we get an upgrade response (and hence no
893 // new data) when the write miss completes.
894 // As long as CPUs do proper store/load forwarding
895 // internally, and have a sufficiently weak memory
896 // model, this is probably unnecessary, but at some
897 // point it must have seemed like we needed it...
875 assert(pkt->needsExclusive());
898 assert(pkt->needsWritable());
876 assert(!blk->isWritable());
877 blk->status &= ~BlkReadable;
878 }
879 // Here we are using forward_time, modelling the latency of
880 // a miss (outbound) just as forwardLatency, neglecting the
881 // lookupLatency component.
882 allocateMissBuffer(pkt, forward_time);
883 }

--- 11 unchanged lines hidden (view full) ---

895
896 return true;
897}
898
899
900// See comment in cache.hh.
901PacketPtr
902Cache::getBusPacket(PacketPtr cpu_pkt, CacheBlk *blk,
899 assert(!blk->isWritable());
900 blk->status &= ~BlkReadable;
901 }
902 // Here we are using forward_time, modelling the latency of
903 // a miss (outbound) just as forwardLatency, neglecting the
904 // lookupLatency component.
905 allocateMissBuffer(pkt, forward_time);
906 }

--- 11 unchanged lines hidden (view full) ---

918
919 return true;
920}
921
922
923// See comment in cache.hh.
924PacketPtr
925Cache::getBusPacket(PacketPtr cpu_pkt, CacheBlk *blk,
903 bool needsExclusive) const
926 bool needsWritable) const
904{
905 bool blkValid = blk && blk->isValid();
906
907 if (cpu_pkt->req->isUncacheable()) {
908 // note that at the point we see the uncacheable request we
909 // flush any block, but there could be an outstanding MSHR,
910 // and the cache could have filled again before we actually
911 // send out the forwarded uncacheable request (blk could thus

--- 14 unchanged lines hidden (view full) ---

926
927 MemCmd cmd;
928 // @TODO make useUpgrades a parameter.
929 // Note that ownership protocols require upgrade, otherwise a
930 // write miss on a shared owned block will generate a ReadExcl,
931 // which will clobber the owned copy.
932 const bool useUpgrades = true;
933 if (blkValid && useUpgrades) {
927{
928 bool blkValid = blk && blk->isValid();
929
930 if (cpu_pkt->req->isUncacheable()) {
931 // note that at the point we see the uncacheable request we
932 // flush any block, but there could be an outstanding MSHR,
933 // and the cache could have filled again before we actually
934 // send out the forwarded uncacheable request (blk could thus

--- 14 unchanged lines hidden (view full) ---

949
950 MemCmd cmd;
951 // @TODO make useUpgrades a parameter.
952 // Note that ownership protocols require upgrade, otherwise a
953 // write miss on a shared owned block will generate a ReadExcl,
954 // which will clobber the owned copy.
955 const bool useUpgrades = true;
956 if (blkValid && useUpgrades) {
934 // only reason to be here is that blk is shared
935 // (read-only) and we need exclusive
936 assert(needsExclusive);
957 // only reason to be here is that blk is read only and we need
958 // it to be writable
959 assert(needsWritable);
937 assert(!blk->isWritable());
938 cmd = cpu_pkt->isLLSC() ? MemCmd::SCUpgradeReq : MemCmd::UpgradeReq;
939 } else if (cpu_pkt->cmd == MemCmd::SCUpgradeFailReq ||
940 cpu_pkt->cmd == MemCmd::StoreCondFailReq) {
941 // Even though this SC will fail, we still need to send out the
942 // request and get the data to supply it to other snoopers in the case
943 // where the determination the StoreCond fails is delayed due to
944 // all caches not being on the same local bus.
945 cmd = MemCmd::SCUpgradeFailReq;
946 } else if (cpu_pkt->cmd == MemCmd::WriteLineReq) {
947 // forward as invalidate to all other caches, this gives us
960 assert(!blk->isWritable());
961 cmd = cpu_pkt->isLLSC() ? MemCmd::SCUpgradeReq : MemCmd::UpgradeReq;
962 } else if (cpu_pkt->cmd == MemCmd::SCUpgradeFailReq ||
963 cpu_pkt->cmd == MemCmd::StoreCondFailReq) {
964 // Even though this SC will fail, we still need to send out the
965 // request and get the data to supply it to other snoopers in the case
966 // where the determination the StoreCond fails is delayed due to
967 // all caches not being on the same local bus.
968 cmd = MemCmd::SCUpgradeFailReq;
969 } else if (cpu_pkt->cmd == MemCmd::WriteLineReq) {
970 // forward as invalidate to all other caches, this gives us
948 // the line in exclusive state, and invalidates all other
971 // the line in Exclusive state, and invalidates all other
949 // copies
950 cmd = MemCmd::InvalidateReq;
951 } else {
952 // block is invalid
972 // copies
973 cmd = MemCmd::InvalidateReq;
974 } else {
975 // block is invalid
953 cmd = needsExclusive ? MemCmd::ReadExReq :
976 cmd = needsWritable ? MemCmd::ReadExReq :
954 (isReadOnly ? MemCmd::ReadCleanReq : MemCmd::ReadSharedReq);
955 }
956 PacketPtr pkt = new Packet(cpu_pkt->req, cmd, blkSize);
957
977 (isReadOnly ? MemCmd::ReadCleanReq : MemCmd::ReadSharedReq);
978 }
979 PacketPtr pkt = new Packet(cpu_pkt->req, cmd, blkSize);
980
958 // if there are sharers in the upper levels, pass that info downstream
959 if (cpu_pkt->sharedAsserted()) {
981 // if there are upstream caches that have already marked the
982 // packet as having sharers (not passing writable), pass that info
983 // downstream
984 if (cpu_pkt->hasSharers()) {
960 // note that cpu_pkt may have spent a considerable time in the
961 // MSHR queue and that the information could possibly be out
962 // of date, however, there is no harm in conservatively
985 // note that cpu_pkt may have spent a considerable time in the
986 // MSHR queue and that the information could possibly be out
987 // of date, however, there is no harm in conservatively
963 // assuming the block is shared
964 pkt->assertShared();
965 DPRINTF(Cache, "%s passing shared from %s to %s addr %#llx size %d\n",
988 // assuming the block has sharers
989 pkt->setHasSharers();
990 DPRINTF(Cache, "%s passing hasSharers from %s to %s addr %#llx "
991 "size %d\n",
966 __func__, cpu_pkt->cmdString(), pkt->cmdString(),
967 pkt->getAddr(), pkt->getSize());
968 }
969
970 // the packet should be block aligned
971 assert(pkt->getAddr() == blockAlign(pkt->getAddr()));
972
973 pkt->allocate();

--- 13 unchanged lines hidden (view full) ---

987 bool last_level_cache = false;
988
989 // Forward the request if the system is in cache bypass mode.
990 if (system->bypassCaches())
991 return ticksToCycles(memSidePort->sendAtomic(pkt));
992
993 promoteWholeLineWrites(pkt);
994
992 __func__, cpu_pkt->cmdString(), pkt->cmdString(),
993 pkt->getAddr(), pkt->getSize());
994 }
995
996 // the packet should be block aligned
997 assert(pkt->getAddr() == blockAlign(pkt->getAddr()));
998
999 pkt->allocate();

--- 13 unchanged lines hidden (view full) ---

1013 bool last_level_cache = false;
1014
1015 // Forward the request if the system is in cache bypass mode.
1016 if (system->bypassCaches())
1017 return ticksToCycles(memSidePort->sendAtomic(pkt));
1018
1019 promoteWholeLineWrites(pkt);
1020
995 if (pkt->memInhibitAsserted()) {
1021 if (pkt->cacheResponding()) {
996 // have to invalidate ourselves and any lower caches even if
997 // upper cache will be responding
998 if (pkt->isInvalidate()) {
999 CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure());
1000 if (blk && blk->isValid()) {
1001 tags->invalidate(blk);
1002 blk->invalidate();
1022 // have to invalidate ourselves and any lower caches even if
1023 // upper cache will be responding
1024 if (pkt->isInvalidate()) {
1025 CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure());
1026 if (blk && blk->isValid()) {
1027 tags->invalidate(blk);
1028 blk->invalidate();
1003 DPRINTF(Cache, "rcvd mem-inhibited %s on %#llx (%s):"
1029 DPRINTF(Cache, "Other cache responding to %s on %#llx (%s):"
1004 " invalidating\n",
1005 pkt->cmdString(), pkt->getAddr(),
1006 pkt->isSecure() ? "s" : "ns");
1007 }
1008 if (!last_level_cache) {
1030 " invalidating\n",
1031 pkt->cmdString(), pkt->getAddr(),
1032 pkt->isSecure() ? "s" : "ns");
1033 }
1034 if (!last_level_cache) {
1009 DPRINTF(Cache, "forwarding mem-inhibited %s on %#llx (%s)\n",
1035 DPRINTF(Cache, "Other cache responding to %s on %#llx (%s):"
1036 " forwarding\n",
1010 pkt->cmdString(), pkt->getAddr(),
1011 pkt->isSecure() ? "s" : "ns");
1012 lat += ticksToCycles(memSidePort->sendAtomic(pkt));
1013 }
1014 } else {
1037 pkt->cmdString(), pkt->getAddr(),
1038 pkt->isSecure() ? "s" : "ns");
1039 lat += ticksToCycles(memSidePort->sendAtomic(pkt));
1040 }
1041 } else {
1015 DPRINTF(Cache, "rcvd mem-inhibited %s on %#llx: not responding\n",
1042 DPRINTF(Cache, "Other cache responding to %s on %#llx: "
1043 "not responding\n",
1016 pkt->cmdString(), pkt->getAddr());
1017 }
1018
1019 return lat * clockPeriod();
1020 }
1021
1022 // should assert here that there are no outstanding MSHRs or
1023 // writebacks... that would mean that someone used an atomic

--- 5 unchanged lines hidden (view full) ---

1029
1030 // handle writebacks resulting from the access here to ensure they
1031 // logically proceed anything happening below
1032 doWritebacksAtomic(writebacks);
1033
1034 if (!satisfied) {
1035 // MISS
1036
1044 pkt->cmdString(), pkt->getAddr());
1045 }
1046
1047 return lat * clockPeriod();
1048 }
1049
1050 // should assert here that there are no outstanding MSHRs or
1051 // writebacks... that would mean that someone used an atomic

--- 5 unchanged lines hidden (view full) ---

1057
1058 // handle writebacks resulting from the access here to ensure they
1059 // logically proceed anything happening below
1060 doWritebacksAtomic(writebacks);
1061
1062 if (!satisfied) {
1063 // MISS
1064
1037 PacketPtr bus_pkt = getBusPacket(pkt, blk, pkt->needsExclusive());
1065 PacketPtr bus_pkt = getBusPacket(pkt, blk, pkt->needsWritable());
1038
1039 bool is_forward = (bus_pkt == NULL);
1040
1041 if (is_forward) {
1042 // just forwarding the same request to the next level
1043 // no local cache operation involved
1044 bus_pkt = pkt;
1045 }

--- 130 unchanged lines hidden (view full) ---

1176 // needs to be found. As a result we always update the request if
1177 // we have it, but only declare it satisfied if we are the owner.
1178
1179 // see if we have data at all (owned or otherwise)
1180 bool have_data = blk && blk->isValid()
1181 && pkt->checkFunctional(&cbpw, blk_addr, is_secure, blkSize,
1182 blk->data);
1183
1066
1067 bool is_forward = (bus_pkt == NULL);
1068
1069 if (is_forward) {
1070 // just forwarding the same request to the next level
1071 // no local cache operation involved
1072 bus_pkt = pkt;
1073 }

--- 130 unchanged lines hidden (view full) ---

1204 // needs to be found. As a result we always update the request if
1205 // we have it, but only declare it satisfied if we are the owner.
1206
1207 // see if we have data at all (owned or otherwise)
1208 bool have_data = blk && blk->isValid()
1209 && pkt->checkFunctional(&cbpw, blk_addr, is_secure, blkSize,
1210 blk->data);
1211
1184 // data we have is dirty if marked as such or if valid & ownership
1185 // pending due to outstanding UpgradeReq
1212 // data we have is dirty if marked as such or if we have an
1213 // in-service MSHR that is pending a modified line
1186 bool have_dirty =
1187 have_data && (blk->isDirty() ||
1214 bool have_dirty =
1215 have_data && (blk->isDirty() ||
1188 (mshr && mshr->inService && mshr->isPendingDirty()));
1216 (mshr && mshr->inService && mshr->isPendingModified()));
1189
1190 bool done = have_dirty
1191 || cpuSidePort->checkFunctional(pkt)
1192 || mshrQueue.checkFunctional(pkt, blk_addr)
1193 || writeBuffer.checkFunctional(pkt, blk_addr)
1194 || memSidePort->checkFunctional(pkt);
1195
1196 DPRINTF(Cache, "functional %s %#llx (%s) %s%s%s\n",

--- 79 unchanged lines hidden (view full) ---

1276 mshr_uncacheable_lat[stats_cmd_idx][pkt->req->masterId()] +=
1277 miss_latency;
1278 } else {
1279 assert(pkt->req->masterId() < system->maxMasters());
1280 mshr_miss_latency[stats_cmd_idx][pkt->req->masterId()] +=
1281 miss_latency;
1282 }
1283
1217
1218 bool done = have_dirty
1219 || cpuSidePort->checkFunctional(pkt)
1220 || mshrQueue.checkFunctional(pkt, blk_addr)
1221 || writeBuffer.checkFunctional(pkt, blk_addr)
1222 || memSidePort->checkFunctional(pkt);
1223
1224 DPRINTF(Cache, "functional %s %#llx (%s) %s%s%s\n",

--- 79 unchanged lines hidden (view full) ---

1304 mshr_uncacheable_lat[stats_cmd_idx][pkt->req->masterId()] +=
1305 miss_latency;
1306 } else {
1307 assert(pkt->req->masterId() < system->maxMasters());
1308 mshr_miss_latency[stats_cmd_idx][pkt->req->masterId()] +=
1309 miss_latency;
1310 }
1311
1284 // upgrade deferred targets if we got exclusive
1285 if (!pkt->sharedAsserted()) {
1286 mshr->promoteExclusive();
1312 // upgrade deferred targets if the response has no sharers, and is
1313 // thus passing writable
1314 if (!pkt->hasSharers()) {
1315 mshr->promoteWritable();
1287 }
1288
1289 bool is_fill = !mshr->isForward &&
1290 (pkt->isRead() || pkt->cmd == MemCmd::UpgradeResp);
1291
1292 CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure());
1293
1294 if (is_fill && !is_error) {

--- 35 unchanged lines hidden (view full) ---

1330 // unlike the other packet flows, where data is found in other
1331 // caches or memory and brought back, write-line requests always
1332 // have the data right away, so the above check for "is fill?"
1333 // cannot actually be determined until examining the stored MSHR
1334 // state. We "catch up" with that logic here, which is duplicated
1335 // from above.
1336 if (tgt_pkt->cmd == MemCmd::WriteLineReq) {
1337 assert(!is_error);
1316 }
1317
1318 bool is_fill = !mshr->isForward &&
1319 (pkt->isRead() || pkt->cmd == MemCmd::UpgradeResp);
1320
1321 CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure());
1322
1323 if (is_fill && !is_error) {

--- 35 unchanged lines hidden (view full) ---

1359 // unlike the other packet flows, where data is found in other
1360 // caches or memory and brought back, write-line requests always
1361 // have the data right away, so the above check for "is fill?"
1362 // cannot actually be determined until examining the stored MSHR
1363 // state. We "catch up" with that logic here, which is duplicated
1364 // from above.
1365 if (tgt_pkt->cmd == MemCmd::WriteLineReq) {
1366 assert(!is_error);
1338 // we got the block in exclusive state, so promote any
1339 // deferred targets if possible
1340 mshr->promoteExclusive();
1367 // we got the block in a writable state, so promote
1368 // any deferred targets if possible
1369 mshr->promoteWritable();
1341 // NB: we use the original packet here and not the response!
1342 blk = handleFill(tgt_pkt, blk, writebacks, mshr->allocOnFill);
1343 assert(blk != NULL);
1344
1345 // treat as a fill, and discard the invalidation
1346 // response
1347 is_fill = true;
1348 is_invalidate = false;

--- 184 unchanged lines hidden (view full) ---

1533 DPRINTF(Cache, "Create Writeback %#llx writable: %d, dirty: %d\n",
1534 pkt->getAddr(), blk->isWritable(), blk->isDirty());
1535
1536 if (blk->isWritable()) {
1537 // not asserting shared means we pass the block in modified
1538 // state, mark our own block non-writeable
1539 blk->status &= ~BlkWritable;
1540 } else {
1370 // NB: we use the original packet here and not the response!
1371 blk = handleFill(tgt_pkt, blk, writebacks, mshr->allocOnFill);
1372 assert(blk != NULL);
1373
1374 // treat as a fill, and discard the invalidation
1375 // response
1376 is_fill = true;
1377 is_invalidate = false;

--- 184 unchanged lines hidden (view full) ---

1562 DPRINTF(Cache, "Create Writeback %#llx writable: %d, dirty: %d\n",
1563 pkt->getAddr(), blk->isWritable(), blk->isDirty());
1564
1565 if (blk->isWritable()) {
1566 // not asserting shared means we pass the block in modified
1567 // state, mark our own block non-writeable
1568 blk->status &= ~BlkWritable;
1569 } else {
1541 // we are in the owned state, tell the receiver
1542 pkt->assertShared();
1570 // we are in the Owned state, tell the receiver
1571 pkt->setHasSharers();
1543 }
1544
1545 // make sure the block is not marked dirty
1546 blk->status &= ~BlkDirty;
1547
1548 pkt->allocate();
1549 std::memcpy(pkt->getPtr<uint8_t>(), blk->data, blkSize);
1550

--- 96 unchanged lines hidden (view full) ---

1647
1648 if (blk->isValid()) {
1649 Addr repl_addr = tags->regenerateBlkAddr(blk->tag, blk->set);
1650 MSHR *repl_mshr = mshrQueue.findMatch(repl_addr, blk->isSecure());
1651 if (repl_mshr) {
1652 // must be an outstanding upgrade request
1653 // on a block we're about to replace...
1654 assert(!blk->isWritable() || blk->isDirty());
1572 }
1573
1574 // make sure the block is not marked dirty
1575 blk->status &= ~BlkDirty;
1576
1577 pkt->allocate();
1578 std::memcpy(pkt->getPtr<uint8_t>(), blk->data, blkSize);
1579

--- 96 unchanged lines hidden (view full) ---

1676
1677 if (blk->isValid()) {
1678 Addr repl_addr = tags->regenerateBlkAddr(blk->tag, blk->set);
1679 MSHR *repl_mshr = mshrQueue.findMatch(repl_addr, blk->isSecure());
1680 if (repl_mshr) {
1681 // must be an outstanding upgrade request
1682 // on a block we're about to replace...
1683 assert(!blk->isWritable() || blk->isDirty());
1655 assert(repl_mshr->needsExclusive());
1684 assert(repl_mshr->needsWritable());
1656 // too hard to replace block with transient state
1657 // allocation failed, block not inserted
1658 return NULL;
1659 } else {
1660 DPRINTF(Cache, "replacement: replacing %#llx (%s) with %#llx (%s): %s\n",
1661 repl_addr, blk->isSecure() ? "s" : "ns",
1662 addr, is_secure ? "s" : "ns",
1663 blk->isDirty() ? "writeback" : "clean");

--- 84 unchanged lines hidden (view full) ---

1748 if (is_secure)
1749 blk->status |= BlkSecure;
1750 blk->status |= BlkValid | BlkReadable;
1751
1752 // sanity check for whole-line writes, which should always be
1753 // marked as writable as part of the fill, and then later marked
1754 // dirty as part of satisfyCpuSideRequest
1755 if (pkt->cmd == MemCmd::WriteLineReq) {
1685 // too hard to replace block with transient state
1686 // allocation failed, block not inserted
1687 return NULL;
1688 } else {
1689 DPRINTF(Cache, "replacement: replacing %#llx (%s) with %#llx (%s): %s\n",
1690 repl_addr, blk->isSecure() ? "s" : "ns",
1691 addr, is_secure ? "s" : "ns",
1692 blk->isDirty() ? "writeback" : "clean");

--- 84 unchanged lines hidden (view full) ---

1777 if (is_secure)
1778 blk->status |= BlkSecure;
1779 blk->status |= BlkValid | BlkReadable;
1780
1781 // sanity check for whole-line writes, which should always be
1782 // marked as writable as part of the fill, and then later marked
1783 // dirty as part of satisfyCpuSideRequest
1784 if (pkt->cmd == MemCmd::WriteLineReq) {
1756 assert(!pkt->sharedAsserted());
1785 assert(!pkt->hasSharers());
1757 // at the moment other caches do not respond to the
1758 // invalidation requests corresponding to a whole-line write
1786 // at the moment other caches do not respond to the
1787 // invalidation requests corresponding to a whole-line write
1759 assert(!pkt->memInhibitAsserted());
1788 assert(!pkt->cacheResponding());
1760 }
1761
1789 }
1790
1762 if (!pkt->sharedAsserted()) {
1763 // we could get non-shared responses from memory (rather than
1764 // a cache) even in a read-only cache, note that we set this
1765 // bit even for a read-only cache as we use it to represent
1766 // the exclusive state
1791 // here we deal with setting the appropriate state of the line,
1792 // and we start by looking at the hasSharers flag, and ignore the
1793 // cacheResponding flag (normally signalling dirty data) if the
1794 // packet has sharers, thus the line is never allocated as Owned
1795 // (dirty but not writable), and always ends up being either
1796 // Shared, Exclusive or Modified, see Packet::setCacheResponding
1797 // for more details
1798 if (!pkt->hasSharers()) {
1799 // we could get a writable line from memory (rather than a
1800 // cache) even in a read-only cache, note that we set this bit
1801 // even for a read-only cache, possibly revisit this decision
1767 blk->status |= BlkWritable;
1768
1802 blk->status |= BlkWritable;
1803
1769 // If we got this via cache-to-cache transfer (i.e., from a
1770 // cache that was an owner) and took away that owner's copy,
1771 // then we need to write it back. Normally this happens
1772 // anyway as a side effect of getting a copy to write it, but
1773 // there are cases (such as failed store conditionals or
1774 // compare-and-swaps) where we'll demand an exclusive copy but
1775 // end up not writing it.
1776 if (pkt->memInhibitAsserted()) {
1804 // check if we got this via cache-to-cache transfer (i.e., from a
1805 // cache that had the block in Modified or Owned state)
1806 if (pkt->cacheResponding()) {
1807 // we got the block in Modified state, and invalidated the
1808 // owners copy
1777 blk->status |= BlkDirty;
1778
1779 chatty_assert(!isReadOnly, "Should never see dirty snoop response "
1780 "in read-only cache %s\n", name());
1781 }
1782 }
1783
1784 DPRINTF(Cache, "Block addr %#llx (%s) moving from state %x to %s\n",

--- 37 unchanged lines hidden (view full) ---

1822 PacketPtr pkt = req_pkt;
1823 if (!already_copied)
1824 // do not clear flags, and allocate space for data if the
1825 // packet needs it (the only packets that carry data are read
1826 // responses)
1827 pkt = new Packet(req_pkt, false, req_pkt->isRead());
1828
1829 assert(req_pkt->req->isUncacheable() || req_pkt->isInvalidate() ||
1809 blk->status |= BlkDirty;
1810
1811 chatty_assert(!isReadOnly, "Should never see dirty snoop response "
1812 "in read-only cache %s\n", name());
1813 }
1814 }
1815
1816 DPRINTF(Cache, "Block addr %#llx (%s) moving from state %x to %s\n",

--- 37 unchanged lines hidden (view full) ---

1854 PacketPtr pkt = req_pkt;
1855 if (!already_copied)
1856 // do not clear flags, and allocate space for data if the
1857 // packet needs it (the only packets that carry data are read
1858 // responses)
1859 pkt = new Packet(req_pkt, false, req_pkt->isRead());
1860
1861 assert(req_pkt->req->isUncacheable() || req_pkt->isInvalidate() ||
1830 pkt->sharedAsserted());
1862 pkt->hasSharers());
1831 pkt->makeTimingResponse();
1832 if (pkt->isRead()) {
1833 pkt->setDataFromBlock(blk_data, blkSize);
1834 }
1835 if (pkt->cmd == MemCmd::ReadResp && pending_inval) {
1836 // Assume we defer a response to a read from a far-away cache
1837 // A, then later defer a ReadExcl from a cache B on the same
1863 pkt->makeTimingResponse();
1864 if (pkt->isRead()) {
1865 pkt->setDataFromBlock(blk_data, blkSize);
1866 }
1867 if (pkt->cmd == MemCmd::ReadResp && pending_inval) {
1868 // Assume we defer a response to a read from a far-away cache
1869 // A, then later defer a ReadExcl from a cache B on the same
1838 // bus as us. We'll assert MemInhibit in both cases, but in
1839 // the latter case MemInhibit will keep the invalidation from
1840 // reaching cache A. This special response tells cache A that
1841 // it gets the block to satisfy its read, but must immediately
1842 // invalidate it.
1870 // bus as us. We'll assert cacheResponding in both cases, but
1871 // in the latter case cacheResponding will keep the
1872 // invalidation from reaching cache A. This special response
1873 // tells cache A that it gets the block to satisfy its read,
1874 // but must immediately invalidate it.
1843 pkt->cmd = MemCmd::ReadRespWithInvalidate;
1844 }
1845 // Here we consider forward_time, paying for just forward latency and
1846 // also charging the delay provided by the xbar.
1847 // forward_time is used as send_time in next allocateWriteBuffer().
1848 Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay;
1849 // Here we reset the timing of the packet.
1850 pkt->headerDelay = pkt->payloadDelay = 0;

--- 14 unchanged lines hidden (view full) ---

1865 // pending_inval only makes sense on deferred snoops
1866 assert(!(pending_inval && !is_deferred));
1867 assert(pkt->isRequest());
1868
1869 // the packet may get modified if we or a forwarded snooper
1870 // responds in atomic mode, so remember a few things about the
1871 // original packet up front
1872 bool invalidate = pkt->isInvalidate();
1875 pkt->cmd = MemCmd::ReadRespWithInvalidate;
1876 }
1877 // Here we consider forward_time, paying for just forward latency and
1878 // also charging the delay provided by the xbar.
1879 // forward_time is used as send_time in next allocateWriteBuffer().
1880 Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay;
1881 // Here we reset the timing of the packet.
1882 pkt->headerDelay = pkt->payloadDelay = 0;

--- 14 unchanged lines hidden (view full) ---

1897 // pending_inval only makes sense on deferred snoops
1898 assert(!(pending_inval && !is_deferred));
1899 assert(pkt->isRequest());
1900
1901 // the packet may get modified if we or a forwarded snooper
1902 // responds in atomic mode, so remember a few things about the
1903 // original packet up front
1904 bool invalidate = pkt->isInvalidate();
1873 bool M5_VAR_USED needs_exclusive = pkt->needsExclusive();
1905 bool M5_VAR_USED needs_writable = pkt->needsWritable();
1874
1875 uint32_t snoop_delay = 0;
1876
1877 if (forwardSnoops) {
1878 // first propagate snoop upward to see if anyone above us wants to
1879 // handle it. save & restore packet src since it will get
1880 // rewritten to be relative to cpu-side bus (if any)
1906
1907 uint32_t snoop_delay = 0;
1908
1909 if (forwardSnoops) {
1910 // first propagate snoop upward to see if anyone above us wants to
1911 // handle it. save & restore packet src since it will get
1912 // rewritten to be relative to cpu-side bus (if any)
1881 bool alreadyResponded = pkt->memInhibitAsserted();
1913 bool alreadyResponded = pkt->cacheResponding();
1882 if (is_timing) {
1883 // copy the packet so that we can clear any flags before
1884 // forwarding it upwards, we also allocate data (passing
1885 // the pointer along in case of static data), in case
1886 // there is a snoop hit in upper levels
1887 Packet snoopPkt(pkt, true, true);
1888 snoopPkt.setExpressSnoop();
1889 // the snoop packet does not need to wait any additional
1890 // time
1891 snoopPkt.headerDelay = snoopPkt.payloadDelay = 0;
1892 cpuSidePort->sendTimingSnoopReq(&snoopPkt);
1893
1894 // add the header delay (including crossbar and snoop
1895 // delays) of the upward snoop to the snoop delay for this
1896 // cache
1897 snoop_delay += snoopPkt.headerDelay;
1898
1914 if (is_timing) {
1915 // copy the packet so that we can clear any flags before
1916 // forwarding it upwards, we also allocate data (passing
1917 // the pointer along in case of static data), in case
1918 // there is a snoop hit in upper levels
1919 Packet snoopPkt(pkt, true, true);
1920 snoopPkt.setExpressSnoop();
1921 // the snoop packet does not need to wait any additional
1922 // time
1923 snoopPkt.headerDelay = snoopPkt.payloadDelay = 0;
1924 cpuSidePort->sendTimingSnoopReq(&snoopPkt);
1925
1926 // add the header delay (including crossbar and snoop
1927 // delays) of the upward snoop to the snoop delay for this
1928 // cache
1929 snoop_delay += snoopPkt.headerDelay;
1930
1899 if (snoopPkt.memInhibitAsserted()) {
1931 if (snoopPkt.cacheResponding()) {
1900 // cache-to-cache response from some upper cache
1901 assert(!alreadyResponded);
1932 // cache-to-cache response from some upper cache
1933 assert(!alreadyResponded);
1902 pkt->assertMemInhibit();
1934 pkt->setCacheResponding();
1903 }
1935 }
1904 if (snoopPkt.sharedAsserted()) {
1905 pkt->assertShared();
1936 // upstream cache has the block, or has an outstanding
1937 // MSHR, pass the flag on
1938 if (snoopPkt.hasSharers()) {
1939 pkt->setHasSharers();
1906 }
1907 // If this request is a prefetch or clean evict and an upper level
1908 // signals block present, make sure to propagate the block
1909 // presence to the requester.
1910 if (snoopPkt.isBlockCached()) {
1911 pkt->setBlockCached();
1912 }
1913 } else {
1914 cpuSidePort->sendAtomicSnoop(pkt);
1940 }
1941 // If this request is a prefetch or clean evict and an upper level
1942 // signals block present, make sure to propagate the block
1943 // presence to the requester.
1944 if (snoopPkt.isBlockCached()) {
1945 pkt->setBlockCached();
1946 }
1947 } else {
1948 cpuSidePort->sendAtomicSnoop(pkt);
1915 if (!alreadyResponded && pkt->memInhibitAsserted()) {
1949 if (!alreadyResponded && pkt->cacheResponding()) {
1916 // cache-to-cache response from some upper cache:
1917 // forward response to original requester
1918 assert(pkt->isResponse());
1919 }
1920 }
1921 }
1922
1923 if (!blk || !blk->isValid()) {

--- 12 unchanged lines hidden (view full) ---

1936
1937 // We may end up modifying both the block state and the packet (if
1938 // we respond in atomic mode), so just figure out what to do now
1939 // and then do it later. If we find dirty data while snooping for
1940 // an invalidate, we don't need to send a response. The
1941 // invalidation itself is taken care of below.
1942 bool respond = blk->isDirty() && pkt->needsResponse() &&
1943 pkt->cmd != MemCmd::InvalidateReq;
1950 // cache-to-cache response from some upper cache:
1951 // forward response to original requester
1952 assert(pkt->isResponse());
1953 }
1954 }
1955 }
1956
1957 if (!blk || !blk->isValid()) {

--- 12 unchanged lines hidden (view full) ---

1970
1971 // We may end up modifying both the block state and the packet (if
1972 // we respond in atomic mode), so just figure out what to do now
1973 // and then do it later. If we find dirty data while snooping for
1974 // an invalidate, we don't need to send a response. The
1975 // invalidation itself is taken care of below.
1976 bool respond = blk->isDirty() && pkt->needsResponse() &&
1977 pkt->cmd != MemCmd::InvalidateReq;
1944 bool have_exclusive = blk->isWritable();
1978 bool have_writable = blk->isWritable();
1945
1946 // Invalidate any prefetch's from below that would strip write permissions
1947 // MemCmd::HardPFReq is only observed by upstream caches. After missing
1948 // above and in it's own cache, a new MemCmd::ReadReq is created that
1949 // downstream caches observe.
1950 if (pkt->mustCheckAbove()) {
1951 DPRINTF(Cache, "Found addr %#llx in upper level cache for snoop %s from"
1952 " lower cache\n", pkt->getAddr(), pkt->cmdString());
1953 pkt->setBlockCached();
1954 return snoop_delay;
1955 }
1956
1957 if (!pkt->req->isUncacheable() && pkt->isRead() && !invalidate) {
1979
1980 // Invalidate any prefetch's from below that would strip write permissions
1981 // MemCmd::HardPFReq is only observed by upstream caches. After missing
1982 // above and in it's own cache, a new MemCmd::ReadReq is created that
1983 // downstream caches observe.
1984 if (pkt->mustCheckAbove()) {
1985 DPRINTF(Cache, "Found addr %#llx in upper level cache for snoop %s from"
1986 " lower cache\n", pkt->getAddr(), pkt->cmdString());
1987 pkt->setBlockCached();
1988 return snoop_delay;
1989 }
1990
1991 if (!pkt->req->isUncacheable() && pkt->isRead() && !invalidate) {
1958 // reading non-exclusive shared data, note that we retain
1959 // the block in owned state if it is dirty, with the response
1960 // taken care of below, and otherwhise simply downgrade to
1961 // shared
1962 assert(!needs_exclusive);
1963 pkt->assertShared();
1992 // reading without requiring the line in a writable state,
1993 // note that we retain the block as Owned if it is Modified
1994 // (dirty data), with the response taken care of below, and
1995 // otherwhise simply downgrade from Exclusive to Shared (or
1996 // remain in Shared)
1997 assert(!needs_writable);
1998 pkt->setHasSharers();
1964 blk->status &= ~BlkWritable;
1965 }
1966
1967 if (respond) {
1968 // prevent anyone else from responding, cache as well as
1969 // memory, and also prevent any memory from even seeing the
1999 blk->status &= ~BlkWritable;
2000 }
2001
2002 if (respond) {
2003 // prevent anyone else from responding, cache as well as
2004 // memory, and also prevent any memory from even seeing the
1970 // request (with current inhibited semantics), note that this
1971 // applies both to reads and writes and that for writes it
1972 // works thanks to the fact that we still have dirty data and
1973 // will write it back at a later point
1974 assert(!pkt->memInhibitAsserted());
1975 pkt->assertMemInhibit();
1976 if (have_exclusive) {
2005 // request
2006 pkt->setCacheResponding();
2007 if (have_writable) {
2008 // inform the cache hierarchy that this cache had the line
2009 // in the Modified state so that we avoid unnecessary
2010 // invalidations (see Packet::setResponderHadWritable)
2011 pkt->setResponderHadWritable();
2012
1977 // in the case of an uncacheable request there is no point
2013 // in the case of an uncacheable request there is no point
1978 // in setting the exclusive flag, but since the recipient
1979 // does not care there is no harm in doing so, in any case
1980 // it is just a hint
1981 pkt->setSupplyExclusive();
2014 // in setting the responderHadWritable flag, but since the
2015 // recipient does not care there is no harm in doing so
2016 } else {
2017 // if the packet has needsWritable set we invalidate our
2018 // copy below and all other copies will be invalidates
2019 // through express snoops, and if needsWritable is not set
2020 // we already called setHasSharers above
1982 }
2021 }
2022
1983 if (is_timing) {
1984 doTimingSupplyResponse(pkt, blk->data, is_deferred, pending_inval);
1985 } else {
1986 pkt->makeAtomicResponse();
1987 pkt->setDataFromBlock(blk->data, blkSize);
1988 }
1989 }
1990

--- 94 unchanged lines hidden (view full) ---

2085 // any CleanEvicts from travelling down the memory hierarchy.
2086 pkt->setBlockCached();
2087 DPRINTF(Cache, "Squashing %s from lower cache on writequeue hit"
2088 " %#x\n", pkt->cmdString(), pkt->getAddr());
2089 return;
2090 }
2091
2092 if (wb_pkt->cmd == MemCmd::WritebackDirty) {
2023 if (is_timing) {
2024 doTimingSupplyResponse(pkt, blk->data, is_deferred, pending_inval);
2025 } else {
2026 pkt->makeAtomicResponse();
2027 pkt->setDataFromBlock(blk->data, blkSize);
2028 }
2029 }
2030

--- 94 unchanged lines hidden (view full) ---

2125 // any CleanEvicts from travelling down the memory hierarchy.
2126 pkt->setBlockCached();
2127 DPRINTF(Cache, "Squashing %s from lower cache on writequeue hit"
2128 " %#x\n", pkt->cmdString(), pkt->getAddr());
2129 return;
2130 }
2131
2132 if (wb_pkt->cmd == MemCmd::WritebackDirty) {
2093 assert(!pkt->memInhibitAsserted());
2094 pkt->assertMemInhibit();
2095 if (!pkt->needsExclusive()) {
2096 pkt->assertShared();
2097 // the writeback is no longer passing exclusivity (the
2098 // receiving cache should consider the block owned
2099 // rather than modified)
2100 wb_pkt->assertShared();
2133 // we have dirty data, and so will proceed to respond
2134 pkt->setCacheResponding();
2135 if (!pkt->needsWritable()) {
2136 // the packet should end up in the Shared state (non
2137 // writable) on the completion of the fill
2138 pkt->setHasSharers();
2139 // similarly, the writeback is no longer passing
2140 // writeable (the receiving cache should consider the
2141 // block Owned rather than Modified)
2142 wb_pkt->setHasSharers();
2101 } else {
2143 } else {
2102 // if we're not asserting the shared line, we need to
2103 // invalidate our copy. we'll do that below as long as
2104 // the packet's invalidate flag is set...
2144 // we need to invalidate our copy. we do that
2145 // below.
2105 assert(pkt->isInvalidate());
2106 }
2107 doTimingSupplyResponse(pkt, wb_pkt->getConstPtr<uint8_t>(),
2108 false, false);
2109 } else {
2110 // on hitting a clean writeback we play it safe and do not
2111 // provide a response, the block may be dirty somewhere
2112 // else
2113 assert(wb_pkt->isCleanEviction());
2114 // The cache technically holds the block until the
2115 // corresponding message reaches the crossbar
2116 // below. Therefore when a snoop encounters a CleanEvict
2146 assert(pkt->isInvalidate());
2147 }
2148 doTimingSupplyResponse(pkt, wb_pkt->getConstPtr<uint8_t>(),
2149 false, false);
2150 } else {
2151 // on hitting a clean writeback we play it safe and do not
2152 // provide a response, the block may be dirty somewhere
2153 // else
2154 assert(wb_pkt->isCleanEviction());
2155 // The cache technically holds the block until the
2156 // corresponding message reaches the crossbar
2157 // below. Therefore when a snoop encounters a CleanEvict
2117 // or WritebackClean message we must set assertShared
2118 // (just like when it encounters a Writeback) to avoid the
2119 // snoop filter prematurely clearing the holder bit in the
2120 // crossbar below
2121 if (!pkt->needsExclusive()) {
2122 pkt->assertShared();
2123 // the writeback is no longer passing exclusivity (the
2124 // receiving cache should consider the block owned
2125 // rather than modified)
2126 wb_pkt->assertShared();
2158 // or WritebackClean message we must call
2159 // setHasSharers (just like when it encounters a
2160 // Writeback) to avoid the snoop filter prematurely
2161 // clearing the holder bit in the crossbar below
2162 if (!pkt->needsWritable()) {
2163 pkt->setHasSharers();
2164 // the writeback is no longer passing writeable (the
2165 // receiving cache should consider the block Owned
2166 // rather than Modified)
2167 wb_pkt->setHasSharers();
2127 } else {
2128 assert(pkt->isInvalidate());
2129 }
2130 }
2131
2132 if (pkt->isInvalidate()) {
2133 // Invalidation trumps our writeback... discard here
2134 // Note: markInService will remove entry from writeback buffer.

--- 140 unchanged lines hidden (view full) ---

2275 snoop_pkt.setExpressSnoop();
2276 // Assert that packet is either Writeback or CleanEvict and not a
2277 // prefetch request because prefetch requests need an MSHR and may
2278 // generate a snoop response.
2279 assert(pkt->isEviction());
2280 snoop_pkt.senderState = NULL;
2281 cpuSidePort->sendTimingSnoopReq(&snoop_pkt);
2282 // Writeback/CleanEvict snoops do not generate a snoop response.
2168 } else {
2169 assert(pkt->isInvalidate());
2170 }
2171 }
2172
2173 if (pkt->isInvalidate()) {
2174 // Invalidation trumps our writeback... discard here
2175 // Note: markInService will remove entry from writeback buffer.

--- 140 unchanged lines hidden (view full) ---

2316 snoop_pkt.setExpressSnoop();
2317 // Assert that packet is either Writeback or CleanEvict and not a
2318 // prefetch request because prefetch requests need an MSHR and may
2319 // generate a snoop response.
2320 assert(pkt->isEviction());
2321 snoop_pkt.senderState = NULL;
2322 cpuSidePort->sendTimingSnoopReq(&snoop_pkt);
2323 // Writeback/CleanEvict snoops do not generate a snoop response.
2283 assert(!(snoop_pkt.memInhibitAsserted()));
2324 assert(!(snoop_pkt.cacheResponding()));
2284 return snoop_pkt.isBlockCached();
2285 } else {
2286 cpuSidePort->sendAtomicSnoop(pkt);
2287 return pkt->isBlockCached();
2288 }
2289}
2290
2291PacketPtr

--- 30 unchanged lines hidden (view full) ---

2322 cpuSidePort->sendTimingSnoopReq(&snoop_pkt);
2323
2324 // Check to see if the prefetch was squashed by an upper cache (to
2325 // prevent us from grabbing the line) or if a Check to see if a
2326 // writeback arrived between the time the prefetch was placed in
2327 // the MSHRs and when it was selected to be sent or if the
2328 // prefetch was squashed by an upper cache.
2329
2325 return snoop_pkt.isBlockCached();
2326 } else {
2327 cpuSidePort->sendAtomicSnoop(pkt);
2328 return pkt->isBlockCached();
2329 }
2330}
2331
2332PacketPtr

--- 30 unchanged lines hidden (view full) ---

2363 cpuSidePort->sendTimingSnoopReq(&snoop_pkt);
2364
2365 // Check to see if the prefetch was squashed by an upper cache (to
2366 // prevent us from grabbing the line) or if a Check to see if a
2367 // writeback arrived between the time the prefetch was placed in
2368 // the MSHRs and when it was selected to be sent or if the
2369 // prefetch was squashed by an upper cache.
2370
2330 // It is important to check memInhibitAsserted before
2331 // prefetchSquashed. If another cache has asserted MEM_INGIBIT, it
2332 // will be sending a response which will arrive at the MSHR
2333 // allocated ofr this request. Checking the prefetchSquash first
2334 // may result in the MSHR being prematurely deallocated.
2335
2336 if (snoop_pkt.memInhibitAsserted()) {
2371 // It is important to check cacheResponding before
2372 // prefetchSquashed. If another cache has committed to
2373 // responding, it will be sending a dirty response which will
2374 // arrive at the MSHR allocated for this request. Checking the
2375 // prefetchSquash first may result in the MSHR being
2376 // prematurely deallocated.
2377 if (snoop_pkt.cacheResponding()) {
2337 auto M5_VAR_USED r = outstandingSnoop.insert(snoop_pkt.req);
2338 assert(r.second);
2378 auto M5_VAR_USED r = outstandingSnoop.insert(snoop_pkt.req);
2379 assert(r.second);
2339 // If we are getting a non-shared response it is dirty
2340 bool pending_dirty_resp = !snoop_pkt.sharedAsserted();
2341 markInService(mshr, pending_dirty_resp);
2380
2381 // if we are getting a snoop response with no sharers it
2382 // will be allocated as Modified
2383 bool pending_modified_resp = !snoop_pkt.hasSharers();
2384 markInService(mshr, pending_modified_resp);
2385
2342 DPRINTF(Cache, "Upward snoop of prefetch for addr"
2343 " %#x (%s) hit\n",
2344 tgt_pkt->getAddr(), tgt_pkt->isSecure()? "s": "ns");
2345 return NULL;
2346 }
2347
2348 if (snoop_pkt.isBlockCached() || blk != NULL) {
2349 DPRINTF(Cache, "Block present, prefetch squashed by cache. "

--- 9 unchanged lines hidden (view full) ---

2359 }
2360 }
2361
2362 if (mshr->isForwardNoResponse()) {
2363 // no response expected, just forward packet as it is
2364 assert(tags->findBlock(mshr->blkAddr, mshr->isSecure) == NULL);
2365 pkt = tgt_pkt;
2366 } else {
2386 DPRINTF(Cache, "Upward snoop of prefetch for addr"
2387 " %#x (%s) hit\n",
2388 tgt_pkt->getAddr(), tgt_pkt->isSecure()? "s": "ns");
2389 return NULL;
2390 }
2391
2392 if (snoop_pkt.isBlockCached() || blk != NULL) {
2393 DPRINTF(Cache, "Block present, prefetch squashed by cache. "

--- 9 unchanged lines hidden (view full) ---

2403 }
2404 }
2405
2406 if (mshr->isForwardNoResponse()) {
2407 // no response expected, just forward packet as it is
2408 assert(tags->findBlock(mshr->blkAddr, mshr->isSecure) == NULL);
2409 pkt = tgt_pkt;
2410 } else {
2367 pkt = getBusPacket(tgt_pkt, blk, mshr->needsExclusive());
2411 pkt = getBusPacket(tgt_pkt, blk, mshr->needsWritable());
2368
2369 mshr->isForward = (pkt == NULL);
2370
2371 if (mshr->isForward) {
2372 // not a cache block request, but a response is expected
2373 // make copy of current packet to forward, keep current
2374 // copy for response handling
2375 pkt = new Packet(tgt_pkt, false, true);

--- 73 unchanged lines hidden (view full) ---

2449
2450bool
2451Cache::CpuSidePort::recvTimingReq(PacketPtr pkt)
2452{
2453 assert(!cache->system->bypassCaches());
2454
2455 bool success = false;
2456
2412
2413 mshr->isForward = (pkt == NULL);
2414
2415 if (mshr->isForward) {
2416 // not a cache block request, but a response is expected
2417 // make copy of current packet to forward, keep current
2418 // copy for response handling
2419 pkt = new Packet(tgt_pkt, false, true);

--- 73 unchanged lines hidden (view full) ---

2493
2494bool
2495Cache::CpuSidePort::recvTimingReq(PacketPtr pkt)
2496{
2497 assert(!cache->system->bypassCaches());
2498
2499 bool success = false;
2500
2457 // always let inhibited requests through, even if blocked,
2458 // ultimately we should check if this is an express snoop, but at
2459 // the moment that flag is only set in the cache itself
2460 if (pkt->memInhibitAsserted()) {
2501 // always let packets through if an upstream cache has committed
2502 // to responding, even if blocked (we should technically look at
2503 // the isExpressSnoop flag, but it is set by the cache itself, and
2504 // consequently we have to rely on the cacheResponding flag)
2505 if (pkt->cacheResponding()) {
2461 // do not change the current retry state
2462 bool M5_VAR_USED bypass_success = cache->recvTimingReq(pkt);
2463 assert(bypass_success);
2464 return true;
2465 } else if (blocked || mustSendRetry) {
2466 // either already committed to send a retry, or blocked
2467 success = false;
2468 } else {

--- 123 unchanged lines hidden (view full) ---

2592 }
2593 // note that we have now masked any requestBus and
2594 // schedSendEvent (we will wait for a retry before
2595 // doing anything), and this is so even if we do not
2596 // care about this packet and might override it before
2597 // it gets retried
2598 } else {
2599 // As part of the call to sendTimingReq the packet is
2506 // do not change the current retry state
2507 bool M5_VAR_USED bypass_success = cache->recvTimingReq(pkt);
2508 assert(bypass_success);
2509 return true;
2510 } else if (blocked || mustSendRetry) {
2511 // either already committed to send a retry, or blocked
2512 success = false;
2513 } else {

--- 123 unchanged lines hidden (view full) ---

2637 }
2638 // note that we have now masked any requestBus and
2639 // schedSendEvent (we will wait for a retry before
2640 // doing anything), and this is so even if we do not
2641 // care about this packet and might override it before
2642 // it gets retried
2643 } else {
2644 // As part of the call to sendTimingReq the packet is
2600 // forwarded to all neighbouring caches (and any
2601 // caches above them) as a snoop. The packet is also
2602 // sent to any potential cache below as the
2603 // interconnect is not allowed to buffer the
2604 // packet. Thus at this point we know if any of the
2605 // neighbouring, or the downstream cache is
2606 // responding, and if so, if it is with a dirty line
2607 // or not.
2608 bool pending_dirty_resp = !pkt->sharedAsserted() &&
2609 pkt->memInhibitAsserted();
2645 // forwarded to all neighbouring caches (and any caches
2646 // above them) as a snoop. Thus at this point we know if
2647 // any of the neighbouring caches are responding, and if
2648 // so, we know it is dirty, and we can determine if it is
2649 // being passed as Modified, making our MSHR the ordering
2650 // point
2651 bool pending_modified_resp = !pkt->hasSharers() &&
2652 pkt->cacheResponding();
2610
2653
2611 cache.markInService(mshr, pending_dirty_resp);
2654 cache.markInService(mshr, pending_modified_resp);
2612 }
2613 }
2614
2615 // if we succeeded and are not waiting for a retry, schedule the
2616 // next send considering when the next MSHR is ready, note that
2617 // snoop responses have their own packet queue and thus schedule
2618 // their own events
2619 if (!waitingOnRetry) {

--- 12 unchanged lines hidden ---
2655 }
2656 }
2657
2658 // if we succeeded and are not waiting for a retry, schedule the
2659 // next send considering when the next MSHR is ready, note that
2660 // snoop responses have their own packet queue and thus schedule
2661 // their own events
2662 if (!waitingOnRetry) {

--- 12 unchanged lines hidden ---