gem5  v22.1.0.0
cache_blk.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-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) 2020 Inria
15  * Copyright (c) 2003-2005 The Regents of The University of Michigan
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 
46 #ifndef __MEM_CACHE_CACHE_BLK_HH__
47 #define __MEM_CACHE_CACHE_BLK_HH__
48 
49 #include <cassert>
50 #include <cstdint>
51 #include <iosfwd>
52 #include <list>
53 #include <string>
54 
55 #include "base/printable.hh"
56 #include "base/types.hh"
58 #include "mem/packet.hh"
59 #include "mem/request.hh"
60 #include "sim/cur_tick.hh"
61 
62 namespace gem5
63 {
64 
70 class CacheBlk : public TaggedEntry
71 {
72  public:
77  enum CoherenceBits : unsigned
78  {
80  WritableBit = 0x02,
85  ReadableBit = 0x04,
87  DirtyBit = 0x08,
88 
93  AllBits = 0x0E,
94  };
95 
103  uint8_t *data = nullptr;
104 
110 
111  protected:
116  class Lock
117  {
118  public:
119  ContextID contextId; // locking context
120  Addr lowAddr; // low address of lock range
121  Addr highAddr; // high address of lock range
122 
123  // check for matching execution context, and an address that
124  // is within the lock
125  bool matches(const RequestPtr &req) const
126  {
127  Addr req_low = req->getPaddr();
128  Addr req_high = req_low + req->getSize() -1;
129  return (contextId == req->contextId()) &&
130  (req_low >= lowAddr) && (req_high <= highAddr);
131  }
132 
133  // check if a request is intersecting and thus invalidating the lock
134  bool intersects(const RequestPtr &req) const
135  {
136  Addr req_low = req->getPaddr();
137  Addr req_high = req_low + req->getSize() - 1;
138 
139  return (req_low <= highAddr) && (req_high >= lowAddr);
140  }
141 
142  Lock(const RequestPtr &req)
143  : contextId(req->contextId()),
144  lowAddr(req->getPaddr()),
145  highAddr(lowAddr + req->getSize() - 1)
146  {
147  }
148  };
149 
153 
154  public:
156  {
157  invalidate();
158  }
159 
160  CacheBlk(const CacheBlk&) = delete;
161  CacheBlk& operator=(const CacheBlk&) = delete;
162  CacheBlk(const CacheBlk&&) = delete;
171  virtual CacheBlk&
173  {
174  // Copying an entry into a valid one would imply in skipping all
175  // replacement steps, so it cannot be allowed
176  assert(!isValid());
177  assert(other.isValid());
178 
179  insert(other.getTag(), other.isSecure());
180 
181  if (other.wasPrefetched()) {
182  setPrefetched();
183  }
184  setCoherenceBits(other.coherence);
185  setTaskId(other.getTaskId());
187  setRefCount(other.getRefCount());
188  setSrcRequestorId(other.getSrcRequestorId());
189  std::swap(lockList, other.lockList);
190 
191  other.invalidate();
192 
193  return *this;
194  }
195  virtual ~CacheBlk() {};
196 
200  virtual void invalidate() override
201  {
203 
204  clearPrefetched();
206 
209  setRefCount(0);
211  lockList.clear();
212  }
213 
219  void
221  {
222  assert(isValid());
223  coherence |= bits;
224  }
225 
231  void clearCoherenceBits(unsigned bits) { coherence &= ~bits; }
232 
238  bool
239  isSet(unsigned bits) const
240  {
241  return isValid() && (coherence & bits);
242  }
243 
249  bool wasPrefetched() const { return _prefetched; }
250 
255  void clearPrefetched() { _prefetched = false; }
256 
258  void setPrefetched() { _prefetched = true; }
259 
266  {
267  assert(whenReady != MaxTick);
268  return whenReady;
269  }
270 
278  void setWhenReady(const Tick tick)
279  {
280  assert(tick >= _tickInserted);
281  whenReady = tick;
282  }
283 
285  uint32_t getTaskId() const { return _taskId; }
286 
288  uint32_t getSrcRequestorId() const { return _srcRequestorId; }
289 
291  unsigned getRefCount() const { return _refCount; }
292 
295 
301  Tick
302  getAge() const
303  {
304  assert(_tickInserted <= curTick());
305  return curTick() - _tickInserted;
306  }
307 
319  void insert(const Addr tag, const bool is_secure,
320  const int src_requestor_ID, const uint32_t task_ID);
321  using TaggedEntry::insert;
322 
328  {
329  assert(pkt->isLLSC());
330  auto l = lockList.begin();
331  while (l != lockList.end()) {
332  if (l->intersects(pkt->req))
333  l = lockList.erase(l);
334  else
335  ++l;
336  }
337 
338  lockList.emplace_front(pkt->req);
339  }
340 
345  void clearLoadLocks(const RequestPtr &req)
346  {
347  auto l = lockList.begin();
348  while (l != lockList.end()) {
349  if (l->intersects(req) && l->contextId != req->contextId()) {
350  l = lockList.erase(l);
351  } else {
352  ++l;
353  }
354  }
355  }
356 
363  std::string
364  print() const override
365  {
390  unsigned state =
391  isSet(WritableBit) << 2 | isSet(DirtyBit) << 1 | isValid();
392  char s = '?';
393  switch (state) {
394  case 0b111: s = 'M'; break;
395  case 0b011: s = 'O'; break;
396  case 0b101: s = 'E'; break;
397  case 0b001: s = 'S'; break;
398  case 0b000: s = 'I'; break;
399  default: s = 'T'; break; // @TODO add other types
400  }
401  return csprintf("state: %x (%c) writable: %d readable: %d "
402  "dirty: %d prefetched: %d | %s", coherence, s,
405  }
406 
413  {
414  assert(pkt->isWrite());
415 
416  // common case
417  if (!pkt->isLLSC() && lockList.empty())
418  return true;
419 
420  const RequestPtr &req = pkt->req;
421 
422  if (pkt->isLLSC()) {
423  // it's a store conditional... have to check for matching
424  // load locked.
425  bool success = false;
426 
427  auto l = lockList.begin();
428  while (!success && l != lockList.end()) {
429  if (l->matches(pkt->req)) {
430  // it's a store conditional, and as far as the
431  // memory system can tell, the requesting
432  // context's lock is still valid.
433  success = true;
434  lockList.erase(l);
435  } else {
436  ++l;
437  }
438  }
439 
440  req->setExtraData(success ? 1 : 0);
441  // clear any intersected locks from other contexts (our LL
442  // should already have cleared them)
443  clearLoadLocks(req);
444  return success;
445  } else {
446  // a normal write, if there is any lock not from this
447  // context we clear the list, thus for a private cache we
448  // never clear locks on normal writes
449  clearLoadLocks(req);
450  return true;
451  }
452  }
453 
454  protected:
456  unsigned coherence;
457 
458  // The following setters have been marked as protected because their
459  // respective variables should only be modified at 2 moments:
460  // invalidation and insertion. Because of that, they shall only be
461  // called by the functions that perform those actions.
462 
464  void setTaskId(const uint32_t task_id) { _taskId = task_id; }
465 
467  void setSrcRequestorId(const uint32_t id) { _srcRequestorId = id; }
468 
470  void setRefCount(const unsigned count) { _refCount = count; }
471 
474 
475  private:
477  uint32_t _taskId = 0;
478 
481 
483  unsigned _refCount = 0;
484 
490 
492  bool _prefetched = 0;
493 };
494 
500 class TempCacheBlk final : public CacheBlk
501 {
502  private:
507 
508  public:
513  TempCacheBlk(unsigned size) : CacheBlk()
514  {
515  data = new uint8_t[size];
516  }
517  TempCacheBlk(const TempCacheBlk&) = delete;
519  ~TempCacheBlk() { delete [] data; };
520 
524  void invalidate() override {
526 
527  _addr = MaxAddr;
528  }
529 
530  void
531  insert(const Addr addr, const bool is_secure) override
532  {
533  CacheBlk::insert(addr, is_secure);
534  _addr = addr;
535  }
536 
542  Addr getAddr() const
543  {
544  return _addr;
545  }
546 };
547 
555 {
557  public:
560  void print(std::ostream &o, int verbosity = 0,
561  const std::string &prefix = "") const;
562 };
563 
564 } // namespace gem5
565 
566 #endif //__MEM_CACHE_CACHE_BLK_HH__
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
Simple class to provide virtual print() method on cache blocks without allocating a vtable pointer fo...
Definition: cache_blk.hh:555
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
Definition: cache_blk.cc:72
CacheBlkPrintWrapper(CacheBlk *_blk)
Definition: cache_blk.hh:558
Represents that the indicated thread context has a "lock" on the block, in the LL/SC sense.
Definition: cache_blk.hh:117
Lock(const RequestPtr &req)
Definition: cache_blk.hh:142
bool matches(const RequestPtr &req) const
Definition: cache_blk.hh:125
bool intersects(const RequestPtr &req) const
Definition: cache_blk.hh:134
A Basic Cache block.
Definition: cache_blk.hh:71
virtual CacheBlk & operator=(CacheBlk &&other)
Move assignment operator.
Definition: cache_blk.hh:172
void setWhenReady(const Tick tick)
Set tick at which block's data will be available for access.
Definition: cache_blk.hh:278
CoherenceBits
Cache block's enum listing the supported coherence bits.
Definition: cache_blk.hh:78
@ ReadableBit
Read permission.
Definition: cache_blk.hh:85
@ AllBits
Helper enum value that includes all other bits.
Definition: cache_blk.hh:93
@ WritableBit
write permission
Definition: cache_blk.hh:80
@ DirtyBit
dirty (modified)
Definition: cache_blk.hh:87
Tick whenReady
Which curTick() will this block be accessible.
Definition: cache_blk.hh:109
uint32_t getSrcRequestorId() const
Get the requestor id associated to this block.
Definition: cache_blk.hh:288
int _srcRequestorId
holds the source requestor ID for this block.
Definition: cache_blk.hh:480
Tick getWhenReady() const
Get tick at which block's data will be available for access.
Definition: cache_blk.hh:265
void clearPrefetched()
Clear the prefetching bit.
Definition: cache_blk.hh:255
unsigned _refCount
Number of references to this block since it was brought in.
Definition: cache_blk.hh:483
void setPrefetched()
Marks this blocks as a recently prefetched block.
Definition: cache_blk.hh:258
Tick getAge() const
Get the block's age, that is, the number of ticks since its insertion.
Definition: cache_blk.hh:302
unsigned getRefCount() const
Get the number of references to this block since insertion.
Definition: cache_blk.hh:291
std::string print() const override
Pretty-print tag, set and way, and interpret state bits to readable form including mapping to a MOESI...
Definition: cache_blk.hh:364
bool isSet(unsigned bits) const
Checks the given coherence bits are set.
Definition: cache_blk.hh:239
CacheBlk & operator=(const CacheBlk &)=delete
void setTaskId(const uint32_t task_id)
Set the task id value.
Definition: cache_blk.hh:464
bool _prefetched
Whether this block is an unaccessed hardware prefetch.
Definition: cache_blk.hh:492
void setTickInserted()
Set the current tick as this block's insertion tick.
Definition: cache_blk.hh:473
CacheBlk(const CacheBlk &&)=delete
virtual void insert(const Addr tag, const bool is_secure)
Insert the block by assigning it a tag and marking it valid.
Definition: tagged_entry.hh:93
virtual void invalidate() override
Invalidate the block and clear all state.
Definition: cache_blk.hh:200
uint32_t _taskId
Task Id associated with this block.
Definition: cache_blk.hh:477
bool checkWrite(PacketPtr pkt)
Handle interaction of load-locked operations and stores.
Definition: cache_blk.hh:412
void clearCoherenceBits(unsigned bits)
Clear the corresponding coherence bits.
Definition: cache_blk.hh:231
void clearLoadLocks(const RequestPtr &req)
Clear the any load lock that intersect the request, and is from a different context.
Definition: cache_blk.hh:345
void increaseRefCount()
Get the number of references to this block since insertion.
Definition: cache_blk.hh:294
uint32_t getTaskId() const
Get the task id associated to this block.
Definition: cache_blk.hh:285
void trackLoadLocked(PacketPtr pkt)
Track the fact that a local locked was issued to the block.
Definition: cache_blk.hh:327
bool wasPrefetched() const
Check if this block was the result of a hardware prefetch, yet to be touched.
Definition: cache_blk.hh:249
CacheBlk(const CacheBlk &)=delete
virtual ~CacheBlk()
Definition: cache_blk.hh:195
void setSrcRequestorId(const uint32_t id)
Set the source requestor id.
Definition: cache_blk.hh:467
void setRefCount(const unsigned count)
Set the number of references to this block since insertion.
Definition: cache_blk.hh:470
std::list< Lock > lockList
List of thread contexts that have performed a load-locked (LL) on the block since the last store.
Definition: cache_blk.hh:152
uint8_t * data
Contains a copy of the data in this block for easy access.
Definition: cache_blk.hh:103
unsigned coherence
The current coherence status of this block.
Definition: cache_blk.hh:456
Tick _tickInserted
Tick on which the block was inserted in the cache.
Definition: cache_blk.hh:489
void setCoherenceBits(unsigned bits)
Sets the corresponding coherence bits.
Definition: cache_blk.hh:220
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
bool isWrite() const
Definition: packet.hh:593
RequestPtr req
A pointer to the original request.
Definition: packet.hh:376
bool isLLSC() const
Definition: packet.hh:619
Abstract base class for objects which support being printed to a stream for debugging.
Definition: printable.hh:48
@ invldRequestorId
Invalid requestor id for assertion checking only.
Definition: request.hh:286
A tagged entry is an entry containing a tag.
Definition: tagged_entry.hh:47
virtual bool isValid() const
Checks if the entry is valid.
Definition: tagged_entry.hh:57
std::string print() const override
Prints relevant information about this entry.
virtual void invalidate()
Invalidate the block.
virtual void insert(const Addr tag, const bool is_secure)
Insert the block by assigning it a tag and marking it valid.
Definition: tagged_entry.hh:93
Special instance of CacheBlk for use with tempBlk that deals with its block address regeneration.
Definition: cache_blk.hh:501
void insert(const Addr addr, const bool is_secure) override
Insert the block by assigning it a tag and marking it valid.
Definition: cache_blk.hh:531
Addr getAddr() const
Get block's address.
Definition: cache_blk.hh:542
TempCacheBlk(unsigned size)
Creates a temporary cache block, with its own storage.
Definition: cache_blk.hh:513
void invalidate() override
Invalidate the block and clear all state.
Definition: cache_blk.hh:524
Addr _addr
Copy of the block's address, used to regenerate tempBlock's address.
Definition: cache_blk.hh:506
TempCacheBlk & operator=(const TempCacheBlk &)=delete
TempCacheBlk(const TempCacheBlk &)=delete
STL list class.
Definition: stl.hh:51
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:76
atomic_var_t state
Definition: helpers.cc:188
Bitfield< 33 > id
Definition: misc_types.hh:257
constexpr RegId o(int index)
Definition: int.hh:147
Bitfield< 1 > s
Definition: pagetable.hh:64
Bitfield< 55 > l
Definition: pagetable.hh:54
Bitfield< 3 > addr
Definition: types.hh:84
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
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
const Tick MaxTick
Definition: types.hh:60
int ContextID
Globally unique thread context ID.
Definition: types.hh:239
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
const Addr MaxAddr
Definition: types.hh:171
Declaration of the Packet class.
Declaration of a request, the overall memory request consisting of the parts of the request that are ...

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