gem5  v21.1.0.2
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;
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;
478 
481 
483  unsigned _refCount;
484 
490 
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;
518  TempCacheBlk& operator=(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__
tagged_entry.hh
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::CacheBlk::Lock::highAddr
Addr highAddr
Definition: cache_blk.hh:121
gem5::CacheBlk::_refCount
unsigned _refCount
Number of references to this block since it was brought in.
Definition: cache_blk.hh:483
gem5::CacheBlkPrintWrapper::~CacheBlkPrintWrapper
virtual ~CacheBlkPrintWrapper()
Definition: cache_blk.hh:559
gem5::CacheBlk::clearPrefetched
void clearPrefetched()
Clear the prefetching bit.
Definition: cache_blk.hh:255
gem5::CacheBlk::lockList
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
gem5::TempCacheBlk::_addr
Addr _addr
Copy of the block's address, used to regenerate tempBlock's address.
Definition: cache_blk.hh:506
gem5::TempCacheBlk::invalidate
void invalidate() override
Invalidate the block and clear all state.
Definition: cache_blk.hh:524
gem5::Packet::req
RequestPtr req
A pointer to the original request.
Definition: packet.hh:366
gem5::TaggedEntry::print
std::string print() const override
Prints relevant information about this entry.
Definition: tagged_entry.hh:111
cur_tick.hh
gem5::TempCacheBlk
Special instance of CacheBlk for use with tempBlk that deals with its block address regeneration.
Definition: cache_blk.hh:500
gem5::MaxTick
const Tick MaxTick
Definition: types.hh:60
gem5::Packet::isWrite
bool isWrite() const
Definition: packet.hh:583
gem5::CacheBlk::clearCoherenceBits
void clearCoherenceBits(unsigned bits)
Clear the corresponding coherence bits.
Definition: cache_blk.hh:231
gem5::CacheBlk::setTickInserted
void setTickInserted()
Set the current tick as this block's insertion tick.
Definition: cache_blk.hh:473
gem5::CacheBlk::checkWrite
bool checkWrite(PacketPtr pkt)
Handle interaction of load-locked operations and stores.
Definition: cache_blk.hh:412
gem5::csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
gem5::CacheBlk::WritableBit
@ WritableBit
write permission
Definition: cache_blk.hh:80
gem5::TempCacheBlk::operator=
TempCacheBlk & operator=(const TempCacheBlk &)=delete
request.hh
gem5::CacheBlk::operator=
virtual CacheBlk & operator=(CacheBlk &&other)
Move assignment operator.
Definition: cache_blk.hh:172
gem5::CacheBlk::setPrefetched
void setPrefetched()
Marks this blocks as a recently prefetched block.
Definition: cache_blk.hh:258
printable.hh
gem5::CacheBlk
A Basic Cache block.
Definition: cache_blk.hh:70
packet.hh
gem5::TempCacheBlk::TempCacheBlk
TempCacheBlk(unsigned size)
Creates a temporary cache block, with its own storage.
Definition: cache_blk.hh:513
gem5::TempCacheBlk::getAddr
Addr getAddr() const
Get block's address.
Definition: cache_blk.hh:542
gem5::CacheBlk::increaseRefCount
void increaseRefCount()
Get the number of references to this block since insertion.
Definition: cache_blk.hh:294
gem5::Printable
Abstract base class for objects which support being printed to a stream for debugging.
Definition: printable.hh:47
gem5::CacheBlk::getTaskId
uint32_t getTaskId() const
Get the task id associated to this block.
Definition: cache_blk.hh:285
gem5::CacheBlk::setWhenReady
void setWhenReady(const Tick tick)
Set tick at which block's data will be available for access.
Definition: cache_blk.hh:278
gem5::CacheBlk::~CacheBlk
virtual ~CacheBlk()
Definition: cache_blk.hh:195
gem5::TaggedEntry
A tagged entry is an entry containing a tag.
Definition: tagged_entry.hh:46
gem5::CacheBlk::CacheBlk
CacheBlk()
Definition: cache_blk.hh:155
gem5::MaxAddr
const Addr MaxAddr
Definition: types.hh:171
gem5::X86ISA::count
count
Definition: misc.hh:709
gem5::Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:283
gem5::CacheBlk::getSrcRequestorId
uint32_t getSrcRequestorId() const
Get the requestor id associated to this block.
Definition: cache_blk.hh:288
gem5::CacheBlk::_srcRequestorId
int _srcRequestorId
holds the source requestor ID for this block.
Definition: cache_blk.hh:480
gem5::CacheBlk::clearLoadLocks
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
gem5::CacheBlk::getAge
Tick getAge() const
Get the block's age, that is, the number of ticks since its insertion.
Definition: cache_blk.hh:302
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::RequestPtr
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
gem5::ArmISA::s
Bitfield< 4 > s
Definition: misc_types.hh:561
gem5::CacheBlk::setCoherenceBits
void setCoherenceBits(unsigned bits)
Sets the corresponding coherence bits.
Definition: cache_blk.hh:220
gem5::Packet::isLLSC
bool isLLSC() const
Definition: packet.hh:609
gem5::CacheBlk::print
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
gem5::MipsISA::l
Bitfield< 5 > l
Definition: pra_constants.hh:323
gem5::bits
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
gem5::TaggedEntry::invalidate
virtual void invalidate()
Invalidate the block.
Definition: tagged_entry.hh:103
gem5::TempCacheBlk::~TempCacheBlk
~TempCacheBlk()
Definition: cache_blk.hh:519
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::CacheBlk::CoherenceBits
CoherenceBits
Cache block's enum listing the supported coherence bits.
Definition: cache_blk.hh:77
gem5::CacheBlk::DirtyBit
@ DirtyBit
dirty (modified)
Definition: cache_blk.hh:87
gem5::CacheBlk::setRefCount
void setRefCount(const unsigned count)
Set the number of references to this block since insertion.
Definition: cache_blk.hh:470
gem5::CacheBlk::Lock::contextId
ContextID contextId
Definition: cache_blk.hh:119
gem5::CacheBlk::data
uint8_t * data
Contains a copy of the data in this block for easy access.
Definition: cache_blk.hh:103
gem5::CacheBlk::whenReady
Tick whenReady
Which curTick() will this block be accessible.
Definition: cache_blk.hh:109
gem5::CacheBlk::getWhenReady
Tick getWhenReady() const
Get tick at which block's data will be available for access.
Definition: cache_blk.hh:265
gem5::CacheBlk::Lock::Lock
Lock(const RequestPtr &req)
Definition: cache_blk.hh:142
gem5::CacheBlk::Lock
Represents that the indicated thread context has a "lock" on the block, in the LL/SC sense.
Definition: cache_blk.hh:116
gem5::context_switch_task_id::Unknown
@ Unknown
Definition: request.hh:85
gem5::CacheBlk::Lock::lowAddr
Addr lowAddr
Definition: cache_blk.hh:120
gem5::CacheBlk::Lock::matches
bool matches(const RequestPtr &req) const
Definition: cache_blk.hh:125
gem5::TaggedEntry::insert
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
types.hh
gem5::ContextID
int ContextID
Globally unique thread context ID.
Definition: types.hh:246
gem5::CacheBlk::wasPrefetched
bool wasPrefetched() const
Check if this block was the result of a hardware prefetch, yet to be touched.
Definition: cache_blk.hh:249
gem5::CacheBlk::_taskId
uint32_t _taskId
Task Id associated with this block.
Definition: cache_blk.hh:477
gem5::CacheBlk::trackLoadLocked
void trackLoadLocked(PacketPtr pkt)
Track the fact that a local locked was issued to the block.
Definition: cache_blk.hh:327
gem5::CacheBlk::isSet
bool isSet(unsigned bits) const
Checks the given coherence bits are set.
Definition: cache_blk.hh:239
gem5::CacheBlk::Lock::intersects
bool intersects(const RequestPtr &req) const
Definition: cache_blk.hh:134
gem5::CacheBlkPrintWrapper::print
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
Definition: cache_blk.cc:72
gem5::ArmISA::id
Bitfield< 33 > id
Definition: misc_types.hh:250
gem5::TempCacheBlk::insert
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
gem5::CacheBlk::_tickInserted
Tick _tickInserted
Tick on which the block was inserted in the cache.
Definition: cache_blk.hh:489
gem5::CacheBlkPrintWrapper
Simple class to provide virtual print() method on cache blocks without allocating a vtable pointer fo...
Definition: cache_blk.hh:554
gem5::CacheBlk::setTaskId
void setTaskId(const uint32_t task_id)
Set the task id value.
Definition: cache_blk.hh:464
std::list
STL list class.
Definition: stl.hh:51
gem5::CacheBlk::invalidate
virtual void invalidate() override
Invalidate the block and clear all state.
Definition: cache_blk.hh:200
gem5::CacheBlkPrintWrapper::blk
CacheBlk * blk
Definition: cache_blk.hh:556
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::CacheBlk::coherence
unsigned coherence
The current coherence status of this block.
Definition: cache_blk.hh:456
gem5::CacheBlk::getRefCount
unsigned getRefCount() const
Get the number of references to this block since insertion.
Definition: cache_blk.hh:291
gem5::CacheBlk::_prefetched
bool _prefetched
Whether this block is an unaccessed hardware prefetch.
Definition: cache_blk.hh:492
gem5::CacheBlk::operator=
CacheBlk & operator=(const CacheBlk &)=delete
gem5::Request::invldRequestorId
@ invldRequestorId
Invalid requestor id for assertion checking only.
Definition: request.hh:267
gem5::CacheBlk::AllBits
@ AllBits
Helper enum value that includes all other bits.
Definition: cache_blk.hh:93
gem5::CacheBlk::setSrcRequestorId
void setSrcRequestorId(const uint32_t id)
Set the source requestor id.
Definition: cache_blk.hh:467
gem5::TaggedEntry::isValid
virtual bool isValid() const
Checks if the entry is valid.
Definition: tagged_entry.hh:57
gem5::CacheBlkPrintWrapper::CacheBlkPrintWrapper
CacheBlkPrintWrapper(CacheBlk *_blk)
Definition: cache_blk.hh:558
gem5::CacheBlk::insert
void insert(const Addr tag, const bool is_secure, const int src_requestor_ID, const uint32_t task_ID)
Set member variables when a block insertion occurs.
Definition: cache_blk.cc:50
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84
gem5::CacheBlk::ReadableBit
@ ReadableBit
Read permission.
Definition: cache_blk.hh:85

Generated on Tue Sep 21 2021 12:25:29 for gem5 by doxygen 1.8.17