gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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  * Authors: Erik Hallnor
42  * Dave Greene
43  * Nathan Binkert
44  * Steve Reinhardt
45  * Ron Dreslinski
46  * Andreas Sandberg
47  * Nikos Nikoleris
48  */
49 
56 
57 #include <cassert>
58 
59 #include "base/logging.hh"
60 #include "base/trace.hh"
61 #include "base/types.hh"
62 #include "debug/Cache.hh"
63 #include "mem/cache/cache_blk.hh"
64 #include "mem/cache/mshr.hh"
65 #include "params/NoncoherentCache.hh"
66 
67 NoncoherentCache::NoncoherentCache(const NoncoherentCacheParams *p)
68  : BaseCache(p, p->system->cacheLineSize())
69 {
70 }
71 
72 void
74 {
75  // As this a non-coherent cache located below the point of
76  // coherency, we do not expect requests that are typically used to
77  // keep caches coherent (e.g., InvalidateReq or UpdateReq).
78  assert(pkt->isRead() || pkt->isWrite());
79  BaseCache::satisfyRequest(pkt, blk);
80 }
81 
82 bool
84  PacketList &writebacks)
85 {
86  bool success = BaseCache::access(pkt, blk, lat, writebacks);
87 
88  if (pkt->isWriteback() || pkt->cmd == MemCmd::WriteClean) {
89  assert(blk && blk->isValid());
90  // Writeback and WriteClean can allocate and fill even if the
91  // referenced block was not present or it was invalid. If that
92  // is the case, make sure that the new block is marked as
93  // writable
94  blk->status |= BlkWritable;
95  }
96 
97  return success;
98 }
99 
100 void
102 {
103  while (!writebacks.empty()) {
104  PacketPtr wb_pkt = writebacks.front();
105  allocateWriteBuffer(wb_pkt, forward_time);
106  writebacks.pop_front();
107  }
108 }
109 
110 void
112 {
113  while (!writebacks.empty()) {
114  PacketPtr wb_pkt = writebacks.front();
115  memSidePort.sendAtomic(wb_pkt);
116  writebacks.pop_front();
117  delete wb_pkt;
118  }
119 }
120 
121 void
123  Tick forward_time, Tick request_time)
124 {
125  // miss
126  Addr blk_addr = pkt->getBlockAddr(blkSize);
127  MSHR *mshr = mshrQueue.findMatch(blk_addr, pkt->isSecure(), false);
128 
129  // We can always write to a non coherent cache if the block is
130  // present and therefore if we have reached this point then the
131  // block should not be in the cache.
132  assert(mshr || !blk || !blk->isValid());
133 
134  BaseCache::handleTimingReqMiss(pkt, mshr, blk, forward_time, request_time);
135 }
136 
137 void
139 {
140  panic_if(pkt->cacheResponding(), "Should not see packets where cache "
141  "is responding");
142 
143  panic_if(!(pkt->isRead() || pkt->isWrite()),
144  "Should only see read and writes at non-coherent cache\n");
145 
147 }
148 
149 PacketPtr
151  bool needs_writable,
152  bool is_whole_line_write) const
153 {
154  // We also fill for writebacks from the coherent caches above us,
155  // and they do not need responses
156  assert(cpu_pkt->needsResponse());
157 
158  // A miss can happen only due to missing block
159  assert(!blk || !blk->isValid());
160 
161  PacketPtr pkt = new Packet(cpu_pkt->req, MemCmd::ReadReq, blkSize);
162 
163  // the packet should be block aligned
164  assert(pkt->getAddr() == pkt->getBlockAddr(blkSize));
165 
166  pkt->allocate();
167  DPRINTF(Cache, "%s created %s from %s\n", __func__, pkt->print(),
168  cpu_pkt->print());
169  return pkt;
170 }
171 
172 
173 Cycles
175  PacketList &writebacks)
176 {
177  PacketPtr bus_pkt = createMissPacket(pkt, blk, true,
178  pkt->isWholeLineWrite(blkSize));
179  DPRINTF(Cache, "Sending an atomic %s\n", bus_pkt->print());
180 
181  Cycles latency = ticksToCycles(memSidePort.sendAtomic(bus_pkt));
182 
183  assert(bus_pkt->isResponse());
184  // At the moment the only supported downstream requests we issue
185  // are ReadReq and therefore here we should only see the
186  // corresponding responses
187  assert(bus_pkt->isRead());
188  assert(pkt->cmd != MemCmd::UpgradeResp);
189  assert(!bus_pkt->isInvalidate());
190  assert(!bus_pkt->hasSharers());
191 
192  // We are now dealing with the response handling
193  DPRINTF(Cache, "Receive response: %s\n", bus_pkt->print());
194 
195  if (!bus_pkt->isError()) {
196  // Any reponse that does not have an error should be filling,
197  // afterall it is a read response
198  DPRINTF(Cache, "Block for addr %#llx being updated in Cache\n",
199  bus_pkt->getAddr());
200  blk = handleFill(bus_pkt, blk, writebacks, allocOnFill(bus_pkt->cmd));
201  assert(blk);
202  }
203  satisfyRequest(pkt, blk);
204 
205  maintainClusivity(true, blk);
206 
207  // Use the separate bus_pkt to generate response to pkt and
208  // then delete it.
209  if (!pkt->isWriteback() && pkt->cmd != MemCmd::WriteClean) {
210  assert(pkt->needsResponse());
211  pkt->makeAtomicResponse();
212  if (bus_pkt->isError()) {
213  pkt->copyError(bus_pkt);
214  }
215  }
216 
217  delete bus_pkt;
218 
219  return latency;
220 }
221 
222 Tick
224 {
225  panic_if(pkt->cacheResponding(), "Should not see packets where cache "
226  "is responding");
227 
228  panic_if(!(pkt->isRead() || pkt->isWrite()),
229  "Should only see read and writes at non-coherent cache\n");
230 
231  return BaseCache::recvAtomic(pkt);
232 }
233 
234 
235 void
237 {
238  panic_if(!from_cpu_side, "Non-coherent cache received functional snoop"
239  " request\n");
240 
241  BaseCache::functionalAccess(pkt, from_cpu_side);
242 }
243 
244 void
246  CacheBlk *blk)
247 {
248  // First offset for critical word first calculations
249  const int initial_offset = mshr->getTarget()->pkt->getOffset(blkSize);
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  Tick completion_time;
261  // Here we charge on completion_time the delay of the xbar if the
262  // packet comes from it, charged on headerDelay.
263  completion_time = pkt->headerDelay;
264 
265  satisfyRequest(tgt_pkt, blk);
266 
267  // How many bytes past the first request is this one
268  int transfer_offset;
269  transfer_offset = tgt_pkt->getOffset(blkSize) - initial_offset;
270  if (transfer_offset < 0) {
271  transfer_offset += blkSize;
272  }
273  // If not critical word (offset) return payloadDelay.
274  // responseLatency is the latency of the return path
275  // from lower level caches/memory to an upper level cache or
276  // the core.
277  completion_time += clockEdge(responseLatency) +
278  (transfer_offset ? pkt->payloadDelay : 0);
279 
280  assert(tgt_pkt->req->masterId() < system->maxMasters());
281  stats.cmdStats(tgt_pkt).missLatency[tgt_pkt->req->masterId()] +=
282  completion_time - target.recvTime;
283 
284  tgt_pkt->makeTimingResponse();
285  if (pkt->isError())
286  tgt_pkt->copyError(pkt);
287 
288  // Reset the bus additional time as it is now accounted for
289  tgt_pkt->headerDelay = tgt_pkt->payloadDelay = 0;
290  cpuSidePort.schedTimingResp(tgt_pkt, completion_time);
291  break;
292 
294  // handle deferred requests comming from a prefetcher
295  // attached to this cache
296  assert(tgt_pkt->cmd == MemCmd::HardPFReq);
297 
298  if (blk)
299  blk->status |= BlkHWPrefetched;
300 
301  // We have filled the block and the prefetcher does not
302  // require responses.
303  delete tgt_pkt;
304  break;
305 
306  default:
307  // we should never see FromSnoop Targets as this is a
308  // non-coherent cache
309  panic("Illegal target->source enum %d\n", target.source);
310  }
311  }
312 
313  // Reponses are filling and bring in writable blocks, therefore
314  // there should be no deferred targets and all the non-deferred
315  // targets are now serviced.
316  assert(mshr->getNumTargets() == 0);
317 }
318 
319 void
321 {
322  assert(pkt->isResponse());
323  // At the moment the only supported downstream requests we issue
324  // are ReadReq and therefore here we should only see the
325  // corresponding responses
326  assert(pkt->isRead());
327  assert(pkt->cmd != MemCmd::UpgradeResp);
328  assert(!pkt->isInvalidate());
329  // This cache is non-coherent and any memories below are
330  // non-coherent too (non-coherent caches or the main memory),
331  // therefore the fetched block can be marked as writable.
332  assert(!pkt->hasSharers());
333 
335 }
336 
337 PacketPtr
339 {
340  // A dirty block is always written back.
341 
342  // A clean block can we written back, if we turned on writebacks
343  // for clean blocks. This could be useful if there is a cache
344  // below and we want to make sure the block is cached but if the
345  // memory below is the main memory WritebackCleans are
346  // unnecessary.
347 
348  // If we clean writebacks are not enabled, we do not take any
349  // further action for evictions of clean blocks (i.e., CleanEvicts
350  // are unnecessary).
351  PacketPtr pkt = (blk->isDirty() || writebackClean) ?
352  writebackBlk(blk) : nullptr;
353 
354  invalidateBlock(blk);
355 
356  return pkt;
357 }
358 
360 NoncoherentCacheParams::create()
361 {
362  assert(tags);
363  assert(replacement_policy);
364 
365  return new NoncoherentCache(this);
366 }
Miss Status and Handling Register (MSHR) declaration.
virtual bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat, PacketList &writebacks)
Does all the processing necessary to perform the provided request.
Definition: base.cc:1033
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
#define DPRINTF(x,...)
Definition: trace.hh:229
void handleTimingReqMiss(PacketPtr pkt, CacheBlk *blk, Tick forward_time, Tick request_time) override
PacketPtr writebackBlk(CacheBlk *blk)
Create a writeback request for the given block.
Definition: base.cc:1488
State status
The current status of this block.
Definition: cache_blk.hh:108
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:83
Stats::Vector missLatency
Total number of cycles per thread/command spent waiting for a miss.
Definition: base.hh:951
bool isValid() const
Checks that a block is valid.
Definition: cache_blk.hh:206
CpuSidePort cpuSidePort
Definition: base.hh:312
void makeTimingResponse()
Definition: packet.hh:955
int getNumTargets() const
Returns the current number of allocated targets.
Definition: mshr.hh:425
System * system
System we are currently operating in.
Definition: base.hh:925
bool cacheResponding() const
Definition: packet.hh:591
virtual void handleTimingReqMiss(PacketPtr pkt, CacheBlk *blk, Tick forward_time, Tick request_time)=0
BaseCache::CacheStats stats
void invalidateBlock(CacheBlk *blk)
Invalidate a cache block.
Definition: base.cc:1462
A non-coherent cache.
void doWritebacks(PacketList &writebacks, Tick forward_time) override
Insert writebacks into the write buffer.
void doWritebacksAtomic(PacketList &writebacks) override
Send writebacks down the memory hierarchy in atomic mode.
bool isWrite() const
Definition: packet.hh:529
bool isInvalidate() const
Definition: packet.hh:543
bool isRead() const
Definition: packet.hh:528
Cycles handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk, PacketList &writebacks) override
Handle a request in atomic mode that missed in this cache.
MemSidePort memSidePort
Definition: base.hh:313
block was a hardware prefetch yet unaccessed
Definition: cache_blk.hh:76
CacheCmdStats & cmdStats(const PacketPtr p)
Definition: base.hh:982
Addr getBlockAddr(unsigned int blk_size) const
Definition: packet.hh:750
RequestPtr req
A pointer to the original request.
Definition: packet.hh:327
const Cycles responseLatency
The latency of sending reponse to its upper level cache/core on a linefill.
Definition: base.hh:872
virtual void recvTimingReq(PacketPtr pkt)
Performs the access specified by the request.
Definition: base.cc:337
void recvTimingResp(PacketPtr pkt) override
Handles a response (cache line fill/write ack) from the bus.
A coherent cache that can be arranged in flexible topologies.
Definition: cache.hh:69
virtual Tick recvAtomic(PacketPtr pkt)
Performs the access specified by the request.
Definition: base.cc:543
A Basic Cache block.
Definition: cache_blk.hh:87
void functionalAccess(PacketPtr pkt, bool from_cpu_side) override
Performs the access specified by the request.
bool needsResponse() const
Definition: packet.hh:542
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Definition: packet.hh:366
bool isError() const
Definition: packet.hh:555
Addr getOffset(unsigned int blk_size) const
Definition: packet.hh:745
void schedTimingResp(PacketPtr pkt, Tick when)
Schedule the sending of a timing response.
Definition: qport.hh:92
void makeAtomicResponse()
Definition: packet.hh:949
uint64_t Tick
Tick count type.
Definition: types.hh:63
bool isResponse() const
Definition: packet.hh:532
Miss Status and handling Register.
Definition: mshr.hh:72
virtual void recvTimingResp(PacketPtr pkt)
Handles a response (cache line fill/write ack) from the bus.
Definition: base.cc:405
QueueEntry::Target * getTarget() override
Returns a reference to the first target.
Definition: mshr.hh:452
Tick recvAtomic(PacketPtr pkt) override
Performs the access specified by the request.
Addr getAddr() const
Definition: packet.hh:726
void allocateWriteBuffer(PacketPtr pkt, Tick time)
Definition: base.hh:1119
A basic cache interface.
Definition: base.hh:93
NoncoherentCache(const NoncoherentCacheParams *p)
STL list class.
Definition: stl.hh:54
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Definition: packet.hh:384
CacheBlk * handleFill(PacketPtr pkt, CacheBlk *blk, PacketList &writebacks, bool allocate)
Handle a fill operation caused by a received packet.
Definition: base.cc:1309
const bool writebackClean
Determine if clean lines should be written back or not.
Definition: base.hh:630
const unsigned blkSize
Block size of this cache.
Definition: base.hh:843
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:255
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:166
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...
Bitfield< 15 > system
Definition: misc.hh:999
MasterID maxMasters()
Get the number of masters registered in the system.
Definition: system.hh:412
bool hasSharers() const
Definition: packet.hh:618
write permission
Definition: cache_blk.hh:70
Definitions of a simple cache block class.
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:907
void recvTimingReq(PacketPtr pkt) override
Performs the access specified by the request.
bool allocOnFill(MemCmd cmd) const
Determine whether we should allocate on a fill or not.
Definition: base.hh:408
Cycles ticksToCycles(Tick t) const
M5_NODISCARD PacketPtr evictBlock(CacheBlk *blk) override
Evict a cache block.
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
Definition: packet.cc:376
MemCmd cmd
The command field of the packet.
Definition: packet.hh:322
TargetList extractServiceableTargets(PacketPtr pkt)
Extracts the subset of the targets that can be serviced given a received response.
Definition: mshr.cc:541
const PacketPtr pkt
Pending request packet.
Definition: queue_entry.hh:91
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...
void serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt, CacheBlk *blk) override
Service non-deferred MSHR targets using the received response.
bool isSecure() const
Definition: packet.hh:755
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 copyError(Packet *pkt)
Definition: packet.hh:724
Specifies a non-coherent cache.
bool isWholeLineWrite(unsigned blk_size)
Definition: packet.hh:559
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:427
Bitfield< 0 > p
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:185
BaseTags * tags
Tag and data Storage.
Definition: base.hh:324
bool isWriteback() const
Definition: packet.hh:547
bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat, PacketList &writebacks) override
Does all the processing necessary to perform the provided request.
virtual void functionalAccess(PacketPtr pkt, bool from_cpu_side)
Performs the access specified by the request.
Definition: base.cc:623
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:104
MSHRQueue mshrQueue
Miss status registers.
Definition: base.hh:318
void maintainClusivity(bool from_cache, CacheBlk *blk)
Maintain the clusivity of this cache by potentially invalidating a block.
Definition: base.cc:1297
bool isDirty() const
Check to see if a block has been written.
Definition: cache_blk.hh:229

Generated on Fri Feb 28 2020 16:27:01 for gem5 by doxygen 1.8.13