gem5  v22.1.0.0
dyn_inst.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2011, 2021 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) 2004-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 "cpu/o3/dyn_inst.hh"
42 
43 #include <algorithm>
44 
45 #include "base/intmath.hh"
46 #include "debug/DynInst.hh"
47 #include "debug/IQ.hh"
48 #include "debug/O3PipeView.hh"
49 
50 namespace gem5
51 {
52 
53 namespace o3
54 {
55 
56 DynInst::DynInst(const Arrays &arrays, const StaticInstPtr &static_inst,
57  const StaticInstPtr &_macroop, InstSeqNum seq_num, CPU *_cpu)
58  : seqNum(seq_num), staticInst(static_inst), cpu(_cpu),
59  _numSrcs(arrays.numSrcs), _numDests(arrays.numDests),
60  _flatDestIdx(arrays.flatDestIdx), _destIdx(arrays.destIdx),
61  _prevDestIdx(arrays.prevDestIdx), _srcIdx(arrays.srcIdx),
62  _readySrcIdx(arrays.readySrcIdx), macroop(_macroop)
63 {
64  std::fill(_readySrcIdx, _readySrcIdx + (numSrcs() + 7) / 8, 0);
65 
66  status.reset();
67 
68  instFlags.reset();
69  instFlags[RecordResult] = true;
70  instFlags[Predicate] = true;
71  instFlags[MemAccPredicate] = true;
72 
73 #ifndef NDEBUG
74  ++cpu->instcount;
75 
76  if (cpu->instcount > 1500) {
77 #ifdef DEBUG
78  cpu->dumpInsts();
79  dumpSNList();
80 #endif
81  assert(cpu->instcount <= 1500);
82  }
83 
85  "DynInst: [sn:%lli] Instruction created. Instcount for %s = %i\n",
86  seqNum, cpu->name(), cpu->instcount);
87 #endif
88 
89 #ifdef DEBUG
90  cpu->snList.insert(seqNum);
91 #endif
92 
93 }
94 
95 DynInst::DynInst(const Arrays &arrays, const StaticInstPtr &static_inst,
96  const StaticInstPtr &_macroop, const PCStateBase &_pc,
97  const PCStateBase &pred_pc, InstSeqNum seq_num, CPU *_cpu)
98  : DynInst(arrays, static_inst, _macroop, seq_num, _cpu)
99 {
100  set(pc, _pc);
101  set(predPC, pred_pc);
102 }
103 
104 DynInst::DynInst(const Arrays &arrays, const StaticInstPtr &_staticInst,
105  const StaticInstPtr &_macroop)
106  : DynInst(arrays, _staticInst, _macroop, 0, nullptr)
107 {}
108 
109 /*
110  * This custom "new" operator uses the default "new" operator to allocate space
111  * for a DynInst, but also pads out the number of bytes to make room for some
112  * extra structures the DynInst needs. We save time and improve performance by
113  * only going to the heap once to get space for all these structures.
114  *
115  * When a DynInst is allocated with new, the compiler will call this "new"
116  * operator with "count" set to the number of bytes it needs to store the
117  * DynInst. We ultimately call into the default new operator to get those
118  * bytes, but before we do, we pad out "count" so that there will be extra
119  * space for some structures the DynInst needs. We take into account both the
120  * absolute size of these structures, and also what alignment they need.
121  *
122  * Once we've gotten a buffer large enough to hold the DynInst itself and these
123  * extra structures, we construct the extra bits using placement new. This
124  * constructs the structures in place in the space we created for them.
125  *
126  * Next, we return the buffer as the result of our operator. The compiler takes
127  * that buffer and constructs the DynInst in the beginning of it using the
128  * DynInst constructor.
129  *
130  * To avoid having to calculate where these extra structures are twice, once
131  * when making room for them and initializing them, and then once again in the
132  * DynInst constructor, we also pass in a structure called "arrays" which holds
133  * pointers to them. The fields of "arrays" are initialized in this operator,
134  * and are then consumed in the DynInst constructor.
135  */
136 void *
137 DynInst::operator new(size_t count, Arrays &arrays)
138 {
139  // Convenience variables for brevity.
140  const auto num_dests = arrays.numDests;
141  const auto num_srcs = arrays.numSrcs;
142 
143  // Figure out where everything will go.
144  uintptr_t inst = 0;
145  size_t inst_size = count;
146 
147  uintptr_t flat_dest_idx = roundUp(inst + inst_size, alignof(RegId));
148  size_t flat_dest_idx_size = sizeof(*arrays.flatDestIdx) * num_dests;
149 
150  uintptr_t dest_idx =
151  roundUp(flat_dest_idx + flat_dest_idx_size, alignof(PhysRegIdPtr));
152  size_t dest_idx_size = sizeof(*arrays.destIdx) * num_dests;
153 
154  uintptr_t prev_dest_idx =
155  roundUp(dest_idx + dest_idx_size, alignof(PhysRegIdPtr));
156  size_t prev_dest_idx_size = sizeof(*arrays.prevDestIdx) * num_dests;
157 
158  uintptr_t src_idx =
159  roundUp(prev_dest_idx + prev_dest_idx_size, alignof(PhysRegIdPtr));
160  size_t src_idx_size = sizeof(*arrays.srcIdx) * num_srcs;
161 
162  uintptr_t ready_src_idx =
163  roundUp(src_idx + src_idx_size, alignof(uint8_t));
164  size_t ready_src_idx_size =
165  sizeof(*arrays.readySrcIdx) * ((num_srcs + 7) / 8);
166 
167  // Figure out how much space we need in total.
168  size_t total_size = ready_src_idx + ready_src_idx_size;
169 
170  // Actually allocate it.
171  uint8_t *buf = (uint8_t *)::operator new(total_size);
172 
173  // Fill in "arrays" with pointers to all the arrays.
174  arrays.flatDestIdx = (RegId *)(buf + flat_dest_idx);
175  arrays.destIdx = (PhysRegIdPtr *)(buf + dest_idx);
176  arrays.prevDestIdx = (PhysRegIdPtr *)(buf + prev_dest_idx);
177  arrays.srcIdx = (PhysRegIdPtr *)(buf + src_idx);
178  arrays.readySrcIdx = (uint8_t *)(buf + ready_src_idx);
179 
180  // Initialize all the extra components.
181  new (arrays.flatDestIdx) RegId[num_dests];
182  new (arrays.destIdx) PhysRegIdPtr[num_dests];
183  new (arrays.prevDestIdx) PhysRegIdPtr[num_dests];
184  new (arrays.srcIdx) PhysRegIdPtr[num_srcs];
185  new (arrays.readySrcIdx) uint8_t[num_srcs];
186 
187  return buf;
188 }
189 
191 {
192  /*
193  * The buffer this DynInst occupies also holds some of the structures it
194  * points to. We need to call their destructors manually to make sure that
195  * they're cleaned up appropriately, but we don't need to free their memory
196  * explicitly since that's part of the DynInst's buffer and is already
197  * going to be freed as part of deleting the DynInst.
198  */
199  for (int i = 0; i < _numDests; i++) {
200  _flatDestIdx[i].~RegId();
201  _destIdx[i].~PhysRegIdPtr();
202  _prevDestIdx[i].~PhysRegIdPtr();
203  }
204 
205  for (int i = 0; i < _numSrcs; i++)
206  _srcIdx[i].~PhysRegIdPtr();
207 
208  for (int i = 0; i < ((_numSrcs + 7) / 8); i++)
209  _readySrcIdx[i].~uint8_t();
210 
211 #if TRACING_ON
212  if (debug::O3PipeView) {
213  Tick fetch = fetchTick;
214  // fetchTick can be -1 if the instruction fetched outside the trace
215  // window.
216  if (fetch != -1) {
217  Tick val;
218  // Print info needed by the pipeline activity viewer.
219  DPRINTFR(O3PipeView, "O3PipeView:fetch:%llu:0x%08llx:%d:%llu:%s\n",
220  fetch,
221  pcState().instAddr(),
222  pcState().microPC(),
223  seqNum,
224  staticInst->disassemble(pcState().instAddr()));
225 
226  val = (decodeTick == -1) ? 0 : fetch + decodeTick;
227  DPRINTFR(O3PipeView, "O3PipeView:decode:%llu\n", val);
228  val = (renameTick == -1) ? 0 : fetch + renameTick;
229  DPRINTFR(O3PipeView, "O3PipeView:rename:%llu\n", val);
230  val = (dispatchTick == -1) ? 0 : fetch + dispatchTick;
231  DPRINTFR(O3PipeView, "O3PipeView:dispatch:%llu\n", val);
232  val = (issueTick == -1) ? 0 : fetch + issueTick;
233  DPRINTFR(O3PipeView, "O3PipeView:issue:%llu\n", val);
234  val = (completeTick == -1) ? 0 : fetch + completeTick;
235  DPRINTFR(O3PipeView, "O3PipeView:complete:%llu\n", val);
236  val = (commitTick == -1) ? 0 : fetch + commitTick;
237 
238  Tick valS = (storeTick == -1) ? 0 : fetch + storeTick;
239  DPRINTFR(O3PipeView, "O3PipeView:retire:%llu:store:%llu\n",
240  val, valS);
241  }
242  }
243 #endif
244 
245  delete [] memData;
246  delete traceData;
247  fault = NoFault;
248 
249 #ifndef NDEBUG
250  --cpu->instcount;
251 
253  "DynInst: [sn:%lli] Instruction destroyed. Instcount for %s = %i\n",
254  seqNum, cpu->name(), cpu->instcount);
255 #endif
256 #ifdef DEBUG
257  cpu->snList.erase(seqNum);
258 #endif
259 };
260 
261 
262 #ifdef DEBUG
263 void
264 DynInst::dumpSNList()
265 {
266  std::set<InstSeqNum>::iterator sn_it = cpu->snList.begin();
267 
268  int count = 0;
269  while (sn_it != cpu->snList.end()) {
270  cprintf("%i: [sn:%lli] not destroyed\n", count, (*sn_it));
271  count++;
272  sn_it++;
273  }
274 }
275 #endif
276 
277 void
279 {
280  cprintf("T%d : %#08d `", threadNumber, pc->instAddr());
281  std::cout << staticInst->disassemble(pc->instAddr());
282  cprintf("'\n");
283 }
284 
285 void
286 DynInst::dump(std::string &outstring)
287 {
288  std::ostringstream s;
289  s << "T" << threadNumber << " : 0x" << pc->instAddr() << " "
290  << staticInst->disassemble(pc->instAddr());
291 
292  outstring = s.str();
293 }
294 
295 void
297 {
298  DPRINTF(IQ, "[sn:%lli] has %d ready out of %d sources. RTI %d)\n",
300  if (++readyRegs == numSrcRegs()) {
301  setCanIssue();
302  }
303 }
304 
305 void
307 {
308  readySrcIdx(src_idx, true);
309  markSrcRegReady();
310 }
311 
312 
313 void
315 {
316  status.set(Squashed);
317 
319  return;
320 
321  // This inst has been renamed already so it may go through rename
322  // again (e.g. if the squash is due to memory access order violation).
323  // Reset the write counters for all pinned destination register to ensure
324  // that they are in a consistent state for a possible re-rename. This also
325  // ensures that dest regs will be pinned to the same phys register if
326  // re-rename happens.
327  for (int idx = 0; idx < numDestRegs(); idx++) {
328  PhysRegIdPtr phys_dest_reg = renamedDestIdx(idx);
329  if (phys_dest_reg->isPinned()) {
330  phys_dest_reg->incrNumPinnedWrites();
331  if (isPinnedRegsWritten())
332  phys_dest_reg->incrNumPinnedWritesToComplete();
333  }
334  }
336 }
337 
338 Fault
340 {
341  // @todo: Pretty convoluted way to avoid squashing from happening
342  // when using the TC during an instruction's execution
343  // (specifically for instructions that have side-effects that use
344  // the TC). Fix this.
345  bool no_squash_from_TC = thread->noSquashFromTC;
346  thread->noSquashFromTC = true;
347 
348  fault = staticInst->execute(this, traceData);
349 
350  thread->noSquashFromTC = no_squash_from_TC;
351 
352  return fault;
353 }
354 
355 Fault
357 {
358  // @todo: Pretty convoluted way to avoid squashing from happening
359  // when using the TC during an instruction's execution
360  // (specifically for instructions that have side-effects that use
361  // the TC). Fix this.
362  bool no_squash_from_TC = thread->noSquashFromTC;
363  thread->noSquashFromTC = true;
364 
366 
367  thread->noSquashFromTC = no_squash_from_TC;
368 
369  return fault;
370 }
371 
372 Fault
374 {
375  // @todo: Pretty convoluted way to avoid squashing from happening
376  // when using the TC during an instruction's execution
377  // (specifically for instructions that have side-effects that use
378  // the TC). Fix this.
379  bool no_squash_from_TC = thread->noSquashFromTC;
380  thread->noSquashFromTC = true;
381 
382  if (cpu->checker) {
383  if (isStoreConditional()) {
384  reqToVerify->setExtraData(pkt->req->getExtraData());
385  }
386  }
387 
388  fault = staticInst->completeAcc(pkt, this, traceData);
389 
390  thread->noSquashFromTC = no_squash_from_TC;
391 
392  return fault;
393 }
394 
395 void
396 DynInst::trap(const Fault &fault)
397 {
399 }
400 
401 Fault
403  const std::vector<bool> &byte_enable)
404 {
405  assert(byte_enable.size() == size);
406  return cpu->pushRequest(
407  dynamic_cast<DynInstPtr::PtrType>(this),
408  /* ld */ true, nullptr, size, addr, flags, nullptr, nullptr,
409  byte_enable);
410 }
411 
412 Fault
414 {
415  const unsigned int size = 8;
416  return cpu->pushRequest(
417  dynamic_cast<DynInstPtr::PtrType>(this),
418  /* ld */ true, nullptr, size, 0x0ul, flags, nullptr, nullptr,
419  std::vector<bool>(size, true));
420 }
421 
422 Fault
423 DynInst::writeMem(uint8_t *data, unsigned size, Addr addr,
424  Request::Flags flags, uint64_t *res,
425  const std::vector<bool> &byte_enable)
426 {
427  assert(byte_enable.size() == size);
428  return cpu->pushRequest(
429  dynamic_cast<DynInstPtr::PtrType>(this),
430  /* st */ false, data, size, addr, flags, res, nullptr,
431  byte_enable);
432 }
433 
434 Fault
436  AtomicOpFunctorPtr amo_op)
437 {
438  // atomic memory instructions do not have data to be written to memory yet
439  // since the atomic operations will be executed directly in cache/memory.
440  // Therefore, its `data` field is nullptr.
441  // Atomic memory requests need to carry their `amo_op` fields to cache/
442  // memory
443  return cpu->pushRequest(
444  dynamic_cast<DynInstPtr::PtrType>(this),
445  /* atomic */ false, nullptr, size, addr, flags, nullptr,
446  std::move(amo_op), std::vector<bool>(size, true));
447 }
448 
449 } // namespace o3
450 } // namespace gem5
#define DPRINTFR(x,...)
Definition: trace.hh:200
#define DPRINTF(x,...)
Definition: trace.hh:186
const char data[]
virtual std::string name() const
Definition: named.hh:47
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
RequestPtr req
A pointer to the original request.
Definition: packet.hh:376
Physical register ID.
Definition: reg_class.hh:392
void incrNumPinnedWritesToComplete()
Definition: reg_class.hh:484
void incrNumPinnedWrites()
Definition: reg_class.hh:467
bool isPinned() const
Definition: reg_class.hh:469
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:91
virtual const std::string & disassemble(Addr pc, const loader::SymbolTable *symtab=nullptr) const
Return string representation of disassembled instruction.
Definition: static_inst.cc:60
virtual Fault execute(ExecContext *xc, trace::InstRecord *traceData) const =0
virtual Fault completeAcc(Packet *pkt, ExecContext *xc, trace::InstRecord *trace_data) const
Definition: static_inst.hh:295
virtual Fault initiateAcc(ExecContext *xc, trace::InstRecord *traceData) const
Definition: static_inst.hh:289
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
Definition: cpu.hh:94
gem5::Checker< DynInstPtr > * checker
Pointer to the checker, which can dynamically verify instruction results at run time.
Definition: cpu.hh:524
void dumpInsts()
Debug function to print all instructions on the list.
Definition: cpu.cc:1372
Fault pushRequest(const DynInstPtr &inst, bool isLoad, uint8_t *data, unsigned int size, Addr addr, Request::Flags flags, uint64_t *res, AtomicOpFunctorPtr amo_op=nullptr, const std::vector< bool > &byte_enable=std::vector< bool >())
CPU pushRequest function, forwards request to LSQ.
Definition: cpu.hh:549
void trap(const Fault &fault, ThreadID tid, const StaticInstPtr &inst)
Traps to handle given fault.
Definition: cpu.cc:791
int instcount
Count of total number of dynamic instructions in flight.
Definition: cpu.hh:377
const PCStateBase & pcState() const override
Read the PC state of this instruction.
Definition: dyn_inst.hh:884
uint8_t readyRegs
How many source registers are ready.
Definition: dyn_inst.hh:329
uint8_t * memData
Pointer to the data for the memory access.
Definition: dyn_inst.hh:346
bool isStoreConditional() const
Definition: dyn_inst.hh:543
RequestPtr reqToVerify
Definition: dyn_inst.hh:366
ThreadState * thread
Pointer to the thread state.
Definition: dyn_inst.hh:134
PhysRegIdPtr * _prevDestIdx
Definition: dyn_inst.hh:230
std::unique_ptr< PCStateBase > predPC
Predicted PC state after this instruction.
Definition: dyn_inst.hh:323
RegId * _flatDestIdx
Definition: dyn_inst.hh:222
Fault writeMem(uint8_t *data, unsigned size, Addr addr, Request::Flags flags, uint64_t *res, const std::vector< bool > &byte_enable) override
Definition: dyn_inst.cc:423
uint8_t * _readySrcIdx
Definition: dyn_inst.hh:236
bool readyToIssue() const
Returns whether or not this instruction is ready to issue.
Definition: dyn_inst.hh:745
@ Squashed
Instruction has committed.
Definition: dyn_inst.hh:156
Fault completeAcc(PacketPtr pkt)
Completes the access.
Definition: dyn_inst.cc:373
Fault fault
The kind of fault this instruction has generated.
Definition: dyn_inst.hh:137
std::unique_ptr< PCStateBase > pc
PC state for this instruction.
Definition: dyn_inst.hh:206
ThreadID threadNumber
The thread this instruction is from.
Definition: dyn_inst.hh:316
std::bitset< MaxFlags > instFlags
Definition: dyn_inst.hh:194
bool readySrcIdx(int idx) const
Definition: dyn_inst.hh:302
bool isPinnedRegsRenamed() const
Returns whether pinned registers are renamed.
Definition: dyn_inst.hh:844
Fault initiateMemAMO(Addr addr, unsigned size, Request::Flags flags, AtomicOpFunctorPtr amo_op) override
Definition: dyn_inst.cc:435
size_t numDestRegs() const
Returns the number of destination registers.
Definition: dyn_inst.hh:680
void dump()
Dumps out contents of this BaseDynInst.
Definition: dyn_inst.cc:278
const StaticInstPtr staticInst
The StaticInst used by this BaseDynInst.
Definition: dyn_inst.hh:126
void setSquashed()
Sets this instruction as squashed.
Definition: dyn_inst.cc:314
Fault initiateMemRead(Addr addr, unsigned size, Request::Flags flags, const std::vector< bool > &byte_enable) override
Definition: dyn_inst.cc:402
CPU * cpu
Pointer to the Impl's CPU object.
Definition: dyn_inst.hh:129
void trap(const Fault &fault)
Traps to handle specified fault.
Definition: dyn_inst.cc:396
trace::InstRecord * traceData
InstRecord that tracks this instructions.
Definition: dyn_inst.hh:140
Fault execute()
Executes the instruction.
Definition: dyn_inst.cc:339
bool isPinnedRegsSquashDone() const
Return whether dest registers' pinning status updated after squash.
Definition: dyn_inst.hh:869
PhysRegIdPtr renamedDestIdx(int idx) const
Definition: dyn_inst.hh:261
std::bitset< NumStatus > status
The status of this BaseDynInst.
Definition: dyn_inst.hh:197
void setPinnedRegsSquashDone()
Sets dest registers' status updated after squash.
Definition: dyn_inst.hh:876
DynInst(const StaticInstPtr &staticInst, const StaticInstPtr &macroop, InstSeqNum seq_num, CPU *cpu)
Fault initiateMemMgmtCmd(Request::Flags flags) override
Initiate a memory management command with no valid address.
Definition: dyn_inst.cc:413
bool isPinnedRegsWritten() const
Returns whether destination registers are written.
Definition: dyn_inst.hh:856
InstSeqNum seqNum
The sequence number of the instruction.
Definition: dyn_inst.hh:123
void markSrcRegReady()
Records that one of the source registers is ready.
Definition: dyn_inst.cc:296
size_t numSrcRegs() const
Returns the number of source registers.
Definition: dyn_inst.hh:677
PhysRegIdPtr * _destIdx
Definition: dyn_inst.hh:226
size_t numSrcs() const
Definition: dyn_inst.hh:239
Fault initiateAcc()
Initiates the access.
Definition: dyn_inst.cc:356
void setCanIssue()
Sets this instruction as ready to issue.
Definition: dyn_inst.hh:742
size_t numDests() const
Definition: dyn_inst.hh:240
PhysRegIdPtr * _srcIdx
Definition: dyn_inst.hh:233
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
Definition: amo.hh:242
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
Definition: intmath.hh:260
uint8_t flags
Definition: helpers.cc:66
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 12, 11 > set
Definition: misc_types.hh:709
Bitfield< 1 > s
Definition: pagetable.hh:64
Bitfield< 63 > val
Definition: misc.hh:776
Bitfield< 3 > addr
Definition: types.hh:84
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< FaultBase > Fault
Definition: types.hh:248
uint16_t RegIndex
Definition: types.hh:176
void cprintf(const char *format, const Args &...args)
Definition: cprintf.hh:155
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
constexpr decltype(nullptr) NoFault
Definition: types.hh:253
uint64_t InstSeqNum
Definition: inst_seq.hh:40
PhysRegId * PhysRegIdPtr
Definition: reg_class.hh:487

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