gem5  v22.1.0.0
abstract_mem.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2012,2017-2019 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) 2001-2005 The Regents of The University of Michigan
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 #include "mem/abstract_mem.hh"
42 
43 #include <vector>
44 
47 #include "cpu/thread_context.hh"
48 #include "debug/LLSC.hh"
49 #include "debug/MemoryAccess.hh"
50 #include "mem/packet_access.hh"
51 #include "sim/system.hh"
52 
53 namespace gem5
54 {
55 
56 namespace memory
57 {
58 
60  ClockedObject(p), range(p.range), pmemAddr(NULL),
61  backdoor(params().range, nullptr,
62  (MemBackdoor::Flags)(MemBackdoor::Readable |
63  MemBackdoor::Writeable)),
64  confTableReported(p.conf_table_reported), inAddrMap(p.in_addr_map),
65  kvmMap(p.kvm_map), _system(NULL),
66  stats(*this)
67 {
68  panic_if(!range.valid() || !range.size(),
69  "Memory range %s must be valid with non-zero size.",
70  range.to_string());
71 }
72 
73 void
75 {
77 
78  const auto &file = params().image_file;
79  if (file == "")
80  return;
81 
82  auto *object = loader::createObjectFile(file, true);
83  fatal_if(!object, "%s: Could not load %s.", name(), file);
84 
85  loader::debugSymbolTable.insert(*object->symtab().globals());
86  loader::MemoryImage image = object->buildImage();
87 
88  AddrRange image_range(image.minAddr(), image.maxAddr());
89  if (!range.contains(image_range.start())) {
90  warn("%s: Moving image from %s to memory address range %s.",
91  name(), image_range.to_string(), range.to_string());
92  image = image.offset(range.start());
93  image_range = AddrRange(image.minAddr(), image.maxAddr());
94  }
95  panic_if(!image_range.isSubset(range), "%s: memory image %s doesn't fit.",
96  name(), file);
97 
98  PortProxy proxy([this](PacketPtr pkt) { functionalAccess(pkt); },
99  system()->cacheLineSize());
100 
101  panic_if(!image.write(proxy), "%s: Unable to write image.");
102 }
103 
104 void
106 {
107  // If there was an existing backdoor, let everybody know it's going away.
108  if (backdoor.ptr())
110 
111  // The back door can't handle interleaved memory.
112  backdoor.ptr(range.interleaved() ? nullptr : pmem_addr);
113 
114  pmemAddr = pmem_addr;
115 }
116 
118  : statistics::Group(&_mem), mem(_mem),
119  ADD_STAT(bytesRead, statistics::units::Byte::get(),
120  "Number of bytes read from this memory"),
121  ADD_STAT(bytesInstRead, statistics::units::Byte::get(),
122  "Number of instructions bytes read from this memory"),
123  ADD_STAT(bytesWritten, statistics::units::Byte::get(),
124  "Number of bytes written to this memory"),
125  ADD_STAT(numReads, statistics::units::Count::get(),
126  "Number of read requests responded to by this memory"),
127  ADD_STAT(numWrites, statistics::units::Count::get(),
128  "Number of write requests responded to by this memory"),
129  ADD_STAT(numOther, statistics::units::Count::get(),
130  "Number of other requests responded to by this memory"),
131  ADD_STAT(bwRead, statistics::units::Rate<
132  statistics::units::Byte, statistics::units::Second>::get(),
133  "Total read bandwidth from this memory"),
134  ADD_STAT(bwInstRead,
135  statistics::units::Rate<
136  statistics::units::Byte, statistics::units::Second>::get(),
137  "Instruction read bandwidth from this memory"),
138  ADD_STAT(bwWrite, statistics::units::Rate<
139  statistics::units::Byte, statistics::units::Second>::get(),
140  "Write bandwidth from this memory"),
141  ADD_STAT(bwTotal, statistics::units::Rate<
142  statistics::units::Byte, statistics::units::Second>::get(),
143  "Total bandwidth to/from this memory")
144 {
145 }
146 
147 void
149 {
150  using namespace statistics;
151 
153 
154  System *sys = mem.system();
155  assert(sys);
156  const auto max_requestors = sys->maxRequestors();
157 
158  bytesRead
159  .init(max_requestors)
160  .flags(total | nozero | nonan)
161  ;
162  for (int i = 0; i < max_requestors; i++) {
163  bytesRead.subname(i, sys->getRequestorName(i));
164  }
165 
166  bytesInstRead
167  .init(max_requestors)
168  .flags(total | nozero | nonan)
169  ;
170  for (int i = 0; i < max_requestors; i++) {
171  bytesInstRead.subname(i, sys->getRequestorName(i));
172  }
173 
174  bytesWritten
175  .init(max_requestors)
176  .flags(total | nozero | nonan)
177  ;
178  for (int i = 0; i < max_requestors; i++) {
179  bytesWritten.subname(i, sys->getRequestorName(i));
180  }
181 
182  numReads
183  .init(max_requestors)
184  .flags(total | nozero | nonan)
185  ;
186  for (int i = 0; i < max_requestors; i++) {
187  numReads.subname(i, sys->getRequestorName(i));
188  }
189 
190  numWrites
191  .init(max_requestors)
192  .flags(total | nozero | nonan)
193  ;
194  for (int i = 0; i < max_requestors; i++) {
195  numWrites.subname(i, sys->getRequestorName(i));
196  }
197 
198  numOther
199  .init(max_requestors)
200  .flags(total | nozero | nonan)
201  ;
202  for (int i = 0; i < max_requestors; i++) {
203  numOther.subname(i, sys->getRequestorName(i));
204  }
205 
206  bwRead
207  .precision(0)
208  .prereq(bytesRead)
209  .flags(total | nozero | nonan)
210  ;
211  for (int i = 0; i < max_requestors; i++) {
212  bwRead.subname(i, sys->getRequestorName(i));
213  }
214 
215  bwInstRead
216  .precision(0)
217  .prereq(bytesInstRead)
218  .flags(total | nozero | nonan)
219  ;
220  for (int i = 0; i < max_requestors; i++) {
221  bwInstRead.subname(i, sys->getRequestorName(i));
222  }
223 
224  bwWrite
225  .precision(0)
226  .prereq(bytesWritten)
227  .flags(total | nozero | nonan)
228  ;
229  for (int i = 0; i < max_requestors; i++) {
230  bwWrite.subname(i, sys->getRequestorName(i));
231  }
232 
233  bwTotal
234  .precision(0)
235  .prereq(bwTotal)
236  .flags(total | nozero | nonan)
237  ;
238  for (int i = 0; i < max_requestors; i++) {
239  bwTotal.subname(i, sys->getRequestorName(i));
240  }
241 
242  bwRead = bytesRead / simSeconds;
243  bwInstRead = bytesInstRead / simSeconds;
244  bwWrite = bytesWritten / simSeconds;
245  bwTotal = (bytesRead + bytesWritten) / simSeconds;
246 }
247 
248 AddrRange
250 {
251  return range;
252 }
253 
254 // Add load-locked to tracking list. Should only be called if the
255 // operation is a load and the LLSC flag is set.
256 void
258 {
259  const RequestPtr &req = pkt->req;
260  Addr paddr = LockedAddr::mask(req->getPaddr());
261 
262  // first we check if we already have a locked addr for this
263  // xc. Since each xc only gets one, we just update the
264  // existing record with the new address.
266 
267  for (i = lockedAddrList.begin(); i != lockedAddrList.end(); ++i) {
268  if (i->matchesContext(req)) {
269  DPRINTF(LLSC, "Modifying lock record: context %d addr %#x\n",
270  req->contextId(), paddr);
271  i->addr = paddr;
272  return;
273  }
274  }
275 
276  // no record for this xc: need to allocate a new one
277  DPRINTF(LLSC, "Adding lock record: context %d addr %#x\n",
278  req->contextId(), paddr);
279  lockedAddrList.push_front(LockedAddr(req));
281 }
282 
283 
284 // Called on *writes* only... both regular stores and
285 // store-conditional operations. Check for conventional stores which
286 // conflict with locked addresses, and for success/failure of store
287 // conditionals.
288 bool
290 {
291  const RequestPtr &req = pkt->req;
292  Addr paddr = LockedAddr::mask(req->getPaddr());
293  bool isLLSC = pkt->isLLSC();
294 
295  // Initialize return value. Non-conditional stores always
296  // succeed. Assume conditional stores will fail until proven
297  // otherwise.
298  bool allowStore = !isLLSC;
299 
300  // Iterate over list. Note that there could be multiple matching records,
301  // as more than one context could have done a load locked to this location.
302  // Only remove records when we succeed in finding a record for (xc, addr);
303  // then, remove all records with this address. Failed store-conditionals do
304  // not blow unrelated reservations.
306 
307  if (isLLSC) {
308  while (i != lockedAddrList.end()) {
309  if (i->addr == paddr && i->matchesContext(req)) {
310  // it's a store conditional, and as far as the memory system can
311  // tell, the requesting context's lock is still valid.
312  DPRINTF(LLSC, "StCond success: context %d addr %#x\n",
313  req->contextId(), paddr);
314  allowStore = true;
315  break;
316  }
317  // If we didn't find a match, keep searching! Someone else may well
318  // have a reservation on this line here but we may find ours in just
319  // a little while.
320  i++;
321  }
322  req->setExtraData(allowStore ? 1 : 0);
323  }
324  // LLSCs that succeeded AND non-LLSC stores both fall into here:
325  if (allowStore) {
326  // We write address paddr. However, there may be several entries with a
327  // reservation on this address (for other contextIds) and they must all
328  // be removed.
329  i = lockedAddrList.begin();
330  while (i != lockedAddrList.end()) {
331  if (i->addr == paddr) {
332  DPRINTF(LLSC, "Erasing lock record: context %d addr %#x\n",
333  i->contextId, paddr);
334  ContextID owner_cid = i->contextId;
335  assert(owner_cid != InvalidContextID);
336  ContextID requestor_cid = req->hasContextId() ?
337  req->contextId() :
339  if (owner_cid != requestor_cid) {
340  ThreadContext* ctx = system()->threads[owner_cid];
342  }
343  i = lockedAddrList.erase(i);
344  } else {
345  i++;
346  }
347  }
348  }
349 
350  return allowStore;
351 }
352 
353 #if TRACING_ON
354 static inline void
355 tracePacket(System *sys, const char *label, PacketPtr pkt)
356 {
357  int size = pkt->getSize();
358  if (size == 1 || size == 2 || size == 4 || size == 8) {
359  ByteOrder byte_order = sys->getGuestByteOrder();
360  DPRINTF(MemoryAccess, "%s from %s of size %i on address %#x data "
361  "%#x %c\n", label, sys->getRequestorName(pkt->req->
362  requestorId()), size, pkt->getAddr(),
363  pkt->getUintX(byte_order),
364  pkt->req->isUncacheable() ? 'U' : 'C');
365  return;
366  }
367  DPRINTF(MemoryAccess, "%s from %s of size %i on address %#x %c\n",
368  label, sys->getRequestorName(pkt->req->requestorId()),
369  size, pkt->getAddr(), pkt->req->isUncacheable() ? 'U' : 'C');
370  DDUMP(MemoryAccess, pkt->getConstPtr<uint8_t>(), pkt->getSize());
371 }
372 
373 # define TRACE_PACKET(A) tracePacket(system(), A, pkt)
374 #else
375 # define TRACE_PACKET(A)
376 #endif
377 
378 void
380 {
381  if (pkt->cacheResponding()) {
382  DPRINTF(MemoryAccess, "Cache responding to %#llx: not responding\n",
383  pkt->getAddr());
384  return;
385  }
386 
387  if (pkt->cmd == MemCmd::CleanEvict || pkt->cmd == MemCmd::WritebackClean) {
388  DPRINTF(MemoryAccess, "CleanEvict on 0x%x: not responding\n",
389  pkt->getAddr());
390  return;
391  }
392 
393  assert(pkt->getAddrRange().isSubset(range));
394 
395  uint8_t *host_addr = toHostAddr(pkt->getAddr());
396 
397  if (pkt->cmd == MemCmd::SwapReq) {
398  if (pkt->isAtomicOp()) {
399  if (pmemAddr) {
400  pkt->setData(host_addr);
401  (*(pkt->getAtomicOp()))(host_addr);
402  }
403  } else {
404  std::vector<uint8_t> overwrite_val(pkt->getSize());
405  uint64_t condition_val64;
406  uint32_t condition_val32;
407 
408  panic_if(!pmemAddr, "Swap only works if there is real memory " \
409  "(i.e. null=False)");
410 
411  bool overwrite_mem = true;
412  // keep a copy of our possible write value, and copy what is at the
413  // memory address into the packet
414  pkt->writeData(&overwrite_val[0]);
415  pkt->setData(host_addr);
416 
417  if (pkt->req->isCondSwap()) {
418  if (pkt->getSize() == sizeof(uint64_t)) {
419  condition_val64 = pkt->req->getExtraData();
420  overwrite_mem = !std::memcmp(&condition_val64, host_addr,
421  sizeof(uint64_t));
422  } else if (pkt->getSize() == sizeof(uint32_t)) {
423  condition_val32 = (uint32_t)pkt->req->getExtraData();
424  overwrite_mem = !std::memcmp(&condition_val32, host_addr,
425  sizeof(uint32_t));
426  } else
427  panic("Invalid size for conditional read/write\n");
428  }
429 
430  if (overwrite_mem)
431  std::memcpy(host_addr, &overwrite_val[0], pkt->getSize());
432 
433  assert(!pkt->req->isInstFetch());
434  TRACE_PACKET("Read/Write");
435  stats.numOther[pkt->req->requestorId()]++;
436  }
437  } else if (pkt->isRead()) {
438  assert(!pkt->isWrite());
439  if (pkt->isLLSC()) {
440  assert(!pkt->fromCache());
441  // if the packet is not coming from a cache then we have
442  // to do the LL/SC tracking here
443  trackLoadLocked(pkt);
444  }
445  if (pmemAddr) {
446  pkt->setData(host_addr);
447  }
448  TRACE_PACKET(pkt->req->isInstFetch() ? "IFetch" : "Read");
449  stats.numReads[pkt->req->requestorId()]++;
450  stats.bytesRead[pkt->req->requestorId()] += pkt->getSize();
451  if (pkt->req->isInstFetch())
452  stats.bytesInstRead[pkt->req->requestorId()] += pkt->getSize();
453  } else if (pkt->isInvalidate() || pkt->isClean()) {
454  assert(!pkt->isWrite());
455  // in a fastmem system invalidating and/or cleaning packets
456  // can be seen due to cache maintenance requests
457 
458  // no need to do anything
459  } else if (pkt->isWrite()) {
460  if (writeOK(pkt)) {
461  if (pmemAddr) {
462  pkt->writeData(host_addr);
463  DPRINTF(MemoryAccess, "%s write due to %s\n",
464  __func__, pkt->print());
465  }
466  assert(!pkt->req->isInstFetch());
467  TRACE_PACKET("Write");
468  stats.numWrites[pkt->req->requestorId()]++;
469  stats.bytesWritten[pkt->req->requestorId()] += pkt->getSize();
470  }
471  } else {
472  panic("Unexpected packet %s", pkt->print());
473  }
474 
475  if (pkt->needsResponse()) {
476  pkt->makeResponse();
477  }
478 }
479 
480 void
482 {
483  assert(pkt->getAddrRange().isSubset(range));
484 
485  uint8_t *host_addr = toHostAddr(pkt->getAddr());
486 
487  if (pkt->isRead()) {
488  if (pmemAddr) {
489  pkt->setData(host_addr);
490  }
491  TRACE_PACKET("Read");
492  pkt->makeResponse();
493  } else if (pkt->isWrite()) {
494  if (pmemAddr) {
495  pkt->writeData(host_addr);
496  }
497  TRACE_PACKET("Write");
498  pkt->makeResponse();
499  } else if (pkt->isPrint()) {
500  Packet::PrintReqState *prs =
501  dynamic_cast<Packet::PrintReqState*>(pkt->senderState);
502  assert(prs);
503  // Need to call printLabels() explicitly since we're not going
504  // through printObj().
505  prs->printLabels();
506  // Right now we just print the single byte at the specified address.
507  ccprintf(prs->os, "%s%#x\n", prs->curPrefix(), *host_addr);
508  } else {
509  panic("AbstractMemory: unimplemented functional command %s",
510  pkt->cmdString());
511  }
512 }
513 
514 } // namespace memory
515 } // namespace gem5
#define TRACE_PACKET(A)
AbstractMemory declaration.
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
Definition: trace.hh:180
#define DPRINTF(x,...)
Definition: trace.hh:186
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition: addr_range.hh:82
virtual void globalClearExclusive()
Definition: isa.hh:120
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
ClockedObjectParams Params
Parameters of ClockedObject.
Wrapper that groups a few flag bits under the same undelying container.
Definition: flags.hh:45
uint8_t * ptr() const
Definition: backdoor.hh:62
@ WritebackClean
Definition: packet.hh:93
@ CleanEvict
Definition: packet.hh:95
virtual std::string name() const
Definition: named.hh:47
Object used to maintain state of a PrintReq.
Definition: packet.hh:479
const std::string & curPrefix()
Returns the current line prefix.
Definition: packet.hh:507
void printLabels()
Print all of the pending unprinted labels on the stack.
Definition: packet.cc:453
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
bool isRead() const
Definition: packet.hh:592
Addr getAddr() const
Definition: packet.hh:805
AtomicOpFunctor * getAtomicOp() const
Accessor function to atomic op.
Definition: packet.hh:843
bool isAtomicOp() const
Definition: packet.hh:844
AddrRange getAddrRange() const
Get address range to which this packet belongs.
Definition: packet.cc:243
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
Definition: packet.cc:368
bool needsResponse() const
Definition: packet.hh:607
SenderState * senderState
This packet's sender state.
Definition: packet.hh:544
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
Definition: packet.hh:1059
bool fromCache() const
Definition: packet.hh:611
void setData(const uint8_t *p)
Copy data into the packet from the provided pointer.
Definition: packet.hh:1280
bool isWrite() const
Definition: packet.hh:593
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
Definition: packet.hh:587
RequestPtr req
A pointer to the original request.
Definition: packet.hh:376
bool isPrint() const
Definition: packet.hh:622
unsigned getSize() const
Definition: packet.hh:815
bool isClean() const
Definition: packet.hh:610
uint64_t getUintX(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness and zero-extended to 64 bits.
Definition: packet.cc:352
const T * getConstPtr() const
Definition: packet.hh:1221
bool isLLSC() const
Definition: packet.hh:619
bool cacheResponding() const
Definition: packet.hh:657
MemCmd cmd
The command field of the packet.
Definition: packet.hh:371
bool isInvalidate() const
Definition: packet.hh:608
void writeData(uint8_t *p) const
Copy data from the packet to the memory at the provided pointer.
Definition: packet.hh:1309
This object is a proxy for a port or other object which implements the functional response protocol,...
Definition: port_proxy.hh:87
unsigned int cacheLineSize() const
Get the cache line size of the system.
Definition: system.hh:311
std::string getRequestorName(RequestorID requestor_id)
Get the name of an object for a given request id.
Definition: system.cc:526
RequestorID maxRequestors()
Get the number of requestors registered in the system.
Definition: system.hh:498
ByteOrder getGuestByteOrder() const
Get the guest byte order.
Definition: system.hh:391
Threads threads
Definition: system.hh:313
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual BaseISA * getIsaPtr() const =0
MemoryImage & offset(Addr by)
bool write(const PortProxy &proxy) const
Definition: memory_image.cc:54
bool insert(const Symbol &symbol)
Insert a new symbol in the table if it does not already exist.
Definition: symtab.cc:55
An abstract memory represents a contiguous block of physical memory, with an associated address range...
void access(PacketPtr pkt)
Perform an untimed memory access and update all the state (e.g.
uint64_t size() const
Get the memory size.
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition: abstract_mem.cc:74
void trackLoadLocked(PacketPtr pkt)
void setBackingStore(uint8_t *pmem_addr)
Set the host memory backing store to be used by this memory controller.
System * system() const
read the system pointer Implemented for completeness with the setter
AbstractMemory(const AbstractMemory &)
bool checkLockedAddrList(PacketPtr pkt)
void functionalAccess(PacketPtr pkt)
Perform an untimed memory read or write without changing anything but the memory itself.
AddrRange getAddrRange() const
Get the address range.
std::list< LockedAddr > lockedAddrList
gem5::memory::AbstractMemory::MemStats stats
uint8_t * toHostAddr(Addr addr) const
Transform a gem5 address space address into its physical counterpart in the host address space.
bool writeOK(PacketPtr pkt)
Locked address class that represents a physical address and a context id.
Definition: abstract_mem.hh:68
static Addr mask(Addr paddr)
Definition: abstract_mem.hh:84
Statistics container.
Definition: group.hh:94
STL list class.
Definition: stl.hh:51
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
bool interleaved() const
Determine if the range is interleaved or not.
Definition: addr_range.hh:284
bool isSubset(const AddrRange &r) const
Determine if this range is a subset of another range, i.e.
Definition: addr_range.hh:445
bool valid() const
Determine if the range is valid.
Definition: addr_range.hh:336
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:471
Addr start() const
Get the start address of the range.
Definition: addr_range.hh:343
Addr size() const
Get the size of the address range.
Definition: addr_range.hh:326
std::string to_string() const
Get a string representation of the range.
Definition: addr_range.hh:360
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:226
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:204
virtual void initState()
initState() is called on each SimObject when not restoring from a checkpoint.
Definition: sim_object.cc:94
const Params & params() const
Definition: sim_object.hh:176
virtual void regStats()
Callback to set stat parameters.
Definition: group.cc:69
#define warn(...)
Definition: logging.hh:246
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 54 > p
Definition: pagetable.hh:70
SymbolTable debugSymbolTable
Global unified debugging symbol table (for target).
Definition: symtab.cc:44
ObjectFile * createObjectFile(const std::string &fname, bool raw)
Definition: object_file.cc:135
const FlagsType nonan
Don't print if this is NAN.
Definition: info.hh:70
const FlagsType nozero
Don't print if this is zero.
Definition: info.hh:68
const FlagsType total
Print the total.
Definition: info.hh:60
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
int ContextID
Globally unique thread context ID.
Definition: types.hh:239
const ContextID InvalidContextID
Definition: types.hh:240
statistics::Formula & simSeconds
Definition: stats.cc:45
void ccprintf(cp::Print &print)
Definition: cprintf.hh:130
statistics::Vector bytesRead
Number of total bytes read from this memory.
statistics::Vector bytesInstRead
Number of instruction bytes read from this memory.
statistics::Vector numReads
Number of read requests.
void regStats() override
Callback to set stat parameters.
statistics::Vector numOther
Number of other requests.
statistics::Vector bytesWritten
Number of bytes written to this memory.
statistics::Vector numWrites
Number of write requests.
Definition: mem.h:38
bool_vector8 mem[]
Definition: reset_stim.h:43

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