cache.cc (11127:f39c2cc0d44e) cache.cc (11130:45a23e44e93d)
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

--- 441 unchanged lines hidden (view full) ---

450 // reset the bit corresponding to this address in the snoop filter
451 // below.
452 allocateWriteBuffer(wbPkt, forward_time);
453 }
454 writebacks.pop_front();
455 }
456}
457
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

--- 441 unchanged lines hidden (view full) ---

450 // reset the bit corresponding to this address in the snoop filter
451 // below.
452 allocateWriteBuffer(wbPkt, forward_time);
453 }
454 writebacks.pop_front();
455 }
456}
457
458void
459Cache::doWritebacksAtomic(PacketList& writebacks)
460{
461 while (!writebacks.empty()) {
462 PacketPtr wbPkt = writebacks.front();
463 // Call isCachedAbove for both Writebacks and CleanEvicts. If
464 // isCachedAbove returns true we set BLOCK_CACHED flag in Writebacks
465 // and discard CleanEvicts.
466 if (isCachedAbove(wbPkt, false)) {
467 if (wbPkt->cmd == MemCmd::Writeback) {
468 // Set BLOCK_CACHED flag in Writeback and send below,
469 // so that the Writeback does not reset the bit
470 // corresponding to this address in the snoop filter
471 // below. We can discard CleanEvicts because cached
472 // copies exist above. Atomic mode isCachedAbove
473 // modifies packet to set BLOCK_CACHED flag
474 memSidePort->sendAtomic(wbPkt);
475 }
476 } else {
477 // If the block is not cached above, send packet below. Both
478 // CleanEvict and Writeback with BLOCK_CACHED flag cleared will
479 // reset the bit corresponding to this address in the snoop filter
480 // below.
481 memSidePort->sendAtomic(wbPkt);
482 }
483 writebacks.pop_front();
484 // In case of CleanEvicts, the packet destructor will delete the
485 // request object because this is a non-snoop request packet which
486 // does not require a response.
487 delete wbPkt;
488 }
489}
458
490
491
459void
460Cache::recvTimingSnoopResp(PacketPtr pkt)
461{
462 DPRINTF(Cache, "%s for %s addr %#llx size %d\n", __func__,
463 pkt->cmdString(), pkt->getAddr(), pkt->getSize());
464
465 assert(pkt->isResponse());
466

--- 481 unchanged lines hidden (view full) ---

948 // access in timing mode
949
950 CacheBlk *blk = NULL;
951 PacketList writebacks;
952 bool satisfied = access(pkt, blk, lat, writebacks);
953
954 // handle writebacks resulting from the access here to ensure they
955 // logically proceed anything happening below
492void
493Cache::recvTimingSnoopResp(PacketPtr pkt)
494{
495 DPRINTF(Cache, "%s for %s addr %#llx size %d\n", __func__,
496 pkt->cmdString(), pkt->getAddr(), pkt->getSize());
497
498 assert(pkt->isResponse());
499

--- 481 unchanged lines hidden (view full) ---

981 // access in timing mode
982
983 CacheBlk *blk = NULL;
984 PacketList writebacks;
985 bool satisfied = access(pkt, blk, lat, writebacks);
986
987 // handle writebacks resulting from the access here to ensure they
988 // logically proceed anything happening below
956 while (!writebacks.empty()){
957 PacketPtr wbPkt = writebacks.front();
958 memSidePort->sendAtomic(wbPkt);
959 writebacks.pop_front();
960 delete wbPkt;
961 }
989 doWritebacksAtomic(writebacks);
962
963 if (!satisfied) {
964 // MISS
965
966 PacketPtr bus_pkt = getBusPacket(pkt, blk, pkt->needsExclusive());
967
968 bool is_forward = (bus_pkt == NULL);
969

--- 65 unchanged lines hidden (view full) ---

1035 // to pollute the cache in atomic mode since there is no bandwidth
1036 // contention. If we ever do want to enable prefetching in atomic
1037 // mode, though, this is the place to do it... see timingAccess()
1038 // for an example (though we'd want to issue the prefetch(es)
1039 // immediately rather than calling requestMemSideBus() as we do
1040 // there).
1041
1042 // Handle writebacks (from the response handling) if needed
990
991 if (!satisfied) {
992 // MISS
993
994 PacketPtr bus_pkt = getBusPacket(pkt, blk, pkt->needsExclusive());
995
996 bool is_forward = (bus_pkt == NULL);
997

--- 65 unchanged lines hidden (view full) ---

1063 // to pollute the cache in atomic mode since there is no bandwidth
1064 // contention. If we ever do want to enable prefetching in atomic
1065 // mode, though, this is the place to do it... see timingAccess()
1066 // for an example (though we'd want to issue the prefetch(es)
1067 // immediately rather than calling requestMemSideBus() as we do
1068 // there).
1069
1070 // Handle writebacks (from the response handling) if needed
1043 while (!writebacks.empty()){
1044 PacketPtr wbPkt = writebacks.front();
1045 memSidePort->sendAtomic(wbPkt);
1046 writebacks.pop_front();
1047 delete wbPkt;
1048 }
1071 doWritebacksAtomic(writebacks);
1049
1050 if (pkt->needsResponse()) {
1051 pkt->makeAtomicResponse();
1052 }
1053
1054 return lat * clockPeriod();
1055}
1056

--- 844 unchanged lines hidden (view full) ---

1901Cache::recvTimingSnoopReq(PacketPtr pkt)
1902{
1903 DPRINTF(Cache, "%s for %s addr %#llx size %d\n", __func__,
1904 pkt->cmdString(), pkt->getAddr(), pkt->getSize());
1905
1906 // Snoops shouldn't happen when bypassing caches
1907 assert(!system->bypassCaches());
1908
1072
1073 if (pkt->needsResponse()) {
1074 pkt->makeAtomicResponse();
1075 }
1076
1077 return lat * clockPeriod();
1078}
1079

--- 844 unchanged lines hidden (view full) ---

1924Cache::recvTimingSnoopReq(PacketPtr pkt)
1925{
1926 DPRINTF(Cache, "%s for %s addr %#llx size %d\n", __func__,
1927 pkt->cmdString(), pkt->getAddr(), pkt->getSize());
1928
1929 // Snoops shouldn't happen when bypassing caches
1930 assert(!system->bypassCaches());
1931
1909 // no need to snoop writebacks or requests that are not in range
1932 // no need to snoop requests that are not in range
1910 if (!inRange(pkt->getAddr())) {
1911 return;
1912 }
1913
1914 bool is_secure = pkt->isSecure();
1915 CacheBlk *blk = tags->findBlock(pkt->getAddr(), is_secure);
1916
1917 Addr blk_addr = blockAlign(pkt->getAddr());

--- 121 unchanged lines hidden (view full) ---

2039}
2040
2041Tick
2042Cache::recvAtomicSnoop(PacketPtr pkt)
2043{
2044 // Snoops shouldn't happen when bypassing caches
2045 assert(!system->bypassCaches());
2046
1933 if (!inRange(pkt->getAddr())) {
1934 return;
1935 }
1936
1937 bool is_secure = pkt->isSecure();
1938 CacheBlk *blk = tags->findBlock(pkt->getAddr(), is_secure);
1939
1940 Addr blk_addr = blockAlign(pkt->getAddr());

--- 121 unchanged lines hidden (view full) ---

2062}
2063
2064Tick
2065Cache::recvAtomicSnoop(PacketPtr pkt)
2066{
2067 // Snoops shouldn't happen when bypassing caches
2068 assert(!system->bypassCaches());
2069
2047 // no need to snoop writebacks or requests that are not in range. In
2048 // atomic we have no Writebacks/CleanEvicts queued and no prefetches,
2049 // hence there is no need to snoop upwards and determine if they are
2050 // present above.
2051 if (pkt->evictingBlock() || !inRange(pkt->getAddr())) {
2070 // no need to snoop requests that are not in range.
2071 if (!inRange(pkt->getAddr())) {
2052 return 0;
2053 }
2054
2055 CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure());
2056 uint32_t snoop_delay = handleSnoop(pkt, blk, false, false, false);
2057 return snoop_delay + lookupLatency * clockPeriod();
2058}
2059

--- 79 unchanged lines hidden (view full) ---

2139 }
2140 }
2141 }
2142
2143 return NULL;
2144}
2145
2146bool
2072 return 0;
2073 }
2074
2075 CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure());
2076 uint32_t snoop_delay = handleSnoop(pkt, blk, false, false, false);
2077 return snoop_delay + lookupLatency * clockPeriod();
2078}
2079

--- 79 unchanged lines hidden (view full) ---

2159 }
2160 }
2161 }
2162
2163 return NULL;
2164}
2165
2166bool
2147Cache::isCachedAbove(const PacketPtr pkt) const
2167Cache::isCachedAbove(PacketPtr pkt, bool is_timing) const
2148{
2149 if (!forwardSnoops)
2150 return false;
2151 // Mirroring the flow of HardPFReqs, the cache sends CleanEvict and
2152 // Writeback snoops into upper level caches to check for copies of the
2153 // same block. Using the BLOCK_CACHED flag with the Writeback/CleanEvict
2154 // packet, the cache can inform the crossbar below of presence or absence
2155 // of the block.
2168{
2169 if (!forwardSnoops)
2170 return false;
2171 // Mirroring the flow of HardPFReqs, the cache sends CleanEvict and
2172 // Writeback snoops into upper level caches to check for copies of the
2173 // same block. Using the BLOCK_CACHED flag with the Writeback/CleanEvict
2174 // packet, the cache can inform the crossbar below of presence or absence
2175 // of the block.
2156
2157 Packet snoop_pkt(pkt, true, false);
2158 snoop_pkt.setExpressSnoop();
2159 // Assert that packet is either Writeback or CleanEvict and not a prefetch
2160 // request because prefetch requests need an MSHR and may generate a snoop
2161 // response.
2162 assert(pkt->evictingBlock());
2163 snoop_pkt.senderState = NULL;
2164 cpuSidePort->sendTimingSnoopReq(&snoop_pkt);
2165 // Writeback/CleanEvict snoops do not generate a separate snoop response.
2166 assert(!(snoop_pkt.memInhibitAsserted()));
2167 return snoop_pkt.isBlockCached();
2176 if (is_timing) {
2177 Packet snoop_pkt(pkt, true, false);
2178 snoop_pkt.setExpressSnoop();
2179 // Assert that packet is either Writeback or CleanEvict and not a
2180 // prefetch request because prefetch requests need an MSHR and may
2181 // generate a snoop response.
2182 assert(pkt->evictingBlock());
2183 snoop_pkt.senderState = NULL;
2184 cpuSidePort->sendTimingSnoopReq(&snoop_pkt);
2185 // Writeback/CleanEvict snoops do not generate a snoop response.
2186 assert(!(snoop_pkt.memInhibitAsserted()));
2187 return snoop_pkt.isBlockCached();
2188 } else {
2189 cpuSidePort->sendAtomicSnoop(pkt);
2190 return pkt->isBlockCached();
2191 }
2168}
2169
2170PacketPtr
2171Cache::getTimingPacket()
2172{
2173 MSHR *mshr = getNextMSHR();
2174
2175 if (mshr == NULL) {

--- 336 unchanged lines hidden ---
2192}
2193
2194PacketPtr
2195Cache::getTimingPacket()
2196{
2197 MSHR *mshr = getNextMSHR();
2198
2199 if (mshr == NULL) {

--- 336 unchanged lines hidden ---