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}
490
491
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);
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);
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
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())) {
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
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 }
2192}
2193
2194PacketPtr
2195Cache::getTimingPacket()
2196{
2197 MSHR *mshr = getNextMSHR();
2198
2199 if (mshr == NULL) {

--- 336 unchanged lines hidden ---