689 lines
20 KiB
C++
689 lines
20 KiB
C++
/*
|
|
* \file trc_pkt_elem_etmv3.cpp
|
|
* \brief OpenCSD :
|
|
*
|
|
* \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
|
|
*/
|
|
|
|
/*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software without
|
|
* specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <cstring>
|
|
#include <sstream>
|
|
#include <iomanip>
|
|
|
|
#include "opencsd/etmv3/trc_pkt_elem_etmv3.h"
|
|
|
|
EtmV3TrcPacket::EtmV3TrcPacket()
|
|
{
|
|
m_pkt_data.addr.size = VA_32BIT; // etm v3 only handles 32 bit addresses.
|
|
}
|
|
|
|
EtmV3TrcPacket::~EtmV3TrcPacket()
|
|
{
|
|
}
|
|
|
|
// update interface - set packet values
|
|
|
|
// clear this packet info
|
|
void EtmV3TrcPacket::Clear()
|
|
{
|
|
// clear structure flags and counter elements etc, that work per packet.
|
|
// leave intra packet data unchanged
|
|
m_pkt_data.addr.pkt_bits = 0;
|
|
m_pkt_data.prev_isa = m_pkt_data.curr_isa; // mark ISA as not changed
|
|
m_pkt_data.exception.bits.present = 0;
|
|
m_pkt_data.atom.num = 0;
|
|
m_pkt_data.cycle_count = 0;
|
|
m_pkt_data.context.updated = 0;
|
|
m_pkt_data.context.updated_c = 0;
|
|
m_pkt_data.context.updated_v = 0;
|
|
m_pkt_data.data.ooo_tag = 0;
|
|
m_pkt_data.data.value = 0;
|
|
m_pkt_data.data.update_addr = 0;
|
|
m_pkt_data.data.update_be = 0;
|
|
m_pkt_data.data.update_dval = 0;
|
|
m_pkt_data.ts_update_bits = 0;
|
|
m_pkt_data.isync_info.has_cycle_count = 0;
|
|
m_pkt_data.isync_info.has_LSipAddress = 0;
|
|
m_pkt_data.isync_info.no_address = 0;
|
|
}
|
|
|
|
// reset all state including intra packet
|
|
void EtmV3TrcPacket::ResetState()
|
|
{
|
|
memset(&m_pkt_data,0,sizeof(ocsd_etmv3_pkt));
|
|
m_pkt_data.curr_isa = m_pkt_data.prev_isa = ocsd_isa_unknown;
|
|
}
|
|
|
|
void EtmV3TrcPacket::UpdateAddress(const ocsd_vaddr_t partAddrVal, const int updateBits)
|
|
{
|
|
ocsd_vaddr_t validMask = OCSD_VA_MASK;
|
|
validMask >>= OCSD_MAX_VA_BITSIZE-updateBits;
|
|
m_pkt_data.addr.pkt_bits = updateBits;
|
|
m_pkt_data.addr.val &= ~validMask;
|
|
m_pkt_data.addr.val |= (partAddrVal & validMask);
|
|
if(updateBits > m_pkt_data.addr.valid_bits)
|
|
m_pkt_data.addr.valid_bits = updateBits;
|
|
}
|
|
|
|
void EtmV3TrcPacket::UpdateDataAddress(const uint32_t value, const uint8_t valid_bits)
|
|
{
|
|
// ETMv3 data addresses 32 bits.
|
|
uint32_t validMask = 0xFFFFFFFF;
|
|
validMask >>= 32-valid_bits;
|
|
m_pkt_data.addr.pkt_bits = valid_bits;
|
|
m_pkt_data.addr.val &= ~validMask;
|
|
m_pkt_data.addr.val |= (value & validMask);
|
|
if(valid_bits > m_pkt_data.addr.valid_bits)
|
|
m_pkt_data.addr.valid_bits = valid_bits;
|
|
m_pkt_data.data.update_addr = 1;
|
|
}
|
|
|
|
void EtmV3TrcPacket::UpdateTimestamp(const uint64_t tsVal, const uint8_t updateBits)
|
|
{
|
|
uint64_t validMask = ~0ULL;
|
|
validMask >>= 64-updateBits;
|
|
m_pkt_data.timestamp &= ~validMask;
|
|
m_pkt_data.timestamp |= (tsVal & validMask);
|
|
m_pkt_data.ts_update_bits = updateBits;
|
|
}
|
|
|
|
|
|
|
|
void EtmV3TrcPacket::SetException( const ocsd_armv7_exception type,
|
|
const uint16_t number,
|
|
const bool cancel,
|
|
const bool cm_type,
|
|
const int irq_n /*= 0*/,
|
|
const int resume /* = 0*/)
|
|
{
|
|
// initial data
|
|
m_pkt_data.exception.bits.cancel = cancel ? 1 : 0;
|
|
m_pkt_data.exception.bits.cm_irq_n = irq_n;
|
|
m_pkt_data.exception.bits.cm_resume = resume;
|
|
m_pkt_data.exception.bits.cm_type = cm_type ? 1 : 0;
|
|
m_pkt_data.exception.number = number;
|
|
m_pkt_data.exception.type = type;
|
|
|
|
// mark as valid in this packet
|
|
m_pkt_data.exception.bits.present = 1;
|
|
}
|
|
|
|
bool EtmV3TrcPacket::UpdateAtomFromPHdr(const uint8_t pHdr, const bool cycleAccurate)
|
|
{
|
|
bool bValid = true;
|
|
uint8_t E = 0, N = 0;
|
|
if(!cycleAccurate)
|
|
{
|
|
if((pHdr & 0x3) == 0x0)
|
|
{
|
|
E = ((pHdr >> 2) & 0xF);
|
|
N = (pHdr & 0x40) ? 1 : 0;
|
|
m_pkt_data.atom.num = E+N;
|
|
m_pkt_data.atom.En_bits = (((uint32_t)0x1) << E) - 1;
|
|
m_pkt_data.p_hdr_fmt = 1;
|
|
}
|
|
else if((pHdr & 0x3) == 0x2)
|
|
{
|
|
m_pkt_data.atom.num = 2;
|
|
m_pkt_data.p_hdr_fmt = 2;
|
|
m_pkt_data.atom.En_bits = (pHdr & 0x8 ? 0 : 1) | (pHdr & 0x4 ? 0 : 0x2);
|
|
}
|
|
else
|
|
bValid = false;
|
|
}
|
|
else
|
|
{
|
|
uint8_t pHdr_code = pHdr & 0xA3;
|
|
switch(pHdr_code)
|
|
{
|
|
case 0x80:
|
|
m_pkt_data.p_hdr_fmt = 1;
|
|
E = ((pHdr >> 2) & 0x7);
|
|
N = (pHdr & 0x40) ? 1 : 0;
|
|
m_pkt_data.atom.num = E+N;
|
|
if(m_pkt_data.atom.num)
|
|
{
|
|
m_pkt_data.atom.En_bits = (((uint32_t)0x1) << E) - 1;
|
|
m_pkt_data.cycle_count = E+N;
|
|
}
|
|
else
|
|
bValid = false; // deprecated 8b'10000000 code
|
|
|
|
break;
|
|
|
|
case 0x82:
|
|
m_pkt_data.p_hdr_fmt = 2;
|
|
if(pHdr & 0x10)
|
|
{
|
|
m_pkt_data.p_hdr_fmt = 4;
|
|
m_pkt_data.atom.num = 1;
|
|
m_pkt_data.cycle_count = 0;
|
|
m_pkt_data.atom.En_bits = pHdr & 0x04 ? 0 : 1;
|
|
}
|
|
else
|
|
{
|
|
m_pkt_data.atom.num = 2;
|
|
m_pkt_data.cycle_count = 1;
|
|
m_pkt_data.atom.En_bits = (pHdr & 0x8 ? 0 : 1) | (pHdr & 0x4 ? 0 : 0x2);
|
|
}
|
|
break;
|
|
|
|
case 0xA0:
|
|
m_pkt_data.p_hdr_fmt = 3;
|
|
m_pkt_data.cycle_count = ((pHdr >> 2) & 7) + 1;
|
|
E = pHdr & 0x40 ? 1 : 0;
|
|
m_pkt_data.atom.num = E;
|
|
m_pkt_data.atom.En_bits = E;
|
|
break;
|
|
|
|
default:
|
|
bValid = false;
|
|
break;
|
|
|
|
}
|
|
}
|
|
return bValid;
|
|
}
|
|
|
|
EtmV3TrcPacket &EtmV3TrcPacket::operator =(const ocsd_etmv3_pkt* p_pkt)
|
|
{
|
|
m_pkt_data = *p_pkt;
|
|
return *this;
|
|
}
|
|
|
|
// printing
|
|
void EtmV3TrcPacket::toString(std::string &str) const
|
|
{
|
|
const char *name;
|
|
const char *desc;
|
|
std::string valStr, ctxtStr = "";
|
|
|
|
name = packetTypeName(m_pkt_data.type, &desc);
|
|
str = name + (std::string)" : " + desc;
|
|
|
|
switch(m_pkt_data.type)
|
|
{
|
|
// print the original header type for the bad sequences.
|
|
case ETM3_PKT_BAD_SEQUENCE:
|
|
case ETM3_PKT_BAD_TRACEMODE:
|
|
name = packetTypeName(m_pkt_data.err_type,0);
|
|
str += "[" + (std::string)name + "]";
|
|
break;
|
|
|
|
case ETM3_PKT_BRANCH_ADDRESS:
|
|
getBranchAddressStr(valStr);
|
|
str += "; " + valStr;
|
|
break;
|
|
|
|
case ETM3_PKT_I_SYNC_CYCLE:
|
|
case ETM3_PKT_I_SYNC:
|
|
getISyncStr(valStr);
|
|
str += "; " + valStr;
|
|
break;
|
|
|
|
case ETM3_PKT_P_HDR:
|
|
getAtomStr(valStr);
|
|
str += "; " + valStr;
|
|
break;
|
|
|
|
case ETM3_PKT_CYCLE_COUNT:
|
|
{
|
|
std::ostringstream oss;
|
|
oss << "; Cycles=" << m_pkt_data.cycle_count;
|
|
str += oss.str();
|
|
}
|
|
break;
|
|
|
|
case ETM3_PKT_CONTEXT_ID:
|
|
{
|
|
std::ostringstream oss;
|
|
oss << "; CtxtID=" << std::hex << "0x" << m_pkt_data.context.ctxtID;
|
|
str += oss.str();
|
|
}
|
|
break;
|
|
|
|
case ETM3_PKT_VMID:
|
|
{
|
|
std::ostringstream oss;
|
|
oss << "; VMID=" << std::hex << "0x" << m_pkt_data.context.VMID;
|
|
str += oss.str();
|
|
}
|
|
break;
|
|
|
|
case ETM3_PKT_TIMESTAMP:
|
|
{
|
|
std::ostringstream oss;
|
|
oss << "; TS=" << std::hex << "0x" << m_pkt_data.timestamp << " (" << std::dec << m_pkt_data.timestamp << ") ";
|
|
str += oss.str();
|
|
}
|
|
break;
|
|
|
|
case ETM3_PKT_OOO_DATA:
|
|
{
|
|
std::ostringstream oss;
|
|
oss << "; Val=" << std::hex << "0x" << m_pkt_data.data.value;
|
|
oss << "; OO_Tag=" << std::hex << "0x" << m_pkt_data.data.ooo_tag;
|
|
str += oss.str();
|
|
}
|
|
break;
|
|
|
|
case ETM3_PKT_VAL_NOT_TRACED:
|
|
if(m_pkt_data.data.update_addr)
|
|
{
|
|
trcPrintableElem::getValStr(valStr,32, m_pkt_data.data.addr.valid_bits,
|
|
m_pkt_data.data.addr.val,true,m_pkt_data.data.addr.pkt_bits);
|
|
str += "; Addr=" + valStr;
|
|
}
|
|
break;
|
|
|
|
case ETM3_PKT_OOO_ADDR_PLC:
|
|
if(m_pkt_data.data.update_addr)
|
|
{
|
|
trcPrintableElem::getValStr(valStr,32, m_pkt_data.data.addr.valid_bits,
|
|
m_pkt_data.data.addr.val,true,m_pkt_data.data.addr.pkt_bits);
|
|
str += "; Addr=" + valStr;
|
|
}
|
|
{
|
|
std::ostringstream oss;
|
|
oss << "; OO_Tag=" << std::hex << "0x" << m_pkt_data.data.ooo_tag;
|
|
str += oss.str();
|
|
}
|
|
break;
|
|
|
|
case ETM3_PKT_NORM_DATA:
|
|
if(m_pkt_data.data.update_addr)
|
|
{
|
|
trcPrintableElem::getValStr(valStr,32, m_pkt_data.data.addr.valid_bits,
|
|
m_pkt_data.data.addr.val,true,m_pkt_data.data.addr.pkt_bits);
|
|
str += "; Addr=" + valStr;
|
|
}
|
|
if(m_pkt_data.data.update_dval)
|
|
{
|
|
std::ostringstream oss;
|
|
oss << "; Val=" << std::hex << "0x" << m_pkt_data.data.value;
|
|
str += oss.str();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void EtmV3TrcPacket::toStringFmt(const uint32_t fmtFlags, std::string &str) const
|
|
{
|
|
// no formatting implemented at present.
|
|
toString(str);
|
|
}
|
|
|
|
const char *EtmV3TrcPacket::packetTypeName(const ocsd_etmv3_pkt_type type, const char **ppDesc) const
|
|
{
|
|
const char *pName = "I_RESERVED";
|
|
const char *pDesc = "Reserved Packet Header";
|
|
|
|
switch(type)
|
|
{
|
|
// markers for unknown packets
|
|
// case ETM3_PKT_NOERROR:, //!< no error in packet - supplimentary data.
|
|
case ETM3_PKT_NOTSYNC: //!< no sync found yet
|
|
pName = "NOTSYNC";
|
|
pDesc = "Trace Stream not synchronised";
|
|
break;
|
|
|
|
case ETM3_PKT_INCOMPLETE_EOT: //!< flushing incomplete/empty packet at end of trace.
|
|
pName = "INCOMPLETE_EOT.";
|
|
pDesc = "Incomplete packet at end of trace data.";
|
|
break;
|
|
|
|
// markers for valid packets
|
|
case ETM3_PKT_BRANCH_ADDRESS:
|
|
pName = "BRANCH_ADDRESS";
|
|
pDesc = "Branch address.";
|
|
break;
|
|
|
|
case ETM3_PKT_A_SYNC:
|
|
pName = "A_SYNC";
|
|
pDesc = "Alignment Synchronisation.";
|
|
break;
|
|
|
|
case ETM3_PKT_CYCLE_COUNT:
|
|
pName = "CYCLE_COUNT";
|
|
pDesc = "Cycle Count.";
|
|
break;
|
|
|
|
case ETM3_PKT_I_SYNC:
|
|
pName = "I_SYNC";
|
|
pDesc = "Instruction Packet synchronisation.";
|
|
break;
|
|
|
|
case ETM3_PKT_I_SYNC_CYCLE:
|
|
pName = "I_SYNC_CYCLE";
|
|
pDesc = "Instruction Packet synchronisation with cycle count.";
|
|
break;
|
|
|
|
case ETM3_PKT_TRIGGER:
|
|
pName = "TRIGGER";
|
|
pDesc = "Trace Trigger Event.";
|
|
break;
|
|
|
|
case ETM3_PKT_P_HDR:
|
|
pName = "P_HDR";
|
|
pDesc = "Atom P-header.";
|
|
break;
|
|
|
|
case ETM3_PKT_STORE_FAIL:
|
|
pName = "STORE_FAIL";
|
|
pDesc = "Data Store Failed.";
|
|
break;
|
|
|
|
case ETM3_PKT_OOO_DATA:
|
|
pName = "OOO_DATA";
|
|
pDesc = "Out of Order data value packet.";
|
|
break;
|
|
|
|
case ETM3_PKT_OOO_ADDR_PLC:
|
|
pName = "OOO_ADDR_PLC";
|
|
pDesc = "Out of Order data address placeholder.";
|
|
break;
|
|
|
|
case ETM3_PKT_NORM_DATA:
|
|
pName = "NORM_DATA";
|
|
pDesc = "Data trace packet.";
|
|
break;
|
|
|
|
case ETM3_PKT_DATA_SUPPRESSED:
|
|
pName = "DATA_SUPPRESSED";
|
|
pDesc = "Data trace suppressed.";
|
|
break;
|
|
|
|
case ETM3_PKT_VAL_NOT_TRACED:
|
|
pName = "VAL_NOT_TRACED";
|
|
pDesc = "Data trace value not traced.";
|
|
break;
|
|
|
|
case ETM3_PKT_IGNORE:
|
|
pName = "IGNORE";
|
|
pDesc = "Packet ignored.";
|
|
break;
|
|
|
|
case ETM3_PKT_CONTEXT_ID:
|
|
pName = "CONTEXT_ID";
|
|
pDesc = "Context ID change.";
|
|
break;
|
|
|
|
case ETM3_PKT_VMID:
|
|
pName = "VMID";
|
|
pDesc = "VMID change.";
|
|
break;
|
|
|
|
case ETM3_PKT_EXCEPTION_ENTRY:
|
|
pName = "EXCEPTION_ENTRY";
|
|
pDesc = "Exception entry data marker.";
|
|
break;
|
|
|
|
case ETM3_PKT_EXCEPTION_EXIT:
|
|
pName = "EXCEPTION_EXIT";
|
|
pDesc = "Exception return.";
|
|
break;
|
|
|
|
case ETM3_PKT_TIMESTAMP:
|
|
pName = "TIMESTAMP";
|
|
pDesc = "Timestamp Value.";
|
|
break;
|
|
|
|
// internal processing types
|
|
// case ETM3_PKT_BRANCH_OR_BYPASS_EOT: not externalised
|
|
|
|
// packet errors
|
|
case ETM3_PKT_BAD_SEQUENCE:
|
|
pName = "BAD_SEQUENCE";
|
|
pDesc = "Invalid sequence for packet type.";
|
|
break;
|
|
|
|
case ETM3_PKT_BAD_TRACEMODE:
|
|
pName = "BAD_TRACEMODE";
|
|
pDesc = "Invalid packet type for this trace mode.";
|
|
break;
|
|
|
|
// leave thest unchanged.
|
|
case ETM3_PKT_RESERVED:
|
|
default:
|
|
break;
|
|
|
|
}
|
|
|
|
if(ppDesc) *ppDesc = pDesc;
|
|
return pName;
|
|
}
|
|
|
|
void EtmV3TrcPacket::getBranchAddressStr(std::string &valStr) const
|
|
{
|
|
std::ostringstream oss;
|
|
std::string subStr;
|
|
|
|
// print address.
|
|
trcPrintableElem::getValStr(subStr,32,m_pkt_data.addr.valid_bits,
|
|
m_pkt_data.addr.val,true,m_pkt_data.addr.pkt_bits);
|
|
oss << "Addr=" << subStr << "; ";
|
|
|
|
// current ISA if changed.
|
|
if(m_pkt_data.curr_isa != m_pkt_data.prev_isa)
|
|
{
|
|
getISAStr(subStr);
|
|
oss << subStr;
|
|
}
|
|
|
|
// S / NS etc if changed.
|
|
if(m_pkt_data.context.updated)
|
|
{
|
|
oss << (m_pkt_data.context.curr_NS ? "NS; " : "S; ");
|
|
oss << (m_pkt_data.context.curr_Hyp ? "Hyp; " : "");
|
|
}
|
|
|
|
// exception?
|
|
if(m_pkt_data.exception.bits.present)
|
|
{
|
|
getExcepStr(subStr);
|
|
oss << subStr;
|
|
}
|
|
valStr = oss.str();
|
|
}
|
|
|
|
void EtmV3TrcPacket::getAtomStr(std::string &valStr) const
|
|
{
|
|
std::ostringstream oss;
|
|
uint32_t bitpattern = m_pkt_data.atom.En_bits; // arranged LSBit oldest, MSbit newest
|
|
|
|
if(!m_pkt_data.cycle_count)
|
|
{
|
|
for(int i = 0; i < m_pkt_data.atom.num; i++)
|
|
{
|
|
oss << ((bitpattern & 0x1) ? "E" : "N"); // in spec read L->R, oldest->newest
|
|
bitpattern >>= 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch(m_pkt_data.p_hdr_fmt)
|
|
{
|
|
case 1:
|
|
for(int i = 0; i < m_pkt_data.atom.num; i++)
|
|
{
|
|
oss << ((bitpattern & 0x1) ? "WE" : "WN"); // in spec read L->R, oldest->newest
|
|
bitpattern >>= 1;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
oss << "W";
|
|
for(int i = 0; i < m_pkt_data.atom.num; i++)
|
|
{
|
|
oss << ((bitpattern & 0x1) ? "E" : "N"); // in spec read L->R, oldest->newest
|
|
bitpattern >>= 1;
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
for(uint32_t i = 0; i < m_pkt_data.cycle_count; i++)
|
|
oss << "W";
|
|
if(m_pkt_data.atom.num)
|
|
oss << ((bitpattern & 0x1) ? "E" : "N"); // in spec read L->R, oldest->newest
|
|
break;
|
|
}
|
|
oss << "; Cycles=" << m_pkt_data.cycle_count;
|
|
}
|
|
valStr = oss.str();
|
|
}
|
|
|
|
void EtmV3TrcPacket::getISyncStr(std::string &valStr) const
|
|
{
|
|
std::ostringstream oss;
|
|
static const char *reason[] = { "Periodic", "Trace Enable", "Restart Overflow", "Debug Exit" };
|
|
|
|
// reason.
|
|
oss << "(" << reason[(int)m_pkt_data.isync_info.reason] << "); ";
|
|
|
|
// full address.
|
|
if(!m_pkt_data.isync_info.no_address)
|
|
{
|
|
if(m_pkt_data.isync_info.has_LSipAddress)
|
|
oss << "Data Instr Addr=0x";
|
|
else
|
|
oss << "Addr=0x";
|
|
oss << std::hex << std::setfill('0') << std::setw(8) << m_pkt_data.addr.val << "; ";
|
|
}
|
|
|
|
oss << (m_pkt_data.context.curr_NS ? "NS; " : "S; ");
|
|
oss << (m_pkt_data.context.curr_Hyp ? "Hyp; " : " ");
|
|
|
|
if(m_pkt_data.context.updated_c)
|
|
{
|
|
oss << "CtxtID=" << std::hex << m_pkt_data.context.ctxtID << "; ";
|
|
}
|
|
|
|
if(m_pkt_data.isync_info.no_address)
|
|
{
|
|
valStr = oss.str();
|
|
return; // bail out at this point if a data only ISYNC
|
|
}
|
|
|
|
std::string isaStr;
|
|
getISAStr(isaStr);
|
|
oss << isaStr;
|
|
|
|
if(m_pkt_data.isync_info.has_cycle_count)
|
|
{
|
|
oss << "Cycles=" << std::dec << m_pkt_data.cycle_count << "; ";
|
|
}
|
|
|
|
if(m_pkt_data.isync_info.has_LSipAddress)
|
|
{
|
|
std::string addrStr;
|
|
|
|
// extract address updata.
|
|
trcPrintableElem::getValStr(addrStr,32,m_pkt_data.data.addr.valid_bits,
|
|
m_pkt_data.data.addr.val,true,m_pkt_data.data.addr.pkt_bits);
|
|
oss << "Curr Instr Addr=" << addrStr << ";";
|
|
}
|
|
valStr = oss.str();
|
|
}
|
|
|
|
void EtmV3TrcPacket::getISAStr(std::string &isaStr) const
|
|
{
|
|
std::ostringstream oss;
|
|
oss << "ISA=";
|
|
switch(m_pkt_data.curr_isa)
|
|
{
|
|
case ocsd_isa_arm:
|
|
oss << "ARM(32); ";
|
|
break;
|
|
|
|
case ocsd_isa_thumb2:
|
|
oss << "Thumb2; ";
|
|
break;
|
|
|
|
case ocsd_isa_aarch64:
|
|
oss << "AArch64; ";
|
|
break;
|
|
|
|
case ocsd_isa_tee:
|
|
oss << "ThumbEE; ";
|
|
break;
|
|
|
|
case ocsd_isa_jazelle:
|
|
oss << "Jazelle; ";
|
|
break;
|
|
|
|
default:
|
|
case ocsd_isa_unknown:
|
|
oss << "Unknown; ";
|
|
break;
|
|
}
|
|
isaStr = oss.str();
|
|
}
|
|
|
|
void EtmV3TrcPacket::getExcepStr(std::string &excepStr) const
|
|
{
|
|
static const char *ARv7Excep[] = {
|
|
"No Exception", "Debug Halt", "SMC", "Hyp",
|
|
"Async Data Abort", "Jazelle", "Reserved", "Reserved",
|
|
"PE Reset", "Undefined Instr", "SVC", "Prefetch Abort",
|
|
"Data Fault", "Generic", "IRQ", "FIQ"
|
|
};
|
|
|
|
static const char *MExcep[] = {
|
|
"No Exception", "IRQ1", "IRQ2", "IRQ3",
|
|
"IRQ4", "IRQ5", "IRQ6", "IRQ7",
|
|
"IRQ0","usage Fault","NMI","SVC",
|
|
"DebugMonitor", "Mem Manage","PendSV","SysTick",
|
|
"Reserved","PE Reset","Reserved","HardFault",
|
|
"Reserved","BusFault","Reserved","Reserved"
|
|
};
|
|
|
|
std::ostringstream oss;
|
|
oss << "Exception=";
|
|
|
|
if(m_pkt_data.exception.bits.cm_type)
|
|
{
|
|
if(m_pkt_data.exception.number < 0x18)
|
|
oss << MExcep[m_pkt_data.exception.number];
|
|
else
|
|
oss << "IRQ" << std::dec << (m_pkt_data.exception.number - 0x10);
|
|
if(m_pkt_data.exception.bits.cm_resume)
|
|
oss << "; Resume=" << m_pkt_data.exception.bits.cm_resume;
|
|
if(m_pkt_data.exception.bits.cancel)
|
|
oss << "; Cancel prev instr";
|
|
}
|
|
else
|
|
{
|
|
oss << ARv7Excep[m_pkt_data.exception.number] << "; ";
|
|
if(m_pkt_data.exception.bits.cancel)
|
|
oss << "; Cancel prev instr";
|
|
}
|
|
excepStr = oss.str();
|
|
}
|
|
/* End of File trc_pkt_elem_etmv3.cpp */
|