cache.cc (11436:f351b7f248db) | cache.cc (11452:4bc3a0c0861c) |
---|---|
1/* 2 * Copyright (c) 2010-2016 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 --- 889 unchanged lines hidden (view full) --- 898 } 899 900 if (next_pf_time != MaxTick) 901 schedMemSideSendEvent(next_pf_time); 902 903 return true; 904} 905 | 1/* 2 * Copyright (c) 2010-2016 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 --- 889 unchanged lines hidden (view full) --- 898 } 899 900 if (next_pf_time != MaxTick) 901 schedMemSideSendEvent(next_pf_time); 902 903 return true; 904} 905 |
906 907// See comment in cache.hh. | |
908PacketPtr | 906PacketPtr |
909Cache::getBusPacket(PacketPtr cpu_pkt, CacheBlk *blk, 910 bool needsWritable) const | 907Cache::createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk, 908 bool needsWritable) const |
911{ | 909{ |
910 // should never see evictions here 911 assert(!cpu_pkt->isEviction()); 912 |
|
912 bool blkValid = blk && blk->isValid(); 913 | 913 bool blkValid = blk && blk->isValid(); 914 |
914 if (cpu_pkt->req->isUncacheable()) { 915 // note that at the point we see the uncacheable request we 916 // flush any block, but there could be an outstanding MSHR, 917 // and the cache could have filled again before we actually 918 // send out the forwarded uncacheable request (blk could thus 919 // be non-null) 920 return NULL; | 915 if (cpu_pkt->req->isUncacheable() || 916 (!blkValid && cpu_pkt->isUpgrade())) { 917 // uncacheable requests and upgrades from upper-level caches 918 // that missed completely just go through as is 919 return nullptr; |
921 } 922 | 920 } 921 |
923 if (!blkValid && 924 (cpu_pkt->isUpgrade() || 925 cpu_pkt->isEviction())) { 926 // Writebacks that weren't allocated in access() and upgrades 927 // from upper-level caches that missed completely just go 928 // through. 929 return NULL; 930 } 931 | |
932 assert(cpu_pkt->needsResponse()); 933 934 MemCmd cmd; 935 // @TODO make useUpgrades a parameter. 936 // Note that ownership protocols require upgrade, otherwise a 937 // write miss on a shared owned block will generate a ReadExcl, 938 // which will clobber the owned copy. 939 const bool useUpgrades = true; --- 87 unchanged lines hidden (view full) --- 1027 1028 // handle writebacks resulting from the access here to ensure they 1029 // logically proceed anything happening below 1030 doWritebacksAtomic(writebacks); 1031 1032 if (!satisfied) { 1033 // MISS 1034 | 922 assert(cpu_pkt->needsResponse()); 923 924 MemCmd cmd; 925 // @TODO make useUpgrades a parameter. 926 // Note that ownership protocols require upgrade, otherwise a 927 // write miss on a shared owned block will generate a ReadExcl, 928 // which will clobber the owned copy. 929 const bool useUpgrades = true; --- 87 unchanged lines hidden (view full) --- 1017 1018 // handle writebacks resulting from the access here to ensure they 1019 // logically proceed anything happening below 1020 doWritebacksAtomic(writebacks); 1021 1022 if (!satisfied) { 1023 // MISS 1024 |
1035 PacketPtr bus_pkt = getBusPacket(pkt, blk, pkt->needsWritable()); | 1025 // deal with the packets that go through the write path of 1026 // the cache, i.e. any evictions and uncacheable writes 1027 if (pkt->isEviction() || 1028 (pkt->req->isUncacheable() && pkt->isWrite())) { 1029 lat += ticksToCycles(memSidePort->sendAtomic(pkt)); 1030 return lat * clockPeriod(); 1031 } 1032 // only misses left |
1036 | 1033 |
1034 PacketPtr bus_pkt = createMissPacket(pkt, blk, pkt->needsWritable()); 1035 |
|
1037 bool is_forward = (bus_pkt == NULL); 1038 1039 if (is_forward) { 1040 // just forwarding the same request to the next level 1041 // no local cache operation involved 1042 bus_pkt = pkt; 1043 } 1044 1045 DPRINTF(Cache, "Sending an atomic %s for %#llx (%s)\n", 1046 bus_pkt->cmdString(), bus_pkt->getAddr(), 1047 bus_pkt->isSecure() ? "s" : "ns"); 1048 1049#if TRACING_ON 1050 CacheBlk::State old_state = blk ? blk->status : 0; 1051#endif 1052 1053 lat += ticksToCycles(memSidePort->sendAtomic(bus_pkt)); 1054 | 1036 bool is_forward = (bus_pkt == NULL); 1037 1038 if (is_forward) { 1039 // just forwarding the same request to the next level 1040 // no local cache operation involved 1041 bus_pkt = pkt; 1042 } 1043 1044 DPRINTF(Cache, "Sending an atomic %s for %#llx (%s)\n", 1045 bus_pkt->cmdString(), bus_pkt->getAddr(), 1046 bus_pkt->isSecure() ? "s" : "ns"); 1047 1048#if TRACING_ON 1049 CacheBlk::State old_state = blk ? blk->status : 0; 1050#endif 1051 1052 lat += ticksToCycles(memSidePort->sendAtomic(bus_pkt)); 1053 |
1054 bool is_invalidate = bus_pkt->isInvalidate(); 1055 |
|
1055 // We are now dealing with the response handling 1056 DPRINTF(Cache, "Receive response: %s for addr %#llx (%s) in state %i\n", 1057 bus_pkt->cmdString(), bus_pkt->getAddr(), 1058 bus_pkt->isSecure() ? "s" : "ns", 1059 old_state); 1060 1061 // If packet was a forward, the response (if any) is already 1062 // in place in the bus_pkt == pkt structure, so we don't need 1063 // to do anything. Otherwise, use the separate bus_pkt to 1064 // generate response to pkt and then delete it. 1065 if (!is_forward) { 1066 if (pkt->needsResponse()) { 1067 assert(bus_pkt->isResponse()); 1068 if (bus_pkt->isError()) { 1069 pkt->makeAtomicResponse(); 1070 pkt->copyError(bus_pkt); | 1056 // We are now dealing with the response handling 1057 DPRINTF(Cache, "Receive response: %s for addr %#llx (%s) in state %i\n", 1058 bus_pkt->cmdString(), bus_pkt->getAddr(), 1059 bus_pkt->isSecure() ? "s" : "ns", 1060 old_state); 1061 1062 // If packet was a forward, the response (if any) is already 1063 // in place in the bus_pkt == pkt structure, so we don't need 1064 // to do anything. Otherwise, use the separate bus_pkt to 1065 // generate response to pkt and then delete it. 1066 if (!is_forward) { 1067 if (pkt->needsResponse()) { 1068 assert(bus_pkt->isResponse()); 1069 if (bus_pkt->isError()) { 1070 pkt->makeAtomicResponse(); 1071 pkt->copyError(bus_pkt); |
1071 } else if (pkt->cmd == MemCmd::InvalidateReq) { 1072 if (blk) { 1073 // invalidate response to a cache that received 1074 // an invalidate request 1075 satisfyCpuSideRequest(pkt, blk); 1076 } | |
1077 } else if (pkt->cmd == MemCmd::WriteLineReq) { 1078 // note the use of pkt, not bus_pkt here. 1079 1080 // write-line request to the cache that promoted 1081 // the write to a whole line 1082 blk = handleFill(pkt, blk, writebacks, 1083 allocOnFill(pkt->cmd)); | 1072 } else if (pkt->cmd == MemCmd::WriteLineReq) { 1073 // note the use of pkt, not bus_pkt here. 1074 1075 // write-line request to the cache that promoted 1076 // the write to a whole line 1077 blk = handleFill(pkt, blk, writebacks, 1078 allocOnFill(pkt->cmd)); |
1079 assert(blk != NULL); 1080 is_invalidate = false; |
|
1084 satisfyCpuSideRequest(pkt, blk); 1085 } else if (bus_pkt->isRead() || 1086 bus_pkt->cmd == MemCmd::UpgradeResp) { 1087 // we're updating cache state to allow us to 1088 // satisfy the upstream request from the cache 1089 blk = handleFill(bus_pkt, blk, writebacks, 1090 allocOnFill(pkt->cmd)); 1091 satisfyCpuSideRequest(pkt, blk); 1092 } else { 1093 // we're satisfying the upstream request without 1094 // modifying cache state, e.g., a write-through 1095 pkt->makeAtomicResponse(); 1096 } 1097 } 1098 delete bus_pkt; 1099 } | 1081 satisfyCpuSideRequest(pkt, blk); 1082 } else if (bus_pkt->isRead() || 1083 bus_pkt->cmd == MemCmd::UpgradeResp) { 1084 // we're updating cache state to allow us to 1085 // satisfy the upstream request from the cache 1086 blk = handleFill(bus_pkt, blk, writebacks, 1087 allocOnFill(pkt->cmd)); 1088 satisfyCpuSideRequest(pkt, blk); 1089 } else { 1090 // we're satisfying the upstream request without 1091 // modifying cache state, e.g., a write-through 1092 pkt->makeAtomicResponse(); 1093 } 1094 } 1095 delete bus_pkt; 1096 } |
1097 1098 if (is_invalidate && blk && blk->isValid()) { 1099 invalidateBlock(blk); 1100 } |
|
1100 } 1101 1102 // Note that we don't invoke the prefetcher at all in atomic mode. 1103 // It's not clear how to do it properly, particularly for 1104 // prefetchers that aggressively generate prefetch candidates and 1105 // rely on bandwidth contention to throttle them; these will tend 1106 // to pollute the cache in atomic mode since there is no bandwidth 1107 // contention. If we ever do want to enable prefetching in atomic --- 1332 unchanged lines hidden (view full) --- 2440 clearBlocked(Blocked_NoMSHRs); 2441 } 2442 return false; 2443 } 2444 } 2445 2446 // either a prefetch that is not present upstream, or a normal 2447 // MSHR request, proceed to get the packet to send downstream | 1101 } 1102 1103 // Note that we don't invoke the prefetcher at all in atomic mode. 1104 // It's not clear how to do it properly, particularly for 1105 // prefetchers that aggressively generate prefetch candidates and 1106 // rely on bandwidth contention to throttle them; these will tend 1107 // to pollute the cache in atomic mode since there is no bandwidth 1108 // contention. If we ever do want to enable prefetching in atomic --- 1332 unchanged lines hidden (view full) --- 2441 clearBlocked(Blocked_NoMSHRs); 2442 } 2443 return false; 2444 } 2445 } 2446 2447 // either a prefetch that is not present upstream, or a normal 2448 // MSHR request, proceed to get the packet to send downstream |
2448 PacketPtr pkt = getBusPacket(tgt_pkt, blk, mshr->needsWritable()); | 2449 PacketPtr pkt = createMissPacket(tgt_pkt, blk, mshr->needsWritable()); |
2449 2450 mshr->isForward = (pkt == NULL); 2451 2452 if (mshr->isForward) { 2453 // not a cache block request, but a response is expected 2454 // make copy of current packet to forward, keep current 2455 // copy for response handling 2456 pkt = new Packet(tgt_pkt, false, true); --- 264 unchanged lines hidden --- | 2450 2451 mshr->isForward = (pkt == NULL); 2452 2453 if (mshr->isForward) { 2454 // not a cache block request, but a response is expected 2455 // make copy of current packet to forward, keep current 2456 // copy for response handling 2457 pkt = new Packet(tgt_pkt, false, true); --- 264 unchanged lines hidden --- |