gem5
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  * Authors: Rune Holm
38  * Marco Elver
39  */
40 
41 #ifndef __MEM_MEM_CHECKER_HH__
42 #define __MEM_MEM_CHECKER_HH__
43 
44 #include <list>
45 #include <map>
46 #include <string>
47 #include <unordered_map>
48 #include <vector>
49 
50 #include "base/logging.hh"
51 #include "base/trace.hh"
52 #include "base/types.hh"
53 #include "debug/MemChecker.hh"
54 #include "params/MemChecker.hh"
55 #include "sim/core.hh"
56 #include "sim/sim_object.hh"
57 
72 class MemChecker : public SimObject
73 {
74  public:
80  typedef uint64_t Serial;
81 
82  static const Serial SERIAL_INITIAL = 0;
83 
89  static const Tick TICK_INITIAL = 0;
90 
94  static const Tick TICK_FUTURE = MaxTick;
95 
99  static const uint8_t DATA_INITIAL = 0x00;
100 
106  {
107  public:
108 
109  Transaction(Serial _serial,
110  Tick _start, Tick _complete,
111  uint8_t _data = DATA_INITIAL)
112  : serial(_serial),
113  start(_start), complete(_complete),
114  data(_data)
115  {}
116 
117  public:
118  Serial serial;
121 
127  uint8_t data;
128 
132  bool operator<(const Transaction& rhs) const
133  { return serial < rhs.serial; }
134  };
135 
142  {
143  public:
145  : start(TICK_FUTURE), complete(TICK_FUTURE),
146  completeMax(TICK_INITIAL), numIncomplete(0)
147  {}
148 
157  void startWrite(Serial serial, Tick _start, uint8_t data);
158 
166  void completeWrite(Serial serial, Tick _complete);
167 
173  void abortWrite(Serial serial);
174 
178  bool isComplete() const { return complete != TICK_FUTURE; }
179 
180  public:
183 
188  std::unordered_map<Serial, Transaction> writes;
189 
190  private:
193  };
194 
197 
203  class ByteTracker : public Named
204  {
205  public:
206 
207  ByteTracker(Addr addr = 0, const MemChecker *parent = NULL)
208  : Named((parent != NULL ? parent->name() : "") +
209  csprintf(".ByteTracker@%#llx", addr))
210  {
211  // The initial transaction has start == complete == TICK_INITIAL,
212  // indicating that there has been no real write to this location;
213  // therefore, upon checking, we do not expect any particular value.
214  readObservations.emplace_back(
215  Transaction(SERIAL_INITIAL, TICK_INITIAL, TICK_INITIAL,
216  DATA_INITIAL));
217  }
218 
225  void startRead(Serial serial, Tick start);
226 
251  bool inExpectedData(Tick start, Tick complete, uint8_t data);
252 
260  bool completeRead(Serial serial, Tick complete, uint8_t data);
261 
271  void startWrite(Serial serial, Tick start, uint8_t data);
272 
280  void completeWrite(Serial serial, Tick complete);
281 
288  void abortWrite(Serial serial);
289 
300  { return _lastExpectedData; }
301 
302  private:
303 
311  WriteCluster* getIncompleteWriteCluster();
312 
322  template <class TList>
323  typename TList::iterator lastCompletedTransaction(TList *l, Tick before)
324  {
325  assert(!l->empty());
326 
327  // Scanning backwards increases the chances of getting a match
328  // quicker.
329  auto it = l->end();
330 
331  for (--it; it != l->begin() && it->complete >= before; --it);
332 
333  return it;
334  }
335 
345  void pruneTransactions();
346 
347  private:
348 
355  std::map<Serial, Transaction> outstandingReads;
356 
360  TransactionList readObservations;
361 
365  WriteClusterList writeClusters;
366 
371  };
372 
373  public:
374 
375  MemChecker(const MemCheckerParams *p)
376  : SimObject(p),
377  nextSerial(SERIAL_INITIAL)
378  {}
379 
380  virtual ~MemChecker() {}
381 
391  Serial startRead(Tick start, Addr addr, size_t size);
392 
403  Serial startWrite(Tick start, Addr addr, size_t size, const uint8_t *data);
404 
418  bool completeRead(Serial serial, Tick complete,
419  Addr addr, size_t size, uint8_t *data);
420 
431  void completeWrite(Serial serial, Tick complete, Addr addr, size_t size);
432 
441  void abortWrite(Serial serial, Addr addr, size_t size);
442 
452  void reset()
453  { byte_trackers.clear(); }
454 
463  void reset(Addr addr, size_t size);
464 
474  const std::string& getErrorMessage() const { return errorMessage; }
475 
476  private:
481  {
482  auto it = byte_trackers.find(addr);
483  if (it == byte_trackers.end()) {
484  it = byte_trackers.insert(
485  std::make_pair(addr, ByteTracker(addr, this))).first;
486  }
487  return &it->second;
488  };
489 
490  private:
494  std::string errorMessage;
495 
500  Serial nextSerial;
501 
513  std::unordered_map<Addr, ByteTracker> byte_trackers;
514 };
515 
516 inline MemChecker::Serial
518 {
520  "starting read: serial = %d, start = %d, addr = %#llx, "
521  "size = %d\n", nextSerial, start, addr , size);
522 
523  for (size_t i = 0; i < size; ++i) {
524  getByteTracker(addr + i)->startRead(nextSerial, start);
525  }
526 
527  return nextSerial++;
528 }
529 
530 inline MemChecker::Serial
531 MemChecker::startWrite(Tick start, Addr addr, size_t size, const uint8_t *data)
532 {
534  "starting write: serial = %d, start = %d, addr = %#llx, "
535  "size = %d\n", nextSerial, start, addr, size);
536 
537  for (size_t i = 0; i < size; ++i) {
538  getByteTracker(addr + i)->startWrite(nextSerial, start, data[i]);
539  }
540 
541  return nextSerial++;
542 }
543 
544 inline void
546  Addr addr, size_t size)
547 {
549  "completing write: serial = %d, complete = %d, "
550  "addr = %#llx, size = %d\n", serial, complete, addr, size);
551 
552  for (size_t i = 0; i < size; ++i) {
553  getByteTracker(addr + i)->completeWrite(serial, complete);
554  }
555 }
556 
557 inline void
559 {
561  "aborting write: serial = %d, addr = %#llx, size = %d\n",
562  serial, addr, size);
563 
564  for (size_t i = 0; i < size; ++i) {
565  getByteTracker(addr + i)->abortWrite(serial);
566  }
567 }
568 
569 #endif // __MEM_MEM_CHECKER_HH__
#define DPRINTF(x,...)
Definition: trace.hh:212
std::list< WriteCluster > WriteClusterList
Definition: mem_checker.hh:196
static const Serial SERIAL_INITIAL
Initial serial.
Definition: mem_checker.hh:82
void completeWrite(Serial serial, Tick complete, Addr addr, size_t size)
Completes a previously started write transaction.
Definition: mem_checker.hh:545
ByteTracker(Addr addr=0, const MemChecker *parent=NULL)
Definition: mem_checker.hh:207
static const uint8_t DATA_INITIAL
Initial data value.
Definition: mem_checker.hh:99
Bitfield< 7 > i
Definition: miscregs.hh:1412
Tick complete
Completion tick.
Definition: mem_checker.hh:120
void abortWrite(Serial serial, Addr addr, size_t size)
Aborts a previously started write transaction.
Definition: mem_checker.hh:558
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
TransactionList readObservations
List of completed reads, i.e.
Definition: mem_checker.hh:360
ByteTracker * getByteTracker(Addr addr)
Returns the instance of ByteTracker for the requested location.
Definition: mem_checker.hh:480
ip6_addr_t addr
Definition: inet.hh:335
WriteClusterList writeClusters
List of write clusters for this address.
Definition: mem_checker.hh:365
std::vector< uint8_t > _lastExpectedData
See lastExpectedData().
Definition: mem_checker.hh:370
The Transaction class captures the lifetimes of read and write operations, and the values they consum...
Definition: mem_checker.hh:105
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:188
Serial nextSerial
Next distinct serial to be assigned to the next transaction to be started.
Definition: mem_checker.hh:500
bool operator<(const Transaction &rhs) const
Orders Transactions for use with std::map.
Definition: mem_checker.hh:132
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:299
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:80
MemChecker(const MemCheckerParams *p)
Definition: mem_checker.hh:375
Definition: trace.hh:140
MemChecker.
Definition: mem_checker.hh:72
const std::string & getErrorMessage() const
In completeRead, if an error is encountered, this does not print nor cause an error, but instead should be handled by the caller.
Definition: mem_checker.hh:474
const Tick MaxTick
Definition: types.hh:65
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
std::unordered_map< Addr, ByteTracker > byte_trackers
Maintain a map of address –> byte-tracker.
Definition: mem_checker.hh:513
uint64_t Tick
Tick count type.
Definition: types.hh:63
The ByteTracker keeps track of transactions for the same byte – all outstanding reads, the completed reads (and what they observed) and write clusters (see WriteCluster).
Definition: mem_checker.hh:203
void reset()
Resets the entire checker.
Definition: mem_checker.hh:452
std::string errorMessage
Detailed error message of the last violation in completeRead.
Definition: mem_checker.hh:488
virtual ~MemChecker()
Definition: mem_checker.hh:380
void completeWrite(Serial serial, Tick complete)
Completes a write transaction.
Definition: mem_checker.cc:265
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
virtual const std::string name() const
Definition: sim_object.hh:117
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:323
void startWrite(Serial serial, Tick start, uint8_t data)
Starts a write transaction.
Definition: mem_checker.cc:258
static const Tick TICK_INITIAL
The initial tick the system starts with.
Definition: mem_checker.hh:89
The WriteCluster class captures sets of writes where all writes are overlapping with at least one oth...
Definition: mem_checker.hh:141
Tick start
Start of earliest write in cluster.
Definition: mem_checker.hh:181
std::list< Transaction > TransactionList
Definition: mem_checker.hh:195
void abortWrite(Serial serial)
Aborts a write transaction.
Definition: mem_checker.cc:272
Serial startWrite(Tick start, Addr addr, size_t size, const uint8_t *data)
Starts a write transaction.
Definition: mem_checker.hh:531
uint8_t data
Depending on the memory operation, the data value either represents: for writes, the value written up...
Definition: mem_checker.hh:127
Transaction(Serial _serial, Tick _start, Tick _complete, uint8_t _data=DATA_INITIAL)
Definition: mem_checker.hh:109
std::map< Serial, Transaction > outstandingReads
Maintains a map of Serial -> Transaction for all outstanding reads.
Definition: mem_checker.hh:355
Tick start
Start tick.
Definition: mem_checker.hh:119
Serial serial
Unique identifying serial.
Definition: mem_checker.hh:118
static const Tick TICK_FUTURE
The maximum value that curTick() could ever return.
Definition: mem_checker.hh:94
Tick complete
Completion of last write in cluster.
Definition: mem_checker.hh:182
Bitfield< 0 > p
Serial startRead(Tick start, Addr addr, size_t size)
Starts a read transaction.
Definition: mem_checker.hh:517
Bitfield< 5 > l
Abstract superclass for simulation objects.
Definition: sim_object.hh:94
void startRead(Serial serial, Tick start)
Starts a read transaction.
Definition: mem_checker.cc:123

Generated on Fri Apr 20 2018 09:05:03 for gem5 by doxygen 1.8.13