1 /*
2 * \file trc_pkt_elem_etmv4i.cpp
3 * \brief OpenCSD :
4 *
5 * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
6 */
7
8 /*
9 * Redistribution and use in source and binary forms, with or without modification,
10 * are permitted provided that the following conditions are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of the copyright holder nor the names of its contributors
20 * may be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34 #include <sstream>
35 #include <iomanip>
36
37 #include "opencsd/etmv4/trc_pkt_elem_etmv4i.h"
38
EtmV4ITrcPacket()39 EtmV4ITrcPacket::EtmV4ITrcPacket()
40 {
41 }
42
~EtmV4ITrcPacket()43 EtmV4ITrcPacket::~EtmV4ITrcPacket()
44 {
45 }
46
initStartState()47 void EtmV4ITrcPacket::initStartState()
48 {
49 // clear packet state to start of trace (first sync or post discontinuity)
50
51 // clear all valid bits
52 pkt_valid.val = 0;
53
54 // virtual address
55 v_addr.pkt_bits = 0;
56 v_addr.valid_bits = 0;
57 v_addr_ISA = 0;
58
59 // timestamp
60 ts.bits_changed = 0;
61 ts.timestamp = 0;
62
63 // per packet init
64 initNextPacket();
65 }
66
initNextPacket()67 void EtmV4ITrcPacket::initNextPacket()
68 {
69 // clear valid bits for elements that are only valid over a single packet.
70 pkt_valid.bits.cc_valid = 0;
71 pkt_valid.bits.commit_elem_valid = 0;
72 atom.num = 0;
73 context.updated = 0;
74 context.updated_v = 0;
75 context.updated_c = 0;
76 err_type = ETM4_PKT_I_NO_ERR_TYPE;
77 }
78
79 // printing
toString(std::string & str) const80 void EtmV4ITrcPacket::toString(std::string &str) const
81 {
82 const char *name;
83 const char *desc;
84 std::string valStr, ctxtStr = "";
85
86 name = packetTypeName(type, &desc);
87 str = name + (std::string)" : " + desc;
88
89 // extended descriptions
90 switch (type)
91 {
92 case ETM4_PKT_I_BAD_SEQUENCE:
93 case ETM4_PKT_I_INCOMPLETE_EOT:
94 name = packetTypeName(err_type, 0);
95 str += "[" + (std::string)name + "]";
96 break;
97
98 case ETM4_PKT_I_ADDR_CTXT_L_32IS0:
99 case ETM4_PKT_I_ADDR_CTXT_L_32IS1:
100 contextStr(ctxtStr);
101 case ETM4_PKT_I_ADDR_L_32IS0:
102 case ETM4_PKT_I_ADDR_L_32IS1:
103 trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true, (v_addr.pkt_bits < 32) ? v_addr.pkt_bits : 0);
104 str += "; Addr=" + valStr + "; " + ctxtStr;
105 break;
106
107 case ETM4_PKT_I_ADDR_CTXT_L_64IS0:
108 case ETM4_PKT_I_ADDR_CTXT_L_64IS1:
109 contextStr(ctxtStr);
110 case ETM4_PKT_I_ADDR_L_64IS0:
111 case ETM4_PKT_I_ADDR_L_64IS1:
112 trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true, (v_addr.pkt_bits < 64) ? v_addr.pkt_bits : 0);
113 str += "; Addr=" + valStr + "; " + ctxtStr;
114 break;
115
116 case ETM4_PKT_I_CTXT:
117 contextStr(ctxtStr);
118 str += "; " + ctxtStr;
119 break;
120
121 case ETM4_PKT_I_ADDR_S_IS0:
122 case ETM4_PKT_I_ADDR_S_IS1:
123 trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true, v_addr.pkt_bits);
124 str += "; Addr=" + valStr;
125 break;
126
127 case ETM4_PKT_I_ADDR_MATCH:
128 addrMatchIdx(valStr);
129 str += ", " + valStr;
130 trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true);
131 str += "; Addr=" + valStr + "; " + ctxtStr;
132 break;
133
134 case ETM4_PKT_I_ATOM_F1:
135 case ETM4_PKT_I_ATOM_F2:
136 case ETM4_PKT_I_ATOM_F3:
137 case ETM4_PKT_I_ATOM_F4:
138 case ETM4_PKT_I_ATOM_F5:
139 case ETM4_PKT_I_ATOM_F6:
140 atomSeq(valStr);
141 str += "; " + valStr;
142 break;
143
144 case ETM4_PKT_I_EXCEPT:
145 exceptionInfo(valStr);
146 str += "; " + valStr;
147 break;
148
149 case ETM4_PKT_I_TIMESTAMP:
150 {
151 std::ostringstream oss;
152 oss << "; Updated val = " << std::hex << "0x" << ts.timestamp;
153 if (pkt_valid.bits.cc_valid)
154 oss << "; CC=" << std::hex << "0x" << cycle_count;
155 str += oss.str();
156 }
157 break;
158
159 case ETM4_PKT_I_TRACE_INFO:
160 {
161 std::ostringstream oss;
162 oss << "; INFO=" << std::hex << "0x" << trace_info.val;
163 if (trace_info.bits.cc_enabled)
164 oss << "; CC_THRESHOLD=" << std::hex << "0x" << cc_threshold;
165 str += oss.str();
166 }
167 break;
168
169 case ETM4_PKT_I_CCNT_F1:
170 case ETM4_PKT_I_CCNT_F2:
171 case ETM4_PKT_I_CCNT_F3:
172 {
173 std::ostringstream oss;
174 oss << "; Count=" << std::hex << "0x" << cycle_count;
175 str += oss.str();
176 }
177 break;
178 }
179 }
180
toStringFmt(const uint32_t fmtFlags,std::string & str) const181 void EtmV4ITrcPacket::toStringFmt(const uint32_t fmtFlags, std::string &str) const
182 {
183 toString(str); // TBD add in formatted response.
184 }
185
packetTypeName(const ocsd_etmv4_i_pkt_type type,const char ** ppDesc) const186 const char *EtmV4ITrcPacket::packetTypeName(const ocsd_etmv4_i_pkt_type type, const char **ppDesc) const
187 {
188 const char *pName = "I_RESERVED";
189 const char *pDesc = "Reserved Packet Header";
190
191 switch(type)
192 {
193 case ETM4_PKT_I_RESERVED: break; // default;
194
195 case ETM4_PKT_I_NOTSYNC:
196 pName = "I_NOT_SYNC";
197 pDesc = "I Stream not synchronised";
198 break;
199
200 case ETM4_PKT_I_BAD_SEQUENCE:
201 pName = "I_BAD_SEQUENCE";
202 pDesc = "Invalid Sequence in packet.";
203 break;
204
205 case ETM4_PKT_I_BAD_TRACEMODE:
206 pName = "I_BAD_TRACEMODE";
207 pDesc = "Invalid Packet for trace mode.";
208 break;
209
210 case ETM4_PKT_I_INCOMPLETE_EOT:
211 pName = "I_INCOMPLETE_EOT";
212 pDesc = "Incomplete packet at end of trace.";
213 break;
214
215 case ETM4_PKT_I_NO_ERR_TYPE:
216 pName = "I_NO_ERR_TYPE";
217 pDesc = "No Error Type.";
218 break;
219
220 case ETM4_PKT_I_EXTENSION:
221 pName = "I_EXTENSION";
222 pDesc = "Extention packet header.";
223 break;
224
225 case ETM4_PKT_I_ADDR_CTXT_L_32IS0:
226 pName = "I_ADDR_CTXT_L_32IS0";
227 pDesc = "Address & Context, Long, 32 bit, IS0.";
228 break;
229
230 case ETM4_PKT_I_ADDR_CTXT_L_32IS1:
231 pName = "I_ADDR_CTXT_L_32IS1";
232 pDesc = "Address & Context, Long, 32 bit, IS0.";
233 break;
234
235 case ETM4_PKT_I_ADDR_CTXT_L_64IS0:
236 pName = "I_ADDR_CTXT_L_64IS0";
237 pDesc = "Address & Context, Long, 64 bit, IS0.";
238 break;
239
240 case ETM4_PKT_I_ADDR_CTXT_L_64IS1:
241 pName = "I_ADDR_CTXT_L_64IS1";
242 pDesc = "Address & Context, Long, 64 bit, IS1.";
243 break;
244
245 case ETM4_PKT_I_CTXT:
246 pName = "I_CTXT";
247 pDesc = "Context Packet.";
248 break;
249
250 case ETM4_PKT_I_ADDR_MATCH:
251 pName = "I_ADDR_MATCH";
252 pDesc = "Exact Address Match.";
253 break;
254
255 case ETM4_PKT_I_ADDR_L_32IS0:
256 pName = "I_ADDR_L_32IS0";
257 pDesc = "Address, Long, 32 bit, IS0.";
258 break;
259
260 case ETM4_PKT_I_ADDR_L_32IS1:
261 pName = "I_ADDR_L_32IS1";
262 pDesc = "Address, Long, 32 bit, IS1.";
263 break;
264
265 case ETM4_PKT_I_ADDR_L_64IS0:
266 pName = "I_ADDR_L_64IS0";
267 pDesc = "Address, Long, 64 bit, IS0.";
268 break;
269
270 case ETM4_PKT_I_ADDR_L_64IS1:
271 pName = "I_ADDR_L_64IS1";
272 pDesc = "Address, Long, 64 bit, IS1.";
273 break;
274
275 case ETM4_PKT_I_ADDR_S_IS0:
276 pName = "I_ADDR_S_IS0";
277 pDesc = "Address, Short, IS0.";
278 break;
279
280 case ETM4_PKT_I_ADDR_S_IS1:
281 pName = "I_ADDR_S_IS1";
282 pDesc = "Address, Short, IS1.";
283 break;
284
285 case ETM4_PKT_I_Q:
286 pName = "I_Q";
287 pDesc = "Q Packet.";
288 break;
289
290 case ETM4_PKT_I_ATOM_F1:
291 pName = "I_ATOM_F1";
292 pDesc = "Atom format 1.";
293 break;
294
295 case ETM4_PKT_I_ATOM_F2:
296 pName = "I_ATOM_F2";
297 pDesc = "Atom format 2.";
298 break;
299
300 case ETM4_PKT_I_ATOM_F3:
301 pName = "I_ATOM_F3";
302 pDesc = "Atom format 3.";
303 break;
304
305 case ETM4_PKT_I_ATOM_F4:
306 pName = "I_ATOM_F4";
307 pDesc = "Atom format 4.";
308 break;
309
310 case ETM4_PKT_I_ATOM_F5:
311 pName = "I_ATOM_F5";
312 pDesc = "Atom format 5.";
313 break;
314
315 case ETM4_PKT_I_ATOM_F6:
316 pName = "I_ATOM_F6";
317 pDesc = "Atom format 6.";
318 break;
319
320 case ETM4_PKT_I_COND_FLUSH:
321 pName = "I_COND_FLUSH";
322 pDesc = "Conditional Flush.";
323 break;
324
325 case ETM4_PKT_I_COND_I_F1:
326 pName = "I_COND_I_F1";
327 pDesc = "Conditional Instruction, format 1.";
328 break;
329
330 case ETM4_PKT_I_COND_I_F2:
331 pName = "I_COND_I_F2";
332 pDesc = "Conditional Instruction, format 2.";
333 break;
334
335 case ETM4_PKT_I_COND_I_F3:
336 pName = "I_COND_I_F3";
337 pDesc = "Conditional Instruction, format 3.";
338 break;
339
340 case ETM4_PKT_I_COND_RES_F1:
341 pName = "I_COND_RES_F1";
342 pDesc = "Conditional Result, format 1.";
343 break;
344
345 case ETM4_PKT_I_COND_RES_F2:
346 pName = "I_COND_RES_F2";
347 pDesc = "Conditional Result, format 2.";
348 break;
349
350 case ETM4_PKT_I_COND_RES_F3:
351 pName = "I_COND_RES_F3";
352 pDesc = "Conditional Result, format 3.";
353 break;
354
355 case ETM4_PKT_I_COND_RES_F4:
356 pName = "I_COND_RES_F4";
357 pDesc = "Conditional Result, format 4.";
358 break;
359
360 case ETM4_PKT_I_CCNT_F1:
361 pName = "I_CCNT_F1";
362 pDesc = "Cycle Count format 1.";
363 break;
364
365 case ETM4_PKT_I_CCNT_F2:
366 pName = "I_CCNT_F2";
367 pDesc = "Cycle Count format 2.";
368 break;
369
370 case ETM4_PKT_I_CCNT_F3:
371 pName = "I_CCNT_F3";
372 pDesc = "Cycle Count format 3.";
373 break;
374
375 case ETM4_PKT_I_NUM_DS_MKR:
376 pName = "I_NUM_DS_MKR";
377 pDesc = "Data Synchronisation Marker - Numbered.";
378 break;
379
380 case ETM4_PKT_I_UNNUM_DS_MKR:
381 pName = "I_UNNUM_DS_MKR";
382 pDesc = "Data Synchronisation Marker - Unnumbered.";
383 break;
384
385 case ETM4_PKT_I_EVENT:
386 pName = "I_EVENT";
387 pDesc = "Trace Event.";
388 break;
389
390 case ETM4_PKT_I_EXCEPT:
391 pName = "I_EXCEPT";
392 pDesc = "Exception.";
393 break;
394
395 case ETM4_PKT_I_EXCEPT_RTN:
396 pName = "I_EXCEPT_RTN";
397 pDesc = "Exception Return.";
398 break;
399
400 case ETM4_PKT_I_TIMESTAMP:
401 pName = "I_TIMESTAMP";
402 pDesc = "Timestamp.";
403 break;
404
405 case ETM4_PKT_I_CANCEL_F1:
406 pName = "I_CANCEL_F1";
407 pDesc = "Cancel Format 1.";
408 break;
409 case ETM4_PKT_I_CANCEL_F2:
410 pName = "I_CANCEL_F2";
411 pDesc = "Cancel Format 2.";
412 break;
413
414 case ETM4_PKT_I_CANCEL_F3:
415 pName = "I_CANCEL_F3";
416 pDesc = "Cancel Format 3.";
417 break;
418
419 case ETM4_PKT_I_COMMIT:
420 pName = "I_COMMIT";
421 pDesc = "Commit";
422 break;
423
424 case ETM4_PKT_I_MISPREDICT:
425 pName = "I_MISPREDICT";
426 pDesc = "Mispredict.";
427 break;
428
429 case ETM4_PKT_I_TRACE_INFO:
430 pName = "I_TRACE_INFO";
431 pDesc = "Trace Info.";
432 break;
433
434 case ETM4_PKT_I_TRACE_ON:
435 pName = "I_TRACE_ON";
436 pDesc = "Trace On.";
437 break;
438
439 case ETM4_PKT_I_ASYNC:
440 pName = "I_ASYNC";
441 pDesc = "Alignment Synchronisation.";
442 break;
443
444 case ETM4_PKT_I_DISCARD:
445 pName = "I_DISCARD";
446 pDesc = "Discard.";
447 break;
448
449 case ETM4_PKT_I_OVERFLOW:
450 pName = "I_OVERFLOW";
451 pDesc = "Overflow.";
452 break;
453 }
454
455 if(ppDesc) *ppDesc = pDesc;
456 return pName;
457 }
458
contextStr(std::string & ctxtStr) const459 void EtmV4ITrcPacket::contextStr(std::string &ctxtStr) const
460 {
461 ctxtStr = "";
462 if(pkt_valid.bits.context_valid)
463 {
464 std::ostringstream oss;
465 if(context.updated)
466 {
467 oss << "Ctxt: " << (context.SF ? "AArch64," : "AArch32, ") << "EL" << context.EL << ", " << (context.NS ? "NS; " : "S; ");
468 if(context.updated_c)
469 {
470 oss << "CID=0x" << std::hex << std::setfill('0') << std::setw(8) << context.ctxtID << "; ";
471 }
472 if(context.updated_v)
473 {
474 oss << "VMID=0x" << std::hex << std::setfill('0') << std::setw(4) << context.VMID << "; ";
475 }
476 }
477 else
478 {
479 oss << "Ctxt: Same";
480 }
481 ctxtStr = oss.str();
482 }
483 }
484
atomSeq(std::string & valStr) const485 void EtmV4ITrcPacket::atomSeq(std::string &valStr) const
486 {
487 std::ostringstream oss;
488 uint32_t bitpattern = atom.En_bits;
489 for(int i = 0; i < atom.num; i++)
490 {
491 oss << ((bitpattern & 0x1) ? "E" : "N");
492 bitpattern >>= 1;
493 }
494 valStr = oss.str();
495 }
496
addrMatchIdx(std::string & valStr) const497 void EtmV4ITrcPacket::addrMatchIdx(std::string &valStr) const
498 {
499 std::ostringstream oss;
500 oss << "[" << (uint16_t)addr_exact_match_idx << "]";
501 valStr = oss.str();
502 }
503
exceptionInfo(std::string & valStr) const504 void EtmV4ITrcPacket::exceptionInfo(std::string &valStr) const
505 {
506 std::ostringstream oss;
507
508 static const char *ARv8Excep[] = {
509 "PE Reset", "Debug Halt", "Call", "Trap",
510 "System Error", "Reserved", "Inst Debug", "Data Debug",
511 "Reserved", "Reserved", "Alignment", "Inst Fault",
512 "Data Fault", "Reserved", "IRQ", "FIQ"
513 };
514
515 static const char *MExcep[] = {
516 "Reserved", "PE Reset", "NMI", "HardFault",
517 "MemManage", "BusFault", "UsageFault", "Reserved",
518 "Reserved","Reserved","Reserved","SVC",
519 "DebugMonitor", "Reserved","PendSV","SysTick",
520 "IRQ0","IRQ1","IRQ2","IRQ3",
521 "IRQ4","IRQ5","IRQ6","IRQ7",
522 "DebugHalt", "LazyFP Push", "Lockup", "Reserved",
523 "Reserved","Reserved","Reserved","Reserved"
524 };
525
526 if(exception_info.m_type == 0)
527 {
528 if(exception_info.exceptionType < 0x10)
529 oss << " " << ARv8Excep[exception_info.exceptionType] << ";";
530 else
531 oss << " Reserved;";
532
533 }
534 else
535 {
536 if(exception_info.exceptionType < 0x20)
537 oss << " " << MExcep[exception_info.exceptionType] << ";";
538 else if((exception_info.exceptionType >= 0x208) && (exception_info.exceptionType <= 0x3EF))
539 oss << " IRQ" << (int)(exception_info.exceptionType - 0x200) << ";";
540 else
541 oss << " Reserved;";
542 if(exception_info.m_fault_pending)
543 oss << " Fault Pending;";
544 }
545
546 if(exception_info.addr_interp == 0x1)
547 oss << " Ret Addr Follows;";
548 else if(exception_info.addr_interp == 0x2)
549 oss << " Ret Addr Follows, Match Prev;";
550
551 valStr = oss.str();
552 }
553
operator =(const ocsd_etmv4_i_pkt * p_pkt)554 EtmV4ITrcPacket &EtmV4ITrcPacket::operator =(const ocsd_etmv4_i_pkt* p_pkt)
555 {
556 *dynamic_cast<ocsd_etmv4_i_pkt *>(this) = *p_pkt;
557 return *this;
558 }
559
560 /* End of File trc_pkt_elem_etmv4i.cpp */
561