gem5  v22.1.0.0
mem_checker.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 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  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #ifndef __MEM_MEM_CHECKER_HH__
39 #define __MEM_MEM_CHECKER_HH__
40 
41 #include <cassert>
42 #include <cstdint>
43 #include <list>
44 #include <map>
45 #include <string>
46 #include <unordered_map>
47 #include <vector>
48 
49 #include "base/cprintf.hh"
50 #include "base/named.hh"
51 #include "base/trace.hh"
52 #include "base/types.hh"
53 #include "debug/MemChecker.hh"
54 #include "params/MemChecker.hh"
55 #include "sim/sim_object.hh"
56 
57 namespace gem5
58 {
59 
74 class MemChecker : public SimObject
75 {
76  public:
82  typedef uint64_t Serial;
83 
84  static const Serial SERIAL_INITIAL = 0;
85 
91  static const Tick TICK_INITIAL = 0;
92 
96  static const Tick TICK_FUTURE = MaxTick;
97 
101  static const uint8_t DATA_INITIAL = 0x00;
102 
108  {
109  public:
110 
112  Tick _start, Tick _complete,
113  uint8_t _data = DATA_INITIAL)
114  : serial(_serial),
115  start(_start), complete(_complete),
116  data(_data)
117  {}
118 
119  public:
123 
129  uint8_t data;
130 
134  bool operator<(const Transaction& rhs) const
135  { return serial < rhs.serial; }
136  };
137 
144  {
145  public:
149  {}
150 
159  void startWrite(Serial serial, Tick _start, uint8_t data);
160 
168  void completeWrite(Serial serial, Tick _complete);
169 
175  void abortWrite(Serial serial);
176 
180  bool isComplete() const { return complete != TICK_FUTURE; }
181 
182  public:
185 
190  std::unordered_map<Serial, Transaction> writes;
191 
192  private:
195  };
196 
199 
205  class ByteTracker : public Named
206  {
207  public:
208 
209  ByteTracker(Addr addr = 0, const MemChecker *parent = NULL)
210  : Named((parent != NULL ? parent->name() : "") +
211  csprintf(".ByteTracker@%#llx", addr))
212  {
213  // The initial transaction has start == complete == TICK_INITIAL,
214  // indicating that there has been no real write to this location;
215  // therefore, upon checking, we do not expect any particular value.
216  readObservations.emplace_back(
218  DATA_INITIAL));
219  }
220 
227  void startRead(Serial serial, Tick start);
228 
253  bool inExpectedData(Tick start, Tick complete, uint8_t data);
254 
262  bool completeRead(Serial serial, Tick complete, uint8_t data);
263 
273  void startWrite(Serial serial, Tick start, uint8_t data);
274 
282  void completeWrite(Serial serial, Tick complete);
283 
290  void abortWrite(Serial serial);
291 
302  { return _lastExpectedData; }
303 
304  private:
305 
314 
324  template <class TList>
325  typename TList::iterator lastCompletedTransaction(TList *l, Tick before)
326  {
327  assert(!l->empty());
328 
329  // Scanning backwards increases the chances of getting a match
330  // quicker.
331  auto it = l->end();
332 
333  for (--it; it != l->begin() && it->complete >= before; --it);
334 
335  return it;
336  }
337 
347  void pruneTransactions();
348 
349  private:
350 
357  std::map<Serial, Transaction> outstandingReads;
358 
363 
368 
373  };
374 
375  public:
376 
377  MemChecker(const MemCheckerParams &p)
378  : SimObject(p),
380  {}
381 
382  virtual ~MemChecker() {}
383 
393  Serial startRead(Tick start, Addr addr, size_t size);
394 
405  Serial startWrite(Tick start, Addr addr, size_t size, const uint8_t *data);
406 
420  bool completeRead(Serial serial, Tick complete,
421  Addr addr, size_t size, uint8_t *data);
422 
433  void completeWrite(Serial serial, Tick complete, Addr addr, size_t size);
434 
443  void abortWrite(Serial serial, Addr addr, size_t size);
444 
454  void reset()
455  { byte_trackers.clear(); }
456 
465  void reset(Addr addr, size_t size);
466 
476  const std::string& getErrorMessage() const { return errorMessage; }
477 
478  private:
483  {
484  auto it = byte_trackers.find(addr);
485  if (it == byte_trackers.end()) {
486  it = byte_trackers.insert(
487  std::make_pair(addr, ByteTracker(addr, this))).first;
488  }
489  return &it->second;
490  };
491 
492  private:
496  std::string errorMessage;
497 
503 
515  std::unordered_map<Addr, ByteTracker> byte_trackers;
516 };
517 
518 inline MemChecker::Serial
519 MemChecker::startRead(Tick start, Addr addr, size_t size)
520 {
522  "starting read: serial = %d, start = %d, addr = %#llx, "
523  "size = %d\n", nextSerial, start, addr , size);
524 
525  for (size_t i = 0; i < size; ++i) {
527  }
528 
529  return nextSerial++;
530 }
531 
532 inline MemChecker::Serial
533 MemChecker::startWrite(Tick start, Addr addr, size_t size, const uint8_t *data)
534 {
536  "starting write: serial = %d, start = %d, addr = %#llx, "
537  "size = %d\n", nextSerial, start, addr, size);
538 
539  for (size_t i = 0; i < size; ++i) {
541  }
542 
543  return nextSerial++;
544 }
545 
546 inline void
548  Addr addr, size_t size)
549 {
551  "completing write: serial = %d, complete = %d, "
552  "addr = %#llx, size = %d\n", serial, complete, addr, size);
553 
554  for (size_t i = 0; i < size; ++i) {
555  getByteTracker(addr + i)->completeWrite(serial, complete);
556  }
557 }
558 
559 inline void
561 {
563  "aborting write: serial = %d, addr = %#llx, size = %d\n",
564  serial, addr, size);
565 
566  for (size_t i = 0; i < size; ++i) {
567  getByteTracker(addr + i)->abortWrite(serial);
568  }
569 }
570 
571 } // namespace gem5
572 
573 #endif // __MEM_MEM_CHECKER_HH__
#define DPRINTF(x,...)
Definition: trace.hh:186
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
const char data[]
The ByteTracker keeps track of transactions for the same byte – all outstanding reads,...
Definition: mem_checker.hh:206
std::vector< uint8_t > _lastExpectedData
See lastExpectedData().
Definition: mem_checker.hh:372
void abortWrite(Serial serial)
Aborts a write transaction.
Definition: mem_checker.cc:276
void completeWrite(Serial serial, Tick complete)
Completes a write transaction.
Definition: mem_checker.cc:268
bool completeRead(Serial serial, Tick complete, uint8_t data)
Completes a read transaction that is still outstanding.
Definition: mem_checker.cc:226
WriteCluster * getIncompleteWriteCluster()
Convenience function to return the most recent incomplete write cluster.
Definition: mem_checker.cc:251
ByteTracker(Addr addr=0, const MemChecker *parent=NULL)
Definition: mem_checker.hh:209
bool inExpectedData(Tick start, Tick complete, uint8_t data)
Given a start and end time (of any read transaction), this function iterates through all data that su...
Definition: mem_checker.cc:132
void startWrite(Serial serial, Tick start, uint8_t data)
Starts a write transaction.
Definition: mem_checker.cc:261
std::map< Serial, Transaction > outstandingReads
Maintains a map of Serial -> Transaction for all outstanding reads.
Definition: mem_checker.hh:357
void pruneTransactions()
Prunes no longer needed transactions.
Definition: mem_checker.cc:282
void startRead(Serial serial, Tick start)
Starts a read transaction.
Definition: mem_checker.cc:125
TransactionList readObservations
List of completed reads, i.e.
Definition: mem_checker.hh:362
WriteClusterList writeClusters
List of write clusters for this address.
Definition: mem_checker.hh:367
TList::iterator lastCompletedTransaction(TList *l, Tick before)
Helper function to return an iterator to the entry of a container of Transaction compatible classes,...
Definition: mem_checker.hh:325
const std::vector< uint8_t > & lastExpectedData() const
This function returns the expected data that inExpectedData iterated through in the last call.
Definition: mem_checker.hh:301
The Transaction class captures the lifetimes of read and write operations, and the values they consum...
Definition: mem_checker.hh:108
uint8_t data
Depending on the memory operation, the data value either represents: for writes, the value written up...
Definition: mem_checker.hh:129
Transaction(Serial _serial, Tick _start, Tick _complete, uint8_t _data=DATA_INITIAL)
Definition: mem_checker.hh:111
Serial serial
Unique identifying serial.
Definition: mem_checker.hh:120
bool operator<(const Transaction &rhs) const
Orders Transactions for use with std::map.
Definition: mem_checker.hh:134
Tick complete
Completion tick.
Definition: mem_checker.hh:122
The WriteCluster class captures sets of writes where all writes are overlapping with at least one oth...
Definition: mem_checker.hh:144
void completeWrite(Serial serial, Tick _complete)
Completes a write transaction.
Definition: mem_checker.cc:74
std::unordered_map< Serial, Transaction > writes
Map of Serial --> Transaction of all writes in cluster; contains all, in-flight or already completed.
Definition: mem_checker.hh:190
void abortWrite(Serial serial)
Aborts a write transaction.
Definition: mem_checker.cc:106
void startWrite(Serial serial, Tick _start, uint8_t data)
Starts a write transaction.
Definition: mem_checker.cc:47
Tick start
Start of earliest write in cluster.
Definition: mem_checker.hh:183
Tick complete
Completion of last write in cluster.
Definition: mem_checker.hh:184
MemChecker.
Definition: mem_checker.hh:75
Serial nextSerial
Next distinct serial to be assigned to the next transaction to be started.
Definition: mem_checker.hh:502
ByteTracker * getByteTracker(Addr addr)
Returns the instance of ByteTracker for the requested location.
Definition: mem_checker.hh:482
MemChecker(const MemCheckerParams &p)
Definition: mem_checker.hh:377
void abortWrite(Serial serial, Addr addr, size_t size)
Aborts a previously started write transaction.
Definition: mem_checker.hh:560
bool completeRead(Serial serial, Tick complete, Addr addr, size_t size, uint8_t *data)
Completes a previously started read transaction.
Definition: mem_checker.cc:302
static const uint8_t DATA_INITIAL
Initial data value.
Definition: mem_checker.hh:101
std::unordered_map< Addr, ByteTracker > byte_trackers
Maintain a map of address --> byte-tracker.
Definition: mem_checker.hh:515
static const Tick TICK_FUTURE
The maximum value that curTick() could ever return.
Definition: mem_checker.hh:96
static const Serial SERIAL_INITIAL
Initial serial.
Definition: mem_checker.hh:84
std::list< Transaction > TransactionList
Definition: mem_checker.hh:197
virtual ~MemChecker()
Definition: mem_checker.hh:382
void reset()
Resets the entire checker.
Definition: mem_checker.hh:454
Serial startWrite(Tick start, Addr addr, size_t size, const uint8_t *data)
Starts a write transaction.
Definition: mem_checker.hh:533
const std::string & getErrorMessage() const
In completeRead, if an error is encountered, this does not print nor cause an error,...
Definition: mem_checker.hh:476
uint64_t Serial
The Serial type is used to be able to uniquely identify a transaction as it passes through the system...
Definition: mem_checker.hh:82
Serial startRead(Tick start, Addr addr, size_t size)
Starts a read transaction.
Definition: mem_checker.hh:519
std::string errorMessage
Detailed error message of the last violation in completeRead.
Definition: mem_checker.hh:490
void completeWrite(Serial serial, Tick complete, Addr addr, size_t size)
Completes a previously started write transaction.
Definition: mem_checker.hh:547
static const Tick TICK_INITIAL
The initial tick the system starts with.
Definition: mem_checker.hh:91
std::list< WriteCluster > WriteClusterList
Definition: mem_checker.hh:198
Interface for things with names.
Definition: named.hh:39
virtual std::string name() const
Definition: named.hh:47
Abstract superclass for simulation objects.
Definition: sim_object.hh:148
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 55 > l
Definition: pagetable.hh:54
Bitfield< 54 > p
Definition: pagetable.hh:70
Bitfield< 3 > addr
Definition: types.hh:84
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
const Tick MaxTick
Definition: types.hh:60
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161

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