gem5 v23.0.0.1
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
tarmac_record.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 "tarmac_tracer.hh"
44
45namespace gem5
46{
47
48using namespace ArmISA;
49
50namespace trace {
51
52// TARMAC Instruction Record static variables
54
55std::string
57{
58 switch (isetstate) {
60 return "A";
62 return "T";
64 return "O";
65 default:
66 return "Unsupported";
67 }
68}
69
70std::string
72{
73 switch (opMode) {
74 case MODE_EL0T:
75 return "EL0t";
76 case MODE_EL1T:
77 return "EL1t";
78 case MODE_EL1H:
79 return "EL1h";
80 case MODE_EL2T:
81 return "EL2t";
82 case MODE_EL2H:
83 return "EL2h";
84 case MODE_EL3T:
85 return "EL3t";
86 case MODE_EL3H:
87 return "EL3h";
88 case MODE_USER:
89 return "usr";
90 case MODE_FIQ:
91 return "fiq";
92 case MODE_IRQ:
93 return "irq";
94 case MODE_SVC:
95 return "svc";
96 case MODE_MON:
97 return "mon";
98 case MODE_ABORT:
99 return "abt";
100 case MODE_HYP:
101 return "hyp";
102 case MODE_UNDEFINED:
103 return "und";
104 case MODE_SYSTEM:
105 return "sys";
106 default:
107 return "Unsupported";
108 }
109}
110
111// TarmacTracerRecord ctor
113 const StaticInstPtr _staticInst,
114 const PCStateBase &_pc,
115 TarmacTracer& _tracer,
116 const StaticInstPtr _macroStaticInst)
117 : TarmacBaseRecord(_when, _thread, _staticInst,
118 _pc, _macroStaticInst),
119 tracer(_tracer)
120{
121}
122
124 const TarmacContext& tarmCtx,
125 bool predicate)
126 : InstEntry(tarmCtx.thread, *tarmCtx.pc, tarmCtx.staticInst, predicate)
127{
128 secureMode = isSecure(tarmCtx.thread);
129
130 auto arm_inst = static_cast<const ArmStaticInst*>(
131 tarmCtx.staticInst.get()
132 );
133
134 // Get the instruction size as a number of bits:
135 // (multiply byte size by 8)
136 instSize = (arm_inst->instSize() << 3);
137
138 // Mask the opcode using the instruction size: the
139 // opcode field will otherwise be 32 bit wide even
140 // for 16bit (Thumb) instruction.
141 opcode = arm_inst->encoding();
142
143 // Update the instruction count: number of executed
144 // instructions.
145 instCount++;
146}
147
149 const TarmacContext& tarmCtx,
150 uint8_t _size, Addr _addr, uint64_t _data)
151 : MemEntry(_size, _addr, _data),
152 loadAccess(tarmCtx.staticInst->isLoad())
153{
154}
155
157 const TarmacContext& tarmCtx,
158 const RegId& reg)
159 : RegEntry(*tarmCtx.pc),
160 regValid(false),
161 regId(reg)
162{
163}
164
165void
167{
168 // Fill the register entry data, according to register
169 // class.
170 switch (regId.classValue()) {
171 case CCRegClass:
172 updateCC(tarmCtx);
173 break;
174 case FloatRegClass:
175 updateFloat(tarmCtx);
176 break;
177 case IntRegClass:
178 updateInt(tarmCtx);
179 break;
180 case MiscRegClass:
181 updateMisc(tarmCtx);
182 break;
183 case VecRegClass:
184 updateVec(tarmCtx);
185 break;
186 case VecPredRegClass:
187 updatePred(tarmCtx);
188 break;
189 default:
190 // If unsupported format, do nothing: non updating
191 // the register will prevent it to be printed.
192 break;
193 }
194}
195
196void
198{
199 auto thread = tarmCtx.thread;
200
201 regValid = true;
202 regName = miscRegName[regId.index()];
203 values[Lo] = thread->readMiscRegNoEffect(regId.index());
204
205 // If it is the CPSR:
206 // update the value of the CPSR register and add
207 // the CC flags on top of the value
208 if (regId.index() == MISCREG_CPSR) {
210 cpsr.nz = thread->getReg(cc_reg::Nz);
211 cpsr.c = thread->getReg(cc_reg::C);
212 cpsr.v = thread->getReg(cc_reg::V);
213 cpsr.ge = thread->getReg(cc_reg::Ge);
214
215 // update the entry value
216 values[Lo] = cpsr;
217 }
218}
219
220void
222{
223 auto thread = tarmCtx.thread;
224
225 regValid = true;
226 regName = cc_reg::RegName[regId.index()];
227 values[Lo] = thread->getReg(regId);
228}
229
230void
232{
233 regValid = true;
234 regName = "f" + std::to_string(regId.index());
235 panic("ARM doesn't support float registers.");
236}
237
238void
240{
241 auto thread = tarmCtx.thread;
242
243 // Reading operating mode from CPSR.
244 // This is needed when printing the register name in case
245 // of banked register (e.g. lr_svc)
247 OperatingMode mode = (OperatingMode)(uint8_t)cpsr.mode;
248
249 std::string reg_suffix;
250 if (mode != MODE_USER) {
251 reg_suffix = "_" + opModeToStr(mode);
252 }
253
254 regValid = true;
255 switch (regId.index()) {
256 case int_reg::Pc:
257 regName = "pc";
258 break;
259 case StackPointerReg:
260 regName = "sp" + reg_suffix ;
261 break;
262 case FramePointerReg:
263 regName = "fp" + reg_suffix;
264 break;
265 case ReturnAddressReg:
266 regName = "lr" + reg_suffix;
267 break;
268 default:
269 regName = "r" + std::to_string(regId.index());
270 break;
271 }
272 values[Lo] = thread->getReg(regId);
273}
274
275void
277 const TarmacContext& tarmCtx)
278{
279 // Generate an instruction entry in the record and
280 // add it to the Instruction Queue
281 queue.push_back(
282 std::make_unique<TraceInstEntry>(tarmCtx, predicate)
283 );
284}
285
286void
288 const TarmacContext& tarmCtx)
289{
290 // Generate a memory entry in the record if the record
291 // implies a valid memory access, and add it to the
292 // Memory Queue
293 if (getMemValid()) {
294 queue.push_back(
295 std::make_unique<TraceMemEntry>(tarmCtx,
296 static_cast<uint8_t>(getSize()),
297 getAddr(), getIntData())
298 );
299 }
300}
301
302void
304 const TarmacContext& tarmCtx)
305{
306 // Generate an entry for every ARM register being
307 // written by the current instruction
308 for (auto reg = 0; reg < staticInst->numDestRegs(); ++reg) {
309
310 RegId reg_id = staticInst->destRegIdx(reg);
311
312 // Creating a single register change entry
313 auto single_reg = genRegister<TraceRegEntry>(tarmCtx, reg_id);
314
315 // Copying the entry and adding it to the "list"
316 // of entries to be dumped to trace.
317 queue.push_back(std::make_unique<TraceRegEntry>(single_reg));
318 }
319
320 // Gem5 is treating CPSR flags as separate registers (CC registers),
321 // in contrast with Tarmac specification: we need to merge the gem5 CC
322 // entries altogether with the CPSR register and produce a single entry.
323 mergeCCEntry<TraceRegEntry>(queue, tarmCtx);
324}
325
326void
328{
329 // Generate and print all the record's entries.
330 auto &instQueue = tracer.instQueue;
331 auto &memQueue = tracer.memQueue;
332 auto &regQueue = tracer.regQueue;
333
334 const TarmacContext tarmCtx(
335 thread,
337 *pc
338 );
339
340 if (!staticInst->isMicroop()) {
341 // Current instruction is NOT a micro-instruction:
342 // Generate Tarmac entries and dump them immediately
343
344 // Generate Tarmac entries and add them to the respective
345 // queues.
346 addInstEntry(instQueue, tarmCtx);
347 addMemEntry(memQueue, tarmCtx);
348 addRegEntry(regQueue, tarmCtx);
349
350 // Flush (print) any queued entry.
351 flushQueues(instQueue, memQueue, regQueue);
352
353 } else {
354 // Current instruction is a micro-instruction:
355 // save micro entries into dedicated queues and flush them
356 // into the tracefile only when the MACRO-instruction
357 // has completed.
358
359 if (staticInst->isFirstMicroop()) {
360 addInstEntry(instQueue, tarmCtx);
361 }
362
363 addRegEntry(regQueue, tarmCtx);
364 addMemEntry(memQueue, tarmCtx);
365
366 if (staticInst->isLastMicroop()) {
367 // Flush (print) any queued entry.
368 flushQueues(instQueue, memQueue, regQueue);
369 }
370 }
371}
372
373template<typename Queue>
374void
376{
377 std::ostream &outs = tracer.output();
378
379 for (const auto &single_entry : queue) {
380 single_entry->print(outs);
381 }
382
383 queue.clear();
384}
385
386template<typename Queue, typename... Args>
387void
389{
390 flushQueues(queue);
391 flushQueues(args...);
392}
393
394void
396 std::ostream& outs,
397 int verbosity,
398 const std::string &prefix) const
399{
400 // Pad the opcode
401 std::string opcode_str = csprintf("%0*x", instSize >> 2, opcode);
402
403 // Print the instruction record formatted according
404 // to the Tarmac specification
405 ccprintf(outs, "%s clk %s (%u) %08x %s %s %s_%s : %s\n",
406 curTick(), /* Tick time */
407 taken? "IT" : "IS", /* Instruction taken/skipped */
408 instCount, /* Instruction count */
409 addr, /* Instruction address */
410 opcode_str, /* Instruction opcode */
411 iSetStateToStr(isetstate), /* Instruction Set */
412 opModeToStr(mode), /* Exception level */
413 secureMode? "s" : "ns", /* Security */
414 disassemble); /* Instruction disass */
415}
416
417void
419 std::ostream& outs,
420 int verbosity,
421 const std::string &prefix) const
422{
423 // Print the memory record formatted according
424 // to the Tarmac specification
425 ccprintf(outs, "%s clk M%s%d %08x %0*x\n",
426 curTick(), /* Tick time */
427 loadAccess? "R" : "W", /* Access type */
428 size, /* Access size */
429 addr, /* Memory address */
430 size*2, /* Padding with access size */
431 data); /* Memory data */
432}
433
434void
436 std::ostream& outs,
437 int verbosity,
438 const std::string &prefix) const
439{
440 // Print the register record formatted according
441 // to the Tarmac specification
442 if (regValid)
443 ccprintf(outs, "%s clk R %s %08x\n",
444 curTick(), /* Tick time */
445 regName, /* Register name */
446 values[Lo]); /* Register value */
447}
448
449} // namespace trace
450} // namespace gem5
A high-level queue interface, to be used by both the MSHR queue and the write buffer.
Definition queue.hh:71
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:93
bool isFirstMicroop() const
uint8_t numDestRegs() const
Number of destination registers.
const RegId & destRegIdx(int i) const
Return logical index (architectural reg num) of i'th destination reg.
bool isLastMicroop() const
bool isMicroop() const
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal getReg(const RegId &reg) const
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
Addr addr
The address that was accessed.
Definition insttracer.hh:85
StaticInstPtr staticInst
Definition insttracer.hh:70
StaticInstPtr macroStaticInst
Definition insttracer.hh:72
ThreadContext * thread
Definition insttracer.hh:67
std::unique_ptr< PCStateBase > pc
Definition insttracer.hh:71
uint64_t getIntData() const
bool predicate
is the predicate for execution this inst true or false (not execed)?
union gem5::trace::InstRecord::Data data
Addr size
The size of the memory request.
Definition insttracer.hh:86
ISetState
ARM instruction set state.
This object type is encapsulating the informations needed by a Tarmac record to generate it's own ent...
const StaticInstPtr staticInst
virtual void addInstEntry(std::vector< InstPtr > &queue, const TarmacContext &ptr)
Generates an Entry for the executed instruction.
virtual void addRegEntry(std::vector< RegPtr > &queue, const TarmacContext &ptr)
Generate an Entry for every register being written.
virtual void dump() override
TarmacTracerRecord(Tick _when, ThreadContext *_thread, const StaticInstPtr _staticInst, const PCStateBase &_pc, TarmacTracer &_tracer, const StaticInstPtr _macroStaticInst=NULL)
void flushQueues(Queue &queue)
Flush queues to the trace output.
virtual void addMemEntry(std::vector< MemPtr > &queue, const TarmacContext &ptr)
Generates an Entry for every triggered memory access.
TarmacTracer & tracer
Reference to tracer.
Tarmac Tracer: this tracer generates a new Tarmac Record for every instruction being executed in gem5...
std::vector< InstPtr > instQueue
Collection of heterogeneous printable entries: could be representing either instructions,...
std::vector< RegPtr > regQueue
std::vector< MemPtr > memQueue
STL vector class.
Definition stl.hh:37
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
constexpr RegId V
Definition cc.hh:96
constexpr RegId C
Definition cc.hh:95
constexpr RegId Ge
Definition cc.hh:97
const char *const RegName[NumRegs]
Definition cc.hh:64
constexpr RegId Nz
Definition cc.hh:94
constexpr auto & Pc
Definition int.hh:276
@ MODE_UNDEFINED
Definition types.hh:295
Bitfield< 4, 0 > mode
Definition misc_types.hh:74
bool isSecure(ThreadContext *tc)
Definition utility.cc:74
constexpr auto & StackPointerReg
Definition int.hh:654
constexpr auto & ReturnAddressReg
Definition int.hh:655
@ MISCREG_CPSR
Definition misc.hh:66
Bitfield< 24, 21 > opcode
Definition types.hh:92
const char *const miscRegName[]
Definition misc.hh:1748
constexpr auto & FramePointerReg
Definition int.hh:653
Bitfield< 4 > pc
Bitfield< 5, 3 > reg
Definition types.hh:92
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
uint64_t Tick
Tick count type.
Definition types.hh:58
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
@ VecPredRegClass
Definition reg_class.hh:66
@ FloatRegClass
Floating-point register.
Definition reg_class.hh:61
@ CCRegClass
Condition-code register.
Definition reg_class.hh:68
@ VecRegClass
Vector Register.
Definition reg_class.hh:63
@ IntRegClass
Integer register.
Definition reg_class.hh:60
@ MiscRegClass
Control (misc) register.
Definition reg_class.hh:69
void ccprintf(cp::Print &print)
Definition cprintf.hh:130
TARMAC instruction trace record.
TARMAC memory access trace record (stores only).
TARMAC register trace record.
bool secureMode
True if instruction is executed in secure mode.
virtual void print(std::ostream &outs, int verbosity=0, const std::string &prefix="") const override
static uint64_t instCount
Number of instructions being traced.
uint8_t instSize
Instruction size: 16 for 16-bit Thumb Instruction 32 otherwise (ARM and BigThumb)
TraceInstEntry(const TarmacContext &tarmCtx, bool predicate)
TraceMemEntry(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 update(const TarmacContext &tarmCtx)
This updates the register entry using the update table.
virtual void updateCC(const TarmacContext &tarmCtx)
virtual void updateFloat(const TarmacContext &tarmCtx)
virtual void print(std::ostream &outs, int verbosity=0, const std::string &prefix="") const override
virtual void updateMisc(const TarmacContext &tarmCtx)
Register update functions.
TraceRegEntry(const TarmacContext &tarmCtx, const RegId &reg)
virtual void updateInt(const TarmacContext &tarmCtx)

Generated on Mon Jul 10 2023 15:31:57 for gem5 by doxygen 1.9.7