gem5  v22.1.0.0
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"
55 #include "mem/cache/cache_blk.hh"
56 #include "mem/cache/mshr.hh"
57 #include "params/NoncoherentCache.hh"
58 
59 namespace gem5
60 {
61 
62 NoncoherentCache::NoncoherentCache(const NoncoherentCacheParams &p)
63  : BaseCache(p, p.system->cacheLineSize())
64 {
65  assert(p.tags);
66  assert(p.replacement_policy);
67 }
68 
69 void
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());
76  BaseCache::satisfyRequest(pkt, blk);
77 }
78 
79 bool
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 
97 void
99 {
100  while (!writebacks.empty()) {
101  PacketPtr wb_pkt = writebacks.front();
102  allocateWriteBuffer(wb_pkt, forward_time);
103  writebacks.pop_front();
104  }
105 }
106 
107 void
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 
118 void
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 
134 void
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 
146 PacketPtr
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 
170 Cycles
172  PacketList &writebacks)
173 {
174  PacketPtr bus_pkt = createMissPacket(pkt, blk, true,
175  pkt->isWholeLineWrite(blkSize));
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 
219 Tick
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 
232 void
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 
241 void
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 
324 void
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 
342 PacketPtr
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:186
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:96
virtual void functionalAccess(PacketPtr pkt, bool from_cpu_side)
Performs the access specified by the request.
Definition: base.cc:713
virtual void recvTimingReq(PacketPtr pkt)
Performs the access specified by the request.
Definition: base.cc:403
CpuSidePort cpuSidePort
Definition: base.hh:338
void invalidateBlock(CacheBlk *blk)
Invalidate a cache block.
Definition: base.cc:1662
const bool writebackClean
Determine if clean lines should be written back or not.
Definition: base.hh:675
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:441
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:1087
gem5::BaseCache::CacheStats stats
MSHRQueue mshrQueue
Miss status registers.
Definition: base.hh:344
const unsigned blkSize
Block size of this cache.
Definition: base.hh:888
const Cycles responseLatency
The latency of sending reponse to its upper level cache/core on a linefill.
Definition: base.hh:917
MemSidePort memSidePort
Definition: base.hh:339
virtual Tick recvAtomic(PacketPtr pkt)
Performs the access specified by the request.
Definition: base.cc:633
virtual void recvTimingResp(PacketPtr pkt)
Handles a response (cache line fill/write ack) from the bus.
Definition: base.cc:487
virtual bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat, PacketList &writebacks)
Does all the processing necessary to perform the provided request.
Definition: base.cc:1228
void allocateWriteBuffer(PacketPtr pkt, Tick time)
Definition: base.hh:1191
CacheBlk * handleFill(PacketPtr pkt, CacheBlk *blk, PacketList &writebacks, bool allocate)
Handle a fill operation caused by a received packet.
Definition: base.cc:1509
PacketPtr writebackBlk(CacheBlk *blk)
Create a writeback request for the given block.
Definition: base.cc:1691
void maintainClusivity(bool from_cache, CacheBlk *blk)
Maintain the clusivity of this cache by potentially invalidating a block.
Definition: base.cc:1497
System * system
System we are currently operating in.
Definition: base.hh:986
A Basic Cache block.
Definition: cache_blk.hh:71
@ WritableBit
write permission
Definition: cache_blk.hh:80
@ DirtyBit
dirty (modified)
Definition: cache_blk.hh:87
void setPrefetched()
Marks this blocks as a recently prefetched block.
Definition: cache_blk.hh:258
bool isSet(unsigned bits) const
Checks the given coherence bits are set.
Definition: cache_blk.hh:239
void setCoherenceBits(unsigned bits)
Sets the corresponding coherence bits.
Definition: cache_blk.hh:220
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:547
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
@ WriteClean
Definition: packet.hh:94
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:294
bool isRead() const
Definition: packet.hh:592
bool isSecure() const
Definition: packet.hh:834
Addr getAddr() const
Definition: packet.hh:805
bool isError() const
Definition: packet.hh:621
bool isResponse() const
Definition: packet.hh:597
void makeTimingResponse()
Definition: packet.hh:1077
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
Definition: packet.cc:368
void copyError(Packet *pkt)
Definition: packet.hh:803
bool needsResponse() const
Definition: packet.hh:607
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Definition: packet.hh:448
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Definition: packet.hh:430
Addr getOffset(unsigned int blk_size) const
Definition: packet.hh:824
bool isWrite() const
Definition: packet.hh:593
Addr getBlockAddr(unsigned int blk_size) const
Definition: packet.hh:829
RequestPtr req
A pointer to the original request.
Definition: packet.hh:376
bool isWriteback() const
Definition: packet.hh:612
bool cacheResponding() const
Definition: packet.hh:657
void makeAtomicResponse()
Definition: packet.hh:1071
MemCmd cmd
The command field of the packet.
Definition: packet.hh:371
bool isInvalidate() const
Definition: packet.hh:608
bool isWholeLineWrite(unsigned blk_size)
Definition: packet.hh:625
bool hasSharers() const
Definition: packet.hh:684
void allocate()
Allocate memory for the packet.
Definition: packet.hh:1354
PacketPtr pkt
Pending request packet.
Definition: queue_entry.hh:93
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:93
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:464
RequestorID maxRequestors()
Get the number of requestors registered in the system.
Definition: system.hh:498
virtual bool isValid() const
Checks if the entry is valid.
Definition: tagged_entry.hh:57
STL list class.
Definition: stl.hh:51
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:204
Miss Status and Handling Register (MSHR) declaration.
Bitfield< 54 > p
Definition: pagetable.hh:70
Bitfield< 15 > system
Definition: misc.hh:1004
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:109
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
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:1017
CacheCmdStats & cmdStats(const PacketPtr p)
Definition: base.hh:1048

Generated on Wed Dec 21 2022 10:22:36 for gem5 by doxygen 1.9.1