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

Generated on Tue Sep 21 2021 12:24:46 for gem5 by doxygen 1.8.17