Deleted Added
sdiff udiff text old ( 12715:0c8b4f376378 ) new ( 12719:68a20fbd07a6 )
full compact
1/*
2 * Copyright (c) 2010-2018 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

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

1317
1318 // Reset the bus additional time as it is now accounted for
1319 pkt->headerDelay = pkt->payloadDelay = 0;
1320
1321 cpuSidePort->schedTimingResp(pkt, completion_time, true);
1322}
1323
1324void
1325Cache::recvTimingResp(PacketPtr pkt)
1326{
1327 assert(pkt->isResponse());
1328
1329 // all header delay should be paid for by the crossbar, unless
1330 // this is a prefetch response from above
1331 panic_if(pkt->headerDelay != 0 && pkt->cmd != MemCmd::HardPFResp,
1332 "%s saw a non-zero packet delay\n", name());
1333
1334 bool is_error = pkt->isError();
1335
1336 if (is_error) {
1337 DPRINTF(Cache, "%s: Cache received %s with error\n", __func__,
1338 pkt->print());
1339 }
1340
1341 DPRINTF(Cache, "%s: Handling response %s\n", __func__,
1342 pkt->print());
1343
1344 // if this is a write, we should be looking at an uncacheable
1345 // write
1346 if (pkt->isWrite()) {
1347 assert(pkt->req->isUncacheable());
1348 handleUncacheableWriteResp(pkt);
1349 return;
1350 }
1351
1352 // we have dealt with any (uncacheable) writes above, from here on
1353 // we know we are dealing with an MSHR due to a miss or a prefetch
1354 MSHR *mshr = dynamic_cast<MSHR*>(pkt->popSenderState());
1355 assert(mshr);
1356
1357 if (mshr == noTargetMSHR) {
1358 // we always clear at least one target
1359 clearBlocked(Blocked_NoTargets);
1360 noTargetMSHR = nullptr;
1361 }
1362
1363 // Initial target is used just for stats
1364 MSHR::Target *initial_tgt = mshr->getTarget();
1365 int stats_cmd_idx = initial_tgt->pkt->cmdToIndex();
1366 Tick miss_latency = curTick() - initial_tgt->recvTime;
1367
1368 if (pkt->req->isUncacheable()) {
1369 assert(pkt->req->masterId() < system->maxMasters());
1370 mshr_uncacheable_lat[stats_cmd_idx][pkt->req->masterId()] +=
1371 miss_latency;
1372 } else {
1373 assert(pkt->req->masterId() < system->maxMasters());
1374 mshr_miss_latency[stats_cmd_idx][pkt->req->masterId()] +=
1375 miss_latency;
1376 }
1377
1378 bool wasFull = mshrQueue.isFull();
1379
1380 PacketList writebacks;
1381
1382 Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay;
1383
1384 bool is_fill = !mshr->isForward &&
1385 (pkt->isRead() || pkt->cmd == MemCmd::UpgradeResp);
1386
1387 CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure());
1388 const bool valid_blk = blk && blk->isValid();
1389 // If the response indicates that there are no sharers and we
1390 // either had the block already or the response is filling we can
1391 // promote our copy to writable
1392 if (!pkt->hasSharers() &&
1393 (is_fill || (valid_blk && !pkt->req->isCacheInvalidate()))) {
1394 mshr->promoteWritable();
1395 }
1396
1397 if (is_fill && !is_error) {
1398 DPRINTF(Cache, "Block for addr %#llx being updated in Cache\n",
1399 pkt->getAddr());
1400
1401 blk = handleFill(pkt, blk, writebacks, mshr->allocOnFill());
1402 assert(blk != nullptr);
1403 }
1404
1405 // allow invalidation responses originating from write-line
1406 // requests to be discarded
1407 bool is_invalidate = pkt->isInvalidate();
1408
1409 // The block was marked as not readable while there was a pending
1410 // cache maintenance operation, restore its flag.
1411 if (pkt->isClean() && !is_invalidate && valid_blk) {
1412 blk->status |= BlkReadable;
1413 }
1414
1415 // First offset for critical word first calculations
1416 int initial_offset = initial_tgt->pkt->getOffset(blkSize);
1417
1418 MSHR::TargetList targets = mshr->extractServiceableTargets(pkt);
1419 for (auto &target: targets) {
1420 Packet *tgt_pkt = target.pkt;
1421 switch (target.source) {
1422 case MSHR::Target::FromCPU:
1423 Tick completion_time;
1424 // Here we charge on completion_time the delay of the xbar if the
1425 // packet comes from it, charged on headerDelay.

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

1445 if (tgt_pkt->cmd == MemCmd::WriteLineReq) {
1446 assert(!is_error);
1447 // we got the block in a writable state, so promote
1448 // any deferred targets if possible
1449 mshr->promoteWritable();
1450 // NB: we use the original packet here and not the response!
1451 blk = handleFill(tgt_pkt, blk, writebacks,
1452 targets.allocOnFill);
1453 assert(blk != nullptr);
1454
1455 // treat as a fill, and discard the invalidation
1456 // response
1457 is_fill = true;
1458 is_invalidate = false;
1459 }
1460
1461 if (is_fill) {

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

1574 // should not invalidate the block, so check if the
1575 // invalidation should be discarded
1576 if (is_invalidate || mshr->hasPostInvalidate()) {
1577 invalidateBlock(blk);
1578 } else if (mshr->hasPostDowngrade()) {
1579 blk->status &= ~BlkWritable;
1580 }
1581 }
1582
1583 if (mshr->promoteDeferredTargets()) {
1584 // avoid later read getting stale data while write miss is
1585 // outstanding.. see comment in timingAccess()
1586 if (blk) {
1587 blk->status &= ~BlkReadable;
1588 }
1589 mshrQueue.markPending(mshr);
1590 schedMemSideSendEvent(clockEdge() + pkt->payloadDelay);
1591 } else {
1592 mshrQueue.deallocate(mshr);
1593 if (wasFull && !mshrQueue.isFull()) {
1594 clearBlocked(Blocked_NoMSHRs);
1595 }
1596
1597 // Request the bus for a prefetch if this deallocation freed enough
1598 // MSHRs for a prefetch to take place
1599 if (prefetcher && mshrQueue.canPrefetch()) {
1600 Tick next_pf_time = std::max(prefetcher->nextPrefetchReadyTime(),
1601 clockEdge());
1602 if (next_pf_time != MaxTick)
1603 schedMemSideSendEvent(next_pf_time);
1604 }
1605 }
1606 // reset the xbar additional timinig as it is now accounted for
1607 pkt->headerDelay = pkt->payloadDelay = 0;
1608
1609 // if we used temp block, check to see if its valid and then clear it out
1610 if (blk == tempBlock && tempBlock->isValid()) {
1611 PacketPtr wb_pkt = tempBlock->isDirty() || writebackClean ?
1612 writebackBlk(blk) : cleanEvictBlk(blk);
1613 writebacks.push_back(wb_pkt);
1614 invalidateBlock(tempBlock);
1615 }
1616
1617 // copy writebacks to write buffer
1618 doWritebacks(writebacks, forward_time);
1619
1620 DPRINTF(CacheVerbose, "%s: Leaving with %s\n", __func__, pkt->print());
1621 delete pkt;
1622}
1623
1624PacketPtr

--- 1235 unchanged lines hidden ---