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 ---