1325c1325,1326
< Cache::recvTimingResp(PacketPtr pkt)
---
> Cache::serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt, CacheBlk *blk,
> PacketList &writebacks)
1327,1363d1327
< assert(pkt->isResponse());
<
< // all header delay should be paid for by the crossbar, unless
< // this is a prefetch response from above
< panic_if(pkt->headerDelay != 0 && pkt->cmd != MemCmd::HardPFResp,
< "%s saw a non-zero packet delay\n", name());
<
< bool is_error = pkt->isError();
<
< if (is_error) {
< DPRINTF(Cache, "%s: Cache received %s with error\n", __func__,
< pkt->print());
< }
<
< DPRINTF(Cache, "%s: Handling response %s\n", __func__,
< pkt->print());
<
< // if this is a write, we should be looking at an uncacheable
< // write
< if (pkt->isWrite()) {
< assert(pkt->req->isUncacheable());
< handleUncacheableWriteResp(pkt);
< return;
< }
<
< // we have dealt with any (uncacheable) writes above, from here on
< // we know we are dealing with an MSHR due to a miss or a prefetch
< MSHR *mshr = dynamic_cast<MSHR*>(pkt->popSenderState());
< assert(mshr);
<
< if (mshr == noTargetMSHR) {
< // we always clear at least one target
< clearBlocked(Blocked_NoTargets);
< noTargetMSHR = nullptr;
< }
<
< // Initial target is used just for stats
1365,1366c1329,1330
< int stats_cmd_idx = initial_tgt->pkt->cmdToIndex();
< Tick miss_latency = curTick() - initial_tgt->recvTime;
---
> // First offset for critical word first calculations
> const int initial_offset = initial_tgt->pkt->getOffset(blkSize);
1368,1383c1332
< if (pkt->req->isUncacheable()) {
< assert(pkt->req->masterId() < system->maxMasters());
< mshr_uncacheable_lat[stats_cmd_idx][pkt->req->masterId()] +=
< miss_latency;
< } else {
< assert(pkt->req->masterId() < system->maxMasters());
< mshr_miss_latency[stats_cmd_idx][pkt->req->masterId()] +=
< miss_latency;
< }
<
< bool wasFull = mshrQueue.isFull();
<
< PacketList writebacks;
<
< Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay;
<
---
> const bool is_error = pkt->isError();
1386,1404d1334
<
< CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure());
< const bool valid_blk = blk && blk->isValid();
< // If the response indicates that there are no sharers and we
< // either had the block already or the response is filling we can
< // promote our copy to writable
< if (!pkt->hasSharers() &&
< (is_fill || (valid_blk && !pkt->req->isCacheInvalidate()))) {
< mshr->promoteWritable();
< }
<
< if (is_fill && !is_error) {
< DPRINTF(Cache, "Block for addr %#llx being updated in Cache\n",
< pkt->getAddr());
<
< blk = handleFill(pkt, blk, writebacks, mshr->allocOnFill());
< assert(blk != nullptr);
< }
<
1409,1417d1338
< // The block was marked as not readable while there was a pending
< // cache maintenance operation, restore its flag.
< if (pkt->isClean() && !is_invalidate && valid_blk) {
< blk->status |= BlkReadable;
< }
<
< // First offset for critical word first calculations
< int initial_offset = initial_tgt->pkt->getOffset(blkSize);
<
1453c1374
< assert(blk != nullptr);
---
> assert(blk);
1581a1503
> }
1582a1505,1588
> void
> Cache::recvTimingResp(PacketPtr pkt)
> {
> assert(pkt->isResponse());
>
> // all header delay should be paid for by the crossbar, unless
> // this is a prefetch response from above
> panic_if(pkt->headerDelay != 0 && pkt->cmd != MemCmd::HardPFResp,
> "%s saw a non-zero packet delay\n", name());
>
> const bool is_error = pkt->isError();
>
> if (is_error) {
> DPRINTF(Cache, "%s: Cache received %s with error\n", __func__,
> pkt->print());
> }
>
> DPRINTF(Cache, "%s: Handling response %s\n", __func__,
> pkt->print());
>
> // if this is a write, we should be looking at an uncacheable
> // write
> if (pkt->isWrite()) {
> assert(pkt->req->isUncacheable());
> handleUncacheableWriteResp(pkt);
> return;
> }
>
> // we have dealt with any (uncacheable) writes above, from here on
> // we know we are dealing with an MSHR due to a miss or a prefetch
> MSHR *mshr = dynamic_cast<MSHR*>(pkt->popSenderState());
> assert(mshr);
>
> if (mshr == noTargetMSHR) {
> // we always clear at least one target
> clearBlocked(Blocked_NoTargets);
> noTargetMSHR = nullptr;
> }
>
> // Initial target is used just for stats
> MSHR::Target *initial_tgt = mshr->getTarget();
> int stats_cmd_idx = initial_tgt->pkt->cmdToIndex();
> Tick miss_latency = curTick() - initial_tgt->recvTime;
>
> if (pkt->req->isUncacheable()) {
> assert(pkt->req->masterId() < system->maxMasters());
> mshr_uncacheable_lat[stats_cmd_idx][pkt->req->masterId()] +=
> miss_latency;
> } else {
> assert(pkt->req->masterId() < system->maxMasters());
> mshr_miss_latency[stats_cmd_idx][pkt->req->masterId()] +=
> miss_latency;
> }
>
> PacketList writebacks;
>
> bool is_fill = !mshr->isForward &&
> (pkt->isRead() || pkt->cmd == MemCmd::UpgradeResp);
>
> CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure());
>
> if (is_fill && !is_error) {
> DPRINTF(Cache, "Block for addr %#llx being updated in Cache\n",
> pkt->getAddr());
>
> blk = handleFill(pkt, blk, writebacks, mshr->allocOnFill());
> assert(blk != nullptr);
> }
>
> if (blk && blk->isValid() && pkt->isClean() && !pkt->isInvalidate()) {
> // The block was marked not readable while there was a pending
> // cache maintenance operation, restore its flag.
> blk->status |= BlkReadable;
> }
>
> if (blk && blk->isWritable() && !pkt->req->isCacheInvalidate()) {
> // If at this point the referenced block is writable and the
> // response is not a cache invalidate, we promote targets that
> // were deferred as we couldn't guarrantee a writable copy
> mshr->promoteWritable();
> }
>
> serviceMSHRTargets(mshr, pkt, blk, writebacks);
>
1591a1598,1601
> // while we deallocate an mshr from the queue we still have to
> // check the isFull condition before and after as we might
> // have been using the reserved entries already
> const bool was_full = mshrQueue.isFull();
1593c1603
< if (wasFull && !mshrQueue.isFull()) {
---
> if (was_full && !mshrQueue.isFull()) {
1606,1607d1615
< // reset the xbar additional timinig as it is now accounted for
< pkt->headerDelay = pkt->payloadDelay = 0;
1616a1625
> const Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay;