Deleted Added
sdiff udiff text old ( 13954:2f400a5f2627 ) new ( 14035:60068a2d56e0 )
full compact
1/*
2 * Copyright (c) 2010-2019 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

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

156
157/////////////////////////////////////////////////////
158//
159// Access path: requests coming in from the CPU side
160//
161/////////////////////////////////////////////////////
162
163bool
164Cache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
165 PacketList &writebacks)
166{
167
168 if (pkt->req->isUncacheable()) {
169 assert(pkt->isRequest());
170
171 chatty_assert(!(isReadOnly && pkt->isWrite()),
172 "Should never see a write in a read-only cache %s\n",
173 name());
174
175 DPRINTF(Cache, "%s for %s\n", __func__, pkt->print());
176
177 // flush and invalidate any existing block
178 CacheBlk *old_blk(tags->findBlock(pkt->getAddr(), pkt->isSecure()));
179 if (old_blk && old_blk->isValid()) {
180 BaseCache::evictBlock(old_blk, writebacks);
181 }
182
183 blk = nullptr;
184 // lookupLatency is the latency in case the request is uncacheable.
185 lat = lookupLatency;
186 return false;
187 }
188
189 return BaseCache::access(pkt, blk, lat, writebacks);
190}
191
192void
193Cache::doWritebacks(PacketList& writebacks, Tick forward_time)
194{
195 while (!writebacks.empty()) {
196 PacketPtr wbPkt = writebacks.front();
197 // We use forwardLatency here because we are copying writebacks to
198 // write buffer.
199
200 // Call isCachedAbove for Writebacks, CleanEvicts and
201 // WriteCleans to discover if the block is cached above.
202 if (isCachedAbove(wbPkt)) {
203 if (wbPkt->cmd == MemCmd::CleanEvict) {
204 // Delete CleanEvict because cached copies exist above. The
205 // packet destructor will delete the request object because
206 // this is a non-snoop request packet which does not require a
207 // response.
208 delete wbPkt;
209 } else if (wbPkt->cmd == MemCmd::WritebackClean) {
210 // clean writeback, do not send since the block is
211 // still cached above
212 assert(writebackClean);
213 delete wbPkt;
214 } else {
215 assert(wbPkt->cmd == MemCmd::WritebackDirty ||
216 wbPkt->cmd == MemCmd::WriteClean);
217 // Set BLOCK_CACHED flag in Writeback and send below, so that
218 // the Writeback does not reset the bit corresponding to this
219 // address in the snoop filter below.
220 wbPkt->setBlockCached();
221 allocateWriteBuffer(wbPkt, forward_time);
222 }
223 } else {
224 // If the block is not cached above, send packet below. Both
225 // CleanEvict and Writeback with BLOCK_CACHED flag cleared will
226 // reset the bit corresponding to this address in the snoop filter
227 // below.
228 allocateWriteBuffer(wbPkt, forward_time);
229 }
230 writebacks.pop_front();
231 }
232}
233
234void
235Cache::doWritebacksAtomic(PacketList& writebacks)
236{
237 while (!writebacks.empty()) {
238 PacketPtr wbPkt = writebacks.front();
239 // Call isCachedAbove for both Writebacks and CleanEvicts. If
240 // isCachedAbove returns true we set BLOCK_CACHED flag in Writebacks
241 // and discard CleanEvicts.
242 if (isCachedAbove(wbPkt, false)) {
243 if (wbPkt->cmd == MemCmd::WritebackDirty ||
244 wbPkt->cmd == MemCmd::WriteClean) {
245 // Set BLOCK_CACHED flag in Writeback and send below,
246 // so that the Writeback does not reset the bit
247 // corresponding to this address in the snoop filter
248 // below. We can discard CleanEvicts because cached
249 // copies exist above. Atomic mode isCachedAbove
250 // modifies packet to set BLOCK_CACHED flag
251 memSidePort.sendAtomic(wbPkt);
252 }
253 } else {
254 // If the block is not cached above, send packet below. Both
255 // CleanEvict and Writeback with BLOCK_CACHED flag cleared will
256 // reset the bit corresponding to this address in the snoop filter
257 // below.
258 memSidePort.sendAtomic(wbPkt);
259 }
260 writebacks.pop_front();
261 // In case of CleanEvicts, the packet destructor will delete the
262 // request object because this is a non-snoop request packet which
263 // does not require a response.
264 delete wbPkt;
265 }
266}
267
268
269void
270Cache::recvTimingSnoopResp(PacketPtr pkt)
271{
272 DPRINTF(Cache, "%s for %s\n", __func__, pkt->print());
273
274 // determine if the response is from a snoop request we created
275 // (in which case it should be in the outstandingSnoop), or if we
276 // merely forwarded someone else's snoop request

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

558 pkt->allocate();
559 DPRINTF(Cache, "%s: created %s from %s\n", __func__, pkt->print(),
560 cpu_pkt->print());
561 return pkt;
562}
563
564
565Cycles
566Cache::handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk,
567 PacketList &writebacks)
568{
569 // deal with the packets that go through the write path of
570 // the cache, i.e. any evictions and writes
571 if (pkt->isEviction() || pkt->cmd == MemCmd::WriteClean ||
572 (pkt->req->isUncacheable() && pkt->isWrite())) {
573 Cycles latency = ticksToCycles(memSidePort.sendAtomic(pkt));
574
575 // at this point, if the request was an uncacheable write

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

621 pkt->copyError(bus_pkt);
622 } else if (pkt->isWholeLineWrite(blkSize)) {
623 // note the use of pkt, not bus_pkt here.
624
625 // write-line request to the cache that promoted
626 // the write to a whole line
627 const bool allocate = allocOnFill(pkt->cmd) &&
628 (!writeAllocator || writeAllocator->allocate());
629 blk = handleFill(bus_pkt, blk, writebacks, allocate);
630 assert(blk != NULL);
631 is_invalidate = false;
632 satisfyRequest(pkt, blk);
633 } else if (bus_pkt->isRead() ||
634 bus_pkt->cmd == MemCmd::UpgradeResp) {
635 // we're updating cache state to allow us to
636 // satisfy the upstream request from the cache
637 blk = handleFill(bus_pkt, blk, writebacks,
638 allocOnFill(pkt->cmd));
639 satisfyRequest(pkt, blk);
640 maintainClusivity(pkt->fromCache(), blk);
641 } else {
642 // we're satisfying the upstream request without
643 // modifying cache state, e.g., a write-through
644 pkt->makeAtomicResponse();
645 }
646 }

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

1016
1017 bool respond = false;
1018 bool blk_valid = blk && blk->isValid();
1019 if (pkt->isClean()) {
1020 if (blk_valid && blk->isDirty()) {
1021 DPRINTF(CacheVerbose, "%s: packet (snoop) %s found block: %s\n",
1022 __func__, pkt->print(), blk->print());
1023 PacketPtr wb_pkt = writecleanBlk(blk, pkt->req->getDest(), pkt->id);
1024 PacketList writebacks;
1025 writebacks.push_back(wb_pkt);
1026
1027 if (is_timing) {
1028 // anything that is merely forwarded pays for the forward
1029 // latency and the delay provided by the crossbar
1030 Tick forward_time = clockEdge(forwardLatency) +
1031 pkt->headerDelay;
1032 doWritebacks(writebacks, forward_time);
1033 } else {
1034 doWritebacksAtomic(writebacks);
1035 }
1036 pkt->setSatisfied();
1037 }
1038 } else if (!blk_valid) {
1039 DPRINTF(CacheVerbose, "%s: snoop miss for %s\n", __func__,
1040 pkt->print());
1041 if (is_deferred) {
1042 // we no longer have the block, and will not respond, but a

--- 359 unchanged lines hidden ---