gem5 v24.0.0.0
Loading...
Searching...
No Matches
noncoherent_cache.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2018 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
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan
15 * Copyright (c) 2010,2015 Advanced Micro Devices, Inc.
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 */
41
48
49#include <cassert>
50
51#include "base/logging.hh"
52#include "base/trace.hh"
53#include "base/types.hh"
54#include "debug/Cache.hh"
56#include "mem/cache/mshr.hh"
57#include "params/NoncoherentCache.hh"
58
59namespace gem5
60{
61
62NoncoherentCache::NoncoherentCache(const NoncoherentCacheParams &p)
63 : BaseCache(p, p.system->cacheLineSize())
64{
65 assert(p.tags);
66 assert(p.replacement_policy);
67}
68
69void
71{
72 // As this a non-coherent cache located below the point of
73 // coherency, we do not expect requests that are typically used to
74 // keep caches coherent (e.g., InvalidateReq or UpdateReq).
75 assert(pkt->isRead() || pkt->isWrite());
77}
78
79bool
81 PacketList &writebacks)
82{
83 bool success = BaseCache::access(pkt, blk, lat, writebacks);
84
85 if (pkt->isWriteback() || pkt->cmd == MemCmd::WriteClean) {
86 assert(blk && blk->isValid());
87 // Writeback and WriteClean can allocate and fill even if the
88 // referenced block was not present or it was invalid. If that
89 // is the case, make sure that the new block is marked as
90 // writable
92 }
93
94 return success;
95}
96
97void
99{
100 while (!writebacks.empty()) {
101 PacketPtr wb_pkt = writebacks.front();
102 allocateWriteBuffer(wb_pkt, forward_time);
103 writebacks.pop_front();
104 }
105}
106
107void
109{
110 while (!writebacks.empty()) {
111 PacketPtr wb_pkt = writebacks.front();
112 memSidePort.sendAtomic(wb_pkt);
113 writebacks.pop_front();
114 delete wb_pkt;
115 }
116}
117
118void
120 Tick forward_time, Tick request_time)
121{
122 // miss
123 Addr blk_addr = pkt->getBlockAddr(blkSize);
124 MSHR *mshr = mshrQueue.findMatch(blk_addr, pkt->isSecure(), false);
125
126 // We can always write to a non coherent cache if the block is
127 // present and therefore if we have reached this point then the
128 // block should not be in the cache.
129 assert(mshr || !blk || !blk->isValid());
130
131 BaseCache::handleTimingReqMiss(pkt, mshr, blk, forward_time, request_time);
132}
133
134void
136{
137 panic_if(pkt->cacheResponding(), "Should not see packets where cache "
138 "is responding");
139
140 panic_if(!(pkt->isRead() || pkt->isWrite()),
141 "Should only see read and writes at non-coherent cache\n");
142
144}
145
148 bool needs_writable,
149 bool is_whole_line_write) const
150{
151 // We also fill for writebacks from the coherent caches above us,
152 // and they do not need responses
153 assert(cpu_pkt->needsResponse());
154
155 // A miss can happen only due to missing block
156 assert(!blk || !blk->isValid());
157
158 PacketPtr pkt = new Packet(cpu_pkt->req, MemCmd::ReadReq, blkSize);
159
160 // the packet should be block aligned
161 assert(pkt->getAddr() == pkt->getBlockAddr(blkSize));
162
163 pkt->allocate();
164 DPRINTF(Cache, "%s created %s from %s\n", __func__, pkt->print(),
165 cpu_pkt->print());
166 return pkt;
167}
168
169
170Cycles
172 PacketList &writebacks)
173{
174 PacketPtr bus_pkt = createMissPacket(pkt, blk, true,
176 DPRINTF(Cache, "Sending an atomic %s\n", bus_pkt->print());
177
178 Cycles latency = ticksToCycles(memSidePort.sendAtomic(bus_pkt));
179
180 assert(bus_pkt->isResponse());
181 // At the moment the only supported downstream requests we issue
182 // are ReadReq and therefore here we should only see the
183 // corresponding responses
184 assert(bus_pkt->isRead());
185 assert(pkt->cmd != MemCmd::UpgradeResp);
186 assert(!bus_pkt->isInvalidate());
187 assert(!bus_pkt->hasSharers());
188
189 // We are now dealing with the response handling
190 DPRINTF(Cache, "Receive response: %s\n", bus_pkt->print());
191
192 if (!bus_pkt->isError()) {
193 // Any reponse that does not have an error should be filling,
194 // afterall it is a read response
195 DPRINTF(Cache, "Block for addr %#llx being updated in Cache\n",
196 bus_pkt->getAddr());
197 blk = handleFill(bus_pkt, blk, writebacks, allocOnFill(bus_pkt->cmd));
198 assert(blk);
199 }
200 satisfyRequest(pkt, blk);
201
202 maintainClusivity(true, blk);
203
204 // Use the separate bus_pkt to generate response to pkt and
205 // then delete it.
206 if (!pkt->isWriteback() && pkt->cmd != MemCmd::WriteClean) {
207 assert(pkt->needsResponse());
208 pkt->makeAtomicResponse();
209 if (bus_pkt->isError()) {
210 pkt->copyError(bus_pkt);
211 }
212 }
213
214 delete bus_pkt;
215
216 return latency;
217}
218
219Tick
221{
222 panic_if(pkt->cacheResponding(), "Should not see packets where cache "
223 "is responding");
224
225 panic_if(!(pkt->isRead() || pkt->isWrite()),
226 "Should only see read and writes at non-coherent cache\n");
227
228 return BaseCache::recvAtomic(pkt);
229}
230
231
232void
234{
235 panic_if(!from_cpu_side, "Non-coherent cache received functional snoop"
236 " request\n");
237
238 BaseCache::functionalAccess(pkt, from_cpu_side);
239}
240
241void
243 CacheBlk *blk)
244{
245 // First offset for critical word first calculations
246 const int initial_offset = mshr->getTarget()->pkt->getOffset(blkSize);
247
248 bool from_core = false;
249 bool from_pref = false;
250
251 MSHR::TargetList targets = mshr->extractServiceableTargets(pkt);
252 for (auto &target: targets) {
253 Packet *tgt_pkt = target.pkt;
254
255 switch (target.source) {
257 // handle deferred requests comming from a cache or core
258 // above
259
260 from_core = true;
261
262 Tick completion_time;
263 // Here we charge on completion_time the delay of the xbar if the
264 // packet comes from it, charged on headerDelay.
265 completion_time = pkt->headerDelay;
266
267 satisfyRequest(tgt_pkt, blk);
268
269 // How many bytes past the first request is this one
270 int transfer_offset;
271 transfer_offset = tgt_pkt->getOffset(blkSize) - initial_offset;
272 if (transfer_offset < 0) {
273 transfer_offset += blkSize;
274 }
275 // If not critical word (offset) return payloadDelay.
276 // responseLatency is the latency of the return path
277 // from lower level caches/memory to an upper level cache or
278 // the core.
279 completion_time += clockEdge(responseLatency) +
280 (transfer_offset ? pkt->payloadDelay : 0);
281
282 assert(tgt_pkt->req->requestorId() < system->maxRequestors());
283 stats.cmdStats(tgt_pkt).missLatency[tgt_pkt->req->requestorId()] +=
284 completion_time - target.recvTime;
285
286 tgt_pkt->makeTimingResponse();
287 if (pkt->isError())
288 tgt_pkt->copyError(pkt);
289
290 // Reset the bus additional time as it is now accounted for
291 tgt_pkt->headerDelay = tgt_pkt->payloadDelay = 0;
292 cpuSidePort.schedTimingResp(tgt_pkt, completion_time);
293 break;
294
296 // handle deferred requests comming from a prefetcher
297 // attached to this cache
298 assert(tgt_pkt->cmd == MemCmd::HardPFReq);
299
300 from_pref = true;
301
302 // We have filled the block and the prefetcher does not
303 // require responses.
304 delete tgt_pkt;
305 break;
306
307 default:
308 // we should never see FromSnoop Targets as this is a
309 // non-coherent cache
310 panic("Illegal target->source enum %d\n", target.source);
311 }
312 }
313
314 if (blk && !from_core && from_pref) {
315 blk->setPrefetched();
316 }
317
318 // Reponses are filling and bring in writable blocks, therefore
319 // there should be no deferred targets and all the non-deferred
320 // targets are now serviced.
321 assert(mshr->getNumTargets() == 0);
322}
323
324void
326{
327 assert(pkt->isResponse());
328 // At the moment the only supported downstream requests we issue
329 // are ReadReq and therefore here we should only see the
330 // corresponding responses
331 assert(pkt->isRead());
332 assert(pkt->cmd != MemCmd::UpgradeResp);
333 assert(!pkt->isInvalidate());
334 // This cache is non-coherent and any memories below are
335 // non-coherent too (non-coherent caches or the main memory),
336 // therefore the fetched block can be marked as writable.
337 assert(!pkt->hasSharers());
338
340}
341
344{
345 // A dirty block is always written back.
346
347 // A clean block can we written back, if we turned on writebacks
348 // for clean blocks. This could be useful if there is a cache
349 // below and we want to make sure the block is cached but if the
350 // memory below is the main memory WritebackCleans are
351 // unnecessary.
352
353 // If we clean writebacks are not enabled, we do not take any
354 // further action for evictions of clean blocks (i.e., CleanEvicts
355 // are unnecessary).
357 writebackBlk(blk) : nullptr;
358
359 invalidateBlock(blk);
360
361 return pkt;
362}
363
364} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
Definitions of a simple cache block class.
A basic cache interface.
Definition base.hh:100
virtual void functionalAccess(PacketPtr pkt, bool from_cpu_side)
Performs the access specified by the request.
Definition base.cc:718
virtual void recvTimingReq(PacketPtr pkt)
Performs the access specified by the request.
Definition base.cc:407
CpuSidePort cpuSidePort
Definition base.hh:317
void invalidateBlock(CacheBlk *blk)
Invalidate a cache block.
Definition base.cc:1679
const bool writebackClean
Determine if clean lines should be written back or not.
Definition base.hh:681
virtual void handleTimingReqMiss(PacketPtr pkt, CacheBlk *blk, Tick forward_time, Tick request_time)=0
bool allocOnFill(MemCmd cmd) const
Determine whether we should allocate on a fill or not.
Definition base.hh:447
virtual void satisfyRequest(PacketPtr pkt, CacheBlk *blk, bool deferred_response=false, bool pending_downgrade=false)
Perform any necessary updates to the block and perform any data exchange between the packet and the b...
Definition base.cc:1098
gem5::BaseCache::CacheStats stats
MSHRQueue mshrQueue
Miss status registers.
Definition base.hh:347
const unsigned blkSize
Block size of this cache.
Definition base.hh:894
const Cycles responseLatency
The latency of sending reponse to its upper level cache/core on a linefill.
Definition base.hh:923
MemSidePort memSidePort
Definition base.hh:318
virtual Tick recvAtomic(PacketPtr pkt)
Performs the access specified by the request.
Definition base.cc:638
virtual void recvTimingResp(PacketPtr pkt)
Handles a response (cache line fill/write ack) from the bus.
Definition base.cc:492
virtual bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat, PacketList &writebacks)
Does all the processing necessary to perform the provided request.
Definition base.cc:1242
void allocateWriteBuffer(PacketPtr pkt, Tick time)
Definition base.hh:1197
CacheBlk * handleFill(PacketPtr pkt, CacheBlk *blk, PacketList &writebacks, bool allocate)
Handle a fill operation caused by a received packet.
Definition base.cc:1523
PacketPtr writebackBlk(CacheBlk *blk)
Create a writeback request for the given block.
Definition base.cc:1708
void maintainClusivity(bool from_cache, CacheBlk *blk)
Maintain the clusivity of this cache by potentially invalidating a block.
Definition base.cc:1511
System * system
System we are currently operating in.
Definition base.hh:992
A Basic Cache block.
Definition cache_blk.hh:72
@ WritableBit
write permission
Definition cache_blk.hh:81
@ DirtyBit
dirty (modified)
Definition cache_blk.hh:88
void setPrefetched()
Marks this blocks as a recently prefetched block.
Definition cache_blk.hh:261
bool isSet(unsigned bits) const
Checks the given coherence bits are set.
Definition cache_blk.hh:242
void setCoherenceBits(unsigned bits)
Sets the corresponding coherence bits.
Definition cache_blk.hh:223
virtual bool isValid() const
Checks if the entry is valid.
A coherent cache that can be arranged in flexible topologies.
Definition cache.hh:68
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Cycles ticksToCycles(Tick t) const
Cycles is a wrapper class for representing cycle counts, i.e.
Definition types.hh:79
Miss Status and handling Register.
Definition mshr.hh:75
TargetList extractServiceableTargets(PacketPtr pkt)
Extracts the subset of the targets that can be serviced given a received response.
Definition mshr.cc:548
int getNumTargets() const
Returns the current number of allocated targets.
Definition mshr.hh:446
QueueEntry::Target * getTarget() override
Returns a reference to the first target.
Definition mshr.hh:473
NoncoherentCache(const NoncoherentCacheParams &p)
void doWritebacksAtomic(PacketList &writebacks) override
Send writebacks down the memory hierarchy in atomic mode.
PacketPtr evictBlock(CacheBlk *blk) override
Evict a cache block.
void functionalAccess(PacketPtr pkt, bool from_cpu_side) override
Performs the access specified by the request.
bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat, PacketList &writebacks) override
Does all the processing necessary to perform the provided request.
void recvTimingReq(PacketPtr pkt) override
Performs the access specified by the request.
PacketPtr createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk, bool needs_writable, bool is_whole_line_write) const override
Create an appropriate downstream bus request packet.
void doWritebacks(PacketList &writebacks, Tick forward_time) override
Insert writebacks into the write buffer.
void handleTimingReqMiss(PacketPtr pkt, CacheBlk *blk, Tick forward_time, Tick request_time) override
void satisfyRequest(PacketPtr pkt, CacheBlk *blk, bool deferred_response=false, bool pending_downgrade=false) override
Perform any necessary updates to the block and perform any data exchange between the packet and the b...
Tick recvAtomic(PacketPtr pkt) override
Performs the access specified by the request.
Cycles handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk, PacketList &writebacks) override
Handle a request in atomic mode that missed in this cache.
void serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt, CacheBlk *blk) override
Service non-deferred MSHR targets using the received response.
void recvTimingResp(PacketPtr pkt) override
Handles a response (cache line fill/write ack) from the bus.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
bool isRead() const
Definition packet.hh:593
bool isSecure() const
Definition packet.hh:836
Addr getAddr() const
Definition packet.hh:807
bool isError() const
Definition packet.hh:622
bool isResponse() const
Definition packet.hh:598
void makeTimingResponse()
Definition packet.hh:1080
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
Definition packet.cc:368
void copyError(Packet *pkt)
Definition packet.hh:805
bool needsResponse() const
Definition packet.hh:608
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Definition packet.hh:449
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Definition packet.hh:431
Addr getOffset(unsigned int blk_size) const
Definition packet.hh:826
bool isWrite() const
Definition packet.hh:594
Addr getBlockAddr(unsigned int blk_size) const
Definition packet.hh:831
RequestPtr req
A pointer to the original request.
Definition packet.hh:377
bool isWriteback() const
Definition packet.hh:613
bool cacheResponding() const
Definition packet.hh:659
void makeAtomicResponse()
Definition packet.hh:1074
MemCmd cmd
The command field of the packet.
Definition packet.hh:372
bool isInvalidate() const
Definition packet.hh:609
bool isWholeLineWrite(unsigned blk_size)
Definition packet.hh:626
bool hasSharers() const
Definition packet.hh:686
void allocate()
Allocate memory for the packet.
Definition packet.hh:1367
PacketPtr pkt
Pending request packet.
Entry * findMatch(Addr blk_addr, bool is_secure, bool ignore_uncacheable=true) const
Find the first entry that matches the provided address.
Definition queue.hh:168
void schedTimingResp(PacketPtr pkt, Tick when)
Schedule the sending of a timing response.
Definition qport.hh:94
Tick sendAtomic(PacketPtr pkt)
Send an atomic request packet, where the data is moved and the state is updated in zero time,...
Definition port.hh:552
RequestorID maxRequestors()
Get the number of requestors registered in the system.
Definition system.hh:495
STL list class.
Definition stl.hh:51
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:214
Miss Status and Handling Register (MSHR) declaration.
Bitfield< 0 > p
Bitfield< 15 > system
Definition misc.hh:1032
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
uint64_t Tick
Tick count type.
Definition types.hh:58
Specifies a non-coherent cache.
statistics::Vector missLatency
Total number of ticks per thread/command spent waiting for a miss.
Definition base.hh:1023
CacheCmdStats & cmdStats(const PacketPtr p)
Definition base.hh:1054

Generated on Tue Jun 18 2024 16:24:05 for gem5 by doxygen 1.11.0