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 
39 EtmV4ITrcPacket::EtmV4ITrcPacket()
40 {
41 }
42 
43 EtmV4ITrcPacket::~EtmV4ITrcPacket()
44 {
45 }
46 
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 
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
80 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     case ETM4_PKT_I_RESERVED_CFG:
95         name = packetTypeName(err_type, 0);
96         str += "[" + (std::string)name + "]";
97         break;
98 
99     case ETM4_PKT_I_ADDR_CTXT_L_32IS0:
100     case ETM4_PKT_I_ADDR_CTXT_L_32IS1:
101         contextStr(ctxtStr);
102     case ETM4_PKT_I_ADDR_L_32IS0:
103     case ETM4_PKT_I_ADDR_L_32IS1:
104         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);
105         str += "; Addr=" + valStr + "; " + ctxtStr;
106         break;
107 
108     case ETM4_PKT_I_ADDR_CTXT_L_64IS0:
109     case ETM4_PKT_I_ADDR_CTXT_L_64IS1:
110         contextStr(ctxtStr);
111     case ETM4_PKT_I_ADDR_L_64IS0:
112     case ETM4_PKT_I_ADDR_L_64IS1:
113         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);
114         str += "; Addr=" + valStr + "; " + ctxtStr;
115         break;
116 
117     case ETM4_PKT_I_CTXT:
118         contextStr(ctxtStr);
119         str += "; " + ctxtStr;
120         break;
121 
122     case ETM4_PKT_I_ADDR_S_IS0:
123     case ETM4_PKT_I_ADDR_S_IS1:
124         trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true, v_addr.pkt_bits);
125         str += "; Addr=" + valStr;
126         break;
127 
128     case ETM4_PKT_I_ADDR_MATCH:
129         addrMatchIdx(valStr);
130         str += ", " + valStr;
131         trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true);
132         str += "; Addr=" + valStr + "; " + ctxtStr;
133         break;
134 
135     case ETM4_PKT_I_ATOM_F1:
136     case ETM4_PKT_I_ATOM_F2:
137     case ETM4_PKT_I_ATOM_F3:
138     case ETM4_PKT_I_ATOM_F4:
139     case ETM4_PKT_I_ATOM_F5:
140     case ETM4_PKT_I_ATOM_F6:
141         atomSeq(valStr);
142         str += "; " + valStr;
143         break;
144 
145     case ETM4_PKT_I_EXCEPT:
146         exceptionInfo(valStr);
147         str += "; " + valStr;
148         break;
149 
150     case ETM4_PKT_I_TIMESTAMP:
151         {
152             std::ostringstream oss;
153             oss << "; Updated val = " << std::hex << "0x" << ts.timestamp;
154             if (pkt_valid.bits.cc_valid)
155                 oss << "; CC=" << std::hex << "0x" << cycle_count;
156             str += oss.str();
157         }
158         break;
159 
160     case ETM4_PKT_I_TRACE_INFO:
161         {
162             std::ostringstream oss;
163             oss << "; INFO=" << std::hex << "0x" << trace_info.val;
164             if (trace_info.bits.cc_enabled)
165                 oss << "; CC_THRESHOLD=" << std::hex << "0x" << cc_threshold;
166             str += oss.str();
167         }
168         break;
169 
170     case ETM4_PKT_I_CCNT_F1:
171     case ETM4_PKT_I_CCNT_F2:
172     case ETM4_PKT_I_CCNT_F3:
173         {
174             std::ostringstream oss;
175             oss << "; Count=" << std::hex << "0x" << cycle_count;
176             str += oss.str();
177         }
178         break;
179     }
180 }
181 
182 void EtmV4ITrcPacket::toStringFmt(const uint32_t fmtFlags, std::string &str) const
183 {
184     toString(str);  // TBD add in formatted response.
185 }
186 
187 const char *EtmV4ITrcPacket::packetTypeName(const ocsd_etmv4_i_pkt_type type, const char **ppDesc) const
188 {
189     const char *pName = "I_UNKNOWN";
190     const char *pDesc = "Unknown Packet Header";
191 
192     switch(type)
193     {
194     case ETM4_PKT_I_NOTSYNC:
195         pName = "I_NOT_SYNC";
196         pDesc = "I Stream not synchronised";
197         break;
198 
199     case ETM4_PKT_I_INCOMPLETE_EOT:
200         pName = "I_INCOMPLETE_EOT";
201         pDesc = "Incomplete packet at end of trace.";
202         break;
203 
204     case ETM4_PKT_I_NO_ERR_TYPE:
205         pName = "I_NO_ERR_TYPE";
206         pDesc = "No Error Type.";
207         break;
208 
209     case ETM4_PKT_I_BAD_SEQUENCE:
210         pName = "I_BAD_SEQUENCE";
211         pDesc = "Invalid Sequence in packet.";
212         break;
213 
214     case ETM4_PKT_I_BAD_TRACEMODE:
215         pName = "I_BAD_TRACEMODE";
216         pDesc = "Invalid Packet for trace mode.";
217         break;
218 
219     case ETM4_PKT_I_RESERVED:
220         pName = "I_RESERVED";
221         pDesc = "Reserved Packet Header";
222         break;
223 
224     case ETM4_PKT_I_RESERVED_CFG:
225         pName = "I_RESERVED_CFG";
226         pDesc = "Reserved header for current configuration.";
227         break;
228 
229     case ETM4_PKT_I_EXTENSION:
230         pName = "I_EXTENSION";
231         pDesc = "Extension packet header.";
232         break;
233 
234     case ETM4_PKT_I_TRACE_INFO:
235         pName = "I_TRACE_INFO";
236         pDesc = "Trace Info.";
237         break;
238 
239     case ETM4_PKT_I_TIMESTAMP:
240         pName = "I_TIMESTAMP";
241         pDesc = "Timestamp.";
242         break;
243 
244     case ETM4_PKT_I_TRACE_ON:
245         pName = "I_TRACE_ON";
246         pDesc = "Trace On.";
247         break;
248 
249     case ETM4_PKT_I_FUNC_RET:
250         pName = "I_FUNC_RET";
251         pDesc = "V8M - function return.";
252         break;
253 
254     case ETM4_PKT_I_EXCEPT:
255         pName = "I_EXCEPT";
256         pDesc = "Exception.";
257         break;
258 
259     case ETM4_PKT_I_EXCEPT_RTN:
260         pName = "I_EXCEPT_RTN";
261         pDesc = "Exception Return.";
262         break;
263 
264     case ETM4_PKT_I_CCNT_F1:
265         pName = "I_CCNT_F1";
266         pDesc = "Cycle Count format 1.";
267         break;
268 
269     case ETM4_PKT_I_CCNT_F2:
270         pName = "I_CCNT_F2";
271         pDesc = "Cycle Count format 2.";
272         break;
273 
274     case ETM4_PKT_I_CCNT_F3:
275         pName = "I_CCNT_F3";
276         pDesc = "Cycle Count format 3.";
277         break;
278 
279     case ETM4_PKT_I_NUM_DS_MKR:
280         pName = "I_NUM_DS_MKR";
281         pDesc = "Data Synchronisation Marker - Numbered.";
282         break;
283 
284     case ETM4_PKT_I_UNNUM_DS_MKR:
285         pName = "I_UNNUM_DS_MKR";
286         pDesc = "Data Synchronisation Marker - Unnumbered.";
287         break;
288 
289     case ETM4_PKT_I_COMMIT:
290         pName = "I_COMMIT";
291         pDesc = "Commit";
292         break;
293 
294     case ETM4_PKT_I_CANCEL_F1:
295         pName = "I_CANCEL_F1";
296         pDesc = "Cancel Format 1.";
297         break;
298 
299     case ETM4_PKT_I_MISPREDICT:
300         pName = "I_MISPREDICT";
301         pDesc = "Mispredict.";
302         break;
303 
304     case ETM4_PKT_I_CANCEL_F2:
305         pName = "I_CANCEL_F2";
306         pDesc = "Cancel Format 2.";
307         break;
308 
309     case ETM4_PKT_I_CANCEL_F3:
310         pName = "I_CANCEL_F3";
311         pDesc = "Cancel Format 3.";
312         break;
313 
314     case ETM4_PKT_I_COND_I_F2:
315         pName = "I_COND_I_F2";
316         pDesc = "Conditional Instruction, format 2.";
317         break;
318 
319     case ETM4_PKT_I_COND_FLUSH:
320         pName = "I_COND_FLUSH";
321         pDesc = "Conditional Flush.";
322         break;
323 
324     case ETM4_PKT_I_COND_RES_F4:
325         pName = "I_COND_RES_F4";
326         pDesc = "Conditional Result, format 4.";
327         break;
328 
329     case ETM4_PKT_I_COND_RES_F2:
330         pName = "I_COND_RES_F2";
331         pDesc = "Conditional Result, format 2.";
332         break;
333 
334     case ETM4_PKT_I_COND_RES_F3:
335         pName = "I_COND_RES_F3";
336         pDesc = "Conditional Result, format 3.";
337         break;
338 
339     case ETM4_PKT_I_COND_RES_F1:
340         pName = "I_COND_RES_F1";
341         pDesc = "Conditional Result, format 1.";
342         break;
343 
344     case ETM4_PKT_I_COND_I_F1:
345         pName = "I_COND_I_F1";
346         pDesc = "Conditional Instruction, format 1.";
347         break;
348 
349     case ETM4_PKT_I_COND_I_F3:
350         pName = "I_COND_I_F3";
351         pDesc = "Conditional Instruction, format 3.";
352         break;
353 
354     case ETM4_PKT_I_IGNORE:
355         pName = "I_IGNORE";
356         pDesc = "Ignore.";
357         break;
358 
359     case ETM4_PKT_I_EVENT:
360         pName = "I_EVENT";
361         pDesc = "Trace Event.";
362         break;
363 
364     case ETM4_PKT_I_CTXT:
365         pName = "I_CTXT";
366         pDesc = "Context Packet.";
367         break;
368 
369     case ETM4_PKT_I_ADDR_CTXT_L_32IS0:
370         pName = "I_ADDR_CTXT_L_32IS0";
371         pDesc = "Address & Context, Long, 32 bit, IS0.";
372         break;
373 
374     case ETM4_PKT_I_ADDR_CTXT_L_32IS1:
375         pName = "I_ADDR_CTXT_L_32IS1";
376         pDesc = "Address & Context, Long, 32 bit, IS0.";
377         break;
378 
379     case ETM4_PKT_I_ADDR_CTXT_L_64IS0:
380         pName = "I_ADDR_CTXT_L_64IS0";
381         pDesc = "Address & Context, Long, 64 bit, IS0.";
382         break;
383 
384     case ETM4_PKT_I_ADDR_CTXT_L_64IS1:
385         pName = "I_ADDR_CTXT_L_64IS1";
386         pDesc = "Address & Context, Long, 64 bit, IS1.";
387         break;
388 
389     case ETM4_PKT_I_ADDR_MATCH:
390         pName = "I_ADDR_MATCH";
391         pDesc = "Exact Address Match.";
392         break;
393 
394     case ETM4_PKT_I_ADDR_S_IS0:
395         pName = "I_ADDR_S_IS0";
396         pDesc = "Address, Short, IS0.";
397         break;
398 
399     case ETM4_PKT_I_ADDR_S_IS1:
400         pName = "I_ADDR_S_IS1";
401         pDesc = "Address, Short, IS1.";
402         break;
403 
404     case ETM4_PKT_I_ADDR_L_32IS0:
405         pName = "I_ADDR_L_32IS0";
406         pDesc = "Address, Long, 32 bit, IS0.";
407         break;
408 
409     case ETM4_PKT_I_ADDR_L_32IS1:
410         pName = "I_ADDR_L_32IS1";
411         pDesc = "Address, Long, 32 bit, IS1.";
412         break;
413 
414     case ETM4_PKT_I_ADDR_L_64IS0:
415         pName = "I_ADDR_L_64IS0";
416         pDesc = "Address, Long, 64 bit, IS0.";
417         break;
418 
419     case ETM4_PKT_I_ADDR_L_64IS1:
420         pName = "I_ADDR_L_64IS1";
421         pDesc = "Address, Long, 64 bit, IS1.";
422         break;
423 
424     case ETM4_PKT_I_Q:
425         pName = "I_Q";
426         pDesc = "Q Packet.";
427         break;
428 
429     case ETM4_PKT_I_ATOM_F6:
430         pName = "I_ATOM_F6";
431         pDesc = "Atom format 6.";
432         break;
433 
434     case ETM4_PKT_I_ATOM_F5:
435         pName = "I_ATOM_F5";
436         pDesc = "Atom format 5.";
437         break;
438 
439     case ETM4_PKT_I_ATOM_F2:
440         pName = "I_ATOM_F2";
441         pDesc = "Atom format 2.";
442         break;
443 
444     case ETM4_PKT_I_ATOM_F4:
445         pName = "I_ATOM_F4";
446         pDesc = "Atom format 4.";
447         break;
448 
449     case ETM4_PKT_I_ATOM_F1:
450         pName = "I_ATOM_F1";
451         pDesc = "Atom format 1.";
452         break;
453 
454     case ETM4_PKT_I_ATOM_F3:
455         pName = "I_ATOM_F3";
456         pDesc = "Atom format 3.";
457         break;
458 
459     case ETM4_PKT_I_ASYNC:
460         pName = "I_ASYNC";
461         pDesc = "Alignment Synchronisation.";
462         break;
463 
464     case ETM4_PKT_I_DISCARD:
465         pName = "I_DISCARD";
466         pDesc = "Discard.";
467         break;
468 
469     case ETM4_PKT_I_OVERFLOW:
470         pName = "I_OVERFLOW";
471         pDesc = "Overflow.";
472         break;
473 
474     default:
475         break;
476     }
477 
478     if(ppDesc) *ppDesc = pDesc;
479     return pName;
480 }
481 
482 void EtmV4ITrcPacket::contextStr(std::string &ctxtStr) const
483 {
484     ctxtStr = "";
485     if(pkt_valid.bits.context_valid)
486     {
487         std::ostringstream oss;
488         if(context.updated)
489         {
490             oss << "Ctxt: " << (context.SF ? "AArch64," : "AArch32, ") << "EL" << context.EL << ", " << (context.NS ? "NS; " : "S; ");
491             if(context.updated_c)
492             {
493                 oss << "CID=0x" << std::hex << std::setfill('0') << std::setw(8) << context.ctxtID << "; ";
494             }
495             if(context.updated_v)
496             {
497                 oss << "VMID=0x" << std::hex << std::setfill('0') << std::setw(4) << context.VMID << "; ";
498             }
499         }
500         else
501         {
502             oss << "Ctxt: Same";
503         }
504         ctxtStr = oss.str();
505     }
506 }
507 
508 void EtmV4ITrcPacket::atomSeq(std::string &valStr) const
509 {
510     std::ostringstream oss;
511     uint32_t bitpattern = atom.En_bits;
512     for(int i = 0; i < atom.num; i++)
513     {
514         oss << ((bitpattern & 0x1) ? "E" : "N");
515         bitpattern >>= 1;
516     }
517     valStr = oss.str();
518 }
519 
520 void EtmV4ITrcPacket::addrMatchIdx(std::string &valStr) const
521 {
522     std::ostringstream oss;
523     oss << "[" << (uint16_t)addr_exact_match_idx << "]";
524     valStr = oss.str();
525 }
526 
527 void EtmV4ITrcPacket::exceptionInfo(std::string &valStr) const
528 {
529     std::ostringstream oss;
530 
531     static const char *ARv8Excep[] = {
532         "PE Reset", "Debug Halt", "Call", "Trap",
533         "System Error", "Reserved", "Inst Debug", "Data Debug",
534         "Reserved", "Reserved", "Alignment", "Inst Fault",
535         "Data Fault", "Reserved", "IRQ", "FIQ"
536     };
537 
538     static const char *MExcep[] = {
539         "Reserved", "PE Reset", "NMI", "HardFault",
540         "MemManage", "BusFault", "UsageFault", "Reserved",
541         "Reserved","Reserved","Reserved","SVC",
542         "DebugMonitor", "Reserved","PendSV","SysTick",
543         "IRQ0","IRQ1","IRQ2","IRQ3",
544         "IRQ4","IRQ5","IRQ6","IRQ7",
545         "DebugHalt", "LazyFP Push", "Lockup", "Reserved",
546         "Reserved","Reserved","Reserved","Reserved"
547     };
548 
549     if(exception_info.m_type == 0)
550     {
551         if(exception_info.exceptionType < 0x10)
552             oss << " " << ARv8Excep[exception_info.exceptionType] << ";";
553         else
554             oss << " Reserved;";
555 
556     }
557     else
558     {
559         if(exception_info.exceptionType < 0x20)
560             oss << " " << MExcep[exception_info.exceptionType] << ";";
561         else if((exception_info.exceptionType >= 0x208) && (exception_info.exceptionType <= 0x3EF))
562             oss << " IRQ" << (int)(exception_info.exceptionType - 0x200) << ";";
563         else
564             oss << " Reserved;";
565         if(exception_info.m_fault_pending)
566             oss << " Fault Pending;";
567     }
568 
569     if(exception_info.addr_interp == 0x1)
570         oss << " Ret Addr Follows;";
571     else if(exception_info.addr_interp == 0x2)
572         oss << " Ret Addr Follows, Match Prev;";
573 
574     valStr = oss.str();
575 }
576 
577 EtmV4ITrcPacket &EtmV4ITrcPacket::operator =(const ocsd_etmv4_i_pkt* p_pkt)
578 {
579     *dynamic_cast<ocsd_etmv4_i_pkt *>(this) = *p_pkt;
580     return *this;
581 }
582 
583 /* End of File trc_pkt_elem_etmv4i.cpp */
584