Deleted Added
sdiff udiff text old ( 11600:a38c3f9c82d1 ) new ( 11601:382e0637fae0 )
full compact
1/*
2 * Copyright (c) 2010-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

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

141 if (overwrite_mem) {
142 std::memcpy(blk_data, &overwrite_val, pkt->getSize());
143 blk->status |= BlkDirty;
144 }
145}
146
147
148void
149Cache::satisfyCpuSideRequest(PacketPtr pkt, CacheBlk *blk,
150 bool deferred_response, bool pending_downgrade)
151{
152 assert(pkt->isRequest());
153
154 assert(blk && blk->isValid());
155 // Occasionally this is not true... if we are a lower-level cache
156 // satisfying a string of Read and ReadEx requests from
157 // upper-level caches, a Read will mark the block as shared but we
158 // can satisfy a following ReadEx anyway since we can rely on the

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

225 // copy of the line
226 if (blk->isDirty()) {
227 // special considerations if we're owner:
228 if (!deferred_response) {
229 // respond with the line in Modified state
230 // (cacheResponding set, hasSharers not set)
231 pkt->setCacheResponding();
232
233 if (clusivity == Enums::mostly_excl) {
234 // if this cache is mostly exclusive with
235 // respect to the cache above, drop the
236 // block, no need to first unset the dirty
237 // bit
238 invalidateBlock(blk);
239 } else {
240 // if this cache is mostly inclusive, we
241 // keep the block in the Exclusive state,
242 // and pass it upwards as Modified
243 // (writable and dirty), hence we have
244 // multiple caches, all on the same path
245 // towards memory, all considering the
246 // same block writable, but only one
247 // considering it Modified
248
249 // we get away with multiple caches (on
250 // the same path to memory) considering
251 // the block writeable as we always enter
252 // the cache hierarchy through a cache,
253 // and first snoop upwards in all other
254 // branches
255 blk->status &= ~BlkDirty;
256 }
257 } else {
258 // if we're responding after our own miss,
259 // there's a window where the recipient didn't
260 // know it was getting ownership and may not
261 // have responded to snoops correctly, so we
262 // have to respond with a shared line
263 pkt->setHasSharers();
264 }

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

428 // it.
429 return true;
430 }
431 // We didn't find the block here, propagate the CleanEvict further
432 // down the memory hierarchy. Returning false will treat the CleanEvict
433 // like a Writeback which could not find a replaceable block so has to
434 // go to next level.
435 return false;
436 } else if ((blk != nullptr) &&
437 (pkt->needsWritable() ? blk->isWritable() :
438 blk->isReadable())) {
439 // OK to satisfy access
440 incHitCount(pkt);
441 satisfyCpuSideRequest(pkt, blk);
442 return true;
443 }
444
445 // Can't satisfy access normally... either no block (blk == nullptr)
446 // or have block but need writable
447
448 incMissCount(pkt);
449
450 if (blk == nullptr && pkt->isLLSC() && pkt->isWrite()) {
451 // complete miss on store conditional... just give up now
452 pkt->req->setExtraData(0);
453 return true;
454 }
455
456 return false;
457}
458
459void
460Cache::doWritebacks(PacketList& writebacks, Tick forward_time)
461{
462 while (!writebacks.empty()) {
463 PacketPtr wbPkt = writebacks.front();
464 // We use forwardLatency here because we are copying writebacks to
465 // write buffer. Call isCachedAbove for both Writebacks and
466 // CleanEvicts. If isCachedAbove returns true we set BLOCK_CACHED flag
467 // in Writebacks and discard CleanEvicts.

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

1068 // note the use of pkt, not bus_pkt here.
1069
1070 // write-line request to the cache that promoted
1071 // the write to a whole line
1072 blk = handleFill(pkt, blk, writebacks,
1073 allocOnFill(pkt->cmd));
1074 assert(blk != NULL);
1075 is_invalidate = false;
1076 satisfyCpuSideRequest(pkt, blk);
1077 } else if (bus_pkt->isRead() ||
1078 bus_pkt->cmd == MemCmd::UpgradeResp) {
1079 // we're updating cache state to allow us to
1080 // satisfy the upstream request from the cache
1081 blk = handleFill(bus_pkt, blk, writebacks,
1082 allocOnFill(pkt->cmd));
1083 satisfyCpuSideRequest(pkt, blk);
1084 } else {
1085 // we're satisfying the upstream request without
1086 // modifying cache state, e.g., a write-through
1087 pkt->makeAtomicResponse();
1088 }
1089 }
1090 delete bus_pkt;
1091 }

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

1313
1314 // allow invalidation responses originating from write-line
1315 // requests to be discarded
1316 bool is_invalidate = pkt->isInvalidate();
1317
1318 // First offset for critical word first calculations
1319 int initial_offset = initial_tgt->pkt->getOffset(blkSize);
1320
1321 while (mshr->hasTargets()) {
1322 MSHR::Target *target = mshr->getTarget();
1323 Packet *tgt_pkt = target->pkt;
1324
1325 switch (target->source) {
1326 case MSHR::Target::FromCPU:
1327 Tick completion_time;
1328 // Here we charge on completion_time the delay of the xbar if the

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

1335 // immediately with dummy data so the core would be able to
1336 // retire it. This request completes right here, so we
1337 // deallocate it.
1338 delete tgt_pkt->req;
1339 delete tgt_pkt;
1340 break; // skip response
1341 }
1342
1343 // unlike the other packet flows, where data is found in other
1344 // caches or memory and brought back, write-line requests always
1345 // have the data right away, so the above check for "is fill?"
1346 // cannot actually be determined until examining the stored MSHR
1347 // state. We "catch up" with that logic here, which is duplicated
1348 // from above.
1349 if (tgt_pkt->cmd == MemCmd::WriteLineReq) {
1350 assert(!is_error);

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

1357
1358 // treat as a fill, and discard the invalidation
1359 // response
1360 is_fill = true;
1361 is_invalidate = false;
1362 }
1363
1364 if (is_fill) {
1365 satisfyCpuSideRequest(tgt_pkt, blk,
1366 true, mshr->hasPostDowngrade());
1367
1368 // How many bytes past the first request is this one
1369 int transfer_offset =
1370 tgt_pkt->getOffset(blkSize) - initial_offset;
1371 if (transfer_offset < 0) {
1372 transfer_offset += blkSize;
1373 }
1374

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

1446
1447 default:
1448 panic("Illegal target->source enum %d\n", target->source);
1449 }
1450
1451 mshr->popTarget();
1452 }
1453
1454 if (blk && blk->isValid()) {
1455 // an invalidate response stemming from a write line request
1456 // should not invalidate the block, so check if the
1457 // invalidation should be discarded
1458 if (is_invalidate || mshr->hasPostInvalidate()) {
1459 invalidateBlock(blk);
1460 } else if (mshr->hasPostDowngrade()) {
1461 blk->status &= ~BlkWritable;

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

1720 assert(!writeBuffer.findMatch(addr, is_secure));
1721
1722 if (blk == nullptr) {
1723 // better have read new data...
1724 assert(pkt->hasData());
1725
1726 // only read responses and write-line requests have data;
1727 // note that we don't write the data here for write-line - that
1728 // happens in the subsequent satisfyCpuSideRequest.
1729 assert(pkt->isRead() || pkt->cmd == MemCmd::WriteLineReq);
1730
1731 // need to do a replacement if allocating, otherwise we stick
1732 // with the temporary storage
1733 blk = allocate ? allocateBlock(addr, is_secure, writebacks) : nullptr;
1734
1735 if (blk == nullptr) {
1736 // No replaceable block or a mostly exclusive

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

1759 }
1760
1761 if (is_secure)
1762 blk->status |= BlkSecure;
1763 blk->status |= BlkValid | BlkReadable;
1764
1765 // sanity check for whole-line writes, which should always be
1766 // marked as writable as part of the fill, and then later marked
1767 // dirty as part of satisfyCpuSideRequest
1768 if (pkt->cmd == MemCmd::WriteLineReq) {
1769 assert(!pkt->hasSharers());
1770 // at the moment other caches do not respond to the
1771 // invalidation requests corresponding to a whole-line write
1772 assert(!pkt->cacheResponding());
1773 }
1774
1775 // here we deal with setting the appropriate state of the line,

--- 894 unchanged lines hidden ---