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 |
906PacketPtr |
907Cache::createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk, 908 bool needsWritable) const |
909{ |
910 // should never see evictions here 911 assert(!cpu_pkt->isEviction()); 912 |
913 bool blkValid = blk && blk->isValid(); 914 |
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; |
920 } 921 |
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 |
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 |
1033 |
1034 PacketPtr bus_pkt = createMissPacket(pkt, blk, pkt->needsWritable()); 1035 |
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 |
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); |
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; |
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 } |
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 |
2449 PacketPtr pkt = createMissPacket(tgt_pkt, blk, mshr->needsWritable()); |
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 --- |