xref: /freebsd/contrib/opencsd/decoder/source/etmv3/trc_pkt_elem_etmv3.cpp (revision 46e6e290975f19ea62d03f90ac3e523af4dae557)
1 /*
2  * \file       trc_pkt_elem_etmv3.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 
35 #include <cstring>
36 #include <sstream>
37 #include <iomanip>
38 
39 #include "opencsd/etmv3/trc_pkt_elem_etmv3.h"
40 
EtmV3TrcPacket()41 EtmV3TrcPacket::EtmV3TrcPacket()
42 {
43     m_pkt_data.addr.size = VA_32BIT;   // etm v3 only handles 32 bit addresses.
44 }
45 
~EtmV3TrcPacket()46 EtmV3TrcPacket::~EtmV3TrcPacket()
47 {
48 }
49 
50 // update interface - set packet values
51 
52 // clear this packet info
Clear()53 void EtmV3TrcPacket::Clear()
54 {
55     // clear structure flags and counter elements etc, that work per packet.
56     // leave intra packet data unchanged
57     m_pkt_data.addr.pkt_bits = 0;
58     m_pkt_data.prev_isa = m_pkt_data.curr_isa;    // mark ISA as not changed
59     m_pkt_data.exception.bits.present = 0;
60     m_pkt_data.atom.num = 0;
61     m_pkt_data.cycle_count = 0;
62     m_pkt_data.context.updated = 0;
63     m_pkt_data.context.updated_c = 0;
64     m_pkt_data.context.updated_v = 0;
65     m_pkt_data.data.ooo_tag = 0;
66     m_pkt_data.data.value = 0;
67     m_pkt_data.data.update_addr = 0;
68     m_pkt_data.data.update_be = 0;
69     m_pkt_data.data.update_dval = 0;
70     m_pkt_data.ts_update_bits = 0;
71     m_pkt_data.isync_info.has_cycle_count = 0;
72     m_pkt_data.isync_info.has_LSipAddress = 0;
73     m_pkt_data.isync_info.no_address = 0;
74 }
75 
76 // reset all state including intra packet
ResetState()77 void EtmV3TrcPacket::ResetState()
78 {
79     memset(&m_pkt_data,0,sizeof(ocsd_etmv3_pkt));
80     m_pkt_data.curr_isa = m_pkt_data.prev_isa = ocsd_isa_unknown;
81 }
82 
UpdateAddress(const ocsd_vaddr_t partAddrVal,const int updateBits)83 void EtmV3TrcPacket::UpdateAddress(const ocsd_vaddr_t partAddrVal, const int updateBits)
84 {
85     ocsd_vaddr_t validMask = OCSD_VA_MASK;
86     validMask >>= OCSD_MAX_VA_BITSIZE-updateBits;
87     m_pkt_data.addr.pkt_bits = updateBits;
88     m_pkt_data.addr.val &= ~validMask;
89     m_pkt_data.addr.val |= (partAddrVal & validMask);
90     if(updateBits > m_pkt_data.addr.valid_bits)
91         m_pkt_data.addr.valid_bits = updateBits;
92 }
93 
UpdateDataAddress(const uint32_t value,const uint8_t valid_bits)94 void EtmV3TrcPacket::UpdateDataAddress(const uint32_t value, const uint8_t valid_bits)
95 {
96     // ETMv3 data addresses 32 bits.
97     uint32_t validMask = 0xFFFFFFFF;
98     validMask >>= 32-valid_bits;
99     m_pkt_data.addr.pkt_bits = valid_bits;
100     m_pkt_data.addr.val &= ~validMask;
101     m_pkt_data.addr.val |= (value & validMask);
102     if(valid_bits > m_pkt_data.addr.valid_bits)
103         m_pkt_data.addr.valid_bits = valid_bits;
104     m_pkt_data.data.update_addr = 1;
105 }
106 
UpdateTimestamp(const uint64_t tsVal,const uint8_t updateBits)107 void EtmV3TrcPacket::UpdateTimestamp(const uint64_t tsVal, const uint8_t updateBits)
108 {
109     uint64_t validMask = ~0ULL;
110     validMask >>= 64-updateBits;
111     m_pkt_data.timestamp &= ~validMask;
112     m_pkt_data.timestamp |= (tsVal & validMask);
113     m_pkt_data.ts_update_bits = updateBits;
114 }
115 
116 
117 
SetException(const ocsd_armv7_exception type,const uint16_t number,const bool cancel,const bool cm_type,const int irq_n,const int resume)118 void EtmV3TrcPacket::SetException(  const ocsd_armv7_exception type,
119                                     const uint16_t number,
120                                     const bool cancel,
121                                     const bool cm_type,
122                                     const int irq_n  /*= 0*/,
123                                     const int resume /* = 0*/)
124 {
125     // initial data
126     m_pkt_data.exception.bits.cancel = cancel ? 1 : 0;
127     m_pkt_data.exception.bits.cm_irq_n = irq_n;
128     m_pkt_data.exception.bits.cm_resume = resume;
129     m_pkt_data.exception.bits.cm_type = cm_type ? 1 : 0;
130     m_pkt_data.exception.number = number;
131     m_pkt_data.exception.type = type;
132 
133     // mark as valid in this packet
134     m_pkt_data.exception.bits.present = 1;
135 }
136 
UpdateAtomFromPHdr(const uint8_t pHdr,const bool cycleAccurate)137 bool EtmV3TrcPacket::UpdateAtomFromPHdr(const uint8_t pHdr, const bool cycleAccurate)
138 {
139     bool bValid = true;
140     uint8_t E = 0, N = 0;
141     if(!cycleAccurate)
142     {
143         if((pHdr & 0x3) == 0x0)
144         {
145             E = ((pHdr >> 2) & 0xF);
146             N = (pHdr & 0x40) ? 1 : 0;
147             m_pkt_data.atom.num = E+N;
148             m_pkt_data.atom.En_bits = (((uint32_t)0x1) << E) - 1;
149             m_pkt_data.p_hdr_fmt = 1;
150         }
151         else if((pHdr & 0x3) == 0x2)
152         {
153             m_pkt_data.atom.num = 2;
154             m_pkt_data.p_hdr_fmt = 2;
155             m_pkt_data.atom.En_bits = (pHdr & 0x8 ? 0 : 1) |  (pHdr & 0x4 ? 0 : 0x2);
156         }
157         else
158             bValid = false;
159     }
160     else
161     {
162         uint8_t pHdr_code = pHdr & 0xA3;
163         switch(pHdr_code)
164         {
165         case 0x80:
166             m_pkt_data.p_hdr_fmt = 1;
167             E = ((pHdr >> 2) & 0x7);
168             N = (pHdr & 0x40) ? 1 : 0;
169             m_pkt_data.atom.num = E+N;
170             if(m_pkt_data.atom.num)
171             {
172                 m_pkt_data.atom.En_bits = (((uint32_t)0x1) << E) - 1;
173                 m_pkt_data.cycle_count = E+N;
174             }
175             else
176                 bValid = false; // deprecated 8b'10000000 code
177 
178             break;
179 
180         case 0x82:
181             m_pkt_data.p_hdr_fmt = 2;
182             if(pHdr & 0x10)
183             {
184                 m_pkt_data.p_hdr_fmt = 4;
185                 m_pkt_data.atom.num = 1;
186                 m_pkt_data.cycle_count  = 0;
187                 m_pkt_data.atom.En_bits = pHdr & 0x04 ? 0 : 1;
188             }
189             else
190             {
191                 m_pkt_data.atom.num = 2;
192                 m_pkt_data.cycle_count  = 1;
193                 m_pkt_data.atom.En_bits = (pHdr & 0x8 ? 0 : 1) |  (pHdr & 0x4 ? 0 : 0x2);
194             }
195             break;
196 
197         case 0xA0:
198             m_pkt_data.p_hdr_fmt = 3;
199             m_pkt_data.cycle_count  = ((pHdr >> 2) & 7) + 1;
200             E = pHdr & 0x40 ? 1 : 0;
201             m_pkt_data.atom.num = E;
202             m_pkt_data.atom.En_bits = E;
203             break;
204 
205         default:
206             bValid = false;
207             break;
208 
209         }
210     }
211     return bValid;
212 }
213 
operator =(const ocsd_etmv3_pkt * p_pkt)214 EtmV3TrcPacket &EtmV3TrcPacket::operator =(const ocsd_etmv3_pkt* p_pkt)
215 {
216     m_pkt_data = *p_pkt;
217     return *this;
218 }
219 
220     // printing
toString(std::string & str) const221 void EtmV3TrcPacket::toString(std::string &str) const
222 {
223     const char *name;
224     const char *desc;
225     std::string valStr, ctxtStr = "";
226 
227     name = packetTypeName(m_pkt_data.type, &desc);
228     str = name + (std::string)" : " + desc;
229 
230     switch(m_pkt_data.type)
231     {
232         // print the original header type for the bad sequences.
233     case ETM3_PKT_BAD_SEQUENCE:
234     case ETM3_PKT_BAD_TRACEMODE:
235         name = packetTypeName(m_pkt_data.err_type,0);
236         str += "[" + (std::string)name + "]";
237         break;
238 
239     case ETM3_PKT_BRANCH_ADDRESS:
240         getBranchAddressStr(valStr);
241         str += "; " + valStr;
242         break;
243 
244     case ETM3_PKT_I_SYNC_CYCLE:
245     case ETM3_PKT_I_SYNC:
246         getISyncStr(valStr);
247         str += "; " + valStr;
248         break;
249 
250     case ETM3_PKT_P_HDR:
251         getAtomStr(valStr);
252         str += "; " + valStr;
253         break;
254 
255     case ETM3_PKT_CYCLE_COUNT:
256         {
257             std::ostringstream oss;
258             oss << "; Cycles=" << m_pkt_data.cycle_count;
259             str += oss.str();
260         }
261         break;
262 
263     case ETM3_PKT_CONTEXT_ID:
264         {
265             std::ostringstream oss;
266             oss << "; CtxtID=" << std::hex << "0x" << m_pkt_data.context.ctxtID;
267             str += oss.str();
268         }
269         break;
270 
271     case ETM3_PKT_VMID:
272         {
273             std::ostringstream oss;
274             oss << "; VMID=" << std::hex << "0x" << m_pkt_data.context.VMID;
275             str += oss.str();
276         }
277         break;
278 
279     case ETM3_PKT_TIMESTAMP:
280         {
281             std::ostringstream oss;
282             oss << "; TS=" << std::hex << "0x" << m_pkt_data.timestamp << " (" << std::dec << m_pkt_data.timestamp << ") ";
283             str += oss.str();
284         }
285         break;
286 
287     case ETM3_PKT_OOO_DATA:
288         {
289             std::ostringstream oss;
290             oss << "; Val=" << std::hex << "0x" << m_pkt_data.data.value;
291             oss << "; OO_Tag=" << std::hex << "0x" << m_pkt_data.data.ooo_tag;
292             str += oss.str();
293         }
294         break;
295 
296     case ETM3_PKT_VAL_NOT_TRACED:
297         if(m_pkt_data.data.update_addr)
298         {
299             trcPrintableElem::getValStr(valStr,32, m_pkt_data.data.addr.valid_bits,
300                 m_pkt_data.data.addr.val,true,m_pkt_data.data.addr.pkt_bits);
301             str += "; Addr=" + valStr;
302         }
303         break;
304 
305     case ETM3_PKT_OOO_ADDR_PLC:
306         if(m_pkt_data.data.update_addr)
307         {
308             trcPrintableElem::getValStr(valStr,32, m_pkt_data.data.addr.valid_bits,
309                 m_pkt_data.data.addr.val,true,m_pkt_data.data.addr.pkt_bits);
310             str += "; Addr=" + valStr;
311         }
312         {
313             std::ostringstream oss;
314             oss << "; OO_Tag=" << std::hex << "0x" << m_pkt_data.data.ooo_tag;
315             str += oss.str();
316         }
317         break;
318 
319     case ETM3_PKT_NORM_DATA:
320         if(m_pkt_data.data.update_addr)
321         {
322             trcPrintableElem::getValStr(valStr,32, m_pkt_data.data.addr.valid_bits,
323                 m_pkt_data.data.addr.val,true,m_pkt_data.data.addr.pkt_bits);
324             str += "; Addr=" + valStr;
325         }
326         if(m_pkt_data.data.update_dval)
327         {
328             std::ostringstream oss;
329             oss << "; Val=" << std::hex << "0x" << m_pkt_data.data.value;
330             str += oss.str();
331         }
332         break;
333     }
334 }
335 
toStringFmt(const uint32_t fmtFlags,std::string & str) const336 void EtmV3TrcPacket::toStringFmt(const uint32_t fmtFlags, std::string &str) const
337 {
338     // no formatting implemented at present.
339     toString(str);
340 }
341 
packetTypeName(const ocsd_etmv3_pkt_type type,const char ** ppDesc) const342 const char *EtmV3TrcPacket::packetTypeName(const ocsd_etmv3_pkt_type type, const char **ppDesc) const
343 {
344     const char *pName = "I_RESERVED";
345     const char *pDesc = "Reserved Packet Header";
346 
347     switch(type)
348     {
349 // markers for unknown packets
350     // case ETM3_PKT_NOERROR:,        //!< no error in packet - supplimentary data.
351     case ETM3_PKT_NOTSYNC:        //!< no sync found yet
352         pName = "NOTSYNC";
353         pDesc = "Trace Stream not synchronised";
354         break;
355 
356     case ETM3_PKT_INCOMPLETE_EOT: //!< flushing incomplete/empty packet at end of trace.
357         pName = "INCOMPLETE_EOT.";
358         pDesc = "Incomplete packet at end of trace data.";
359         break;
360 
361 // markers for valid packets
362     case ETM3_PKT_BRANCH_ADDRESS:
363         pName = "BRANCH_ADDRESS";
364         pDesc = "Branch address.";
365         break;
366 
367     case ETM3_PKT_A_SYNC:
368         pName = "A_SYNC";
369         pDesc = "Alignment Synchronisation.";
370         break;
371 
372     case ETM3_PKT_CYCLE_COUNT:
373         pName = "CYCLE_COUNT";
374         pDesc = "Cycle Count.";
375         break;
376 
377     case ETM3_PKT_I_SYNC:
378         pName = "I_SYNC";
379         pDesc = "Instruction Packet synchronisation.";
380         break;
381 
382     case ETM3_PKT_I_SYNC_CYCLE:
383         pName = "I_SYNC_CYCLE";
384         pDesc = "Instruction Packet synchronisation with cycle count.";
385         break;
386 
387     case ETM3_PKT_TRIGGER:
388         pName = "TRIGGER";
389         pDesc = "Trace Trigger Event.";
390         break;
391 
392     case ETM3_PKT_P_HDR:
393         pName = "P_HDR";
394         pDesc = "Atom P-header.";
395         break;
396 
397     case ETM3_PKT_STORE_FAIL:
398         pName = "STORE_FAIL";
399         pDesc = "Data Store Failed.";
400         break;
401 
402     case ETM3_PKT_OOO_DATA:
403         pName = "OOO_DATA";
404         pDesc = "Out of Order data value packet.";
405         break;
406 
407     case ETM3_PKT_OOO_ADDR_PLC:
408         pName = "OOO_ADDR_PLC";
409         pDesc = "Out of Order data address placeholder.";
410         break;
411 
412     case ETM3_PKT_NORM_DATA:
413         pName = "NORM_DATA";
414         pDesc = "Data trace packet.";
415         break;
416 
417     case ETM3_PKT_DATA_SUPPRESSED:
418         pName = "DATA_SUPPRESSED";
419         pDesc = "Data trace suppressed.";
420         break;
421 
422     case ETM3_PKT_VAL_NOT_TRACED:
423         pName = "VAL_NOT_TRACED";
424         pDesc = "Data trace value not traced.";
425         break;
426 
427     case ETM3_PKT_IGNORE:
428         pName = "IGNORE";
429         pDesc = "Packet ignored.";
430         break;
431 
432     case ETM3_PKT_CONTEXT_ID:
433         pName = "CONTEXT_ID";
434         pDesc = "Context ID change.";
435         break;
436 
437     case ETM3_PKT_VMID:
438         pName = "VMID";
439         pDesc = "VMID change.";
440         break;
441 
442     case ETM3_PKT_EXCEPTION_ENTRY:
443         pName = "EXCEPTION_ENTRY";
444         pDesc = "Exception entry data marker.";
445         break;
446 
447     case ETM3_PKT_EXCEPTION_EXIT:
448         pName = "EXCEPTION_EXIT";
449         pDesc = "Exception return.";
450         break;
451 
452     case ETM3_PKT_TIMESTAMP:
453         pName = "TIMESTAMP";
454         pDesc = "Timestamp Value.";
455         break;
456 
457 // internal processing types
458     // case ETM3_PKT_BRANCH_OR_BYPASS_EOT: not externalised
459 
460 // packet errors
461     case ETM3_PKT_BAD_SEQUENCE:
462         pName = "BAD_SEQUENCE";
463         pDesc = "Invalid sequence for packet type.";
464         break;
465 
466     case ETM3_PKT_BAD_TRACEMODE:
467         pName = "BAD_TRACEMODE";
468         pDesc = "Invalid packet type for this trace mode.";
469         break;
470 
471         // leave thest unchanged.
472     case ETM3_PKT_RESERVED:
473     default:
474         break;
475 
476     }
477 
478     if(ppDesc) *ppDesc = pDesc;
479     return pName;
480 }
481 
getBranchAddressStr(std::string & valStr) const482 void EtmV3TrcPacket::getBranchAddressStr(std::string &valStr) const
483 {
484     std::ostringstream oss;
485     std::string subStr;
486 
487     // print address.
488     trcPrintableElem::getValStr(subStr,32,m_pkt_data.addr.valid_bits,
489         m_pkt_data.addr.val,true,m_pkt_data.addr.pkt_bits);
490     oss << "Addr=" << subStr << "; ";
491 
492     // current ISA if changed.
493     if(m_pkt_data.curr_isa != m_pkt_data.prev_isa)
494     {
495         getISAStr(subStr);
496         oss << subStr;
497     }
498 
499     // S / NS etc if changed.
500     if(m_pkt_data.context.updated)
501     {
502         oss << (m_pkt_data.context.curr_NS ? "NS; " : "S; ");
503         oss << (m_pkt_data.context.curr_Hyp ? "Hyp; " : "");
504     }
505 
506     // exception?
507     if(m_pkt_data.exception.bits.present)
508     {
509         getExcepStr(subStr);
510         oss << subStr;
511     }
512     valStr = oss.str();
513 }
514 
getAtomStr(std::string & valStr) const515 void EtmV3TrcPacket::getAtomStr(std::string &valStr) const
516 {
517     std::ostringstream oss;
518     uint32_t bitpattern = m_pkt_data.atom.En_bits; // arranged LSBit oldest, MSbit newest
519 
520     if(!m_pkt_data.cycle_count)
521     {
522         for(int i = 0; i < m_pkt_data.atom.num; i++)
523         {
524             oss << ((bitpattern & 0x1) ? "E" : "N"); // in spec read L->R, oldest->newest
525             bitpattern >>= 1;
526         }
527     }
528     else
529     {
530         switch(m_pkt_data.p_hdr_fmt)
531         {
532         case 1:
533             for(int i = 0; i < m_pkt_data.atom.num; i++)
534             {
535                 oss << ((bitpattern & 0x1) ? "WE" : "WN"); // in spec read L->R, oldest->newest
536                 bitpattern >>= 1;
537             }
538             break;
539 
540         case 2:
541             oss << "W";
542             for(int i = 0; i < m_pkt_data.atom.num; i++)
543             {
544                 oss << ((bitpattern & 0x1) ? "E" : "N"); // in spec read L->R, oldest->newest
545                 bitpattern >>= 1;
546             }
547             break;
548 
549         case 3:
550             for(uint32_t i = 0; i < m_pkt_data.cycle_count; i++)
551                 oss << "W";
552             if(m_pkt_data.atom.num)
553                 oss << ((bitpattern & 0x1) ? "E" : "N"); // in spec read L->R, oldest->newest
554             break;
555         }
556         oss << "; Cycles=" << m_pkt_data.cycle_count;
557     }
558     valStr = oss.str();
559 }
560 
getISyncStr(std::string & valStr) const561 void EtmV3TrcPacket::getISyncStr(std::string &valStr) const
562 {
563     std::ostringstream oss;
564     static const char *reason[] = { "Periodic", "Trace Enable", "Restart Overflow", "Debug Exit" };
565 
566     // reason.
567     oss << "(" << reason[(int)m_pkt_data.isync_info.reason] << "); ";
568 
569     // full address.
570     if(!m_pkt_data.isync_info.no_address)
571     {
572         if(m_pkt_data.isync_info.has_LSipAddress)
573             oss << "Data Instr Addr=0x";
574         else
575             oss << "Addr=0x";
576         oss << std::hex << std::setfill('0') << std::setw(8) << m_pkt_data.addr.val << "; ";
577     }
578 
579     oss << (m_pkt_data.context.curr_NS ? "NS; " : "S; ");
580     oss << (m_pkt_data.context.curr_Hyp ? "Hyp; " : " ");
581 
582     if(m_pkt_data.context.updated_c)
583     {
584         oss << "CtxtID=" << std::hex << m_pkt_data.context.ctxtID << "; ";
585     }
586 
587     if(m_pkt_data.isync_info.no_address)
588     {
589         valStr = oss.str();
590         return;     // bail out at this point if a data only ISYNC
591     }
592 
593     std::string isaStr;
594     getISAStr(isaStr);
595     oss << isaStr;
596 
597     if(m_pkt_data.isync_info.has_cycle_count)
598     {
599         oss << "Cycles=" << std::dec << m_pkt_data.cycle_count << "; ";
600     }
601 
602     if(m_pkt_data.isync_info.has_LSipAddress)
603     {
604         std::string addrStr;
605 
606         // extract address updata.
607         trcPrintableElem::getValStr(addrStr,32,m_pkt_data.data.addr.valid_bits,
608             m_pkt_data.data.addr.val,true,m_pkt_data.data.addr.pkt_bits);
609         oss << "Curr Instr Addr=" << addrStr << ";";
610     }
611     valStr = oss.str();
612 }
613 
getISAStr(std::string & isaStr) const614 void EtmV3TrcPacket::getISAStr(std::string &isaStr) const
615 {
616     std::ostringstream oss;
617     oss << "ISA=";
618     switch(m_pkt_data.curr_isa)
619     {
620     case ocsd_isa_arm:
621         oss << "ARM(32); ";
622         break;
623 
624     case ocsd_isa_thumb2:
625         oss << "Thumb2; ";
626         break;
627 
628     case ocsd_isa_aarch64:
629         oss << "AArch64; ";
630         break;
631 
632     case ocsd_isa_tee:
633         oss << "ThumbEE; ";
634         break;
635 
636     case ocsd_isa_jazelle:
637         oss << "Jazelle; ";
638         break;
639 
640     default:
641     case ocsd_isa_unknown:
642         oss << "Unknown; ";
643         break;
644     }
645     isaStr = oss.str();
646 }
647 
getExcepStr(std::string & excepStr) const648 void EtmV3TrcPacket::getExcepStr(std::string &excepStr) const
649 {
650     static const char *ARv7Excep[] = {
651         "No Exception", "Debug Halt", "SMC", "Hyp",
652         "Async Data Abort", "Jazelle", "Reserved", "Reserved",
653         "PE Reset", "Undefined Instr", "SVC", "Prefetch Abort",
654         "Data Fault", "Generic", "IRQ", "FIQ"
655     };
656 
657     static const char *MExcep[] = {
658         "No Exception", "IRQ1", "IRQ2", "IRQ3",
659         "IRQ4", "IRQ5", "IRQ6", "IRQ7",
660         "IRQ0","usage Fault","NMI","SVC",
661         "DebugMonitor", "Mem Manage","PendSV","SysTick",
662         "Reserved","PE Reset","Reserved","HardFault",
663         "Reserved","BusFault","Reserved","Reserved"
664     };
665 
666     std::ostringstream oss;
667     oss << "Exception=";
668 
669     if(m_pkt_data.exception.bits.cm_type)
670     {
671         if(m_pkt_data.exception.number < 0x18)
672             oss << MExcep[m_pkt_data.exception.number];
673         else
674             oss << "IRQ" << std::dec << (m_pkt_data.exception.number - 0x10);
675         if(m_pkt_data.exception.bits.cm_resume)
676             oss << "; Resume=" << m_pkt_data.exception.bits.cm_resume;
677         if(m_pkt_data.exception.bits.cancel)
678             oss << "; Cancel prev instr";
679     }
680     else
681     {
682         oss << ARv7Excep[m_pkt_data.exception.number] << "; ";
683         if(m_pkt_data.exception.bits.cancel)
684             oss << "; Cancel prev instr";
685     }
686     excepStr = oss.str();
687 }
688 /* End of File trc_pkt_elem_etmv3.cpp */
689