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         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 
181 void EtmV4ITrcPacket::toStringFmt(const uint32_t fmtFlags, std::string &str) const
182 {
183     toString(str);  // TBD add in formatted response.
184 }
185 
186 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 
459 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 
485 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 
497 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 
504 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 
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