base.cc (13981:577196ddd040) base.cc (14035:60068a2d56e0)
1/*
2 * Copyright (c) 2012-2013, 2018-2019 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

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

337
338void
339BaseCache::recvTimingReq(PacketPtr pkt)
340{
341 // anything that is merely forwarded pays for the forward latency and
342 // the delay provided by the crossbar
343 Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay;
344
1/*
2 * Copyright (c) 2012-2013, 2018-2019 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

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

337
338void
339BaseCache::recvTimingReq(PacketPtr pkt)
340{
341 // anything that is merely forwarded pays for the forward latency and
342 // the delay provided by the crossbar
343 Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay;
344
345 // Note that lat is passed by reference here. The function
346 // access() will set the lat value.
347 Cycles lat;
348 CacheBlk *blk = nullptr;
345 Cycles lat;
346 CacheBlk *blk = nullptr;
349 bool satisfied = access(pkt, blk, lat);
347 bool satisfied = false;
348 {
349 PacketList writebacks;
350 // Note that lat is passed by reference here. The function
351 // access() will set the lat value.
352 satisfied = access(pkt, blk, lat, writebacks);
350
353
354 // After the evicted blocks are selected, they must be forwarded
355 // to the write buffer to ensure they logically precede anything
356 // happening below
357 doWritebacks(writebacks, clockEdge(lat + forwardLatency));
358 }
359
351 // Here we charge the headerDelay that takes into account the latencies
352 // of the bus, if the packet comes from it.
353 // The latency charged is just the value set by the access() function.
354 // In case of a hit we are neglecting response latency.
355 // In case of a miss we are neglecting forward latency.
356 Tick request_time = clockEdge(lat);
357 // Here we reset the timing of the packet.
358 pkt->headerDelay = pkt->payloadDelay = 0;

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

443 mshr_uncacheable_lat[stats_cmd_idx][pkt->req->masterId()] +=
444 miss_latency;
445 } else {
446 assert(pkt->req->masterId() < system->maxMasters());
447 mshr_miss_latency[stats_cmd_idx][pkt->req->masterId()] +=
448 miss_latency;
449 }
450
360 // Here we charge the headerDelay that takes into account the latencies
361 // of the bus, if the packet comes from it.
362 // The latency charged is just the value set by the access() function.
363 // In case of a hit we are neglecting response latency.
364 // In case of a miss we are neglecting forward latency.
365 Tick request_time = clockEdge(lat);
366 // Here we reset the timing of the packet.
367 pkt->headerDelay = pkt->payloadDelay = 0;

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

452 mshr_uncacheable_lat[stats_cmd_idx][pkt->req->masterId()] +=
453 miss_latency;
454 } else {
455 assert(pkt->req->masterId() < system->maxMasters());
456 mshr_miss_latency[stats_cmd_idx][pkt->req->masterId()] +=
457 miss_latency;
458 }
459
460 PacketList writebacks;
461
451 bool is_fill = !mshr->isForward &&
452 (pkt->isRead() || pkt->cmd == MemCmd::UpgradeResp ||
453 mshr->wasWholeLineWrite);
454
455 // make sure that if the mshr was due to a whole line write then
456 // the response is an invalidation
457 assert(!mshr->wasWholeLineWrite || pkt->isInvalidate());
458
459 CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure());
460
461 if (is_fill && !is_error) {
462 DPRINTF(Cache, "Block for addr %#llx being updated in Cache\n",
463 pkt->getAddr());
464
465 const bool allocate = (writeAllocator && mshr->wasWholeLineWrite) ?
466 writeAllocator->allocate() : mshr->allocOnFill();
462 bool is_fill = !mshr->isForward &&
463 (pkt->isRead() || pkt->cmd == MemCmd::UpgradeResp ||
464 mshr->wasWholeLineWrite);
465
466 // make sure that if the mshr was due to a whole line write then
467 // the response is an invalidation
468 assert(!mshr->wasWholeLineWrite || pkt->isInvalidate());
469
470 CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure());
471
472 if (is_fill && !is_error) {
473 DPRINTF(Cache, "Block for addr %#llx being updated in Cache\n",
474 pkt->getAddr());
475
476 const bool allocate = (writeAllocator && mshr->wasWholeLineWrite) ?
477 writeAllocator->allocate() : mshr->allocOnFill();
467 blk = handleFill(pkt, blk, allocate);
478 blk = handleFill(pkt, blk, writebacks, allocate);
468 assert(blk != nullptr);
469 ppFill->notify(pkt);
470 }
471
472 if (blk && blk->isValid() && pkt->isClean() && !pkt->isInvalidate()) {
473 // The block was marked not readable while there was a pending
474 // cache maintenance operation, restore its flag.
475 blk->status |= BlkReadable;

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

515 clockEdge());
516 if (next_pf_time != MaxTick)
517 schedMemSideSendEvent(next_pf_time);
518 }
519 }
520
521 // if we used temp block, check to see if its valid and then clear it out
522 if (blk == tempBlock && tempBlock->isValid()) {
479 assert(blk != nullptr);
480 ppFill->notify(pkt);
481 }
482
483 if (blk && blk->isValid() && pkt->isClean() && !pkt->isInvalidate()) {
484 // The block was marked not readable while there was a pending
485 // cache maintenance operation, restore its flag.
486 blk->status |= BlkReadable;

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

526 clockEdge());
527 if (next_pf_time != MaxTick)
528 schedMemSideSendEvent(next_pf_time);
529 }
530 }
531
532 // if we used temp block, check to see if its valid and then clear it out
533 if (blk == tempBlock && tempBlock->isValid()) {
523 evictBlock(blk, clockEdge(forwardLatency) + pkt->headerDelay);
534 evictBlock(blk, writebacks);
524 }
525
535 }
536
537 const Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay;
538 // copy writebacks to write buffer
539 doWritebacks(writebacks, forward_time);
540
526 DPRINTF(CacheVerbose, "%s: Leaving with %s\n", __func__, pkt->print());
527 delete pkt;
528}
529
530
531Tick
532BaseCache::recvAtomic(PacketPtr pkt)
533{
534 // should assert here that there are no outstanding MSHRs or
535 // writebacks... that would mean that someone used an atomic
536 // access in timing mode
537
538 // We use lookupLatency here because it is used to specify the latency
539 // to access.
540 Cycles lat = lookupLatency;
541
542 CacheBlk *blk = nullptr;
541 DPRINTF(CacheVerbose, "%s: Leaving with %s\n", __func__, pkt->print());
542 delete pkt;
543}
544
545
546Tick
547BaseCache::recvAtomic(PacketPtr pkt)
548{
549 // should assert here that there are no outstanding MSHRs or
550 // writebacks... that would mean that someone used an atomic
551 // access in timing mode
552
553 // We use lookupLatency here because it is used to specify the latency
554 // to access.
555 Cycles lat = lookupLatency;
556
557 CacheBlk *blk = nullptr;
543 bool satisfied = access(pkt, blk, lat);
558 PacketList writebacks;
559 bool satisfied = access(pkt, blk, lat, writebacks);
544
545 if (pkt->isClean() && blk && blk->isDirty()) {
546 // A cache clean opearation is looking for a dirty
547 // block. If a dirty block is encountered a WriteClean
548 // will update any copies to the path to the memory
549 // until the point of reference.
550 DPRINTF(CacheVerbose, "%s: packet %s found block: %s\n",
551 __func__, pkt->print(), blk->print());
552 PacketPtr wb_pkt = writecleanBlk(blk, pkt->req->getDest(), pkt->id);
560
561 if (pkt->isClean() && blk && blk->isDirty()) {
562 // A cache clean opearation is looking for a dirty
563 // block. If a dirty block is encountered a WriteClean
564 // will update any copies to the path to the memory
565 // until the point of reference.
566 DPRINTF(CacheVerbose, "%s: packet %s found block: %s\n",
567 __func__, pkt->print(), blk->print());
568 PacketPtr wb_pkt = writecleanBlk(blk, pkt->req->getDest(), pkt->id);
569 writebacks.push_back(wb_pkt);
553 pkt->setSatisfied();
570 pkt->setSatisfied();
554 doWritebacksAtomic(wb_pkt);
555 }
556
571 }
572
573 // handle writebacks resulting from the access here to ensure they
574 // logically precede anything happening below
575 doWritebacksAtomic(writebacks);
576 assert(writebacks.empty());
577
557 if (!satisfied) {
578 if (!satisfied) {
558 lat += handleAtomicReqMiss(pkt, blk);
579 lat += handleAtomicReqMiss(pkt, blk, writebacks);
559 }
560
561 // Note that we don't invoke the prefetcher at all in atomic mode.
562 // It's not clear how to do it properly, particularly for
563 // prefetchers that aggressively generate prefetch candidates and
564 // rely on bandwidth contention to throttle them; these will tend
565 // to pollute the cache in atomic mode since there is no bandwidth
566 // contention. If we ever do want to enable prefetching in atomic
567 // mode, though, this is the place to do it... see timingAccess()
568 // for an example (though we'd want to issue the prefetch(es)
569 // immediately rather than calling requestMemSideBus() as we do
570 // there).
571
580 }
581
582 // Note that we don't invoke the prefetcher at all in atomic mode.
583 // It's not clear how to do it properly, particularly for
584 // prefetchers that aggressively generate prefetch candidates and
585 // rely on bandwidth contention to throttle them; these will tend
586 // to pollute the cache in atomic mode since there is no bandwidth
587 // contention. If we ever do want to enable prefetching in atomic
588 // mode, though, this is the place to do it... see timingAccess()
589 // for an example (though we'd want to issue the prefetch(es)
590 // immediately rather than calling requestMemSideBus() as we do
591 // there).
592
593 // do any writebacks resulting from the response handling
594 doWritebacksAtomic(writebacks);
595
572 // if we used temp block, check to see if its valid and if so
573 // clear it out, but only do so after the call to recvAtomic is
574 // finished so that any downstream observers (such as a snoop
575 // filter), first see the fill, and only then see the eviction
576 if (blk == tempBlock && tempBlock->isValid()) {
577 // the atomic CPU calls recvAtomic for fetch and load/store
578 // sequentuially, and we may already have a tempBlock
579 // writeback from the fetch that we have not yet sent

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

771 }
772 }
773
774 return nullptr;
775}
776
777bool
778BaseCache::updateCompressionData(CacheBlk *blk, const uint64_t* data,
596 // if we used temp block, check to see if its valid and if so
597 // clear it out, but only do so after the call to recvAtomic is
598 // finished so that any downstream observers (such as a snoop
599 // filter), first see the fill, and only then see the eviction
600 if (blk == tempBlock && tempBlock->isValid()) {
601 // the atomic CPU calls recvAtomic for fetch and load/store
602 // sequentuially, and we may already have a tempBlock
603 // writeback from the fetch that we have not yet sent

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

795 }
796 }
797
798 return nullptr;
799}
800
801bool
802BaseCache::updateCompressionData(CacheBlk *blk, const uint64_t* data,
779 uint32_t delay, Cycles tag_latency)
803 PacketList &writebacks)
780{
781 // tempBlock does not exist in the tags, so don't do anything for it.
782 if (blk == tempBlock) {
783 return true;
784 }
785
786 // Get superblock of the given block
787 CompressionBlk* compression_blk = static_cast<CompressionBlk*>(blk);

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

861 compression_blk->setDecompressionLatency(decompression_lat);
862
863 // Evict valid blocks
864 for (const auto& evict_blk : evict_blks) {
865 if (evict_blk->isValid()) {
866 if (evict_blk->wasPrefetched()) {
867 unusedPrefetches++;
868 }
804{
805 // tempBlock does not exist in the tags, so don't do anything for it.
806 if (blk == tempBlock) {
807 return true;
808 }
809
810 // Get superblock of the given block
811 CompressionBlk* compression_blk = static_cast<CompressionBlk*>(blk);

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

885 compression_blk->setDecompressionLatency(decompression_lat);
886
887 // Evict valid blocks
888 for (const auto& evict_blk : evict_blks) {
889 if (evict_blk->isValid()) {
890 if (evict_blk->wasPrefetched()) {
891 unusedPrefetches++;
892 }
869 Cycles lat = calculateAccessLatency(evict_blk, delay, tag_latency);
870 evictBlock(evict_blk, clockEdge(lat + forwardLatency));
893 evictBlock(evict_blk, writebacks);
871 }
872 }
873
874 return true;
875}
876
877void
878BaseCache::satisfyRequest(PacketPtr pkt, CacheBlk *blk, bool, bool)

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

996 // we find out it is a miss), and use the tag-only latency.
997 lat = calculateTagOnlyLatency(delay, lookup_lat);
998 }
999
1000 return lat;
1001}
1002
1003bool
894 }
895 }
896
897 return true;
898}
899
900void
901BaseCache::satisfyRequest(PacketPtr pkt, CacheBlk *blk, bool, bool)

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

1019 // we find out it is a miss), and use the tag-only latency.
1020 lat = calculateTagOnlyLatency(delay, lookup_lat);
1021 }
1022
1023 return lat;
1024}
1025
1026bool
1004BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat)
1027BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
1028 PacketList &writebacks)
1005{
1006 // sanity check
1007 assert(pkt->isRequest());
1008
1009 chatty_assert(!(isReadOnly && pkt->isWrite()),
1010 "Should never see a write in a read-only cache %s\n",
1011 name());
1012

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

1095 // a tag lookup for simplicity.
1096 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
1097
1098 return true;
1099 }
1100
1101 if (!blk) {
1102 // need to do a replacement
1029{
1030 // sanity check
1031 assert(pkt->isRequest());
1032
1033 chatty_assert(!(isReadOnly && pkt->isWrite()),
1034 "Should never see a write in a read-only cache %s\n",
1035 name());
1036

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

1119 // a tag lookup for simplicity.
1120 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
1121
1122 return true;
1123 }
1124
1125 if (!blk) {
1126 // need to do a replacement
1103 blk = allocateBlock(pkt, tag_latency);
1127 blk = allocateBlock(pkt, writebacks);
1104 if (!blk) {
1105 // no replaceable block available: give up, fwd to next level.
1106 incMissCount(pkt);
1107
1108 // A writeback searches for the block, then writes the data.
1109 // As the block could not be found, it was a tag-only access.
1110 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
1111
1112 return false;
1113 }
1114
1115 blk->status |= BlkReadable;
1116 } else if (compressor) {
1117 // This is an overwrite to an existing block, therefore we need
1118 // to check for data expansion (i.e., block was compressed with
1119 // a smaller size, and now it doesn't fit the entry anymore).
1120 // If that is the case we might need to evict blocks.
1121 if (!updateCompressionData(blk, pkt->getConstPtr<uint64_t>(),
1128 if (!blk) {
1129 // no replaceable block available: give up, fwd to next level.
1130 incMissCount(pkt);
1131
1132 // A writeback searches for the block, then writes the data.
1133 // As the block could not be found, it was a tag-only access.
1134 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
1135
1136 return false;
1137 }
1138
1139 blk->status |= BlkReadable;
1140 } else if (compressor) {
1141 // This is an overwrite to an existing block, therefore we need
1142 // to check for data expansion (i.e., block was compressed with
1143 // a smaller size, and now it doesn't fit the entry anymore).
1144 // If that is the case we might need to evict blocks.
1145 if (!updateCompressionData(blk, pkt->getConstPtr<uint64_t>(),
1122 pkt->headerDelay, tag_latency)) {
1146 writebacks)) {
1123 // This is a failed data expansion (write), which happened
1124 // after finding the replacement entries and accessing the
1125 // block's data. There were no replaceable entries available
1126 // to make room for the expanded block, and since it does not
1127 // fit anymore and it has been properly updated to contain
1128 // the new data, forward it to the next level
1129 lat = calculateAccessLatency(blk, pkt->headerDelay,
1130 tag_latency);

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

1190 // As the block could not be found, it was a tag-only access.
1191 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
1192
1193 // if this is a write through packet, we don't try to
1194 // allocate if the block is not present
1195 return false;
1196 } else {
1197 // a writeback that misses needs to allocate a new block
1147 // This is a failed data expansion (write), which happened
1148 // after finding the replacement entries and accessing the
1149 // block's data. There were no replaceable entries available
1150 // to make room for the expanded block, and since it does not
1151 // fit anymore and it has been properly updated to contain
1152 // the new data, forward it to the next level
1153 lat = calculateAccessLatency(blk, pkt->headerDelay,
1154 tag_latency);

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

1214 // As the block could not be found, it was a tag-only access.
1215 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
1216
1217 // if this is a write through packet, we don't try to
1218 // allocate if the block is not present
1219 return false;
1220 } else {
1221 // a writeback that misses needs to allocate a new block
1198 blk = allocateBlock(pkt, tag_latency);
1222 blk = allocateBlock(pkt, writebacks);
1199 if (!blk) {
1200 // no replaceable block available: give up, fwd to
1201 // next level.
1202 incMissCount(pkt);
1203
1204 // A writeback searches for the block, then writes the
1205 // data. As the block could not be found, it was a tag-only
1206 // access.

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

1213 blk->status |= BlkReadable;
1214 }
1215 } else if (compressor) {
1216 // This is an overwrite to an existing block, therefore we need
1217 // to check for data expansion (i.e., block was compressed with
1218 // a smaller size, and now it doesn't fit the entry anymore).
1219 // If that is the case we might need to evict blocks.
1220 if (!updateCompressionData(blk, pkt->getConstPtr<uint64_t>(),
1223 if (!blk) {
1224 // no replaceable block available: give up, fwd to
1225 // next level.
1226 incMissCount(pkt);
1227
1228 // A writeback searches for the block, then writes the
1229 // data. As the block could not be found, it was a tag-only
1230 // access.

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

1237 blk->status |= BlkReadable;
1238 }
1239 } else if (compressor) {
1240 // This is an overwrite to an existing block, therefore we need
1241 // to check for data expansion (i.e., block was compressed with
1242 // a smaller size, and now it doesn't fit the entry anymore).
1243 // If that is the case we might need to evict blocks.
1244 if (!updateCompressionData(blk, pkt->getConstPtr<uint64_t>(),
1221 pkt->headerDelay, tag_latency)) {
1245 writebacks)) {
1222 // This is a failed data expansion (write), which happened
1223 // after finding the replacement entries and accessing the
1224 // block's data. There were no replaceable entries available
1225 // to make room for the expanded block, and since it does not
1226 // fit anymore and it has been properly updated to contain
1227 // the new data, forward it to the next level
1228 lat = calculateAccessLatency(blk, pkt->headerDelay,
1229 tag_latency);

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

1306 // if we have responded to a cache, and our block is still
1307 // valid, but not dirty, and this cache is mostly exclusive
1308 // with respect to the cache above, drop the block
1309 invalidateBlock(blk);
1310 }
1311}
1312
1313CacheBlk*
1246 // This is a failed data expansion (write), which happened
1247 // after finding the replacement entries and accessing the
1248 // block's data. There were no replaceable entries available
1249 // to make room for the expanded block, and since it does not
1250 // fit anymore and it has been properly updated to contain
1251 // the new data, forward it to the next level
1252 lat = calculateAccessLatency(blk, pkt->headerDelay,
1253 tag_latency);

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

1330 // if we have responded to a cache, and our block is still
1331 // valid, but not dirty, and this cache is mostly exclusive
1332 // with respect to the cache above, drop the block
1333 invalidateBlock(blk);
1334 }
1335}
1336
1337CacheBlk*
1314BaseCache::handleFill(PacketPtr pkt, CacheBlk *blk, bool allocate)
1338BaseCache::handleFill(PacketPtr pkt, CacheBlk *blk, PacketList &writebacks,
1339 bool allocate)
1315{
1316 assert(pkt->isResponse());
1317 Addr addr = pkt->getAddr();
1318 bool is_secure = pkt->isSecure();
1319#if TRACING_ON
1320 CacheBlk::State old_state = blk ? blk->status : 0;
1321#endif
1322
1323 // When handling a fill, we should have no writes to this line.
1324 assert(addr == pkt->getBlockAddr(blkSize));
1325 assert(!writeBuffer.findMatch(addr, is_secure));
1326
1327 if (!blk) {
1328 // better have read new data...
1329 assert(pkt->hasData() || pkt->cmd == MemCmd::InvalidateResp);
1330
1340{
1341 assert(pkt->isResponse());
1342 Addr addr = pkt->getAddr();
1343 bool is_secure = pkt->isSecure();
1344#if TRACING_ON
1345 CacheBlk::State old_state = blk ? blk->status : 0;
1346#endif
1347
1348 // When handling a fill, we should have no writes to this line.
1349 assert(addr == pkt->getBlockAddr(blkSize));
1350 assert(!writeBuffer.findMatch(addr, is_secure));
1351
1352 if (!blk) {
1353 // better have read new data...
1354 assert(pkt->hasData() || pkt->cmd == MemCmd::InvalidateResp);
1355
1331 // Need to do a replacement if allocating, otherwise we stick
1332 // with the temporary storage. The tag lookup has already been
1333 // done to decide the eviction victims, so it is set to 0 here.
1334 // The eviction itself, however, is delayed until the new data
1335 // for the block that is requesting the replacement arrives.
1336 blk = allocate ? allocateBlock(pkt, Cycles(0)) : nullptr;
1356 // need to do a replacement if allocating, otherwise we stick
1357 // with the temporary storage
1358 blk = allocate ? allocateBlock(pkt, writebacks) : nullptr;
1337
1338 if (!blk) {
1339 // No replaceable block or a mostly exclusive
1340 // cache... just use temporary storage to complete the
1341 // current request and then get rid of it
1342 blk = tempBlock;
1343 tempBlock->insert(addr, is_secure);
1344 DPRINTF(Cache, "using temp block for %#llx (%s)\n", addr,

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

1429 // The block will be ready when the payload arrives and the fill is done
1430 blk->setWhenReady(clockEdge(fillLatency) + pkt->headerDelay +
1431 pkt->payloadDelay);
1432
1433 return blk;
1434}
1435
1436CacheBlk*
1359
1360 if (!blk) {
1361 // No replaceable block or a mostly exclusive
1362 // cache... just use temporary storage to complete the
1363 // current request and then get rid of it
1364 blk = tempBlock;
1365 tempBlock->insert(addr, is_secure);
1366 DPRINTF(Cache, "using temp block for %#llx (%s)\n", addr,

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

1451 // The block will be ready when the payload arrives and the fill is done
1452 blk->setWhenReady(clockEdge(fillLatency) + pkt->headerDelay +
1453 pkt->payloadDelay);
1454
1455 return blk;
1456}
1457
1458CacheBlk*
1437BaseCache::allocateBlock(const PacketPtr pkt, Cycles tag_latency)
1459BaseCache::allocateBlock(const PacketPtr pkt, PacketList &writebacks)
1438{
1439 // Get address
1440 const Addr addr = pkt->getAddr();
1441
1442 // Get secure bit
1443 const bool is_secure = pkt->isSecure();
1444
1445 // Block size and compression related access latency. Only relevant if

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

1502 DPRINTF(CacheRepl, "Evicting %s (%#llx) to make room for " \
1503 "%#llx (%s)\n", blk->print(), regenerateBlkAddr(blk),
1504 addr, is_secure);
1505
1506 if (blk->wasPrefetched()) {
1507 unusedPrefetches++;
1508 }
1509
1460{
1461 // Get address
1462 const Addr addr = pkt->getAddr();
1463
1464 // Get secure bit
1465 const bool is_secure = pkt->isSecure();
1466
1467 // Block size and compression related access latency. Only relevant if

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

1524 DPRINTF(CacheRepl, "Evicting %s (%#llx) to make room for " \
1525 "%#llx (%s)\n", blk->print(), regenerateBlkAddr(blk),
1526 addr, is_secure);
1527
1528 if (blk->wasPrefetched()) {
1529 unusedPrefetches++;
1530 }
1531
1510 Cycles lat =
1511 calculateAccessLatency(blk, pkt->headerDelay, tag_latency);
1512 evictBlock(blk, clockEdge(lat + forwardLatency));
1532 evictBlock(blk, writebacks);
1513 }
1514 }
1515
1516 replacements++;
1517 }
1518
1519 // If using a compressor, set compression data. This must be done before
1520 // block insertion, as compressed tags use this information.

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

1537 if (blk != tempBlock) {
1538 tags->invalidate(blk);
1539 } else {
1540 tempBlock->invalidate();
1541 }
1542}
1543
1544void
1533 }
1534 }
1535
1536 replacements++;
1537 }
1538
1539 // If using a compressor, set compression data. This must be done before
1540 // block insertion, as compressed tags use this information.

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

1557 if (blk != tempBlock) {
1558 tags->invalidate(blk);
1559 } else {
1560 tempBlock->invalidate();
1561 }
1562}
1563
1564void
1545BaseCache::evictBlock(CacheBlk *blk, Tick forward_timing)
1565BaseCache::evictBlock(CacheBlk *blk, PacketList &writebacks)
1546{
1547 PacketPtr pkt = evictBlock(blk);
1548 if (pkt) {
1566{
1567 PacketPtr pkt = evictBlock(blk);
1568 if (pkt) {
1549 if (system->isTimingMode()) {
1550 doWritebacks(pkt, forward_timing);
1551 } else {
1552 doWritebacksAtomic(pkt);
1553 }
1569 writebacks.push_back(pkt);
1554 }
1555}
1556
1557PacketPtr
1558BaseCache::writebackBlk(CacheBlk *blk)
1559{
1560 chatty_assert(!isReadOnly || writebackClean,
1561 "Writeback from read-only cache");

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

1814 // A cache clean opearation is looking for a dirty
1815 // block. If a dirty block is encountered a WriteClean
1816 // will update any copies to the path to the memory
1817 // until the point of reference.
1818 DPRINTF(CacheVerbose, "%s: packet %s found block: %s\n",
1819 __func__, pkt->print(), blk->print());
1820 PacketPtr wb_pkt = writecleanBlk(blk, pkt->req->getDest(),
1821 pkt->id);
1570 }
1571}
1572
1573PacketPtr
1574BaseCache::writebackBlk(CacheBlk *blk)
1575{
1576 chatty_assert(!isReadOnly || writebackClean,
1577 "Writeback from read-only cache");

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

1830 // A cache clean opearation is looking for a dirty
1831 // block. If a dirty block is encountered a WriteClean
1832 // will update any copies to the path to the memory
1833 // until the point of reference.
1834 DPRINTF(CacheVerbose, "%s: packet %s found block: %s\n",
1835 __func__, pkt->print(), blk->print());
1836 PacketPtr wb_pkt = writecleanBlk(blk, pkt->req->getDest(),
1837 pkt->id);
1822 doWritebacks(wb_pkt, 0);
1838 PacketList writebacks;
1839 writebacks.push_back(wb_pkt);
1840 doWritebacks(writebacks, 0);
1823 }
1824
1825 return false;
1826 }
1827}
1828
1829bool
1830BaseCache::sendWriteQueuePacket(WriteQueueEntry* wq_entry)

--- 846 unchanged lines hidden ---
1841 }
1842
1843 return false;
1844 }
1845}
1846
1847bool
1848BaseCache::sendWriteQueuePacket(WriteQueueEntry* wq_entry)

--- 846 unchanged lines hidden ---