2 * \file trc_pkt_elem_etmv3.cpp
5 * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
9 * Redistribution and use in source and binary forms, with or without modification,
10 * are permitted provided that the following conditions are met:
12 * 1. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
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.
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.
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.
39 #include "opencsd/etmv3/trc_pkt_elem_etmv3.h"
41 EtmV3TrcPacket::EtmV3TrcPacket()
43 m_pkt_data.addr.size = VA_32BIT; // etm v3 only handles 32 bit addresses.
46 EtmV3TrcPacket::~EtmV3TrcPacket()
50 // update interface - set packet values
52 // clear this packet info
53 void EtmV3TrcPacket::Clear()
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;
76 // reset all state including intra packet
77 void EtmV3TrcPacket::ResetState()
79 memset(&m_pkt_data,0,sizeof(ocsd_etmv3_pkt));
80 m_pkt_data.curr_isa = m_pkt_data.prev_isa = ocsd_isa_unknown;
83 void EtmV3TrcPacket::UpdateAddress(const ocsd_vaddr_t partAddrVal, const int updateBits)
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;
94 void EtmV3TrcPacket::UpdateDataAddress(const uint32_t value, const uint8_t valid_bits)
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;
107 void EtmV3TrcPacket::UpdateTimestamp(const uint64_t tsVal, const uint8_t updateBits)
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;
118 void EtmV3TrcPacket::SetException( const ocsd_armv7_exception type,
119 const uint16_t number,
122 const int irq_n /*= 0*/,
123 const int resume /* = 0*/)
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;
133 // mark as valid in this packet
134 m_pkt_data.exception.bits.present = 1;
137 bool EtmV3TrcPacket::UpdateAtomFromPHdr(const uint8_t pHdr, const bool cycleAccurate)
140 uint8_t E = 0, N = 0;
143 if((pHdr & 0x3) == 0x0)
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;
151 else if((pHdr & 0x3) == 0x2)
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);
162 uint8_t pHdr_code = pHdr & 0xA3;
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)
172 m_pkt_data.atom.En_bits = (((uint32_t)0x1) << E) - 1;
173 m_pkt_data.cycle_count = E+N;
176 bValid = false; // deprecated 8b'10000000 code
181 m_pkt_data.p_hdr_fmt = 2;
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;
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);
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;
214 EtmV3TrcPacket &EtmV3TrcPacket::operator =(const ocsd_etmv3_pkt* p_pkt)
221 void EtmV3TrcPacket::toString(std::string &str) const
225 std::string valStr, ctxtStr = "";
227 name = packetTypeName(m_pkt_data.type, &desc);
228 str = name + (std::string)" : " + desc;
230 switch(m_pkt_data.type)
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 + "]";
239 case ETM3_PKT_BRANCH_ADDRESS:
240 getBranchAddressStr(valStr);
241 str += "; " + valStr;
244 case ETM3_PKT_I_SYNC_CYCLE:
245 case ETM3_PKT_I_SYNC:
247 str += "; " + valStr;
252 str += "; " + valStr;
255 case ETM3_PKT_CYCLE_COUNT:
257 std::ostringstream oss;
258 oss << "; Cycles=" << m_pkt_data.cycle_count;
263 case ETM3_PKT_CONTEXT_ID:
265 std::ostringstream oss;
266 oss << "; CtxtID=" << std::hex << "0x" << m_pkt_data.context.ctxtID;
273 std::ostringstream oss;
274 oss << "; VMID=" << std::hex << "0x" << m_pkt_data.context.VMID;
279 case ETM3_PKT_TIMESTAMP:
281 std::ostringstream oss;
282 oss << "; TS=" << std::hex << "0x" << m_pkt_data.timestamp << " (" << std::dec << m_pkt_data.timestamp << ") ";
287 case ETM3_PKT_OOO_DATA:
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;
296 case ETM3_PKT_VAL_NOT_TRACED:
297 if(m_pkt_data.data.update_addr)
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;
305 case ETM3_PKT_OOO_ADDR_PLC:
306 if(m_pkt_data.data.update_addr)
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;
313 std::ostringstream oss;
314 oss << "; OO_Tag=" << std::hex << "0x" << m_pkt_data.data.ooo_tag;
319 case ETM3_PKT_NORM_DATA:
320 if(m_pkt_data.data.update_addr)
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;
326 if(m_pkt_data.data.update_dval)
328 std::ostringstream oss;
329 oss << "; Val=" << std::hex << "0x" << m_pkt_data.data.value;
336 void EtmV3TrcPacket::toStringFmt(const uint32_t fmtFlags, std::string &str) const
338 // no formatting implemented at present.
342 const char *EtmV3TrcPacket::packetTypeName(const ocsd_etmv3_pkt_type type, const char **ppDesc) const
344 const char *pName = "I_RESERVED";
345 const char *pDesc = "Reserved Packet Header";
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
353 pDesc = "Trace Stream not synchronised";
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.";
361 // markers for valid packets
362 case ETM3_PKT_BRANCH_ADDRESS:
363 pName = "BRANCH_ADDRESS";
364 pDesc = "Branch address.";
367 case ETM3_PKT_A_SYNC:
369 pDesc = "Alignment Synchronisation.";
372 case ETM3_PKT_CYCLE_COUNT:
373 pName = "CYCLE_COUNT";
374 pDesc = "Cycle Count.";
377 case ETM3_PKT_I_SYNC:
379 pDesc = "Instruction Packet synchronisation.";
382 case ETM3_PKT_I_SYNC_CYCLE:
383 pName = "I_SYNC_CYCLE";
384 pDesc = "Instruction Packet synchronisation with cycle count.";
387 case ETM3_PKT_TRIGGER:
389 pDesc = "Trace Trigger Event.";
394 pDesc = "Atom P-header.";
397 case ETM3_PKT_STORE_FAIL:
398 pName = "STORE_FAIL";
399 pDesc = "Data Store Failed.";
402 case ETM3_PKT_OOO_DATA:
404 pDesc = "Out of Order data value packet.";
407 case ETM3_PKT_OOO_ADDR_PLC:
408 pName = "OOO_ADDR_PLC";
409 pDesc = "Out of Order data address placeholder.";
412 case ETM3_PKT_NORM_DATA:
414 pDesc = "Data trace packet.";
417 case ETM3_PKT_DATA_SUPPRESSED:
418 pName = "DATA_SUPPRESSED";
419 pDesc = "Data trace suppressed.";
422 case ETM3_PKT_VAL_NOT_TRACED:
423 pName = "VAL_NOT_TRACED";
424 pDesc = "Data trace value not traced.";
427 case ETM3_PKT_IGNORE:
429 pDesc = "Packet ignored.";
432 case ETM3_PKT_CONTEXT_ID:
433 pName = "CONTEXT_ID";
434 pDesc = "Context ID change.";
439 pDesc = "VMID change.";
442 case ETM3_PKT_EXCEPTION_ENTRY:
443 pName = "EXCEPTION_ENTRY";
444 pDesc = "Exception entry data marker.";
447 case ETM3_PKT_EXCEPTION_EXIT:
448 pName = "EXCEPTION_EXIT";
449 pDesc = "Exception return.";
452 case ETM3_PKT_TIMESTAMP:
454 pDesc = "Timestamp Value.";
457 // internal processing types
458 // case ETM3_PKT_BRANCH_OR_BYPASS_EOT: not externalised
461 case ETM3_PKT_BAD_SEQUENCE:
462 pName = "BAD_SEQUENCE";
463 pDesc = "Invalid sequence for packet type.";
466 case ETM3_PKT_BAD_TRACEMODE:
467 pName = "BAD_TRACEMODE";
468 pDesc = "Invalid packet type for this trace mode.";
471 // leave thest unchanged.
472 case ETM3_PKT_RESERVED:
478 if(ppDesc) *ppDesc = pDesc;
482 void EtmV3TrcPacket::getBranchAddressStr(std::string &valStr) const
484 std::ostringstream oss;
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 << "; ";
492 // current ISA if changed.
493 if(m_pkt_data.curr_isa != m_pkt_data.prev_isa)
499 // S / NS etc if changed.
500 if(m_pkt_data.context.updated)
502 oss << (m_pkt_data.context.curr_NS ? "NS; " : "S; ");
503 oss << (m_pkt_data.context.curr_Hyp ? "Hyp; " : "");
507 if(m_pkt_data.exception.bits.present)
515 void EtmV3TrcPacket::getAtomStr(std::string &valStr) const
517 std::ostringstream oss;
518 uint32_t bitpattern = m_pkt_data.atom.En_bits; // arranged LSBit oldest, MSbit newest
520 if(!m_pkt_data.cycle_count)
522 for(int i = 0; i < m_pkt_data.atom.num; i++)
524 oss << ((bitpattern & 0x1) ? "E" : "N"); // in spec read L->R, oldest->newest
530 switch(m_pkt_data.p_hdr_fmt)
533 for(int i = 0; i < m_pkt_data.atom.num; i++)
535 oss << ((bitpattern & 0x1) ? "WE" : "WN"); // in spec read L->R, oldest->newest
542 for(int i = 0; i < m_pkt_data.atom.num; i++)
544 oss << ((bitpattern & 0x1) ? "E" : "N"); // in spec read L->R, oldest->newest
550 for(uint32_t i = 0; i < m_pkt_data.cycle_count; i++)
552 if(m_pkt_data.atom.num)
553 oss << ((bitpattern & 0x1) ? "E" : "N"); // in spec read L->R, oldest->newest
556 oss << "; Cycles=" << m_pkt_data.cycle_count;
561 void EtmV3TrcPacket::getISyncStr(std::string &valStr) const
563 std::ostringstream oss;
564 static const char *reason[] = { "Periodic", "Trace Enable", "Restart Overflow", "Debug Exit" };
567 oss << "(" << reason[(int)m_pkt_data.isync_info.reason] << "); ";
570 if(!m_pkt_data.isync_info.no_address)
572 if(m_pkt_data.isync_info.has_LSipAddress)
573 oss << "Data Instr Addr=0x";
576 oss << std::hex << std::setfill('0') << std::setw(8) << m_pkt_data.addr.val << "; ";
579 oss << (m_pkt_data.context.curr_NS ? "NS; " : "S; ");
580 oss << (m_pkt_data.context.curr_Hyp ? "Hyp; " : " ");
582 if(m_pkt_data.context.updated_c)
584 oss << "CtxtID=" << std::hex << m_pkt_data.context.ctxtID << "; ";
587 if(m_pkt_data.isync_info.no_address)
590 return; // bail out at this point if a data only ISYNC
597 if(m_pkt_data.isync_info.has_cycle_count)
599 oss << "Cycles=" << std::dec << m_pkt_data.cycle_count << "; ";
602 if(m_pkt_data.isync_info.has_LSipAddress)
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 << ";";
614 void EtmV3TrcPacket::getISAStr(std::string &isaStr) const
616 std::ostringstream oss;
618 switch(m_pkt_data.curr_isa)
624 case ocsd_isa_thumb2:
628 case ocsd_isa_aarch64:
636 case ocsd_isa_jazelle:
641 case ocsd_isa_unknown:
648 void EtmV3TrcPacket::getExcepStr(std::string &excepStr) const
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"
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"
666 std::ostringstream oss;
669 if(m_pkt_data.exception.bits.cm_type)
671 if(m_pkt_data.exception.number < 0x18)
672 oss << MExcep[m_pkt_data.exception.number];
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";
682 oss << ARv7Excep[m_pkt_data.exception.number] << "; ";
683 if(m_pkt_data.exception.bits.cancel)
684 oss << "; Cancel prev instr";
686 excepStr = oss.str();
688 /* End of File trc_pkt_elem_etmv3.cpp */