gem5  v21.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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/trace.hh"
51 #include "base/types.hh"
52 #include "debug/MemChecker.hh"
53 #include "params/MemChecker.hh"
54 #include "sim/core.hh"
55 #include "sim/sim_object.hh"
56 
71 class MemChecker : public SimObject
72 {
73  public:
79  typedef uint64_t Serial;
80 
81  static const Serial SERIAL_INITIAL = 0;
82 
88  static const Tick TICK_INITIAL = 0;
89 
93  static const Tick TICK_FUTURE = MaxTick;
94 
98  static const uint8_t DATA_INITIAL = 0x00;
99 
105  {
106  public:
107 
109  Tick _start, Tick _complete,
110  uint8_t _data = DATA_INITIAL)
111  : serial(_serial),
112  start(_start), complete(_complete),
113  data(_data)
114  {}
115 
116  public:
120 
126  uint8_t data;
127 
131  bool operator<(const Transaction& rhs) const
132  { return serial < rhs.serial; }
133  };
134 
141  {
142  public:
146  {}
147 
156  void startWrite(Serial serial, Tick _start, uint8_t data);
157 
165  void completeWrite(Serial serial, Tick _complete);
166 
172  void abortWrite(Serial serial);
173 
177  bool isComplete() const { return complete != TICK_FUTURE; }
178 
179  public:
182 
187  std::unordered_map<Serial, Transaction> writes;
188 
189  private:
192  };
193 
196 
202  class ByteTracker : public Named
203  {
204  public:
205 
206  ByteTracker(Addr addr = 0, const MemChecker *parent = NULL)
207  : Named((parent != NULL ? parent->name() : "") +
208  csprintf(".ByteTracker@%#llx", addr))
209  {
210  // The initial transaction has start == complete == TICK_INITIAL,
211  // indicating that there has been no real write to this location;
212  // therefore, upon checking, we do not expect any particular value.
213  readObservations.emplace_back(
215  DATA_INITIAL));
216  }
217 
224  void startRead(Serial serial, Tick start);
225 
250  bool inExpectedData(Tick start, Tick complete, uint8_t data);
251 
259  bool completeRead(Serial serial, Tick complete, uint8_t data);
260 
270  void startWrite(Serial serial, Tick start, uint8_t data);
271 
279  void completeWrite(Serial serial, Tick complete);
280 
287  void abortWrite(Serial serial);
288 
299  { return _lastExpectedData; }
300 
301  private:
302 
311 
321  template <class TList>
322  typename TList::iterator lastCompletedTransaction(TList *l, Tick before)
323  {
324  assert(!l->empty());
325 
326  // Scanning backwards increases the chances of getting a match
327  // quicker.
328  auto it = l->end();
329 
330  for (--it; it != l->begin() && it->complete >= before; --it);
331 
332  return it;
333  }
334 
344  void pruneTransactions();
345 
346  private:
347 
354  std::map<Serial, Transaction> outstandingReads;
355 
360 
365 
370  };
371 
372  public:
373 
374  MemChecker(const MemCheckerParams &p)
375  : SimObject(p),
377  {}
378 
379  virtual ~MemChecker() {}
380 
390  Serial startRead(Tick start, Addr addr, size_t size);
391 
402  Serial startWrite(Tick start, Addr addr, size_t size, const uint8_t *data);
403 
417  bool completeRead(Serial serial, Tick complete,
418  Addr addr, size_t size, uint8_t *data);
419 
430  void completeWrite(Serial serial, Tick complete, Addr addr, size_t size);
431 
440  void abortWrite(Serial serial, Addr addr, size_t size);
441 
451  void reset()
452  { byte_trackers.clear(); }
453 
462  void reset(Addr addr, size_t size);
463 
473  const std::string& getErrorMessage() const { return errorMessage; }
474 
475  private:
480  {
481  auto it = byte_trackers.find(addr);
482  if (it == byte_trackers.end()) {
483  it = byte_trackers.insert(
484  std::make_pair(addr, ByteTracker(addr, this))).first;
485  }
486  return &it->second;
487  };
488 
489  private:
493  std::string errorMessage;
494 
500 
512  std::unordered_map<Addr, ByteTracker> byte_trackers;
513 };
514 
515 inline MemChecker::Serial
516 MemChecker::startRead(Tick start, Addr addr, size_t size)
517 {
519  "starting read: serial = %d, start = %d, addr = %#llx, "
520  "size = %d\n", nextSerial, start, addr , size);
521 
522  for (size_t i = 0; i < size; ++i) {
524  }
525 
526  return nextSerial++;
527 }
528 
529 inline MemChecker::Serial
530 MemChecker::startWrite(Tick start, Addr addr, size_t size, const uint8_t *data)
531 {
533  "starting write: serial = %d, start = %d, addr = %#llx, "
534  "size = %d\n", nextSerial, start, addr, size);
535 
536  for (size_t i = 0; i < size; ++i) {
538  }
539 
540  return nextSerial++;
541 }
542 
543 inline void
545  Addr addr, size_t size)
546 {
548  "completing write: serial = %d, complete = %d, "
549  "addr = %#llx, size = %d\n", serial, complete, addr, size);
550 
551  for (size_t i = 0; i < size; ++i) {
552  getByteTracker(addr + i)->completeWrite(serial, complete);
553  }
554 }
555 
556 inline void
558 {
560  "aborting write: serial = %d, addr = %#llx, size = %d\n",
561  serial, addr, size);
562 
563  for (size_t i = 0; i < size; ++i) {
564  getByteTracker(addr + i)->abortWrite(serial);
565  }
566 }
567 
568 #endif // __MEM_MEM_CHECKER_HH__
MemChecker::ByteTracker::startRead
void startRead(Serial serial, Tick start)
Starts a read transaction.
Definition: mem_checker.cc:121
MemChecker::ByteTracker::lastExpectedData
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:298
MemChecker::abortWrite
void abortWrite(Serial serial, Addr addr, size_t size)
Aborts a previously started write transaction.
Definition: mem_checker.hh:557
MemChecker::WriteCluster::abortWrite
void abortWrite(Serial serial)
Aborts a write transaction.
Definition: mem_checker.cc:102
MemChecker::DATA_INITIAL
static const uint8_t DATA_INITIAL
Initial data value.
Definition: mem_checker.hh:98
data
const char data[]
Definition: circlebuf.test.cc:47
MemChecker::MemChecker
MemChecker(const MemCheckerParams &p)
Definition: mem_checker.hh:374
MemChecker::TransactionList
std::list< Transaction > TransactionList
Definition: mem_checker.hh:194
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
MemChecker::ByteTracker::abortWrite
void abortWrite(Serial serial)
Aborts a write transaction.
Definition: mem_checker.cc:272
MemChecker::ByteTracker::outstandingReads
std::map< Serial, Transaction > outstandingReads
Maintains a map of Serial -> Transaction for all outstanding reads.
Definition: mem_checker.hh:354
MemChecker::Transaction::data
uint8_t data
Depending on the memory operation, the data value either represents: for writes, the value written up...
Definition: mem_checker.hh:126
MemChecker::ByteTracker::completeWrite
void completeWrite(Serial serial, Tick complete)
Completes a write transaction.
Definition: mem_checker.cc:264
MemChecker::WriteCluster
The WriteCluster class captures sets of writes where all writes are overlapping with at least one oth...
Definition: mem_checker.hh:140
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:59
MemChecker::getByteTracker
ByteTracker * getByteTracker(Addr addr)
Returns the instance of ByteTracker for the requested location.
Definition: mem_checker.hh:479
std::vector< uint8_t >
MemChecker::ByteTracker::startWrite
void startWrite(Serial serial, Tick start, uint8_t data)
Starts a write transaction.
Definition: mem_checker.cc:257
MemChecker::getErrorMessage
const std::string & getErrorMessage() const
In completeRead, if an error is encountered, this does not print nor cause an error,...
Definition: mem_checker.hh:473
MemChecker::ByteTracker::lastCompletedTransaction
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:322
MemChecker::WriteCluster::startWrite
void startWrite(Serial serial, Tick _start, uint8_t data)
Starts a write transaction.
Definition: mem_checker.cc:43
MemChecker::~MemChecker
virtual ~MemChecker()
Definition: mem_checker.hh:379
MemChecker::WriteCluster::completeWrite
void completeWrite(Serial serial, Tick _complete)
Completes a write transaction.
Definition: mem_checker.cc:70
MemChecker::Transaction::start
Tick start
Start tick.
Definition: mem_checker.hh:118
MemChecker::SERIAL_INITIAL
static const Serial SERIAL_INITIAL
Initial serial.
Definition: mem_checker.hh:81
MemChecker::ByteTracker
The ByteTracker keeps track of transactions for the same byte – all outstanding reads,...
Definition: mem_checker.hh:202
sim_object.hh
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
MemChecker::WriteCluster::writes
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:187
MemChecker::reset
void reset()
Resets the entire checker.
Definition: mem_checker.hh:451
MemChecker::WriteCluster::start
Tick start
Start of earliest write in cluster.
Definition: mem_checker.hh:180
MemChecker::errorMessage
std::string errorMessage
Detailed error message of the last violation in completeRead.
Definition: mem_checker.hh:487
MemChecker::ByteTracker::writeClusters
WriteClusterList writeClusters
List of write clusters for this address.
Definition: mem_checker.hh:364
MemChecker::startWrite
Serial startWrite(Tick start, Addr addr, size_t size, const uint8_t *data)
Starts a write transaction.
Definition: mem_checker.hh:530
MemChecker::ByteTracker::readObservations
TransactionList readObservations
List of completed reads, i.e.
Definition: mem_checker.hh:359
MemChecker::Transaction::serial
Serial serial
Unique identifying serial.
Definition: mem_checker.hh:117
MemChecker::ByteTracker::completeRead
bool completeRead(Serial serial, Tick complete, uint8_t data)
Completes a read transaction that is still outstanding.
Definition: mem_checker.cc:222
cprintf.hh
MemChecker::TICK_INITIAL
static const Tick TICK_INITIAL
The initial tick the system starts with.
Definition: mem_checker.hh:88
MemChecker::ByteTracker::inExpectedData
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:128
MemChecker::Transaction::complete
Tick complete
Completion tick.
Definition: mem_checker.hh:119
core.hh
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:148
MemChecker::Transaction::operator<
bool operator<(const Transaction &rhs) const
Orders Transactions for use with std::map.
Definition: mem_checker.hh:131
Named
Definition: trace.hh:150
MemChecker::WriteClusterList
std::list< WriteCluster > WriteClusterList
Definition: mem_checker.hh:195
X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:80
MemChecker::completeWrite
void completeWrite(Serial serial, Tick complete, Addr addr, size_t size)
Completes a previously started write transaction.
Definition: mem_checker.hh:544
MemChecker::Transaction::Transaction
Transaction(Serial _serial, Tick _start, Tick _complete, uint8_t _data=DATA_INITIAL)
Definition: mem_checker.hh:108
MemChecker::Transaction
The Transaction class captures the lifetimes of read and write operations, and the values they consum...
Definition: mem_checker.hh:104
MemChecker::WriteCluster::isComplete
bool isComplete() const
Definition: mem_checker.hh:177
MemChecker::TICK_FUTURE
static const Tick TICK_FUTURE
The maximum value that curTick() could ever return.
Definition: mem_checker.hh:93
types.hh
MemChecker::ByteTracker::pruneTransactions
void pruneTransactions()
Prunes no longer needed transactions.
Definition: mem_checker.cc:278
MemChecker::startRead
Serial startRead(Tick start, Addr addr, size_t size)
Starts a read transaction.
Definition: mem_checker.hh:516
MemChecker::byte_trackers
std::unordered_map< Addr, ByteTracker > byte_trackers
Maintain a map of address --> byte-tracker.
Definition: mem_checker.hh:512
MemChecker::ByteTracker::getIncompleteWriteCluster
WriteCluster * getIncompleteWriteCluster()
Convenience function to return the most recent incomplete write cluster.
Definition: mem_checker.cc:247
MemChecker::ByteTracker::ByteTracker
ByteTracker(Addr addr=0, const MemChecker *parent=NULL)
Definition: mem_checker.hh:206
MemChecker
MemChecker.
Definition: mem_checker.hh:71
MemChecker::WriteCluster::WriteCluster
WriteCluster()
Definition: mem_checker.hh:143
trace.hh
MemChecker::WriteCluster::complete
Tick complete
Completion of last write in cluster.
Definition: mem_checker.hh:181
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
std::list< Transaction >
Named::name
const std::string & name() const
Definition: trace.hh:159
MemChecker::ByteTracker::_lastExpectedData
std::vector< uint8_t > _lastExpectedData
See lastExpectedData().
Definition: mem_checker.hh:369
MipsISA::l
Bitfield< 5 > l
Definition: pra_constants.hh:320
MemChecker::nextSerial
Serial nextSerial
Next distinct serial to be assigned to the next transaction to be started.
Definition: mem_checker.hh:499
MemChecker::completeRead
bool completeRead(Serial serial, Tick complete, Addr addr, size_t size, uint8_t *data)
Completes a previously started read transaction.
Definition: mem_checker.cc:298
MemChecker::WriteCluster::completeMax
Tick completeMax
Definition: mem_checker.hh:190
MemChecker::WriteCluster::numIncomplete
size_t numIncomplete
Definition: mem_checker.hh:191
MaxTick
const Tick MaxTick
Definition: types.hh:61
csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:158
MemChecker::Serial
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:79
SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:141

Generated on Tue Mar 23 2021 19:41:27 for gem5 by doxygen 1.8.17