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 --- 463 unchanged lines hidden (view full) --- 472 return; 473 } 474 475 BaseCache::recvTimingReq(pkt); 476} 477 478PacketPtr 479Cache::createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk, |
480 bool needsWritable, 481 bool is_whole_line_write) const |
482{ 483 // should never see evictions here 484 assert(!cpu_pkt->isEviction()); 485 486 bool blkValid = blk && blk->isValid(); 487 488 if (cpu_pkt->req->isUncacheable() || 489 (!blkValid && cpu_pkt->isUpgrade()) || --- 6 unchanged lines hidden (view full) --- 496 assert(cpu_pkt->needsResponse()); 497 498 MemCmd cmd; 499 // @TODO make useUpgrades a parameter. 500 // Note that ownership protocols require upgrade, otherwise a 501 // write miss on a shared owned block will generate a ReadExcl, 502 // which will clobber the owned copy. 503 const bool useUpgrades = true; |
504 assert(cpu_pkt->cmd != MemCmd::WriteLineReq || is_whole_line_write); 505 if (is_whole_line_write) { |
506 assert(!blkValid || !blk->isWritable()); 507 // forward as invalidate to all other caches, this gives us 508 // the line in Exclusive state, and invalidates all other 509 // copies 510 cmd = MemCmd::InvalidateReq; 511 } else if (blkValid && useUpgrades) { 512 // only reason to be here is that blk is read only and we need 513 // it to be writable --- 63 unchanged lines hidden (view full) --- 577 assert(!(pkt->req->isUncacheable() && pkt->isWrite()) || 578 pkt->isResponse()); 579 580 return latency; 581 } 582 583 // only misses left 584 |
585 PacketPtr bus_pkt = createMissPacket(pkt, blk, pkt->needsWritable(), 586 pkt->isWholeLineWrite(blkSize)); |
587 588 bool is_forward = (bus_pkt == nullptr); 589 590 if (is_forward) { 591 // just forwarding the same request to the next level 592 // no local cache operation involved 593 bus_pkt = pkt; 594 } --- 18 unchanged lines hidden (view full) --- 613 // to do anything. Otherwise, use the separate bus_pkt to 614 // generate response to pkt and then delete it. 615 if (!is_forward) { 616 if (pkt->needsResponse()) { 617 assert(bus_pkt->isResponse()); 618 if (bus_pkt->isError()) { 619 pkt->makeAtomicResponse(); 620 pkt->copyError(bus_pkt); |
621 } else if (pkt->isWholeLineWrite(blkSize)) { |
622 // note the use of pkt, not bus_pkt here. 623 624 // write-line request to the cache that promoted 625 // the write to a whole line |
626 blk = handleFill(bus_pkt, blk, writebacks, |
627 allocOnFill(pkt->cmd)); 628 assert(blk != NULL); 629 is_invalidate = false; 630 satisfyRequest(pkt, blk); 631 } else if (bus_pkt->isRead() || 632 bus_pkt->cmd == MemCmd::UpgradeResp) { 633 // we're updating cache state to allow us to 634 // satisfy the upstream request from the cache --- 39 unchanged lines hidden (view full) --- 674{ 675 MSHR::Target *initial_tgt = mshr->getTarget(); 676 // First offset for critical word first calculations 677 const int initial_offset = initial_tgt->pkt->getOffset(blkSize); 678 679 const bool is_error = pkt->isError(); 680 // allow invalidation responses originating from write-line 681 // requests to be discarded |
682 bool is_invalidate = pkt->isInvalidate() && 683 !mshr->wasWholeLineWrite; |
684 685 MSHR::TargetList targets = mshr->extractServiceableTargets(pkt); 686 for (auto &target: targets) { 687 Packet *tgt_pkt = target.pkt; 688 switch (target.source) { 689 case MSHR::Target::FromCPU: 690 Tick completion_time; 691 // Here we charge on completion_time the delay of the xbar if the --- 13 unchanged lines hidden (view full) --- 705 // unlike the other packet flows, where data is found in other 706 // caches or memory and brought back, write-line requests always 707 // have the data right away, so the above check for "is fill?" 708 // cannot actually be determined until examining the stored MSHR 709 // state. We "catch up" with that logic here, which is duplicated 710 // from above. 711 if (tgt_pkt->cmd == MemCmd::WriteLineReq) { 712 assert(!is_error); |
713 assert(blk); |
714 assert(blk->isWritable()); |
715 } 716 717 if (blk && blk->isValid() && !mshr->isForward) { 718 satisfyRequest(tgt_pkt, blk, true, mshr->hasPostDowngrade()); 719 720 // How many bytes past the first request is this one 721 int transfer_offset = 722 tgt_pkt->getOffset(blkSize) - initial_offset; --- 674 unchanged lines hidden --- |