gem5  v20.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 <list>
42 #include <map>
43 #include <string>
44 #include <unordered_map>
45 #include <vector>
46 
47 #include "base/logging.hh"
48 #include "base/trace.hh"
49 #include "base/types.hh"
50 #include "debug/MemChecker.hh"
51 #include "params/MemChecker.hh"
52 #include "sim/core.hh"
53 #include "sim/sim_object.hh"
54 
69 class MemChecker : public SimObject
70 {
71  public:
77  typedef uint64_t Serial;
78 
79  static const Serial SERIAL_INITIAL = 0;
80 
86  static const Tick TICK_INITIAL = 0;
87 
91  static const Tick TICK_FUTURE = MaxTick;
92 
96  static const uint8_t DATA_INITIAL = 0x00;
97 
103  {
104  public:
105 
107  Tick _start, Tick _complete,
108  uint8_t _data = DATA_INITIAL)
109  : serial(_serial),
110  start(_start), complete(_complete),
111  data(_data)
112  {}
113 
114  public:
118 
124  uint8_t data;
125 
129  bool operator<(const Transaction& rhs) const
130  { return serial < rhs.serial; }
131  };
132 
139  {
140  public:
144  {}
145 
154  void startWrite(Serial serial, Tick _start, uint8_t data);
155 
163  void completeWrite(Serial serial, Tick _complete);
164 
170  void abortWrite(Serial serial);
171 
175  bool isComplete() const { return complete != TICK_FUTURE; }
176 
177  public:
180 
185  std::unordered_map<Serial, Transaction> writes;
186 
187  private:
190  };
191 
194 
200  class ByteTracker : public Named
201  {
202  public:
203 
204  ByteTracker(Addr addr = 0, const MemChecker *parent = NULL)
205  : Named((parent != NULL ? parent->name() : "") +
206  csprintf(".ByteTracker@%#llx", addr))
207  {
208  // The initial transaction has start == complete == TICK_INITIAL,
209  // indicating that there has been no real write to this location;
210  // therefore, upon checking, we do not expect any particular value.
211  readObservations.emplace_back(
213  DATA_INITIAL));
214  }
215 
222  void startRead(Serial serial, Tick start);
223 
248  bool inExpectedData(Tick start, Tick complete, uint8_t data);
249 
257  bool completeRead(Serial serial, Tick complete, uint8_t data);
258 
268  void startWrite(Serial serial, Tick start, uint8_t data);
269 
277  void completeWrite(Serial serial, Tick complete);
278 
285  void abortWrite(Serial serial);
286 
297  { return _lastExpectedData; }
298 
299  private:
300 
309 
319  template <class TList>
320  typename TList::iterator lastCompletedTransaction(TList *l, Tick before)
321  {
322  assert(!l->empty());
323 
324  // Scanning backwards increases the chances of getting a match
325  // quicker.
326  auto it = l->end();
327 
328  for (--it; it != l->begin() && it->complete >= before; --it);
329 
330  return it;
331  }
332 
342  void pruneTransactions();
343 
344  private:
345 
352  std::map<Serial, Transaction> outstandingReads;
353 
358 
363 
368  };
369 
370  public:
371 
372  MemChecker(const MemCheckerParams *p)
373  : SimObject(p),
375  {}
376 
377  virtual ~MemChecker() {}
378 
388  Serial startRead(Tick start, Addr addr, size_t size);
389 
400  Serial startWrite(Tick start, Addr addr, size_t size, const uint8_t *data);
401 
415  bool completeRead(Serial serial, Tick complete,
416  Addr addr, size_t size, uint8_t *data);
417 
428  void completeWrite(Serial serial, Tick complete, Addr addr, size_t size);
429 
438  void abortWrite(Serial serial, Addr addr, size_t size);
439 
449  void reset()
450  { byte_trackers.clear(); }
451 
460  void reset(Addr addr, size_t size);
461 
471  const std::string& getErrorMessage() const { return errorMessage; }
472 
473  private:
478  {
479  auto it = byte_trackers.find(addr);
480  if (it == byte_trackers.end()) {
481  it = byte_trackers.insert(
482  std::make_pair(addr, ByteTracker(addr, this))).first;
483  }
484  return &it->second;
485  };
486 
487  private:
491  std::string errorMessage;
492 
498 
510  std::unordered_map<Addr, ByteTracker> byte_trackers;
511 };
512 
513 inline MemChecker::Serial
514 MemChecker::startRead(Tick start, Addr addr, size_t size)
515 {
517  "starting read: serial = %d, start = %d, addr = %#llx, "
518  "size = %d\n", nextSerial, start, addr , size);
519 
520  for (size_t i = 0; i < size; ++i) {
522  }
523 
524  return nextSerial++;
525 }
526 
527 inline MemChecker::Serial
528 MemChecker::startWrite(Tick start, Addr addr, size_t size, const uint8_t *data)
529 {
531  "starting write: serial = %d, start = %d, addr = %#llx, "
532  "size = %d\n", nextSerial, start, addr, size);
533 
534  for (size_t i = 0; i < size; ++i) {
536  }
537 
538  return nextSerial++;
539 }
540 
541 inline void
543  Addr addr, size_t size)
544 {
546  "completing write: serial = %d, complete = %d, "
547  "addr = %#llx, size = %d\n", serial, complete, addr, size);
548 
549  for (size_t i = 0; i < size; ++i) {
550  getByteTracker(addr + i)->completeWrite(serial, complete);
551  }
552 }
553 
554 inline void
556 {
558  "aborting write: serial = %d, addr = %#llx, size = %d\n",
559  serial, addr, size);
560 
561  for (size_t i = 0; i < size; ++i) {
562  getByteTracker(addr + i)->abortWrite(serial);
563  }
564 }
565 
566 #endif // __MEM_MEM_CHECKER_HH__
MemChecker::ByteTracker::startRead
void startRead(Serial serial, Tick start)
Starts a read transaction.
Definition: mem_checker.cc:120
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:296
MemChecker::abortWrite
void abortWrite(Serial serial, Addr addr, size_t size)
Aborts a previously started write transaction.
Definition: mem_checker.hh:555
MemChecker::WriteCluster::abortWrite
void abortWrite(Serial serial)
Aborts a write transaction.
Definition: mem_checker.cc:101
MemChecker::DATA_INITIAL
static const uint8_t DATA_INITIAL
Initial data value.
Definition: mem_checker.hh:96
data
const char data[]
Definition: circlebuf.test.cc:42
MemChecker::TransactionList
std::list< Transaction > TransactionList
Definition: mem_checker.hh:192
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:269
MemChecker::ByteTracker::outstandingReads
std::map< Serial, Transaction > outstandingReads
Maintains a map of Serial -> Transaction for all outstanding reads.
Definition: mem_checker.hh:352
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:124
MemChecker::ByteTracker::completeWrite
void completeWrite(Serial serial, Tick complete)
Completes a write transaction.
Definition: mem_checker.cc:262
MemChecker::WriteCluster
The WriteCluster class captures sets of writes where all writes are overlapping with at least one oth...
Definition: mem_checker.hh:138
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
MemChecker::getByteTracker
ByteTracker * getByteTracker(Addr addr)
Returns the instance of ByteTracker for the requested location.
Definition: mem_checker.hh:477
std::vector< uint8_t >
MemChecker::ByteTracker::startWrite
void startWrite(Serial serial, Tick start, uint8_t data)
Starts a write transaction.
Definition: mem_checker.cc:255
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:471
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:320
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:377
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:116
MemChecker::MemChecker
MemChecker(const MemCheckerParams *p)
Definition: mem_checker.hh:372
MemChecker::SERIAL_INITIAL
static const Serial SERIAL_INITIAL
Initial serial.
Definition: mem_checker.hh:79
MemChecker::ByteTracker
The ByteTracker keeps track of transactions for the same byte – all outstanding reads,...
Definition: mem_checker.hh:200
sim_object.hh
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
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:185
MemChecker::reset
void reset()
Resets the entire checker.
Definition: mem_checker.hh:449
MemChecker::WriteCluster::start
Tick start
Start of earliest write in cluster.
Definition: mem_checker.hh:178
MemChecker::errorMessage
std::string errorMessage
Detailed error message of the last violation in completeRead.
Definition: mem_checker.hh:485
MemChecker::ByteTracker::writeClusters
WriteClusterList writeClusters
List of write clusters for this address.
Definition: mem_checker.hh:362
MemChecker::startWrite
Serial startWrite(Tick start, Addr addr, size_t size, const uint8_t *data)
Starts a write transaction.
Definition: mem_checker.hh:528
MemChecker::ByteTracker::readObservations
TransactionList readObservations
List of completed reads, i.e.
Definition: mem_checker.hh:357
MemChecker::Transaction::serial
Serial serial
Unique identifying serial.
Definition: mem_checker.hh:115
MemChecker::ByteTracker::completeRead
bool completeRead(Serial serial, Tick complete, uint8_t data)
Completes a read transaction that is still outstanding.
Definition: mem_checker.cc:220
MemChecker::TICK_INITIAL
static const Tick TICK_INITIAL
The initial tick the system starts with.
Definition: mem_checker.hh:86
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:127
MemChecker::Transaction::complete
Tick complete
Completion tick.
Definition: mem_checker.hh:117
core.hh
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
MemChecker::Transaction::operator<
bool operator<(const Transaction &rhs) const
Orders Transactions for use with std::map.
Definition: mem_checker.hh:129
Named
Definition: trace.hh:147
MemChecker::WriteClusterList
std::list< WriteCluster > WriteClusterList
Definition: mem_checker.hh:193
MemChecker::completeWrite
void completeWrite(Serial serial, Tick complete, Addr addr, size_t size)
Completes a previously started write transaction.
Definition: mem_checker.hh:542
MemChecker::Transaction::Transaction
Transaction(Serial _serial, Tick _start, Tick _complete, uint8_t _data=DATA_INITIAL)
Definition: mem_checker.hh:106
MemChecker::Transaction
The Transaction class captures the lifetimes of read and write operations, and the values they consum...
Definition: mem_checker.hh:102
MemChecker::WriteCluster::isComplete
bool isComplete() const
Definition: mem_checker.hh:175
MemChecker::TICK_FUTURE
static const Tick TICK_FUTURE
The maximum value that curTick() could ever return.
Definition: mem_checker.hh:91
types.hh
MemChecker::ByteTracker::pruneTransactions
void pruneTransactions()
Prunes no longer needed transactions.
Definition: mem_checker.cc:275
addr
ip6_addr_t addr
Definition: inet.hh:423
MemChecker::startRead
Serial startRead(Tick start, Addr addr, size_t size)
Starts a read transaction.
Definition: mem_checker.hh:514
MemChecker::byte_trackers
std::unordered_map< Addr, ByteTracker > byte_trackers
Maintain a map of address --> byte-tracker.
Definition: mem_checker.hh:510
logging.hh
MemChecker::ByteTracker::getIncompleteWriteCluster
WriteCluster * getIncompleteWriteCluster()
Convenience function to return the most recent incomplete write cluster.
Definition: mem_checker.cc:245
MemChecker::ByteTracker::ByteTracker
ByteTracker(Addr addr=0, const MemChecker *parent=NULL)
Definition: mem_checker.hh:204
MemChecker
MemChecker.
Definition: mem_checker.hh:69
MemChecker::WriteCluster::WriteCluster
WriteCluster()
Definition: mem_checker.hh:141
trace.hh
MemChecker::WriteCluster::complete
Tick complete
Completion of last write in cluster.
Definition: mem_checker.hh:179
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
std::list< Transaction >
Named::name
const std::string & name() const
Definition: trace.hh:156
MemChecker::ByteTracker::_lastExpectedData
std::vector< uint8_t > _lastExpectedData
See lastExpectedData().
Definition: mem_checker.hh:367
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:497
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:295
MemChecker::WriteCluster::completeMax
Tick completeMax
Definition: mem_checker.hh:188
MemChecker::WriteCluster::numIncomplete
size_t numIncomplete
Definition: mem_checker.hh:189
MaxTick
const Tick MaxTick
Definition: types.hh:65
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:77
SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:92

Generated on Wed Sep 30 2020 14:02:13 for gem5 by doxygen 1.8.17