gem5  v22.1.0.0
tarmac_record_v8.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 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  * 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 
39 
40 #include <memory>
41 
43 #include "arch/arm/mmu.hh"
45 
46 namespace gem5
47 {
48 
49 using namespace ArmISA;
50 
51 namespace trace {
52 
53 TarmacTracerRecordV8::TraceInstEntryV8::TraceInstEntryV8(
54  const TarmacContext& tarmCtx,
55  bool predicate)
56  : TraceInstEntry(tarmCtx, predicate),
57  TraceEntryV8(tarmCtx.tarmacCpuName()),
58  paddr(0),
59  paddrValid(false)
60 {
61  const auto thread = tarmCtx.thread;
62 
63  // Evaluate physical address
64  auto mmu = static_cast<ArmISA::MMU*>(thread->getMMUPtr());
65  paddrValid = mmu->translateFunctional(
66  thread, addr, paddr);
67 }
68 
70  const TarmacContext& tarmCtx,
71  uint8_t _size, Addr _addr, uint64_t _data)
72  : TraceMemEntry(tarmCtx, _size, _addr, _data),
73  TraceEntryV8(tarmCtx.tarmacCpuName()),
74  paddr(_addr)
75 {
76  const auto thread = tarmCtx.thread;
77 
78  // Evaluate physical address
79  auto mmu = static_cast<ArmISA::MMU*>(thread->getMMUPtr());
81 }
82 
84  const TarmacContext& tarmCtx,
85  const RegId& reg)
86  : TraceRegEntry(tarmCtx, reg),
87  TraceEntryV8(tarmCtx.tarmacCpuName()),
88  regWidth(64)
89 {
90 }
91 
92 void
94 {
95  // Do not trace pseudo register accesses: invalid
96  // register entry.
97  if (regId.index() > int_reg::NumArchRegs) {
98  regValid = false;
99  return;
100  }
101 
102  TraceRegEntry::updateInt(tarmCtx);
103 
104  if ((regId != int_reg::Pc) || (regId != StackPointerReg) ||
105  (regId != FramePointerReg) || (regId != ReturnAddressReg)) {
106 
107  const auto* arm_inst = static_cast<const ArmStaticInst*>(
108  tarmCtx.staticInst.get()
109  );
110 
111  regWidth = (arm_inst->getIntWidth());
112  if (regWidth == 32) {
113  regName = "W" + std::to_string(regId.index());
114  } else {
115  regName = "X" + std::to_string(regId.index());
116  }
117  }
118 }
119 
120 void
122 {
123  TraceRegEntry::updateMisc(tarmCtx);
124  // System registers are 32bit wide
125  regWidth = 32;
126 }
127 
128 void
130 {
131  auto thread = tarmCtx.thread;
132  ArmISA::VecRegContainer vec_container;
133  thread->getReg(regId, &vec_container);
134  auto vv = vec_container.as<VecElem>();
135 
137  auto num_elements = regWidth / (sizeof(VecElem) * 8);
138 
139  // Resize vector of values
140  values.resize(num_elements);
141 
142  for (auto i = 0; i < num_elements; i++) {
143  values[i] = vv[i];
144  }
145 
146  regValid = true;
147  regName = "Z" + std::to_string(regId.index());
148 }
149 
150 void
152 {
153  auto thread = tarmCtx.thread;
154  ArmISA::VecPredRegContainer pred_container;
155  thread->getReg(regId, &pred_container);
156 
157  // Predicate registers are always 1/8 the size of related vector
158  // registers. (getCurSveVecLenInBits(thread) / 8)
160  auto num_elements = regWidth / 16;
161 
162  // Resize vector of values
163  values.resize(num_elements);
164 
165  // Get a copy of pred_container as a vector of half-words
166  auto vv = pred_container.as<uint16_t>();
167  for (auto i = 0; i < num_elements; i++) {
168  values[i] = vv[i];
169  }
170 
171  regValid = true;
172  regName = "P" + std::to_string(regId.index());
173 }
174 
175 void
177  const TarmacContext& tarmCtx)
178 {
179  // Generate an instruction entry in the record and
180  // add it to the Instruction Queue
181  queue.push_back(
182  std::make_unique<TraceInstEntryV8>(tarmCtx, predicate)
183  );
184 }
185 
186 void
188  const TarmacContext& tarmCtx)
189 {
190  // Generate a memory entry in the record if the record
191  // implies a valid memory access, and add it to the
192  // Memory Queue
193  if (getMemValid()) {
194  queue.push_back(
195  std::make_unique<TraceMemEntryV8>(tarmCtx,
196  static_cast<uint8_t>(getSize()),
197  getAddr(), getIntData())
198  );
199  }
200 }
201 
202 void
204  const TarmacContext& tarmCtx)
205 {
206  // Generate an entry for every ARM register being
207  // written by the current instruction
208  for (auto reg = 0; reg < staticInst->numDestRegs(); ++reg) {
209 
210  RegId reg_id = staticInst->destRegIdx(reg);
211 
212  // Creating a single register change entry
213  auto single_reg = genRegister<TraceRegEntryV8>(tarmCtx, reg_id);
214 
215  // Copying the entry and adding it to the "list"
216  // of entries to be dumped to trace.
217  queue.push_back(std::make_unique<TraceRegEntryV8>(single_reg));
218  }
219 
220  // Gem5 is treating CPSR flags as separate registers (CC registers),
221  // in contrast with Tarmac specification: we need to merge the gem5 CC
222  // entries altogether with the CPSR register and produce a single entry.
223  mergeCCEntry<TraceRegEntryV8>(queue, tarmCtx);
224 }
225 
226 void
228  std::ostream& outs,
229  int verbosity,
230  const std::string &prefix) const
231 {
232  // If there is a valid vaddr->paddr translation, print the
233  // physical address, otherwise print the virtual address only.
234  std::string paddr_str = paddrValid? csprintf(":%012x",paddr) :
235  std::string();
236 
237  // Pad the opcode.
238  std::string opcode_str = csprintf("%0*x", instSize >> 2, opcode);
239 
240  // Print the instruction record formatted according
241  // to the Tarmac specification
242  ccprintf(outs, "%s clk %s %s (%u) %08x%s %s %s %s_%s : %s\n",
243  curTick(), /* Tick time */
244  cpuName, /* Cpu name */
245  taken? "IT" : "IS", /* Instruction taken/skipped */
246  instCount, /* Instruction count */
247  addr, /* Instruction virt address */
248  paddr_str, /* Instruction phys address */
249  opcode_str, /* Instruction opcode */
250  iSetStateToStr(isetstate), /* Instruction Set */
251  opModeToStr(mode), /* Exception level */
252  secureMode? "s" : "ns", /* Security */
253  disassemble); /* Instruction disass */
254 }
255 
256 void
258  std::ostream& outs,
259  int verbosity,
260  const std::string &prefix) const
261 {
262  // Print the memory record formatted according
263  // to the Tarmac specification
264  ccprintf(outs, "%s clk %s M%s%d %08x:%012x %0*x\n",
265  curTick(), /* Tick time */
266  cpuName, /* Cpu name */
267  loadAccess? "R" : "W", /* Access type */
268  size, /* Access size */
269  addr, /* Virt Memory address */
270  paddr, /* Phys Memory address */
271  size*2, /* Padding with access size */
272  data); /* Memory data */
273 }
274 
275 void
277  std::ostream& outs,
278  int verbosity,
279  const std::string &prefix) const
280 {
281  // Print the register record formatted according
282  // to the Tarmac specification
283  if (regValid) {
284  ccprintf(outs, "%s clk %s R %s %s\n",
285  curTick(), /* Tick time */
286  cpuName, /* Cpu name */
287  regName, /* Register name */
288  formatReg()); /* Register value */
289  }
290 }
291 
292 std::string
294 {
295  if (regWidth <= 64) {
296  // Register width is < 64 bit (scalar register).
297  return csprintf("%0*x", regWidth / 4, values[Lo]);
298  } else {
299 
300  // Register width is > 64 bit (vector). Iterate over every vector
301  // element. Since the vector values are stored in Little Endian, print
302  // starting from the last element.
303  std::string reg_val;
304  for (auto it = values.rbegin(); it != values.rend(); it++) {
305  reg_val += csprintf("%0*x_",
306  static_cast<int>(sizeof(VecElem) * 2), *it);
307  }
308 
309  // Remove trailing underscore
310  reg_val.pop_back();
311 
312  return reg_val;
313  }
314 }
315 
316 } // namespace trace
317 } // namespace gem5
static unsigned getCurSveVecLenInBits(ThreadContext *tc)
TranslationGenPtr translateFunctional(Addr start, Addr size, ThreadContext *tc, Mode mode, Request::Flags flags) override
Returns a translation generator for a region of virtual addresses, instead of directly translating a ...
Definition: mmu.hh:91
T * get() const
Directly access the pointer itself without taking a reference.
Definition: refcnt.hh:227
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:91
uint8_t numDestRegs() const
Number of destination registers.
Definition: static_inst.hh:125
const RegId & destRegIdx(int i) const
Return logical index (architectural reg num) of i'th destination reg.
Definition: static_inst.hh:215
virtual RegVal getReg(const RegId &reg) const
virtual BaseMMU * getMMUPtr()=0
Vector Register Abstraction This generic class is the model in a particularization of MVC,...
Definition: vec_reg.hh:124
VecElem * as()
View interposers.
Definition: vec_reg.hh:189
Addr addr
The address that was accessed.
Definition: insttracer.hh:85
StaticInstPtr staticInst
Definition: insttracer.hh:70
bool getMemValid() const
Definition: insttracer.hh:274
ThreadContext * thread
Definition: insttracer.hh:67
uint64_t getIntData() const
Definition: insttracer.hh:276
bool predicate
is the predicate for execution this inst true or false (not execed)?
Definition: insttracer.hh:150
union gem5::trace::InstRecord::Data data
Addr size
The size of the memory request.
Definition: insttracer.hh:86
This object type is encapsulating the informations needed by a Tarmac record to generate it's own ent...
const StaticInstPtr staticInst
void addInstEntry(std::vector< InstPtr > &queue, const TarmacContext &ptr)
Generates an Entry for the executed instruction.
void addRegEntry(std::vector< RegPtr > &queue, const TarmacContext &ptr)
Generate a Record for every register being written.
void addMemEntry(std::vector< MemPtr > &queue, const TarmacContext &ptr)
Generates an Entry for every memory access triggered.
constexpr auto & Pc
Definition: int.hh:276
Bitfield< 4, 0 > mode
Definition: misc_types.hh:74
constexpr auto & StackPointerReg
Definition: int.hh:654
VecPredReg::Container VecPredRegContainer
Definition: vec.hh:71
Bitfield< 7 > i
Definition: misc_types.hh:67
constexpr auto & ReturnAddressReg
Definition: int.hh:655
Bitfield< 24, 21 > opcode
Definition: types.hh:92
constexpr auto & FramePointerReg
Definition: int.hh:653
uint32_t VecElem
Definition: vec.hh:63
constexpr auto & Lo
Definition: int.hh:205
Bitfield< 5, 3 > reg
Definition: types.hh:92
bool regValid(Addr daddr)
Definition: sinicreg.hh:236
std::string iSetStateToStr(TarmacBaseRecord::ISetState isetstate)
Returns the string representation of the instruction set being currently run according to the Tarmac ...
std::string opModeToStr(OperatingMode opMode)
Returns the string representation of the ARM Operating Mode (CPSR.M[3:0] field) according to the Tarm...
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
void ccprintf(cp::Print &print)
Definition: cprintf.hh:130
const std::string to_string(sc_enc enc)
Definition: sc_fxdefs.cc:60
General data shared by all v8 entries.
virtual void print(std::ostream &outs, int verbosity=0, const std::string &prefix="") const override
TraceMemEntryV8(const TarmacContext &tarmCtx, uint8_t _size, Addr _addr, uint64_t _data)
virtual void print(std::ostream &outs, int verbosity=0, const std::string &prefix="") const override
void updateInt(const TarmacContext &tarmCtx) override
virtual void print(std::ostream &outs, int verbosity=0, const std::string &prefix="") const override
TraceRegEntryV8(const TarmacContext &tarmCtx, const RegId &reg)
void updateMisc(const TarmacContext &tarmCtx) override
Register update functions.
std::string formatReg() const
Returning a string which contains the formatted register value: transformed in hex,...
void updateVec(const TarmacContext &tarmCtx) override
void updatePred(const TarmacContext &tarmCtx) override
virtual void updateMisc(const TarmacContext &tarmCtx)
Register update functions.
virtual void updateInt(const TarmacContext &tarmCtx)

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