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