cache.cc (11333:c41d552d6f2e) | cache.cc (11334:9bd2e84abdca) |
---|---|
1/* 2 * Copyright (c) 2010-2015 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 --- 616 unchanged lines hidden (view full) --- 625 "not responding\n", 626 pkt->getAddr(), pkt->isSecure() ? "s" : "ns"); 627 628 // if the packet needs the block to be writable, and the cache 629 // that has promised to respond (setting the cache responding 630 // flag) is not providing writable (it is in Owned rather than 631 // the Modified state), we know that there may be other Shared 632 // copies in the system; go out and invalidate them all | 1/* 2 * Copyright (c) 2010-2015 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 --- 616 unchanged lines hidden (view full) --- 625 "not responding\n", 626 pkt->getAddr(), pkt->isSecure() ? "s" : "ns"); 627 628 // if the packet needs the block to be writable, and the cache 629 // that has promised to respond (setting the cache responding 630 // flag) is not providing writable (it is in Owned rather than 631 // the Modified state), we know that there may be other Shared 632 // copies in the system; go out and invalidate them all |
633 if (pkt->needsWritable() && !pkt->responderHadWritable()) { 634 // an upstream cache that had the line in Owned state 635 // (dirty, but not writable), is responding and thus 636 // transferring the dirty line from one branch of the 637 // cache hierarchy to another | 633 assert(pkt->needsWritable() && !pkt->responderHadWritable()); |
638 | 634 |
639 // send out an express snoop and invalidate all other 640 // copies (snooping a packet that needs writable is the 641 // same as an invalidation), thus turning the Owned line 642 // into a Modified line, note that we don't invalidate the 643 // block in the current cache or any other cache on the 644 // path to memory | 635 // an upstream cache that had the line in Owned state 636 // (dirty, but not writable), is responding and thus 637 // transferring the dirty line from one branch of the 638 // cache hierarchy to another |
645 | 639 |
646 // create a downstream express snoop with cleared packet 647 // flags, there is no need to allocate any data as the 648 // packet is merely used to co-ordinate state transitions 649 Packet *snoop_pkt = new Packet(pkt, true, false); | 640 // send out an express snoop and invalidate all other 641 // copies (snooping a packet that needs writable is the 642 // same as an invalidation), thus turning the Owned line 643 // into a Modified line, note that we don't invalidate the 644 // block in the current cache or any other cache on the 645 // path to memory |
650 | 646 |
651 // also reset the bus time that the original packet has 652 // not yet paid for 653 snoop_pkt->headerDelay = snoop_pkt->payloadDelay = 0; | 647 // create a downstream express snoop with cleared packet 648 // flags, there is no need to allocate any data as the 649 // packet is merely used to co-ordinate state transitions 650 Packet *snoop_pkt = new Packet(pkt, true, false); |
654 | 651 |
655 // make this an instantaneous express snoop, and let the 656 // other caches in the system know that the another cache 657 // is responding, because we have found the authorative 658 // copy (Modified or Owned) that will supply the right 659 // data 660 snoop_pkt->setExpressSnoop(); 661 snoop_pkt->setCacheResponding(); | 652 // also reset the bus time that the original packet has 653 // not yet paid for 654 snoop_pkt->headerDelay = snoop_pkt->payloadDelay = 0; |
662 | 655 |
663 // this express snoop travels towards the memory, and at 664 // every crossbar it is snooped upwards thus reaching 665 // every cache in the system 666 bool M5_VAR_USED success = memSidePort->sendTimingReq(snoop_pkt); 667 // express snoops always succeed 668 assert(success); | 656 // make this an instantaneous express snoop, and let the 657 // other caches in the system know that the another cache 658 // is responding, because we have found the authorative 659 // copy (Modified or Owned) that will supply the right 660 // data 661 snoop_pkt->setExpressSnoop(); 662 snoop_pkt->setCacheResponding(); |
669 | 663 |
670 // main memory will delete the snoop packet 671 } | 664 // this express snoop travels towards the memory, and at 665 // every crossbar it is snooped upwards thus reaching 666 // every cache in the system 667 bool M5_VAR_USED success = memSidePort->sendTimingReq(snoop_pkt); 668 // express snoops always succeed 669 assert(success); |
672 | 670 |
671 // main memory will delete the snoop packet 672 |
|
673 // queue for deletion, as opposed to immediate deletion, as 674 // the sending cache is still relying on the packet 675 pendingDelete.reset(pkt); 676 | 673 // queue for deletion, as opposed to immediate deletion, as 674 // the sending cache is still relying on the packet 675 pendingDelete.reset(pkt); 676 |
677 // no need to take any action in this particular cache as an 678 // upstream cache has already committed to responding, and 679 // either the packet does not need writable (and we can let 680 // the cache that set the cache responding flag pass on the 681 // line without any need for intervention), or if the packet 682 // needs writable it is provided, or we have already sent out 683 // any express snoops in the section above | 677 // no need to take any further action in this particular cache 678 // as an upstram cache has already committed to responding, 679 // and we have already sent out any express snoops in the 680 // section above to ensure all other copies in the system are 681 // invalidated |
684 return true; 685 } 686 687 // anything that is merely forwarded pays for the forward latency and 688 // the delay provided by the crossbar 689 Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay; 690 691 // We use lookupLatency here because it is used to specify the latency --- 331 unchanged lines hidden (view full) --- 1023 if (pkt->cacheResponding()) { 1024 DPRINTF(Cache, "Cache above responding to %#llx (%s): " 1025 "not responding\n", 1026 pkt->getAddr(), pkt->isSecure() ? "s" : "ns"); 1027 1028 // if a cache is responding, and it had the line in Owned 1029 // rather than Modified state, we need to invalidate any 1030 // copies that are not on the same path to memory | 682 return true; 683 } 684 685 // anything that is merely forwarded pays for the forward latency and 686 // the delay provided by the crossbar 687 Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay; 688 689 // We use lookupLatency here because it is used to specify the latency --- 331 unchanged lines hidden (view full) --- 1021 if (pkt->cacheResponding()) { 1022 DPRINTF(Cache, "Cache above responding to %#llx (%s): " 1023 "not responding\n", 1024 pkt->getAddr(), pkt->isSecure() ? "s" : "ns"); 1025 1026 // if a cache is responding, and it had the line in Owned 1027 // rather than Modified state, we need to invalidate any 1028 // copies that are not on the same path to memory |
1031 if (pkt->needsWritable() && !pkt->responderHadWritable()) { 1032 lat += ticksToCycles(memSidePort->sendAtomic(pkt)); 1033 } | 1029 assert(pkt->needsWritable() && !pkt->responderHadWritable()); 1030 lat += ticksToCycles(memSidePort->sendAtomic(pkt)); |
1034 1035 return lat * clockPeriod(); 1036 } 1037 1038 // should assert here that there are no outstanding MSHRs or 1039 // writebacks... that would mean that someone used an atomic 1040 // access in timing mode 1041 --- 1446 unchanged lines hidden (view full) --- 2488 2489bool 2490Cache::CpuSidePort::recvTimingReq(PacketPtr pkt) 2491{ 2492 assert(!cache->system->bypassCaches()); 2493 2494 bool success = false; 2495 | 1031 1032 return lat * clockPeriod(); 1033 } 1034 1035 // should assert here that there are no outstanding MSHRs or 1036 // writebacks... that would mean that someone used an atomic 1037 // access in timing mode 1038 --- 1446 unchanged lines hidden (view full) --- 2485 2486bool 2487Cache::CpuSidePort::recvTimingReq(PacketPtr pkt) 2488{ 2489 assert(!cache->system->bypassCaches()); 2490 2491 bool success = false; 2492 |
2496 // always let packets through if an upstream cache has committed 2497 // to responding, even if blocked (we should technically look at 2498 // the isExpressSnoop flag, but it is set by the cache itself, and 2499 // consequently we have to rely on the cacheResponding flag) 2500 if (pkt->cacheResponding()) { | 2493 // always let express snoop packets through if even if blocked 2494 if (pkt->isExpressSnoop()) { |
2501 // do not change the current retry state 2502 bool M5_VAR_USED bypass_success = cache->recvTimingReq(pkt); 2503 assert(bypass_success); 2504 return true; 2505 } else if (blocked || mustSendRetry) { 2506 // either already committed to send a retry, or blocked 2507 success = false; 2508 } else { --- 161 unchanged lines hidden --- | 2495 // do not change the current retry state 2496 bool M5_VAR_USED bypass_success = cache->recvTimingReq(pkt); 2497 assert(bypass_success); 2498 return true; 2499 } else if (blocked || mustSendRetry) { 2500 // either already committed to send a retry, or blocked 2501 success = false; 2502 } else { --- 161 unchanged lines hidden --- |