Update opencsd to 0.14.2

Sponsored by:	Innovate UK
This commit is contained in:
Andrew Turner 2020-06-17 10:42:20 +00:00
commit b6aadd183a
46 changed files with 2111 additions and 1326 deletions

View File

@ -36,6 +36,9 @@
# xargs -n1 | sort | uniq -d;
# done
# 20200617: update opencsd to 0.14.2
OLD_FILES+=usr/include/opencsd/etmv4/trc_pkt_elem_etmv4d.h
# 20200606: retire binutils build infrastructure
.if !defined(WITH_PORT_BASE_BINUTILS)
OLD_FILES+=usr/bin/as

View File

@ -115,6 +115,9 @@ ocsd_err_t DecoderMngrBase<P,Pt,Pc>::createDecoder(const int create_flags, cons
if(!pkt_proc)
return OCSD_ERR_MEM;
// set the op mode flags
pkt_proc->setComponentOpMode(create_flags & (OCSD_OPFLG_COMP_MODE_MASK | OCSD_OPFLG_PKTPROC_COMMON));
// set the configuration
TrcPktProcBase<P,Pt,Pc> *pProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> *>(pkt_proc);
if(pProcBase == 0)
@ -133,6 +136,9 @@ ocsd_err_t DecoderMngrBase<P,Pt,Pc>::createDecoder(const int create_flags, cons
if(!pkt_dcd)
return OCSD_ERR_MEM;
// set the op mode flags
pkt_dcd->setComponentOpMode(create_flags & (OCSD_OPFLG_COMP_MODE_MASK | OCSD_OPFLG_PKTDEC_COMMON));
// get the decoder base
TrcPktDecodeBase<P,Pc> *pBase = dynamic_cast< TrcPktDecodeBase<P,Pc> *>(pkt_dcd);
if(pBase == 0)

View File

@ -1,6 +1,6 @@
/*
* \file ocsd_gen_elem_stack.h
* \brief OpenCSD : Generic element output stack.
* \file ocsd_gen_elem_list.h
* \brief OpenCSD : Generic element output list.
*
* \copyright Copyright (c) 2016, ARM Limited. All Rights Reserved.
*/
@ -47,7 +47,7 @@
* This should remove some of the requirement on the packet processing to be re-enterant,
* simplifying this code.
*
* Last element(s) on this stack can be marked pending to allow for later cancellation.
* Last element(s) on this list can be marked pending to allow for later cancellation.
* (This required for cancel element in ETMv3 exeception branch).
*
* The "list" is actually a ring buffer - maintaining pointers to indicate current valid elements.
@ -150,4 +150,4 @@ inline void OcsdGenElemList::initSendIf(componentAttachPt<ITrcGenElemIn> *pGenEl
m_sendIf = pGenElemIf;
}
/* End of File ocsd_gen_elem_stack.h */
/* End of File ocsd_gen_elem_list.h */

View File

@ -0,0 +1,109 @@
/*
* \file ocsd_gen_elem_stack.h
* \brief OpenCSD : Generic element output stack.
*
* \copyright Copyright (c) 2020, 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 "trc_gen_elem.h"
#include "comp_attach_pt_t.h"
#include "interfaces/trc_gen_elem_in_i.h"
/* element stack to handle cases where a trace element can generate multiple output packets
maintains the "current" element, which might be sent independently of this stack, and also
ensures that persistent data in the output elements is maintained between elements.
*/
class OcsdGenElemStack
{
public:
OcsdGenElemStack();
~OcsdGenElemStack();
void initSendIf(componentAttachPt<ITrcGenElemIn> *pGenElemIf);
void initCSID(const uint8_t CSID) { m_CSID = CSID; };
OcsdTraceElement &getCurrElem(); //!< get the current element.
ocsd_err_t resetElemStack(); //!< set pointers to base of stack
ocsd_err_t addElem(const ocsd_trc_index_t trc_pkt_idx); //!< add elem to stack and set current.
void setCurrElemIdx(const ocsd_trc_index_t trc_pkt_idx); //!< packet index for this element
ocsd_err_t addElemType(const ocsd_trc_index_t trc_pkt_idx, ocsd_gen_trc_elem_t elem_type);
ocsd_datapath_resp_t sendElements(); //!< send elements on the stack
const int numElemToSend() const;
private:
typedef struct _elemPtr {
OcsdTraceElement *pElem; //!< pointer to the listed trace element
ocsd_trc_index_t trc_pkt_idx; //!< packet index in the trace stream
} elemPtr_t;
const bool isInit(); //!< check correctly initialised.
ocsd_err_t growArray();
void copyPersistentData(int src, int dst); //!< copy across persistent state data between elements
void resetIndexes(); //!< clear down all indexes - reset or send complete.
elemPtr_t *m_pElemArray; //!< an array of pointers to elements.
int m_elemArraySize; //!< number of element pointers in the array
int m_elem_to_send; //!< number of live elements in the stack - init to 1.
int m_curr_elem_idx; //!< index into the element array.
int m_send_elem_idx; //!< next element to send.
//!< send packet info
uint8_t m_CSID;
componentAttachPt<ITrcGenElemIn> *m_sendIf; //!< element send interface.
bool m_is_init;
};
inline const int OcsdGenElemStack::numElemToSend() const
{
return m_elem_to_send;
}
inline void OcsdGenElemStack::initSendIf(componentAttachPt<ITrcGenElemIn> *pGenElemIf)
{
m_sendIf = pGenElemIf;
}
inline void OcsdGenElemStack::setCurrElemIdx(const ocsd_trc_index_t trc_pkt_idx)
{
m_pElemArray[m_curr_elem_idx].trc_pkt_idx = trc_pkt_idx;
}
inline OcsdTraceElement &OcsdGenElemStack::getCurrElem()
{
return *(m_pElemArray[m_curr_elem_idx].pElem);
}
/* End of File ocsd_gen_elem_stack.h */

View File

@ -39,6 +39,23 @@
#include <string>
#include "opencsd/ocsd_if_types.h"
/** @class CoreArchProfileMap
*
* @brief Map core / arch name to profile for decoder.
*
* Helper class for library clients to map core or architecture version names onto
* a profile / arch version pair suitable for use with the decode library.
*
* Valid core names are:-
* - Cortex-Axx : where xx = 5,7,12,15,17,32,35,53,55,57,65,72,73,75,76,77;
* - Cortex-Rxx : where xx = 5,7,8,52;
* - Cortex-Mxx : where xx = 0,0+,3,4,23,33;
*
* Valid architecture profile names are:-
* - ARMv7-A, ARMv7-R, ARMv7-M;
* - ARMv8-A, ARMv8.3A, ARMv8-R, ARMv8-M;
*
*/
class CoreArchProfileMap
{
public:
@ -50,16 +67,31 @@ class CoreArchProfileMap
private:
std::map<std::string, ocsd_arch_profile_t> core_profiles;
std::map<std::string, ocsd_arch_profile_t> arch_profiles;
};
inline ocsd_arch_profile_t CoreArchProfileMap::getArchProfile(const std::string &coreName)
{
ocsd_arch_profile_t ap = { ARCH_UNKNOWN, profile_Unknown };
bool bFound = false;
std::map<std::string, ocsd_arch_profile_t>::const_iterator it;
/* match against the core name map. */
it = core_profiles.find(coreName);
if(it != core_profiles.end())
if (it != core_profiles.end())
{
ap = it->second;
bFound = true;
}
/* scan architecture profiles on no core name match */
if (!bFound)
{
it = arch_profiles.find(coreName);
if (it != arch_profiles.end())
ap = it->second;
}
return ap;
}

View File

@ -72,6 +72,7 @@ class OcsdTraceElement : public trcPrintableElem, public ocsd_generic_trace_elem
void setTraceOnReason(const trace_on_reason_t reason);
void setUnSyncEOTReason(const unsync_info_t reason);
void setAddrRange(const ocsd_vaddr_t st_addr, const ocsd_vaddr_t en_addr, const int num_instr = 1);
void setLastInstrInfo(const bool exec, const ocsd_instr_type last_i_type, const ocsd_instr_subtype last_i_subtype, const uint8_t size);
@ -94,6 +95,7 @@ class OcsdTraceElement : public trcPrintableElem, public ocsd_generic_trace_elem
// return current context
const ocsd_pe_context &getContext() const { return context; };
void copyPersistentData(const OcsdTraceElement &src);
private:
void printSWInfoPkt(std::ostringstream &oss) const;
@ -171,8 +173,8 @@ inline void OcsdTraceElement::init()
inline void OcsdTraceElement::clearPerPktData()
{
flag_bits = 0; // union with trace_on_reason / trace_event
flag_bits = 0; // bit-field with various flags.
exception_number = 0; // union with trace_on_reason / trace_event
ptr_extended_data = 0; // extended data pointer
}
@ -181,6 +183,11 @@ inline void OcsdTraceElement::setTraceOnReason(const trace_on_reason_t reason)
trace_on_reason = reason;
}
inline void OcsdTraceElement::setUnSyncEOTReason(const unsync_info_t reason)
{
unsync_eot_info = reason;
}
inline void OcsdTraceElement::setISA(const ocsd_isa isa_update)
{
isa = isa_update;
@ -201,6 +208,12 @@ inline void OcsdTraceElement::setExtendedDataPtr(const void *data_ptr)
ptr_extended_data = data_ptr;
}
// set persistent data between output packets.
inline void OcsdTraceElement::copyPersistentData(const OcsdTraceElement &src)
{
isa = src.isa;
context = src.context;
}
/** @}*/

View File

@ -85,7 +85,10 @@ class TrcPktDecodeI : public TraceComponent
virtual ocsd_err_t onProtocolConfig() = 0;
virtual const uint8_t getCoreSightTraceID() = 0;
/* init handling */
const bool checkInit();
/* Called on first init confirmation */
virtual void onFirstInitOK() {};
/* data output */
ocsd_datapath_resp_t outputTraceElement(const OcsdTraceElement &elem); // use current index
@ -147,6 +150,8 @@ inline const bool TrcPktDecodeI::checkInit()
init_err_msg = "No instruction decoder interface attached and enabled";
else
m_decode_init_ok = true;
if (m_decode_init_ok)
onFirstInitOK();
}
return m_decode_init_ok;
}

View File

@ -0,0 +1,96 @@
/*
* \file trc_raw_buffer.h
* \brief OpenCSD : Trace raw data byte buffer
*
* \copyright Copyright (c) 2019, 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.
*/
#ifndef ARM_TRC_RAW_BUFFER_H_INCLUDED
#define ARM_TRC_RAW_BUFFER_H_INCLUDED
#include <vector>
class TraceRawBuffer
{
public:
TraceRawBuffer() :
m_bufSize(0),
m_bufProcessed(0),
m_pBuffer(0),
pkt(0)
{};
~TraceRawBuffer() {};
// init the buffer
void init(const uint32_t size, const uint8_t *rawtrace, std::vector<uint8_t> *out_packet);
void copyByteToPkt(); // move a byte to the packet buffer
uint8_t peekNextByte(); // value of next byte in buffer.
bool empty() { return m_bufProcessed == m_bufSize; };
// bytes processed.
uint32_t processed() { return m_bufProcessed; };
// buffer size;
uint32_t size() { return m_bufSize; }
private:
uint32_t m_bufSize;
uint32_t m_bufProcessed;
const uint8_t *m_pBuffer;
std::vector<uint8_t> *pkt;
};
// init the buffer
inline void TraceRawBuffer::init(const uint32_t size, const uint8_t *rawtrace, std::vector<uint8_t> *out_packet)
{
m_bufSize = size;
m_bufProcessed = 0;
m_pBuffer = rawtrace;
pkt = out_packet;
}
inline void TraceRawBuffer::copyByteToPkt()
{
if (!empty()) {
pkt->push_back(m_pBuffer[m_bufProcessed]);
m_bufProcessed++;
}
}
inline uint8_t TraceRawBuffer::peekNextByte()
{
uint8_t val = 0;
if (!empty())
val = m_pBuffer[m_bufProcessed];
return val;
}
#endif // ARM_TRC_RAW_BUFFER_H_INCLUDED

View File

@ -46,10 +46,9 @@ class TrcIDecode : public IInstrDecode
virtual ocsd_err_t DecodeInstruction(ocsd_instr_info *instr_info);
private:
ocsd_err_t DecodeA32(ocsd_instr_info *instr_info);
ocsd_err_t DecodeA64(ocsd_instr_info *instr_info);
ocsd_err_t DecodeT32(ocsd_instr_info *instr_info);
void SetArchVersion(ocsd_instr_info *instr_info);
ocsd_err_t DecodeA32(ocsd_instr_info *instr_info, struct decode_info *info);
ocsd_err_t DecodeA64(ocsd_instr_info *instr_info, struct decode_info *info);
ocsd_err_t DecodeT32(ocsd_instr_info *instr_info, struct decode_info *info);
};
#endif // ARM_TRC_I_DECODE_H_INCLUDED

View File

@ -42,6 +42,12 @@
#include "opencsd/ocsd_if_types.h"
#include <cstdint>
/* supplementary decode information */
struct decode_info {
uint16_t arch_version;
ocsd_instr_subtype instr_sub_type;
};
/*
For Thumb2, test if a halfword is the first half of a 32-bit instruction,
as opposed to a complete 16-bit instruction.
@ -63,19 +69,19 @@ instructions that write to the PC. It does not include exception
instructions such as SVC, HVC and SMC.
(Performance event 0x0C includes these.)
*/
int inst_ARM_is_branch(uint32_t inst);
int inst_Thumb_is_branch(uint32_t inst);
int inst_A64_is_branch(uint32_t inst);
int inst_ARM_is_branch(uint32_t inst, struct decode_info *info);
int inst_Thumb_is_branch(uint32_t inst, struct decode_info *info);
int inst_A64_is_branch(uint32_t inst, struct decode_info *info);
/*
Test whether an instruction is a direct (aka immediate) branch.
Performance event 0x0D counts these.
*/
int inst_ARM_is_direct_branch(uint32_t inst);
int inst_Thumb_is_direct_branch(uint32_t inst);
int inst_Thumb_is_direct_branch_link(uint32_t inst, uint8_t *is_link, uint8_t *is_cond);
int inst_A64_is_direct_branch(uint32_t inst);
int inst_A64_is_direct_branch_link(uint32_t inst, uint8_t *is_link);
int inst_Thumb_is_direct_branch(uint32_t inst, struct decode_info *info);
int inst_Thumb_is_direct_branch_link(uint32_t inst, uint8_t *is_link, uint8_t *is_cond, struct decode_info *info);
int inst_A64_is_direct_branch(uint32_t inst, struct decode_info *info);
int inst_A64_is_direct_branch_link(uint32_t inst, uint8_t *is_link, struct decode_info *info);
/*
Get branch destination for a direct branch.
@ -84,15 +90,15 @@ int inst_ARM_branch_destination(uint32_t addr, uint32_t inst, uint32_t *pnpc);
int inst_Thumb_branch_destination(uint32_t addr, uint32_t inst, uint32_t *pnpc);
int inst_A64_branch_destination(uint64_t addr, uint32_t inst, uint64_t *pnpc);
int inst_ARM_is_indirect_branch(uint32_t inst);
int inst_Thumb_is_indirect_branch_link(uint32_t inst, uint8_t *is_link);
int inst_Thumb_is_indirect_branch(uint32_t inst);
int inst_A64_is_indirect_branch_link(uint32_t inst, uint8_t *is_link);
int inst_A64_is_indirect_branch(uint32_t inst);
int inst_ARM_is_indirect_branch(uint32_t inst, struct decode_info *info);
int inst_Thumb_is_indirect_branch_link(uint32_t inst, uint8_t *is_link, struct decode_info *info);
int inst_Thumb_is_indirect_branch(uint32_t inst, struct decode_info *info);
int inst_A64_is_indirect_branch_link(uint32_t inst, uint8_t *is_link, struct decode_info *info);
int inst_A64_is_indirect_branch(uint32_t inst, struct decode_info *info);
int inst_ARM_is_branch_and_link(uint32_t inst);
int inst_Thumb_is_branch_and_link(uint32_t inst);
int inst_A64_is_branch_and_link(uint32_t inst);
int inst_ARM_is_branch_and_link(uint32_t inst, struct decode_info *info);
int inst_Thumb_is_branch_and_link(uint32_t inst, struct decode_info *info);
int inst_A64_is_branch_and_link(uint32_t inst, struct decode_info *info);
int inst_ARM_is_conditional(uint32_t inst);
int inst_Thumb_is_conditional(uint32_t inst);
@ -128,14 +134,6 @@ int inst_ARM_is_UDF(uint32_t inst);
int inst_Thumb_is_UDF(uint32_t inst);
int inst_A64_is_UDF(uint32_t inst);
/* access sub-type information */
ocsd_instr_subtype get_instr_subtype();
void clear_instr_subtype();
/* set arch version info. */
void set_arch_version(uint16_t version);
#endif // ARM_TRC_IDEC_ARMINST_H_INCLUDED
/* End of File trc_idec_arminst.h */

View File

@ -68,7 +68,6 @@ class TrcMemAccBufPtr: public TrcMemAccessorBase
private:
const uint8_t *m_p_buffer; /**< pointer to the memory buffer */
const uint32_t m_size; /**< size of the memory buffer. */
};
#endif // ARM_TRC_MEM_ACC_BUFPTR_H_INCLUDED

View File

@ -264,6 +264,7 @@ class TrcPktDecodeEtmV3 : public TrcPktDecodeBase<EtmV3TrcPacket, EtmV3Config>
} processor_state_t;
processor_state_t m_curr_state;
unsync_info_t m_unsync_info; //!< additional state for unsync
uint8_t m_CSID; //!< Coresight trace ID for this decoder.
};

View File

@ -38,7 +38,6 @@
#include "trc_cmp_cfg_etmv4.h"
#include "trc_pkt_elem_etmv4i.h"
#include "trc_pkt_elem_etmv4d.h"
#include "trc_pkt_proc_etmv4.h"
#include "trc_pkt_types_etmv4.h"
#include "trc_pkt_decode_etmv4i.h"

View File

@ -56,6 +56,7 @@ typedef enum _p0_elem_t
P0_TS,
P0_CC,
P0_TS_CC,
P0_Q,
P0_OVERFLOW,
P0_FUNC_RET,
} p0_elem_t;
@ -119,6 +120,44 @@ inline TrcStackElemAddr::TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt,
m_addr_val.isa = 0;
}
/************************************************************/
/** Q element */
class TrcStackQElem : public TrcStackElem
{
protected:
TrcStackQElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
virtual ~TrcStackQElem() {};
friend class EtmV4P0Stack;
public:
void setInstrCount(const int instr_count) { m_instr_count = instr_count; };
const int getInstrCount() const { return m_instr_count; }
void setAddr(const etmv4_addr_val_t &addr_val)
{
m_addr_val = addr_val;
m_has_addr = true;
};
const etmv4_addr_val_t &getAddr() const { return m_addr_val; };
const bool hasAddr() const { return m_has_addr; };
private:
bool m_has_addr;
etmv4_addr_val_t m_addr_val;
int m_instr_count;
};
inline TrcStackQElem::TrcStackQElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
TrcStackElem(P0_Q , true, root_pkt, root_index)
{
m_addr_val.val = 0;
m_addr_val.isa = 0;
m_has_addr = false;
m_instr_count = 0;
}
/************************************************************/
/** Context element */
@ -133,9 +172,12 @@ class TrcStackElemCtxt : public TrcStackElem
public:
void setContext(const etmv4_context_t &ctxt) { m_context = ctxt; };
const etmv4_context_t &getContext() const { return m_context; };
void setIS(const uint8_t IS) { m_IS = IS; };
const uint8_t getIS() const { return m_IS; };
private:
etmv4_context_t m_context;
uint8_t m_IS; //!< IS value at time of generation of packet.
};
inline TrcStackElemCtxt::TrcStackElemCtxt(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
@ -188,6 +230,7 @@ class TrcStackElemAtom : public TrcStackElem
const ocsd_atm_val commitOldest();
int cancelNewest(const int nCancel);
void mispredictNewest();
const bool isEmpty() const { return (m_atom.num == 0); };
private:
@ -217,6 +260,16 @@ inline int TrcStackElemAtom::cancelNewest(const int nCancel)
return nRemove;
}
// mispredict newest - flip the bit of the newest atom
inline void TrcStackElemAtom::mispredictNewest()
{
uint32_t mask = 0x1 << (m_atom.num - 1);
if (m_atom.En_bits & mask)
m_atom.En_bits &= ~mask;
else
m_atom.En_bits |= mask;
}
/************************************************************/
/** Generic param element */
@ -252,12 +305,20 @@ class EtmV4P0Stack
void push_front(TrcStackElem *pElem);
void push_back(TrcStackElem *pElem); // insert element when processing
void pop_back();
void pop_back(bool pend_delete = true);
void pop_front(bool pend_delete = true);
TrcStackElem *back();
TrcStackElem *front();
size_t size();
// iterate through stack from front
void from_front_init();
TrcStackElem *from_front_next();
void erase_curr_from_front(); // erase the element last returned
void delete_all();
void delete_back();
void delete_front();
void delete_popped();
// creation functions - create and push if successful.
@ -265,13 +326,13 @@ class EtmV4P0Stack
TrcStackElem *createParamElemNoParam(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, bool back = false);
TrcStackElemAtom *createAtomElem (const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const ocsd_pkt_atom &atom);
TrcStackElemExcept *createExceptElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const bool bSame, const uint16_t excepNum);
TrcStackElemCtxt *createContextElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_context_t &context);
TrcStackElemCtxt *createContextElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_context_t &context, const uint8_t IS, const bool back = false);
TrcStackElemAddr *createAddrElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_addr_val_t &addr_val);
TrcStackQElem *createQElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const int count);
private:
std::deque<TrcStackElem *> m_P0_stack; //!< P0 decode element stack
std::vector<TrcStackElem *> m_popped_elem; //!< save list of popped but not deleted elements.
std::deque<TrcStackElem *>::iterator m_iter; //!< iterate across the list w/o removing stuff
};
inline EtmV4P0Stack::~EtmV4P0Stack()
@ -293,12 +354,20 @@ inline void EtmV4P0Stack::push_back(TrcStackElem *pElem)
}
// pop last element pointer off the stack and stash it for later deletion
inline void EtmV4P0Stack::pop_back()
inline void EtmV4P0Stack::pop_back(bool pend_delete /* = true */)
{
m_popped_elem.push_back(m_P0_stack.back());
if (pend_delete)
m_popped_elem.push_back(m_P0_stack.back());
m_P0_stack.pop_back();
}
inline void EtmV4P0Stack::pop_front(bool pend_delete /* = true */)
{
if (pend_delete)
m_popped_elem.push_back(m_P0_stack.front());
m_P0_stack.pop_front();
}
// pop last element pointer off the stack and delete immediately
inline void EtmV4P0Stack::delete_back()
{
@ -310,12 +379,30 @@ inline void EtmV4P0Stack::delete_back()
}
}
// pop first element pointer off the stack and delete immediately
inline void EtmV4P0Stack::delete_front()
{
if (m_P0_stack.size() > 0)
{
TrcStackElem* pElem = m_P0_stack.front();
delete pElem;
m_P0_stack.pop_front();
}
}
// get a pointer to the last element on the stack
inline TrcStackElem *EtmV4P0Stack::back()
{
return m_P0_stack.back();
}
inline TrcStackElem *EtmV4P0Stack::front()
{
return m_P0_stack.front();
}
// remove and delete all the elements left on the stack
inline void EtmV4P0Stack::delete_all()
{

View File

@ -40,6 +40,7 @@
#include "opencsd/etmv4/trc_cmp_cfg_etmv4.h"
#include "common/trc_gen_elem.h"
#include "common/trc_ret_stack.h"
#include "common/ocsd_gen_elem_stack.h"
#include "opencsd/etmv4/trc_etmv4_stack_elem.h"
class TrcStackElem;
@ -65,35 +66,69 @@ class TrcPktDecodeEtmV4I : public TrcPktDecodeBase<EtmV4ITrcPacket, EtmV4Config>
/* local decode methods */
void initDecoder(); // initial state on creation (zeros all config)
void resetDecoder(); // reset state to start of decode. (moves state, retains config)
virtual void onFirstInitOK(); // override to set init related info.
ocsd_datapath_resp_t decodePacket(bool &Complete); // return true to indicate decode complete - can change FSM to commit state - return is false.
ocsd_datapath_resp_t commitElements(bool &Complete); // commit elements - may get wait response, or flag completion.
ocsd_datapath_resp_t flushEOT();
ocsd_err_t decodePacket(); // decode packet into trace elements. return true to indicate decode complete - can change FSM to commit state - return is false.
ocsd_datapath_resp_t resolveElements(); // commit/cancel trace elements generated from latest / prior packets & send to output - may get wait response, or flag completion.
ocsd_err_t commitElements(); // commit elements - process element stack to generate output packets.
ocsd_err_t commitElemOnEOT();
ocsd_err_t cancelElements(); // cancel elements. These not output
ocsd_err_t mispredictAtom(); // mispredict an atom
ocsd_err_t discardElements(); // discard elements and flush
void doTraceInfoPacket();
void updateContext(TrcStackElemCtxt *pCtxtElem);
void updateContext(TrcStackElemCtxt *pCtxtElem, OcsdTraceElement &elem);
// process atom will output instruction trace, or no memory access trace elements.
ocsd_datapath_resp_t processAtom(const ocsd_atm_val, bool &bCont);
// process atom will create instruction trace, or no memory access trace output elements.
ocsd_err_t processAtom(const ocsd_atm_val atom);
// process an exception element - output instruction trace + exception generic type.
ocsd_datapath_resp_t processException();
ocsd_err_t processException();
// process Q element
ocsd_err_t processQElement();
// process an element that cannot be cancelled / discarded
ocsd_err_t processTS_CC_EventElem(TrcStackElem *pElem);
// process a bad packet
ocsd_datapath_resp_t handleBadPacket(const char *reason);
ocsd_err_t handleBadPacket(const char *reason);
ocsd_datapath_resp_t outputCC(TrcStackElemParam *pParamElem);
ocsd_datapath_resp_t outputTS(TrcStackElemParam *pParamElem, bool withCC);
ocsd_datapath_resp_t outputEvent(TrcStackElemParam *pParamElem);
ocsd_err_t addElemCC(TrcStackElemParam *pParamElem);
ocsd_err_t addElemTS(TrcStackElemParam *pParamElem, bool withCC);
ocsd_err_t addElemEvent(TrcStackElemParam *pParamElem);
private:
void SetInstrInfoInAddrISA(const ocsd_vaddr_t addr_val, const uint8_t isa);
const ocsd_isa calcISA(const bool SF, const uint8_t IS) const
{
if (SF)
return ocsd_isa_aarch64;
return (IS == 0) ? ocsd_isa_arm : ocsd_isa_thumb2;
}
typedef enum {
WP_NOT_FOUND,
WP_FOUND,
WP_NACC
} WP_res_t;
ocsd_err_t traceInstrToWP(bool &bWPFound, const bool traceToAddrNext = false, const ocsd_vaddr_t nextAddrMatch = 0); //!< follow instructions from the current address to a WP. true if good, false if memory cannot be accessed.
typedef struct {
ocsd_vaddr_t st_addr;
ocsd_vaddr_t en_addr;
uint32_t num_instr;
} instr_range_t;
ocsd_datapath_resp_t returnStackPop(); // pop return stack and update instruction address.
//!< follow instructions from the current address to a WP. true if good, false if memory cannot be accessed.
ocsd_err_t traceInstrToWP(instr_range_t &instr_range, WP_res_t &WPRes, const bool traceToAddrNext = false, const ocsd_vaddr_t nextAddrMatch = 0);
ocsd_datapath_resp_t outputTraceRange(const bool executed, ocsd_trc_index_t index);
inline const bool WPFound(WP_res_t res) const { return (res == WP_FOUND); };
inline const bool WPNacc(WP_res_t res) const { return (res == WP_NACC); };
ocsd_err_t returnStackPop(); // pop return stack and update instruction address.
void setElemTraceRange(OcsdTraceElement &elemIn, const instr_range_t &addr_range, const bool executed, ocsd_trc_index_t index);
ocsd_mem_space_acc_t getCurrMemSpace();
//** intra packet state (see ETMv4 spec 6.2.1);
@ -105,14 +140,18 @@ class TrcPktDecodeEtmV4I : public TrcPktDecodeBase<EtmV4ITrcPacket, EtmV4Config>
uint32_t m_vmid_id; // most recent VMID
bool m_is_secure; // true if Secure
bool m_is_64bit; // true if 64 bit
uint8_t m_last_IS; // last instruction set value from address packet.
// cycle counts
int m_cc_threshold;
// speculative trace (unsupported at present in the decoder).
// speculative trace
int m_curr_spec_depth;
int m_max_spec_depth;
int m_max_spec_depth; // nax depth - from ID reg, beyond which auto-commit occurs
int m_unseen_spec_elem; // speculative elements at decode start
/** Remove elements that are associated with data trace */
#ifdef DATA_TRACE_SUPPORTED
// data trace associative elements (unsupported at present in the decoder).
int m_p0_key;
int m_p0_key_max;
@ -121,6 +160,7 @@ class TrcPktDecodeEtmV4I : public TrcPktDecodeBase<EtmV4ITrcPacket, EtmV4Config>
int m_cond_c_key;
int m_cond_r_key;
int m_cond_key_max_incr;
#endif
uint8_t m_CSID; //!< Coresight trace ID for this decoder.
@ -134,55 +174,52 @@ class TrcPktDecodeEtmV4I : public TrcPktDecodeBase<EtmV4ITrcPacket, EtmV4Config>
WAIT_SYNC, //!< waiting for sync packet.
WAIT_TINFO, //!< waiting for trace info packet.
DECODE_PKTS, //!< processing packets - creating decode elements on stack
COMMIT_ELEM, //!< commit elements for execution - create generic trace elements and pass on.
RESOLVE_ELEM, //!< analyze / resolve decode elements - create generic trace elements and pass on.
} processor_state_t;
processor_state_t m_curr_state;
unsync_info_t m_unsync_eot_info; //!< addition info when / why unsync / eot
//** P0 element stack
EtmV4P0Stack m_P0_stack; //!< P0 decode element stack
int m_P0_commit; //!< number of elements to commit
// element resolution
struct {
int P0_commit; //!< number of elements to commit
int P0_cancel; //!< elements to cancel
bool mispredict; //!< mispredict latest atom
bool discard; //!< discard elements
} m_elem_res;
//! true if any of the element resolution fields are non-zero
const bool isElemForRes() const {
return (m_elem_res.P0_commit || m_elem_res.P0_cancel ||
m_elem_res.mispredict || m_elem_res.discard);
}
void clearElemRes() {
m_elem_res.P0_commit = 0;
m_elem_res.P0_cancel = 0;
m_elem_res.mispredict = false;
m_elem_res.discard = false;
}
// packet decode state
bool m_need_ctxt; //!< need context to continue
bool m_need_addr; //!< need an address to continue
bool m_except_pending_addr; //!< next address packet is part of exception.
// exception packet processing state (may need excep elem only, range+excep, range+
typedef enum {
EXCEP_POP, // start of processing read exception packets off the stack and analyze
EXCEP_RANGE, // output a range element
EXCEP_NACC, // output a nacc element
EXCEP_CTXT, // output a ctxt element
EXCEP_EXCEP, // output an ecxeption element.
} excep_proc_state_t;
struct {
excep_proc_state_t proc; //!< state of exception processing
etmv4_addr_val_t addr; //!< excetion return address.
uint32_t number; //!< exception number.
ocsd_trc_index_t index; //!< trace index for exception element
bool addr_b_tgt; //!< return address is also branch tgt address.
} m_excep_info; //!< exception info when processing exception packets
bool m_elem_pending_addr; //!< next address packet is needed for prev element.
ocsd_instr_info m_instr_info; //!< instruction info for code follower - in address is the next to be decoded.
bool m_mem_nacc_pending; //!< need to output a memory access failure packet
ocsd_vaddr_t m_nacc_addr; //!< record unaccessible address
ocsd_pe_context m_pe_context; //!< current context information
etmv4_trace_info_t m_trace_info; //!< trace info for this trace run.
bool m_prev_overflow;
bool m_flush_EOT; //!< true if doing an end of trace flush - cleans up lingering events / TS / CC
TrcAddrReturnStack m_return_stack;
//** output element
OcsdTraceElement m_output_elem;
TrcAddrReturnStack m_return_stack; //!< the address return stack.
//** output element handling
OcsdGenElemStack m_out_elem; //!< output element stack.
OcsdTraceElement &outElem() { return m_out_elem.getCurrElem(); }; //!< current out element
};
#endif // ARM_TRC_PKT_DECODE_ETMV4I_H_INCLUDED

View File

@ -1,73 +0,0 @@
/*
* \file trc_pkt_elem_etmv4d.h
* \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.
*/
#ifndef ARM_TRC_PKT_ELEM_ETMV4D_H_INCLUDED
#define ARM_TRC_PKT_ELEM_ETMV4D_H_INCLUDED
#include "trc_pkt_types_etmv4.h"
#include "common/trc_printable_elem.h"
#include "common/trc_pkt_elem_base.h"
/** @addtogroup trc_pkts
@{*/
/*!
* @class EtmV4DTrcPacket
* @brief ETMv4 Data Trace Protocol Packet .
*
* This class represents a single ETMv4 instruction trace packet, along with intra packet state.
*
*/
class EtmV4DTrcPacket : public TrcPacketBase, public ocsd_etmv4_d_pkt, trcPrintableElem
{
public:
EtmV4DTrcPacket();
~EtmV4DTrcPacket();
// update interface - set packet values
// packet status interface - get packet info.
// printing
virtual void toString(std::string &str) const;
virtual void toStringFmt(const uint32_t fmtFlags, std::string &str) const;
};
/** @}*/
#endif // ARM_TRC_PKT_ELEM_ETMV4D_H_INCLUDED
/* End of File trc_pkt_elem_etmv4d.h */

View File

@ -57,14 +57,7 @@ class Etmv4PktAddrStack
public:
Etmv4PktAddrStack()
{
for (int i = 0; i < 3; i++)
{
m_v_addr[i].pkt_bits = 0;
m_v_addr[i].size = VA_64BIT;
m_v_addr[i].val = 0;
m_v_addr[i].valid_bits = 0;
m_v_addr_ISA[i] = 0;
}
reset_stack();
}
~Etmv4PktAddrStack() {};
@ -87,6 +80,20 @@ class Etmv4PktAddrStack
}
}
// explicit reset for TInfo.
void reset_stack()
{
for (int i = 0; i < 3; i++)
{
m_v_addr[i].pkt_bits = 0;
m_v_addr[i].size = OCSD_MAX_VA_BITSIZE == 64 ? VA_64BIT : VA_32BIT;
m_v_addr[i].val = 0;
m_v_addr[i].valid_bits = OCSD_MAX_VA_BITSIZE;
m_v_addr_ISA[i] = 0;
}
}
private:
ocsd_pkt_vaddr m_v_addr[3]; //!< most recently broadcast address packet
uint8_t m_v_addr_ISA[3];
@ -172,6 +179,7 @@ class EtmV4ITrcPacket : public TrcPacketBase, public ocsd_etmv4_i_pkt, public t
// atom
const ocsd_pkt_atom &getAtom() const { return atom; };
const int getNumAtoms() const { return atom.num; };
// context
const etmv4_context_t &getContext() const { return context; };
@ -188,6 +196,10 @@ class EtmV4ITrcPacket : public TrcPacketBase, public ocsd_etmv4_i_pkt, public t
// cc
const uint32_t getCC() const { return pkt_valid.bits.cc_valid ? cycle_count : 0; };
// speculation
const int getCommitElem() const { return commit_elements; };
const int getCancelElem() const { return cancel_elements; };
// packet type
const bool isBadPacket() const;
@ -227,6 +239,10 @@ inline void EtmV4ITrcPacket::clearTraceInfo()
// set these as defaults - if they don't appear in TINFO this is the state.
setTraceInfo(0);
setTraceInfoSpec(0);
// explicitly reset the stack & zero the current address.
m_addr_stack.reset_stack();
m_addr_stack.get_idx(0, v_addr, v_addr_ISA);
}
inline void EtmV4ITrcPacket::setTraceInfo(const uint32_t infoVal)
@ -450,17 +466,17 @@ inline void EtmV4ITrcPacket::set32BitAddress(const uint32_t addr, const uint8_t
if (pkt_valid.bits.context_valid && context.SF)
{
v_addr.size = VA_64BIT;
if (v_addr.valid_bits < 32) // may be updating a 64 bit address so only set 32 if currently less.
v_addr.valid_bits = 32;
v_addr.val = (v_addr.val & ~mask) | (addr & mask);
}
else
{
v_addr.val = addr;
v_addr.size = VA_32BIT;
v_addr.valid_bits = 32;
}
if (v_addr.valid_bits < 32) // may be updating a 64 bit address so only set 32 if currently less.
v_addr.valid_bits = 32;
v_addr_ISA = IS;
push_vaddr();
}

View File

@ -35,70 +35,13 @@
#ifndef ARM_TRC_PKT_PROC_ETMV4_H_INCLUDED
#define ARM_TRC_PKT_PROC_ETMV4_H_INCLUDED
// split I & D into separate files, retain this header for backward compatibility
// for now just include the I packet processor as that is the only one implemented.
#include "trc_pkt_types_etmv4.h"
#include "trc_pkt_proc_etmv4i.h"
#include "common/trc_pkt_proc_base.h"
class EtmV4IPktProcImpl; /**< ETMv4 I channel packet processor */
class EtmV4DPktProcImpl; /**< ETMv4 D channel packet processor */
class EtmV4ITrcPacket;
class EtmV4DTrcPacket;
class EtmV4Config;
/** @addtogroup ocsd_pkt_proc
@{*/
class TrcPktProcEtmV4I : public TrcPktProcBase< EtmV4ITrcPacket, ocsd_etmv4_i_pkt_type, EtmV4Config>
{
public:
TrcPktProcEtmV4I();
TrcPktProcEtmV4I(int instIDNum);
virtual ~TrcPktProcEtmV4I();
protected:
/* implementation packet processing interface */
virtual ocsd_datapath_resp_t processData( const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed);
virtual ocsd_datapath_resp_t onEOT();
virtual ocsd_datapath_resp_t onReset();
virtual ocsd_datapath_resp_t onFlush();
virtual ocsd_err_t onProtocolConfig();
virtual const bool isBadPacket() const;
friend class EtmV4IPktProcImpl;
EtmV4IPktProcImpl *m_pProcessor;
};
class TrcPktProcEtmV4D : public TrcPktProcBase< EtmV4DTrcPacket, ocsd_etmv4_d_pkt_type, EtmV4Config>
{
public:
TrcPktProcEtmV4D();
TrcPktProcEtmV4D(int instIDNum);
virtual ~TrcPktProcEtmV4D();
protected:
/* implementation packet processing interface */
virtual ocsd_datapath_resp_t processData( const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed);
virtual ocsd_datapath_resp_t onEOT();
virtual ocsd_datapath_resp_t onReset();
virtual ocsd_datapath_resp_t onFlush();
virtual ocsd_err_t onProtocolConfig();
virtual const bool isBadPacket() const;
friend class EtmV4DPktProcImpl;
EtmV4DPktProcImpl *m_pProcessor;
};
/** @}*/
#endif // ARM_TRC_PKT_PROC_ETMV4_H_INCLUDED
/* End of File trc_pkt_proc_etmv4.h */

View File

@ -1,8 +1,8 @@
/*
* \file trc_pkt_proc_etmv4i_impl.h
* \file trc_pkt_proc_etmv4i.h
* \brief OpenCSD : Implementation of ETMv4 packet processing
*
* \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
* \copyright Copyright (c) 2015, 2019 ARM Limited. All Rights Reserved.
*/
/*
@ -35,54 +35,37 @@
#ifndef ARM_TRC_PKT_PROC_ETMV4I_IMPL_H_INCLUDED
#define ARM_TRC_PKT_PROC_ETMV4I_IMPL_H_INCLUDED
#include "trc_pkt_types_etmv4.h"
#include "opencsd/etmv4/trc_pkt_proc_etmv4.h"
#include "opencsd/etmv4/trc_cmp_cfg_etmv4.h"
#include "opencsd/etmv4/trc_pkt_elem_etmv4i.h"
#include "common/trc_raw_buffer.h"
#include "common/trc_pkt_proc_base.h"
class TraceRawBuffer
class EtmV4ITrcPacket;
class EtmV4Config;
/** @addtogroup ocsd_pkt_proc
@{*/
class TrcPktProcEtmV4I : public TrcPktProcBase< EtmV4ITrcPacket, ocsd_etmv4_i_pkt_type, EtmV4Config>
{
public:
TraceRawBuffer();
~TraceRawBuffer() {};
TrcPktProcEtmV4I();
TrcPktProcEtmV4I(int instIDNum);
virtual ~TrcPktProcEtmV4I();
// init the buffer
void init(const uint32_t size, const uint8_t *rawtrace, std::vector<uint8_t> *out_packet);
void copyByteToPkt(); // move a byte to the packet buffer
uint8_t peekNextByte(); // value of next byte in buffer.
bool empty() { return m_bufProcessed == m_bufSize; };
// bytes processed.
uint32_t processed() { return m_bufProcessed; };
// buffer size;
uint32_t size() { return m_bufSize; }
private:
uint32_t m_bufSize;
uint32_t m_bufProcessed;
const uint8_t *m_pBuffer;
std::vector<uint8_t> *pkt;
};
class EtmV4IPktProcImpl
{
public:
EtmV4IPktProcImpl();
~EtmV4IPktProcImpl();
void Initialise(TrcPktProcEtmV4I *p_interface);
ocsd_err_t Configure(const EtmV4Config *p_config);
ocsd_datapath_resp_t processData( const ocsd_trc_index_t index,
protected:
/* implementation packet processing interface */
virtual ocsd_datapath_resp_t processData( const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed);
ocsd_datapath_resp_t onEOT();
ocsd_datapath_resp_t onReset();
ocsd_datapath_resp_t onFlush();
const bool isBadPacket() const;
virtual ocsd_datapath_resp_t onEOT();
virtual ocsd_datapath_resp_t onReset();
virtual ocsd_datapath_resp_t onFlush();
virtual ocsd_err_t onProtocolConfig();
virtual const bool isBadPacket() const;
protected:
typedef enum _process_state {
@ -100,7 +83,6 @@ class EtmV4IPktProcImpl
/** packet processor configuration **/
bool m_isInit;
TrcPktProcEtmV4I *m_interface; /**< The interface to the other decode components */
// etmv4 hardware configuration
EtmV4Config m_config;
@ -111,7 +93,6 @@ class EtmV4IPktProcImpl
int m_currPktIdx; // index into raw packet when expanding
EtmV4ITrcPacket m_curr_packet; // expanded packet
ocsd_trc_index_t m_packet_index; // index of the start of the current packet
// uint32_t m_blockBytesProcessed; // number of bytes processed in the current data block
ocsd_trc_index_t m_blockIndex; // index at the start of the current data block being processed
// searching for sync
@ -207,7 +188,7 @@ class EtmV4IPktProcImpl
int extractShortAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint32_t &value, int &bits);
// packet processing is table driven.
typedef void (EtmV4IPktProcImpl::*PPKTFN)(uint8_t);
typedef void (TrcPktProcEtmV4I::*PPKTFN)(uint8_t);
PPKTFN m_pIPktFn;
struct _pkt_i_table_t {
@ -221,11 +202,13 @@ class EtmV4IPktProcImpl
};
inline const bool EtmV4IPktProcImpl::isBadPacket() const
inline const bool TrcPktProcEtmV4I::isBadPacket() const
{
return m_curr_packet.isBadPacket();
}
/** @}*/
#endif // ARM_TRC_PKT_PROC_ETMV4I_IMPL_H_INCLUDED
/* End of File trc_pkt_proc_etmv4i_impl.h */

View File

@ -85,7 +85,8 @@ typedef enum _ocsd_etmv4_i_pkt_type
// speculation
ETM4_PKT_I_COMMIT = 0x2D, /*!< b00101101 */
ETM4_PKT_I_CANCEL_F1 = 0x2E, /*!< b0010111x */
ETM4_PKT_I_CANCEL_F1 = 0x2E, /*!< b00101110 */
ETM4_PKT_I_CANCEL_F1_MISPRED = 0x2F, /*!< b00101111 */
ETM4_PKT_I_MISPREDICT = 0x30, /*!< b001100xx */
ETM4_PKT_I_CANCEL_F2 = 0x34, /*!< b001101xx */
ETM4_PKT_I_CANCEL_F3 = 0x38, /*!< b00111xxx */

View File

@ -273,11 +273,11 @@ typedef enum _ocsd_dcd_tree_src_t {
/** Core Architecture Version */
typedef enum _ocsd_arch_version {
ARCH_UNKNOWN, /**< unknown architecture */
ARCH_CUSTOM, /**< None ARM, custom architecture */
ARCH_V7, /**< V7 architecture */
ARCH_V8, /**< V8 architecture */
ARCH_V8r3, /**< V8.3 architecture */
ARCH_UNKNOWN = 0x0000, /**< unknown architecture */
ARCH_CUSTOM = 0x0001, /**< None ARM, custom architecture */
ARCH_V7 = 0x0700, /**< V7 architecture */
ARCH_V8 = 0x0800, /**< V8 architecture */
ARCH_V8r3 = 0x0803, /**< V8.3 architecture */
} ocsd_arch_version_t;
// macros for arch version comparisons.
@ -430,9 +430,10 @@ typedef enum _ocsd_mem_space_acc_t {
OCSD_MEM_SPACE_EL1N = 0x2, /**< NS EL1/0 */
OCSD_MEM_SPACE_EL2 = 0x4, /**< NS EL2 */
OCSD_MEM_SPACE_EL3 = 0x8, /**< S EL3 */
OCSD_MEM_SPACE_S = 0x9, /**< Any S */
OCSD_MEM_SPACE_EL2S = 0x10, /**< S EL2 */
OCSD_MEM_SPACE_S = 0x19, /**< Any S */
OCSD_MEM_SPACE_N = 0x6, /**< Any NS */
OCSD_MEM_SPACE_ANY = 0xF, /**< Any sec level / EL - live system use current EL + sec state */
OCSD_MEM_SPACE_ANY = 0x1F, /**< Any sec level / EL - live system use current EL + sec state */
} ocsd_mem_space_acc_t;
/**
@ -494,13 +495,14 @@ typedef struct _ocsd_file_mem_region {
/** @name Packet Processor Operation Control Flags
common operational flags - bottom 16 bits,
component specific - top 16 bits.
protocol component specific - top 16 bits.
(common flags share bitfield with pkt decoder common flags and create flags)
@{*/
#define OCSD_OPFLG_PKTPROC_NOFWD_BAD_PKTS 0x00000001 /**< don't forward bad packets up data path */
#define OCSD_OPFLG_PKTPROC_NOMON_BAD_PKTS 0x00000002 /**< don't forward bad packets to monitor interface */
#define OCSD_OPFLG_PKTPROC_ERR_BAD_PKTS 0x00000004 /**< throw error for bad packets - halt decoding. */
#define OCSD_OPFLG_PKTPROC_UNSYNC_ON_BAD_PKTS 0x00000008 /**< switch to unsynced state on bad packets - wait for next sync point */
#define OCSD_OPFLG_PKTPROC_NOFWD_BAD_PKTS 0x00000010 /**< don't forward bad packets up data path */
#define OCSD_OPFLG_PKTPROC_NOMON_BAD_PKTS 0x00000020 /**< don't forward bad packets to monitor interface */
#define OCSD_OPFLG_PKTPROC_ERR_BAD_PKTS 0x00000040 /**< throw error for bad packets - halt decoding. */
#define OCSD_OPFLG_PKTPROC_UNSYNC_ON_BAD_PKTS 0x00000080 /**< switch to unsynced state on bad packets - wait for next sync point */
/** mask to combine all common packet processor operational control flags */
#define OCSD_OPFLG_PKTPROC_COMMON (OCSD_OPFLG_PKTPROC_NOFWD_BAD_PKTS | \
@ -508,14 +510,18 @@ typedef struct _ocsd_file_mem_region {
OCSD_OPFLG_PKTPROC_ERR_BAD_PKTS | \
OCSD_OPFLG_PKTPROC_UNSYNC_ON_BAD_PKTS )
/** mask for the component spcific flags */
#define OCSD_OPFLG_COMP_MODE_MASK 0xFFFF0000
/** @}*/
/** @name Packet Decoder Operation Control Flags
common operational flags - bottom 16 bits,
component specific - top 16 bits.
@{*/
protcol component specific - top 16 bits.
(common flags share bitfield with pkt processor common flags and create flags)
@{*/
#define OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS 0x00000001 /**< throw error on bad packets input (default is to unsync and wait) */
#define OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS 0x00000100 /**< throw error on bad packets input (default is to unsync and wait) */
/** mask to combine all common packet processor operational control flags */
#define OCSD_OPFLG_PKTDEC_COMMON (OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS)
@ -524,7 +530,8 @@ typedef struct _ocsd_file_mem_region {
/** @name Decoder creation information
Flags to use when creating decoders by name
Flags to use when creating decoders by name.
- share bitfield with pkt processor flags and packet decoder common flags.
Builtin decoder names.

View File

@ -43,8 +43,8 @@
/** @name Library Versioning
@{*/
#define OCSD_VER_MAJOR 0x0 /**< Library Major Version */
#define OCSD_VER_MINOR 0xC /**< Library Minor Version */
#define OCSD_VER_PATCH 0x0 /**< Library Patch Version */
#define OCSD_VER_MINOR 0xE /**< Library Minor Version */
#define OCSD_VER_PATCH 0x2 /**< Library Patch Version */
/** Library version number - MMMMnnpp format.
MMMM = major version,
@ -53,7 +53,7 @@
*/
#define OCSD_VER_NUM ((OCSD_VER_MAJOR << 16) | (OCSD_VER_MINOR << 8) | OCSD_VER_PATCH)
#define OCSD_VER_STRING "0.12.0" /**< Library Version string */
#define OCSD_VER_STRING "0.14.2" /**< Library Version string */
#define OCSD_LIB_NAME "OpenCSD Library" /**< Library name string */
#define OCSD_LIB_SHORT_NAME "OCSD" /**< Library Short name string */
/** @}*/

View File

@ -154,6 +154,7 @@ class TrcPktDecodePtm : public TrcPktDecodeBase<PtmTrcPacket, PtmConfig>
} processor_state_t;
processor_state_t m_curr_state;
unsync_info_t m_unsync_info;
const bool processStateIsCont() const;

View File

@ -79,6 +79,7 @@ class TrcPktDecodeStm : public TrcPktDecodeBase<StmTrcPacket, STMConfig>
} processor_state_t;
processor_state_t m_curr_state;
unsync_info_t m_unsync_info;
ocsd_swt_info_t m_swt_packet_info;

View File

@ -52,6 +52,7 @@ typedef enum _ocsd_gen_trc_elem_t
OCSD_GEN_TRC_ELEM_EO_TRACE, /*!< end of the available trace in the buffer. */
OCSD_GEN_TRC_ELEM_PE_CONTEXT, /*!< PE status update / change (arch, ctxtid, vmid etc). */
OCSD_GEN_TRC_ELEM_INSTR_RANGE, /*!< traced N consecutive instructions from addr (no intervening events or data elements), may have data assoc key */
OCSD_GEN_TRC_ELEM_I_RANGE_NOPATH, /*!< traced N instructions in a range, but incomplete information as to program execution path from start to end of range */
OCSD_GEN_TRC_ELEM_ADDR_NACC, /*!< tracing in inaccessible memory area */
OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN, /*!< address currently unknown - need address packet update */
OCSD_GEN_TRC_ELEM_EXCEPTION, /*!< exception - start address may be exception target, end address may be preferred ret addr. */
@ -75,6 +76,16 @@ typedef struct _trace_event_t {
uint16_t ev_number; /**< event number if numbered event type */
} trace_event_t;
typedef enum _unsync_info_t {
UNSYNC_UNKNOWN, /**< unknown /undefined */
UNSYNC_INIT_DECODER, /**< decoder intialisation - start of trace. */
UNSYNC_RESET_DECODER, /**< decoder reset. */
UNSYNC_OVERFLOW, /**< overflow packet - need to re-sync / end of trace after overflow. */
UNSYNC_DISCARD, /**< specl trace discard - need to re-sync. */
UNSYNC_BAD_PACKET, /**< bad packet at input - resync to restart. */
UNSYNC_EOT, /**< end of trace - no additional info */
} unsync_info_t;
typedef struct _ocsd_generic_trace_elem {
ocsd_gen_trc_elem_t elem_type; /**< Element type - remaining data interpreted according to this value */
ocsd_isa isa; /**< instruction set for executed instructions */
@ -110,6 +121,7 @@ typedef struct _ocsd_generic_trace_elem {
trace_on_reason_t trace_on_reason; /**< reason for the trace on packet */
ocsd_swt_info_t sw_trace_info; /**< software trace packet info */
uint32_t num_instr_range; /**< number of instructions covered by range packet (for T32 this cannot be calculated from en-st/i_size) */
unsync_info_t unsync_eot_info; /**< additional information for unsync / end-of-trace packets. */
};
const void *ptr_extended_data; /**< pointer to extended data buffer (data trace, sw trace payload) / custom structure */

View File

@ -102,7 +102,7 @@ template<class P> ocsd_datapath_resp_t PacketPrinter<P>::PacketDataIn( const ocs
if(!m_bRawPrint && (m_last_resp == OCSD_RESP_WAIT))
{
// expect a flush or a complete reset after a wait.
if((op != OCSD_OP_FLUSH) || (op != OCSD_OP_RESET))
if((op != OCSD_OP_FLUSH) && (op != OCSD_OP_RESET))
{
m_oss <<"ID:"<< std::hex << (uint32_t)m_trcID << "\tERROR: FLUSH operation expected after wait on trace decode path\n";
itemPrintLine(m_oss.str());

View File

@ -130,6 +130,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV3::onEOT()
try {
pElem = GetNextOpElem(resp);
pElem->setType(OCSD_GEN_TRC_ELEM_EO_TRACE);
pElem->setUnSyncEOTReason(UNSYNC_EOT);
m_outputElemList.commitAllPendElem();
m_curr_state = SEND_PKTS;
resp = m_outputElemList.sendElements();
@ -147,6 +148,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV3::onEOT()
ocsd_datapath_resp_t TrcPktDecodeEtmV3::onReset()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
m_unsync_info = UNSYNC_RESET_DECODER;
resetDecoder();
return resp;
}
@ -199,6 +201,7 @@ void TrcPktDecodeEtmV3::initDecoder()
{
m_CSID = 0;
resetDecoder();
m_unsync_info = UNSYNC_INIT_DECODER;
m_code_follower.initInterfaces(getMemoryAccessAttachPt(),getInstrDecodeAttachPt());
m_outputElemList.initSendIf(getTraceElemOutAttachPt());
}
@ -355,6 +358,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV3::decodePacket(bool &pktDone)
catch(ocsdError &err)
{
LogError(err);
m_unsync_info = UNSYNC_BAD_PACKET;
resetDecoder(); // mark decoder as unsynced - dump any current state.
pktDone = true;
}
@ -362,6 +366,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV3::decodePacket(bool &pktDone)
{
LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_FAIL,m_index_curr_pkt,m_CSID,"Bad Packet sequence."));
resp = OCSD_RESP_FATAL_SYS_ERR;
m_unsync_info = UNSYNC_BAD_PACKET;
resetDecoder(); // mark decoder as unsynced - dump any current state.
pktDone = true;
}
@ -375,11 +380,13 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV3::sendUnsyncPacket()
try {
pElem = GetNextOpElem(resp);
pElem->setType(OCSD_GEN_TRC_ELEM_NO_SYNC);
pElem->setUnSyncEOTReason(m_unsync_info);
resp = m_outputElemList.sendElements();
}
catch(ocsdError &err)
{
LogError(err);
m_unsync_info = UNSYNC_BAD_PACKET;
resetDecoder(); // mark decoder as unsynced - dump any current state.
}
return resp;
@ -464,6 +471,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV3::processISync(const bool withCC, const bo
catch(ocsdError &err)
{
LogError(err);
m_unsync_info = UNSYNC_BAD_PACKET;
resetDecoder(); // mark decoder as unsynced - dump any current state.
}
return resp;
@ -531,6 +539,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV3::processBranchAddr()
catch(ocsdError &err)
{
LogError(err);
m_unsync_info = UNSYNC_BAD_PACKET;
resetDecoder(); // mark decoder as unsynced - dump any current state.
}
}
@ -647,6 +656,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV3::processPHdr()
catch(ocsdError &err)
{
LogError(err);
m_unsync_info = UNSYNC_BAD_PACKET;
resetDecoder(); // mark decoder as unsynced - dump any current state.
}
return resp;

View File

@ -90,13 +90,17 @@ TrcStackElemExcept *EtmV4P0Stack::createExceptElem(const ocsd_etmv4_i_pkt_type r
return pElem;
}
TrcStackElemCtxt *EtmV4P0Stack::createContextElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_context_t &context)
TrcStackElemCtxt *EtmV4P0Stack::createContextElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_context_t &context, const uint8_t IS, const bool back /*= false*/)
{
TrcStackElemCtxt *pElem = new (std::nothrow) TrcStackElemCtxt(root_pkt, root_index);
if (pElem)
{
pElem->setContext(context);
push_front(pElem);
pElem->setIS(IS);
if (back)
push_back(pElem);
else
push_front(pElem);
}
return pElem;
@ -113,4 +117,40 @@ TrcStackElemAddr *EtmV4P0Stack::createAddrElem(const ocsd_etmv4_i_pkt_type root_
return pElem;
}
TrcStackQElem *EtmV4P0Stack::createQElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const int count)
{
TrcStackQElem *pElem = new (std::nothrow) TrcStackQElem(root_pkt, root_index);
if (pElem)
{
pElem->setInstrCount(count);
push_front(pElem);
}
return pElem;
}
// iteration functions
void EtmV4P0Stack::from_front_init()
{
m_iter = m_P0_stack.begin();
}
TrcStackElem *EtmV4P0Stack::from_front_next()
{
TrcStackElem *pElem = 0;
if (m_iter != m_P0_stack.end())
{
pElem = *m_iter++;
}
return pElem;
}
void EtmV4P0Stack::erase_curr_from_front()
{
std::deque<TrcStackElem *>::iterator erase_iter;
erase_iter = m_iter;
erase_iter--;
m_P0_stack.erase(erase_iter);
}
/* End of file trc_etmv4_stack_elem.cpp */

File diff suppressed because it is too large Load Diff

View File

@ -1,57 +0,0 @@
/*
* \file trc_pkt_elem_etmv4d.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 "opencsd/etmv4/trc_pkt_elem_etmv4d.h"
EtmV4DTrcPacket::EtmV4DTrcPacket()
{
}
EtmV4DTrcPacket::~EtmV4DTrcPacket()
{
}
// printing
void EtmV4DTrcPacket::toString(std::string &str) const
{
}
void EtmV4DTrcPacket::toStringFmt(const uint32_t fmtFlags, std::string &str) const
{
}
/* End of File trc_pkt_elem_etmv4d.cpp */

View File

@ -161,6 +161,7 @@ void EtmV4ITrcPacket::toString(std::string &str) const
{
std::ostringstream oss;
oss << "; INFO=" << std::hex << "0x" << trace_info.val;
oss << " { CC." << std::dec << trace_info.bits.cc_enabled << " }";
if (trace_info.bits.cc_enabled)
oss << "; CC_THRESHOLD=" << std::hex << "0x" << cc_threshold;
str += oss.str();
@ -176,7 +177,95 @@ void EtmV4ITrcPacket::toString(std::string &str) const
str += oss.str();
}
break;
case ETM4_PKT_I_CANCEL_F1:
{
std::ostringstream oss;
oss << "; Cancel(" << std::dec << cancel_elements << ")";
str += oss.str();
}
break;
case ETM4_PKT_I_CANCEL_F1_MISPRED:
{
std::ostringstream oss;
oss << "; Cancel(" << std::dec << cancel_elements << "), Mispredict";
str += oss.str();
}
break;
case ETM4_PKT_I_MISPREDICT:
{
std::ostringstream oss;
oss << "; ";
if (atom.num) {
atomSeq(valStr);
oss << "Atom: " << valStr << ", ";
}
oss << "Mispredict";
str += oss.str();
}
break;
case ETM4_PKT_I_CANCEL_F2:
{
std::ostringstream oss;
oss << "; ";
if (atom.num) {
atomSeq(valStr);
oss << "Atom: " << valStr << ", ";
}
oss << "Cancel(1), Mispredict";
str += oss.str();
}
break;
case ETM4_PKT_I_CANCEL_F3:
{
std::ostringstream oss;
oss << "; ";
if (atom.num) {
oss << "Atom: E, ";
}
oss << "Cancel(" << std::dec << cancel_elements << "), Mispredict";
str += oss.str();
}
break;
case ETM4_PKT_I_COMMIT:
{
std::ostringstream oss;
oss << "; Commit(" << std::dec << commit_elements << ")";
str += oss.str();
}
break;
case ETM4_PKT_I_Q:
{
std::ostringstream oss;
if (Q_pkt.count_present)
{
oss << "; Count(" << std::dec << Q_pkt.q_count << ")";
str += oss.str();
}
else
str += "; Count(Unknown)";
if (Q_pkt.addr_match)
{
addrMatchIdx(valStr);
str += "; " + valStr;
}
if (Q_pkt.addr_present || Q_pkt.addr_match)
{
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);
str += "; Addr=" + valStr;
}
}
break;
}
}
void EtmV4ITrcPacket::toStringFmt(const uint32_t fmtFlags, std::string &str) const
@ -296,6 +385,12 @@ const char *EtmV4ITrcPacket::packetTypeName(const ocsd_etmv4_i_pkt_type type, co
pDesc = "Cancel Format 1.";
break;
case ETM4_PKT_I_CANCEL_F1_MISPRED:
pName = "I_CANCEL_F1_MISPRED";
pDesc = "Cancel Format 1 + Mispredict.";
break;
case ETM4_PKT_I_MISPREDICT:
pName = "I_MISPREDICT";
pDesc = "Mispredict.";

View File

@ -1,126 +0,0 @@
/*
* \file trc_pkt_proc_etmv4.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 "opencsd/etmv4/trc_pkt_proc_etmv4.h"
#include "trc_pkt_proc_etmv4i_impl.h"
#include "common/ocsd_error.h"
#ifdef __GNUC__
// G++ doesn't like the ## pasting
#define ETMV4I_PKTS_NAME "PKTP_ETMV4I"
#else
// VC++ is fine
#define ETMV4I_PKTS_NAME OCSD_CMPNAME_PREFIX_PKTPROC##"_ETMV4I"
#endif
static const uint32_t ETMV4_SUPPORTED_OP_FLAGS = OCSD_OPFLG_PKTPROC_COMMON;
/***************************************************************************/
/*******************ETM V4 INSTRUCTION *************************************/
/***************************************************************************/
TrcPktProcEtmV4I::TrcPktProcEtmV4I() : TrcPktProcBase(ETMV4I_PKTS_NAME),
m_pProcessor(0)
{
m_supported_op_flags = ETMV4_SUPPORTED_OP_FLAGS;
}
TrcPktProcEtmV4I::TrcPktProcEtmV4I(int instIDNum) : TrcPktProcBase(ETMV4I_PKTS_NAME, instIDNum),
m_pProcessor(0)
{
m_supported_op_flags = ETMV4_SUPPORTED_OP_FLAGS;
}
TrcPktProcEtmV4I::~TrcPktProcEtmV4I()
{
if(m_pProcessor)
delete m_pProcessor;
m_pProcessor = 0;
}
ocsd_err_t TrcPktProcEtmV4I::onProtocolConfig()
{
if(m_pProcessor == 0)
{
m_pProcessor = new (std::nothrow) EtmV4IPktProcImpl();
if(m_pProcessor == 0)
{
LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_MEM));
return OCSD_ERR_MEM;
}
m_pProcessor->Initialise(this);
}
return m_pProcessor->Configure(m_config);
}
ocsd_datapath_resp_t TrcPktProcEtmV4I::processData( const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed)
{
if(m_pProcessor)
return m_pProcessor->processData(index,dataBlockSize,pDataBlock,numBytesProcessed);
return OCSD_RESP_FATAL_NOT_INIT;
}
ocsd_datapath_resp_t TrcPktProcEtmV4I::onEOT()
{
if(m_pProcessor)
return m_pProcessor->onEOT();
return OCSD_RESP_FATAL_NOT_INIT;
}
ocsd_datapath_resp_t TrcPktProcEtmV4I::onReset()
{
if(m_pProcessor)
return m_pProcessor->onReset();
return OCSD_RESP_FATAL_NOT_INIT;
}
ocsd_datapath_resp_t TrcPktProcEtmV4I::onFlush()
{
if(m_pProcessor)
return m_pProcessor->onFlush();
return OCSD_RESP_FATAL_NOT_INIT;
}
const bool TrcPktProcEtmV4I::isBadPacket() const
{
if(m_pProcessor)
return m_pProcessor->isBadPacket();
return false;
}
/* End of File trc_pkt_proc_etmv4.cpp */

View File

@ -1,71 +0,0 @@
/*
* \file trc_pkt_proc_etmv4d_impl.h
* \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.
*/
#ifndef ARM_TRC_PKT_PROC_ETMV4D_IMPL_H_INCLUDED
#define ARM_TRC_PKT_PROC_ETMV4D_IMPL_H_INCLUDED
#include "etmv4/trc_pkt_proc_etmv4.h"
#include "etmv4/trc_cmp_cfg_etmv4.h"
class EtmV4DPktProcImpl
{
public:
EtmV4DPktProcImpl();
~EtmV4DPktProcImpl();
void Initialise(TrcPktProcEtmV4D *p_interface);
ocsd_err_t Configure(const EtmV4Config *p_config);
ocsd_datapath_resp_t processData( const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed);
ocsd_datapath_resp_t onEOT();
ocsd_datapath_resp_t onReset();
ocsd_datapath_resp_t onFlush();
protected:
bool m_isInit;
TrcPktProcEtmV4D *m_interface; /**< The interface to the other decode components */
EtmV4Config m_config;
};
#endif // ARM_TRC_PKT_PROC_ETMV4D_IMPL_H_INCLUDED
/* End of File trc_pkt_proc_etmv4d_impl.h */

View File

@ -1,8 +1,8 @@
/*
* \file trc_pkt_proc_etmv4i_impl.cpp
* \brief OpenCSD :
* \file trc_pkt_proc_etmv4i.cpp
* \brief OpenCSD : Packet processor for ETMv4
*
* \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
* \copyright Copyright (c) 2015, 2019, ARM Limited. All Rights Reserved.
*/
/*
@ -32,87 +32,58 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "trc_pkt_proc_etmv4i_impl.h"
#include "opencsd/etmv4/trc_pkt_proc_etmv4.h"
#include "common/ocsd_error.h"
/* Trace raw input buffer class */
TraceRawBuffer::TraceRawBuffer()
{
m_bufSize = 0;
m_bufProcessed = 0;
m_pBuffer = 0;
pkt = 0;
}
#ifdef __GNUC__
// G++ doesn't like the ## pasting
#define ETMV4I_PKTS_NAME "PKTP_ETMV4I"
#else
// VC++ is fine
#define ETMV4I_PKTS_NAME OCSD_CMPNAME_PREFIX_PKTPROC##"_ETMV4I"
#endif
// init the buffer
void TraceRawBuffer::init(const uint32_t size, const uint8_t *rawtrace, std::vector<uint8_t> *out_packet)
{
m_bufSize = size;
m_bufProcessed = 0;
m_pBuffer = rawtrace;
pkt = out_packet;
}
void TraceRawBuffer::copyByteToPkt()
{
if (!empty()) {
pkt->push_back(m_pBuffer[m_bufProcessed]);
m_bufProcessed++;
}
}
uint8_t TraceRawBuffer::peekNextByte()
{
uint8_t val = 0;
if (!empty())
val = m_pBuffer[m_bufProcessed];
return val;
}
static const uint32_t ETMV4_SUPPORTED_OP_FLAGS = OCSD_OPFLG_PKTPROC_COMMON;
/* trace etmv4 packet processing class */
EtmV4IPktProcImpl::EtmV4IPktProcImpl() :
TrcPktProcEtmV4I::TrcPktProcEtmV4I() : TrcPktProcBase(ETMV4I_PKTS_NAME),
m_isInit(false),
m_interface(0),
m_first_trace_info(false)
{
m_supported_op_flags = ETMV4_SUPPORTED_OP_FLAGS;
}
EtmV4IPktProcImpl::~EtmV4IPktProcImpl()
TrcPktProcEtmV4I::TrcPktProcEtmV4I(int instIDNum) : TrcPktProcBase(ETMV4I_PKTS_NAME, instIDNum),
m_isInit(false),
m_first_trace_info(false)
{
m_supported_op_flags = ETMV4_SUPPORTED_OP_FLAGS;
}
TrcPktProcEtmV4I::~TrcPktProcEtmV4I()
{
}
void EtmV4IPktProcImpl::Initialise(TrcPktProcEtmV4I *p_interface)
ocsd_err_t TrcPktProcEtmV4I::onProtocolConfig()
{
if(p_interface)
{
m_interface = p_interface;
m_isInit = true;
}
InitProcessorState();
InitProcessorState();
m_config = *TrcPktProcBase::getProtocolConfig();
BuildIPacketTable(); // packet table based on config
m_isInit = true;
return OCSD_OK;
}
ocsd_err_t EtmV4IPktProcImpl::Configure(const EtmV4Config *p_config)
{
ocsd_err_t err = OCSD_OK;
if(p_config != 0)
{
m_config = *p_config;
BuildIPacketTable(); // packet table based on config
}
else
{
err = OCSD_ERR_INVALID_PARAM_VAL;
if(m_isInit)
m_interface->LogError(ocsdError(OCSD_ERR_SEV_ERROR,err));
}
return err;
}
ocsd_datapath_resp_t EtmV4IPktProcImpl::processData( const ocsd_trc_index_t index,
ocsd_datapath_resp_t TrcPktProcEtmV4I::processData( const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed)
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
if (!m_isInit)
return OCSD_RESP_FATAL_NOT_INIT;
m_trcIn.init(dataBlockSize, pDataBlock, &m_currPacketData);
m_blockIndex = index;
bool done = false;
@ -122,9 +93,6 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::processData( const ocsd_trc_index_t ind
{
try
{
/* while (((m_blockBytesProcessed < dataBlockSize) ||
((m_blockBytesProcessed == dataBlockSize) && (m_process_state == SEND_PKT))) &&
OCSD_DATA_RESP_IS_CONT(resp))*/
while ( (!m_trcIn.empty() || (m_process_state == SEND_PKT)) &&
OCSD_DATA_RESP_IS_CONT(resp)
)
@ -142,7 +110,7 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::processData( const ocsd_trc_index_t ind
else
{
// unsynced - process data until we see a sync point
m_pIPktFn = &EtmV4IPktProcImpl::iNotSync;
m_pIPktFn = &TrcPktProcEtmV4I::iNotSync;
m_curr_packet.type = ETM4_PKT_I_NOTSYNC;
}
m_process_state = PROC_DATA;
@ -153,8 +121,6 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::processData( const ocsd_trc_index_t ind
{
nextByte = m_trcIn.peekNextByte();
m_trcIn.copyByteToPkt(); // move next byte into the packet
// m_currPacketData.push_back(pDataBlock[m_blockBytesProcessed]);
// m_blockBytesProcessed++;
(this->*m_pIPktFn)(nextByte);
}
break;
@ -181,7 +147,7 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::processData( const ocsd_trc_index_t ind
catch(ocsdError &err)
{
done = true;
m_interface->LogError(err);
LogError(err);
if( (err.getErrorCode() == OCSD_ERR_BAD_PACKET_SEQ) ||
(err.getErrorCode() == OCSD_ERR_INVALID_PCKT_HDR))
{
@ -201,7 +167,7 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::processData( const ocsd_trc_index_t ind
/// vv bad at this point.
resp = OCSD_RESP_FATAL_SYS_ERR;
const ocsdError &fatal = ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_FAIL,m_packet_index,m_config.getTraceID(),"Unknown System Error decoding trace.");
m_interface->LogError(fatal);
LogError(fatal);
}
} while (!done);
@ -209,9 +175,12 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::processData( const ocsd_trc_index_t ind
return resp;
}
ocsd_datapath_resp_t EtmV4IPktProcImpl::onEOT()
ocsd_datapath_resp_t TrcPktProcEtmV4I::onEOT()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
if (!m_isInit)
return OCSD_RESP_FATAL_NOT_INIT;
// if we have a partial packet then send to attached sinks
if(m_currPacketData.size() != 0)
{
@ -222,31 +191,37 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::onEOT()
return resp;
}
ocsd_datapath_resp_t EtmV4IPktProcImpl::onReset()
ocsd_datapath_resp_t TrcPktProcEtmV4I::onReset()
{
if (!m_isInit)
return OCSD_RESP_FATAL_NOT_INIT;
// prepare for new decoding session
InitProcessorState();
return OCSD_RESP_CONT;
}
ocsd_datapath_resp_t EtmV4IPktProcImpl::onFlush()
ocsd_datapath_resp_t TrcPktProcEtmV4I::onFlush()
{
if (!m_isInit)
return OCSD_RESP_FATAL_NOT_INIT;
// packet processor never holds on to flushable data (may have partial packet,
// but any full packets are immediately sent)
return OCSD_RESP_CONT;
}
void EtmV4IPktProcImpl::InitPacketState()
void TrcPktProcEtmV4I::InitPacketState()
{
m_currPacketData.clear();
m_curr_packet.initNextPacket(); // clear for next packet.
m_update_on_unsync_packet_index = 0;
}
void EtmV4IPktProcImpl::InitProcessorState()
void TrcPktProcEtmV4I::InitProcessorState()
{
InitPacketState();
m_pIPktFn = &EtmV4IPktProcImpl::iNotSync;
m_pIPktFn = &TrcPktProcEtmV4I::iNotSync;
m_packet_index = 0;
m_is_sync = false;
m_first_trace_info = false;
@ -255,23 +230,23 @@ void EtmV4IPktProcImpl::InitProcessorState()
m_curr_packet.initStartState();
}
ocsd_datapath_resp_t EtmV4IPktProcImpl::outputPacket()
ocsd_datapath_resp_t TrcPktProcEtmV4I::outputPacket()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
resp = m_interface->outputOnAllInterfaces(m_packet_index,&m_curr_packet,&m_curr_packet.type,m_currPacketData);
resp = outputOnAllInterfaces(m_packet_index,&m_curr_packet,&m_curr_packet.type,m_currPacketData);
return resp;
}
ocsd_datapath_resp_t EtmV4IPktProcImpl::outputUnsyncedRawPacket()
ocsd_datapath_resp_t TrcPktProcEtmV4I::outputUnsyncedRawPacket()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
m_interface->outputRawPacketToMonitor(m_packet_index,&m_curr_packet,m_dump_unsynced_bytes,&m_currPacketData[0]);
outputRawPacketToMonitor(m_packet_index,&m_curr_packet,m_dump_unsynced_bytes,&m_currPacketData[0]);
if(!m_sent_notsync_packet)
{
resp = m_interface->outputDecodedPacket(m_packet_index,&m_curr_packet);
resp = outputDecodedPacket(m_packet_index,&m_curr_packet);
m_sent_notsync_packet = true;
}
@ -283,7 +258,7 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::outputUnsyncedRawPacket()
return resp;
}
void EtmV4IPktProcImpl::iNotSync(const uint8_t lastByte)
void TrcPktProcEtmV4I::iNotSync(const uint8_t lastByte)
{
// is it an extension byte?
if (lastByte == 0x00) // TBD : add check for forced sync in here?
@ -309,7 +284,7 @@ void EtmV4IPktProcImpl::iNotSync(const uint8_t lastByte)
}
}
void EtmV4IPktProcImpl::iPktNoPayload(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktNoPayload(const uint8_t lastByte)
{
// some expansion may be required...
switch(m_curr_packet.type)
@ -338,26 +313,26 @@ void EtmV4IPktProcImpl::iPktNoPayload(const uint8_t lastByte)
m_process_state = SEND_PKT; // now just send it....
}
void EtmV4IPktProcImpl::iPktReserved(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktReserved(const uint8_t lastByte)
{
m_curr_packet.updateErrType(ETM4_PKT_I_RESERVED, lastByte); // swap type for err type
throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_INVALID_PCKT_HDR,m_packet_index,m_config.getTraceID());
}
void EtmV4IPktProcImpl::iPktInvalidCfg(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktInvalidCfg(const uint8_t lastByte)
{
m_curr_packet.updateErrType(ETM4_PKT_I_RESERVED_CFG, lastByte); // swap type for err type
throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_INVALID_PCKT_HDR, m_packet_index, m_config.getTraceID());
}
void EtmV4IPktProcImpl::iPktExtension(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktExtension(const uint8_t lastByte)
{
if(m_currPacketData.size() == 2)
{
// not sync and not next by 0x00 - not sync sequence
if(!m_is_sync && (lastByte != 0x00))
{
m_pIPktFn = &EtmV4IPktProcImpl::iNotSync;
m_pIPktFn = &TrcPktProcEtmV4I::iNotSync;
m_curr_packet.type = ETM4_PKT_I_NOTSYNC;
return;
}
@ -376,7 +351,7 @@ void EtmV4IPktProcImpl::iPktExtension(const uint8_t lastByte)
case 0x00:
m_curr_packet.type = ETM4_PKT_I_ASYNC;
m_pIPktFn = &EtmV4IPktProcImpl::iPktASync; // handle subsequent bytes as async
m_pIPktFn = &TrcPktProcEtmV4I::iPktASync; // handle subsequent bytes as async
break;
default:
@ -388,14 +363,14 @@ void EtmV4IPktProcImpl::iPktExtension(const uint8_t lastByte)
}
}
void EtmV4IPktProcImpl::iPktASync(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktASync(const uint8_t lastByte)
{
if(lastByte != 0x00)
{
// not sync and not next by 0x00 - not sync sequence if < 12
if(!m_is_sync && m_currPacketData.size() != 12)
{
m_pIPktFn = &EtmV4IPktProcImpl::iNotSync;
m_pIPktFn = &TrcPktProcEtmV4I::iNotSync;
m_curr_packet.type = ETM4_PKT_I_NOTSYNC;
return;
}
@ -428,7 +403,7 @@ void EtmV4IPktProcImpl::iPktASync(const uint8_t lastByte)
}
}
void EtmV4IPktProcImpl::iPktTraceInfo(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktTraceInfo(const uint8_t lastByte)
{
if(m_currPacketData.size() == 1) // header
{
@ -500,7 +475,7 @@ void EtmV4IPktProcImpl::iPktTraceInfo(const uint8_t lastByte)
}
void EtmV4IPktProcImpl::iPktTimestamp(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktTimestamp(const uint8_t lastByte)
{
// process the header byte
if(m_currPacketData.size() == 1)
@ -550,7 +525,7 @@ void EtmV4IPktProcImpl::iPktTimestamp(const uint8_t lastByte)
}
}
void EtmV4IPktProcImpl::iPktException(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktException(const uint8_t lastByte)
{
uint16_t excep_type = 0;
@ -582,7 +557,7 @@ void EtmV4IPktProcImpl::iPktException(const uint8_t lastByte)
}
}
void EtmV4IPktProcImpl::iPktCycleCntF123(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktCycleCntF123(const uint8_t lastByte)
{
ocsd_etmv4_i_pkt_type format = m_curr_packet.type;
@ -657,7 +632,7 @@ void EtmV4IPktProcImpl::iPktCycleCntF123(const uint8_t lastByte)
}
}
void EtmV4IPktProcImpl::iPktSpeclRes(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktSpeclRes(const uint8_t lastByte)
{
if(m_currPacketData.size() == 1)
{
@ -671,8 +646,10 @@ void EtmV4IPktProcImpl::iPktSpeclRes(const uint8_t lastByte)
case 0x2: m_curr_packet.setAtomPacket(ATOM_PATTERN, 0x3, 2); break; // EE
case 0x3: m_curr_packet.setAtomPacket(ATOM_PATTERN, 0x0, 1); break; // N
}
if(m_curr_packet.getType() == ETM4_PKT_I_CANCEL_F2)
if (m_curr_packet.getType() == ETM4_PKT_I_CANCEL_F2)
m_curr_packet.setCancelElements(1);
else
m_curr_packet.setCancelElements(0);
m_process_state = SEND_PKT;
break;
@ -694,13 +671,12 @@ void EtmV4IPktProcImpl::iPktSpeclRes(const uint8_t lastByte)
m_curr_packet.setCommitElements(field_val);
else
m_curr_packet.setCancelElements(field_val);
// TBD: sanity check with max spec depth here?
m_process_state = SEND_PKT;
}
}
}
void EtmV4IPktProcImpl::iPktCondInstr(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktCondInstr(const uint8_t lastByte)
{
bool bF1Done = false;
@ -740,7 +716,7 @@ void EtmV4IPktProcImpl::iPktCondInstr(const uint8_t lastByte)
}
}
void EtmV4IPktProcImpl::iPktCondResult(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktCondResult(const uint8_t lastByte)
{
if(m_currPacketData.size() == 1)
{
@ -810,7 +786,7 @@ void EtmV4IPktProcImpl::iPktCondResult(const uint8_t lastByte)
}
}
void EtmV4IPktProcImpl::iPktContext(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktContext(const uint8_t lastByte)
{
bool bSendPacket = false;
@ -852,7 +828,7 @@ void EtmV4IPktProcImpl::iPktContext(const uint8_t lastByte)
}
}
void EtmV4IPktProcImpl::extractAndSetContextInfo(const std::vector<uint8_t> &buffer, const int st_idx)
void TrcPktProcEtmV4I::extractAndSetContextInfo(const std::vector<uint8_t> &buffer, const int st_idx)
{
// on input, buffer index points at the info byte - always present
uint8_t infoByte = m_currPacketData[st_idx];
@ -887,7 +863,7 @@ void EtmV4IPktProcImpl::extractAndSetContextInfo(const std::vector<uint8_t> &buf
}
}
void EtmV4IPktProcImpl::iPktAddrCtxt(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktAddrCtxt(const uint8_t lastByte)
{
if( m_currPacketData.size() == 1)
{
@ -955,7 +931,7 @@ void EtmV4IPktProcImpl::iPktAddrCtxt(const uint8_t lastByte)
}
}
void EtmV4IPktProcImpl::iPktShortAddr(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktShortAddr(const uint8_t lastByte)
{
if (m_currPacketData.size() == 1)
{
@ -980,7 +956,7 @@ void EtmV4IPktProcImpl::iPktShortAddr(const uint8_t lastByte)
}
}
int EtmV4IPktProcImpl::extractShortAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint32_t &value, int &bits)
int TrcPktProcEtmV4I::extractShortAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint32_t &value, int &bits)
{
int IS_shift = (IS == 0) ? 2 : 1;
int idx = 0;
@ -1000,7 +976,7 @@ int EtmV4IPktProcImpl::extractShortAddr(const std::vector<uint8_t> &buffer, cons
return idx;
}
void EtmV4IPktProcImpl::iPktLongAddr(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktLongAddr(const uint8_t lastByte)
{
if(m_currPacketData.size() == 1)
{
@ -1044,7 +1020,7 @@ void EtmV4IPktProcImpl::iPktLongAddr(const uint8_t lastByte)
}
}
void EtmV4IPktProcImpl::iPktQ(const uint8_t lastByte)
void TrcPktProcEtmV4I::iPktQ(const uint8_t lastByte)
{
if(m_currPacketData.size() == 1)
{
@ -1096,7 +1072,7 @@ void EtmV4IPktProcImpl::iPktQ(const uint8_t lastByte)
default:
m_curr_packet.err_type = m_curr_packet.type;
m_curr_packet.type = ETM4_PKT_I_BAD_SEQUENCE;
//SendBadIPacket( PKT_BAD_SEQUENCE, "ERROR: Bad Q packet type", PKT_Q );
m_process_state = SEND_PKT;
break;
}
}
@ -1156,7 +1132,7 @@ void EtmV4IPktProcImpl::iPktQ(const uint8_t lastByte)
}
void EtmV4IPktProcImpl::iAtom(const uint8_t lastByte)
void TrcPktProcEtmV4I::iAtom(const uint8_t lastByte)
{
// patterns lsbit = oldest atom, ms bit = newest.
static const uint32_t f4_patterns[] = {
@ -1228,32 +1204,32 @@ void EtmV4IPktProcImpl::iAtom(const uint8_t lastByte)
}
// header byte processing is table driven.
void EtmV4IPktProcImpl::BuildIPacketTable()
void TrcPktProcEtmV4I::BuildIPacketTable()
{
// initialise everything as reserved.
for(int i = 0; i < 256; i++)
{
m_i_table[i].pkt_type = ETM4_PKT_I_RESERVED;
m_i_table[i].pptkFn = &EtmV4IPktProcImpl::iPktReserved;
m_i_table[i].pptkFn = &TrcPktProcEtmV4I::iPktReserved;
}
// 0x00 - extension
m_i_table[0x00].pkt_type = ETM4_PKT_I_EXTENSION;
m_i_table[0x00].pptkFn = &EtmV4IPktProcImpl::iPktExtension;
m_i_table[0x00].pptkFn = &TrcPktProcEtmV4I::iPktExtension;
// 0x01 - Trace info
m_i_table[0x01].pkt_type = ETM4_PKT_I_TRACE_INFO;
m_i_table[0x01].pptkFn = &EtmV4IPktProcImpl::iPktTraceInfo;
m_i_table[0x01].pptkFn = &TrcPktProcEtmV4I::iPktTraceInfo;
// b0000001x - timestamp
m_i_table[0x02].pkt_type = ETM4_PKT_I_TIMESTAMP;
m_i_table[0x02].pptkFn = &EtmV4IPktProcImpl::iPktTimestamp;
m_i_table[0x02].pptkFn = &TrcPktProcEtmV4I::iPktTimestamp;
m_i_table[0x03].pkt_type = ETM4_PKT_I_TIMESTAMP;
m_i_table[0x03].pptkFn = &EtmV4IPktProcImpl::iPktTimestamp;
m_i_table[0x03].pptkFn = &TrcPktProcEtmV4I::iPktTimestamp;
// b0000 0100 - trace on
m_i_table[0x04].pkt_type = ETM4_PKT_I_TRACE_ON;
m_i_table[0x04].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
m_i_table[0x04].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
// b0000 0101 - Funct ret V8M
@ -1262,30 +1238,30 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
(OCSD_IS_V8_ARCH(m_config.archVersion())) &&
(m_config.FullVersion() >= 0x42))
{
m_i_table[0x05].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
m_i_table[0x05].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
}
// b0000 0110 - exception
m_i_table[0x06].pkt_type = ETM4_PKT_I_EXCEPT;
m_i_table[0x06].pptkFn = &EtmV4IPktProcImpl::iPktException;
m_i_table[0x06].pptkFn = &TrcPktProcEtmV4I::iPktException;
// b0000 0111 - exception return
m_i_table[0x07].pkt_type = ETM4_PKT_I_EXCEPT_RTN;
m_i_table[0x07].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
m_i_table[0x07].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
// b0000 110x - cycle count f2
// b0000 111x - cycle count f1
for(int i = 0; i < 4; i++)
{
m_i_table[0x0C+i].pkt_type = (i >= 2) ? ETM4_PKT_I_CCNT_F1 : ETM4_PKT_I_CCNT_F2;
m_i_table[0x0C+i].pptkFn = &EtmV4IPktProcImpl::iPktCycleCntF123;
m_i_table[0x0C+i].pptkFn = &TrcPktProcEtmV4I::iPktCycleCntF123;
}
// b0001 xxxx - cycle count f3
for(int i = 0; i < 16; i++)
{
m_i_table[0x10+i].pkt_type = ETM4_PKT_I_CCNT_F3;
m_i_table[0x10+i].pptkFn = &EtmV4IPktProcImpl::iPktCycleCntF123;
m_i_table[0x10+i].pptkFn = &TrcPktProcEtmV4I::iPktCycleCntF123;
}
// b0010 0xxx - NDSM
@ -1293,9 +1269,9 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
{
m_i_table[0x20 + i].pkt_type = ETM4_PKT_I_NUM_DS_MKR;
if (m_config.enabledDataTrace())
m_i_table[0x20+i].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
m_i_table[0x20+i].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
else
m_i_table[0x20+i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
m_i_table[0x20+i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
}
// b0010 10xx, b0010 1100 - UDSM
@ -1303,43 +1279,40 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
{
m_i_table[0x28+i].pkt_type = ETM4_PKT_I_UNNUM_DS_MKR;
if (m_config.enabledDataTrace())
m_i_table[0x28+i].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
m_i_table[0x28+i].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
else
m_i_table[0x28+i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
m_i_table[0x28+i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
}
// b0010 1101 - commit
m_i_table[0x2D].pkt_type = ETM4_PKT_I_COMMIT;
m_i_table[0x2D].pptkFn = &EtmV4IPktProcImpl::iPktSpeclRes;
m_i_table[0x2D].pptkFn = &TrcPktProcEtmV4I::iPktSpeclRes;
// b0010 111x - cancel f1
for(int i = 0; i < 2; i++)
{
// G++ doesn't understand [0x2E+i] so...
int idx = i + 0x2E;
m_i_table[idx].pkt_type = ETM4_PKT_I_CANCEL_F1;
m_i_table[idx].pptkFn = &EtmV4IPktProcImpl::iPktSpeclRes;
}
// b0010 111x - cancel f1 (mis pred)
m_i_table[0x2E].pkt_type = ETM4_PKT_I_CANCEL_F1;
m_i_table[0x2E].pptkFn = &TrcPktProcEtmV4I::iPktSpeclRes;
m_i_table[0x2F].pkt_type = ETM4_PKT_I_CANCEL_F1_MISPRED;
m_i_table[0x2F].pptkFn = &TrcPktProcEtmV4I::iPktSpeclRes;
// b0011 00xx - mis predict
for(int i = 0; i < 4; i++)
{
m_i_table[0x30+i].pkt_type = ETM4_PKT_I_MISPREDICT;
m_i_table[0x30+i].pptkFn = &EtmV4IPktProcImpl::iPktSpeclRes;
m_i_table[0x30+i].pptkFn = &TrcPktProcEtmV4I::iPktSpeclRes;
}
// b0011 01xx - cancel f2
for(int i = 0; i < 4; i++)
{
m_i_table[0x34+i].pkt_type = ETM4_PKT_I_CANCEL_F2;
m_i_table[0x34+i].pptkFn = &EtmV4IPktProcImpl::iPktSpeclRes;
m_i_table[0x34+i].pptkFn = &TrcPktProcEtmV4I::iPktSpeclRes;
}
// b0011 1xxx - cancel f3
for(int i = 0; i < 8; i++)
{
m_i_table[0x38+i].pkt_type = ETM4_PKT_I_CANCEL_F3;
m_i_table[0x38+i].pptkFn = &EtmV4IPktProcImpl::iPktSpeclRes;
m_i_table[0x38+i].pptkFn = &TrcPktProcEtmV4I::iPktSpeclRes;
}
bool bCondValid = m_config.hasCondTrace() && m_config.enabledCondITrace();
@ -1349,26 +1322,26 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
{
m_i_table[0x40 + i].pkt_type = ETM4_PKT_I_COND_I_F2;
if (bCondValid)
m_i_table[0x40 + i].pptkFn = &EtmV4IPktProcImpl::iPktCondInstr;
m_i_table[0x40 + i].pptkFn = &TrcPktProcEtmV4I::iPktCondInstr;
else
m_i_table[0x40 + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
m_i_table[0x40 + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
}
// b0100 0011 - cond flush
m_i_table[0x43].pkt_type = ETM4_PKT_I_COND_FLUSH;
if (bCondValid)
m_i_table[0x43].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
m_i_table[0x43].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
else
m_i_table[0x43].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
m_i_table[0x43].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
// b0100 010x, b0100 0110 - cond res f4
for (int i = 0; i < 3; i++)
{
m_i_table[0x44 + i].pkt_type = ETM4_PKT_I_COND_RES_F4;
if (bCondValid)
m_i_table[0x44 + i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
m_i_table[0x44 + i].pptkFn = &TrcPktProcEtmV4I::iPktCondResult;
else
m_i_table[0x44 + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
m_i_table[0x44 + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
}
// b0100 100x, b0100 0110 - cond res f2
@ -1377,17 +1350,17 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
{
m_i_table[0x48 + i].pkt_type = ETM4_PKT_I_COND_RES_F2;
if (bCondValid)
m_i_table[0x48 + i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
m_i_table[0x48 + i].pptkFn = &TrcPktProcEtmV4I::iPktCondResult;
else
m_i_table[0x48 + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
m_i_table[0x48 + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
}
for (int i = 0; i < 3; i++)
{
m_i_table[0x4C + i].pkt_type = ETM4_PKT_I_COND_RES_F2;
if (bCondValid)
m_i_table[0x4C + i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
m_i_table[0x4C + i].pptkFn = &TrcPktProcEtmV4I::iPktCondResult;
else
m_i_table[0x4C + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
m_i_table[0x4C + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
}
// b0101xxxx - cond res f3
@ -1395,9 +1368,9 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
{
m_i_table[0x50 + i].pkt_type = ETM4_PKT_I_COND_RES_F3;
if (bCondValid)
m_i_table[0x50 + i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
m_i_table[0x50 + i].pptkFn = &TrcPktProcEtmV4I::iPktCondResult;
else
m_i_table[0x50 + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
m_i_table[0x50 + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
}
// b011010xx - cond res f1
@ -1405,24 +1378,24 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
{
m_i_table[0x68 + i].pkt_type = ETM4_PKT_I_COND_RES_F1;
if (bCondValid)
m_i_table[0x68 + i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
m_i_table[0x68 + i].pptkFn = &TrcPktProcEtmV4I::iPktCondResult;
else
m_i_table[0x68 + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
m_i_table[0x68 + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
}
// b0110 1100 - cond instr f1
m_i_table[0x6C].pkt_type = ETM4_PKT_I_COND_I_F1;
if (bCondValid)
m_i_table[0x6C].pptkFn = &EtmV4IPktProcImpl::iPktCondInstr;
m_i_table[0x6C].pptkFn = &TrcPktProcEtmV4I::iPktCondInstr;
else
m_i_table[0x6C].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
m_i_table[0x6C].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
// b0110 1101 - cond instr f3
m_i_table[0x6D].pkt_type = ETM4_PKT_I_COND_I_F3;
if (bCondValid)
m_i_table[0x6D].pptkFn = &EtmV4IPktProcImpl::iPktCondInstr;
m_i_table[0x6D].pptkFn = &TrcPktProcEtmV4I::iPktCondInstr;
else
m_i_table[0x6D].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
m_i_table[0x6D].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
// b0110111x - cond res f1
for (int i = 0; i < 2; i++)
@ -1430,30 +1403,30 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
// G++ cannot understand [0x6E+i] so change these round
m_i_table[i + 0x6E].pkt_type = ETM4_PKT_I_COND_RES_F1;
if (bCondValid)
m_i_table[i + 0x6E].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
m_i_table[i + 0x6E].pptkFn = &TrcPktProcEtmV4I::iPktCondResult;
else
m_i_table[i + 0x6E].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
m_i_table[i + 0x6E].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
}
// ETM 4.3 introduces ignore packets
if (m_config.FullVersion() >= 0x43)
{
m_i_table[0x70].pkt_type = ETM4_PKT_I_IGNORE;
m_i_table[0x70].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
m_i_table[0x70].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
}
// b01110001 - b01111111 - event trace
for(int i = 0; i < 15; i++)
{
m_i_table[0x71+i].pkt_type = ETM4_PKT_I_EVENT;
m_i_table[0x71+i].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
m_i_table[0x71+i].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
}
// 0b1000 000x - context
for(int i = 0; i < 2; i++)
{
m_i_table[0x80+i].pkt_type = ETM4_PKT_I_CTXT;
m_i_table[0x80+i].pptkFn = &EtmV4IPktProcImpl::iPktContext;
m_i_table[0x80+i].pptkFn = &TrcPktProcEtmV4I::iPktContext;
}
// 0b1000 0010 to b1000 0011 - addr with ctxt
@ -1461,27 +1434,27 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
for(int i = 0; i < 2; i++)
{
m_i_table[0x82+i].pkt_type = (i == 0) ? ETM4_PKT_I_ADDR_CTXT_L_32IS0 : ETM4_PKT_I_ADDR_CTXT_L_32IS1;
m_i_table[0x82+i].pptkFn = &EtmV4IPktProcImpl::iPktAddrCtxt;
m_i_table[0x82+i].pptkFn = &TrcPktProcEtmV4I::iPktAddrCtxt;
}
for(int i = 0; i < 2; i++)
{
m_i_table[0x85+i].pkt_type = (i == 0) ? ETM4_PKT_I_ADDR_CTXT_L_64IS0 : ETM4_PKT_I_ADDR_CTXT_L_64IS1;
m_i_table[0x85+i].pptkFn = &EtmV4IPktProcImpl::iPktAddrCtxt;
m_i_table[0x85+i].pptkFn = &TrcPktProcEtmV4I::iPktAddrCtxt;
}
// 0b1001 0000 to b1001 0010 - exact match addr
for(int i = 0; i < 3; i++)
{
m_i_table[0x90+i].pkt_type = ETM4_PKT_I_ADDR_MATCH;
m_i_table[0x90+i].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
m_i_table[0x90+i].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
}
// b1001 0101 - b1001 0110 - addr short address
for(int i = 0; i < 2; i++)
{
m_i_table[0x95+i].pkt_type = (i == 0) ? ETM4_PKT_I_ADDR_S_IS0 : ETM4_PKT_I_ADDR_S_IS1;
m_i_table[0x95+i].pptkFn = &EtmV4IPktProcImpl::iPktShortAddr;
m_i_table[0x95+i].pptkFn = &TrcPktProcEtmV4I::iPktShortAddr;
}
// b10011010 - b10011011 - addr long address
@ -1489,12 +1462,12 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
for(int i = 0; i < 2; i++)
{
m_i_table[0x9A+i].pkt_type = (i == 0) ? ETM4_PKT_I_ADDR_L_32IS0 : ETM4_PKT_I_ADDR_L_32IS1;
m_i_table[0x9A+i].pptkFn = &EtmV4IPktProcImpl::iPktLongAddr;
m_i_table[0x9A+i].pptkFn = &TrcPktProcEtmV4I::iPktLongAddr;
}
for(int i = 0; i < 2; i++)
{
m_i_table[0x9D+i].pkt_type = (i == 0) ? ETM4_PKT_I_ADDR_L_64IS0 : ETM4_PKT_I_ADDR_L_64IS1;
m_i_table[0x9D+i].pptkFn = &EtmV4IPktProcImpl::iPktLongAddr;
m_i_table[0x9D+i].pptkFn = &TrcPktProcEtmV4I::iPktLongAddr;
}
// b1010xxxx - Q packet
@ -1515,7 +1488,7 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
default:
// if this config supports Q elem - otherwise reserved again.
if (m_config.hasQElem())
m_i_table[0xA0 + i].pptkFn = &EtmV4IPktProcImpl::iPktQ;
m_i_table[0xA0 + i].pptkFn = &TrcPktProcEtmV4I::iPktQ;
}
}
@ -1523,46 +1496,46 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
for(int i = 0xC0; i <= 0xD4; i++) // atom f6
{
m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F6;
m_i_table[i].pptkFn = &EtmV4IPktProcImpl::iAtom;
m_i_table[i].pptkFn = &TrcPktProcEtmV4I::iAtom;
}
for(int i = 0xD5; i <= 0xD7; i++) // atom f5
{
m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F5;
m_i_table[i].pptkFn = &EtmV4IPktProcImpl::iAtom;
m_i_table[i].pptkFn = &TrcPktProcEtmV4I::iAtom;
}
for(int i = 0xD8; i <= 0xDB; i++) // atom f2
{
m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F2;
m_i_table[i].pptkFn = &EtmV4IPktProcImpl::iAtom;
m_i_table[i].pptkFn = &TrcPktProcEtmV4I::iAtom;
}
for(int i = 0xDC; i <= 0xDF; i++) // atom f4
{
m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F4;
m_i_table[i].pptkFn = &EtmV4IPktProcImpl::iAtom;
m_i_table[i].pptkFn = &TrcPktProcEtmV4I::iAtom;
}
for(int i = 0xE0; i <= 0xF4; i++) // atom f6
{
m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F6;
m_i_table[i].pptkFn = &EtmV4IPktProcImpl::iAtom;
m_i_table[i].pptkFn = &TrcPktProcEtmV4I::iAtom;
}
// atom f5
m_i_table[0xF5].pkt_type = ETM4_PKT_I_ATOM_F5;
m_i_table[0xF5].pptkFn = &EtmV4IPktProcImpl::iAtom;
m_i_table[0xF5].pptkFn = &TrcPktProcEtmV4I::iAtom;
for(int i = 0xF6; i <= 0xF7; i++) // atom f1
{
m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F1;
m_i_table[i].pptkFn = &EtmV4IPktProcImpl::iAtom;
m_i_table[i].pptkFn = &TrcPktProcEtmV4I::iAtom;
}
for(int i = 0xF8; i <= 0xFF; i++) // atom f3
{
m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F3;
m_i_table[i].pptkFn = &EtmV4IPktProcImpl::iAtom;
m_i_table[i].pptkFn = &TrcPktProcEtmV4I::iAtom;
}
}
unsigned EtmV4IPktProcImpl::extractContField(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint32_t &value, const unsigned byte_limit /*= 5*/)
unsigned TrcPktProcEtmV4I::extractContField(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint32_t &value, const unsigned byte_limit /*= 5*/)
{
unsigned idx = 0;
bool lastByte = false;
@ -1586,7 +1559,7 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
return idx;
}
unsigned EtmV4IPktProcImpl::extractContField64(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint64_t &value, const unsigned byte_limit /*= 9*/)
unsigned TrcPktProcEtmV4I::extractContField64(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint64_t &value, const unsigned byte_limit /*= 9*/)
{
unsigned idx = 0;
bool lastByte = false;
@ -1610,7 +1583,7 @@ unsigned EtmV4IPktProcImpl::extractContField64(const std::vector<uint8_t> &buffe
return idx;
}
unsigned EtmV4IPktProcImpl::extractCondResult(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint32_t& key, uint8_t &result)
unsigned TrcPktProcEtmV4I::extractCondResult(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint32_t& key, uint8_t &result)
{
unsigned idx = 0;
bool lastByte = false;
@ -1644,7 +1617,7 @@ unsigned EtmV4IPktProcImpl::extractContField64(const std::vector<uint8_t> &buffe
return idx;
}
int EtmV4IPktProcImpl::extract64BitLongAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint64_t &value)
int TrcPktProcEtmV4I::extract64BitLongAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint64_t &value)
{
value = 0;
if(IS == 0)
@ -1666,7 +1639,7 @@ int EtmV4IPktProcImpl::extract64BitLongAddr(const std::vector<uint8_t> &buffer,
return 8;
}
int EtmV4IPktProcImpl::extract32BitLongAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint32_t &value)
int TrcPktProcEtmV4I::extract32BitLongAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint32_t &value)
{
value = 0;
if(IS == 0)
@ -1684,11 +1657,11 @@ int EtmV4IPktProcImpl::extract32BitLongAddr(const std::vector<uint8_t> &buffer,
return 4;
}
void EtmV4IPktProcImpl::throwBadSequenceError(const char *pszExtMsg)
void TrcPktProcEtmV4I::throwBadSequenceError(const char *pszExtMsg)
{
m_curr_packet.updateErrType(ETM4_PKT_I_BAD_SEQUENCE); // swap type for err type
throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_BAD_PACKET_SEQ,m_packet_index,m_config.getTraceID(),pszExtMsg);
}
/* End of File trc_pkt_proc_etmv4i_impl.cpp */
/* End of File trc_pkt_proc_etmv4i.cpp */

View File

@ -39,21 +39,23 @@
ocsd_err_t TrcIDecode::DecodeInstruction(ocsd_instr_info *instr_info)
{
ocsd_err_t err = OCSD_OK;
clear_instr_subtype();
SetArchVersion(instr_info);
struct decode_info info;
info.instr_sub_type = OCSD_S_INSTR_NONE;
info.arch_version = (uint16_t)(instr_info->pe_type.arch);
switch(instr_info->isa)
{
case ocsd_isa_arm:
err = DecodeA32(instr_info);
err = DecodeA32(instr_info, &info);
break;
case ocsd_isa_thumb2:
err = DecodeT32(instr_info);
err = DecodeT32(instr_info, &info);
break;
case ocsd_isa_aarch64:
err = DecodeA64(instr_info);
err = DecodeA64(instr_info, &info);
break;
case ocsd_isa_tee:
@ -63,27 +65,11 @@ ocsd_err_t TrcIDecode::DecodeInstruction(ocsd_instr_info *instr_info)
err = OCSD_ERR_UNSUPPORTED_ISA;
break;
}
instr_info->sub_type = get_instr_subtype();
instr_info->sub_type = info.instr_sub_type;
return err;
}
void TrcIDecode::SetArchVersion(ocsd_instr_info *instr_info)
{
uint16_t arch = 0x0700;
switch (instr_info->pe_type.arch)
{
case ARCH_V8: arch = 0x0800; break;
case ARCH_V8r3: arch = 0x0803; break;
case ARCH_V7:
default:
break;
}
set_arch_version(arch);
}
ocsd_err_t TrcIDecode::DecodeA32(ocsd_instr_info *instr_info)
ocsd_err_t TrcIDecode::DecodeA32(ocsd_instr_info *instr_info, struct decode_info *info)
{
uint32_t branchAddr = 0;
arm_barrier_t barrier;
@ -93,10 +79,10 @@ ocsd_err_t TrcIDecode::DecodeA32(ocsd_instr_info *instr_info)
instr_info->next_isa = instr_info->isa; // assume same ISA
instr_info->is_link = 0;
if(inst_ARM_is_indirect_branch(instr_info->opcode))
if(inst_ARM_is_indirect_branch(instr_info->opcode, info))
{
instr_info->type = OCSD_INSTR_BR_INDIRECT;
instr_info->is_link = inst_ARM_is_branch_and_link(instr_info->opcode);
instr_info->is_link = inst_ARM_is_branch_and_link(instr_info->opcode, info);
}
else if(inst_ARM_is_direct_branch(instr_info->opcode))
{
@ -108,7 +94,7 @@ ocsd_err_t TrcIDecode::DecodeA32(ocsd_instr_info *instr_info)
branchAddr &= ~0x1;
}
instr_info->branch_addr = (ocsd_vaddr_t)branchAddr;
instr_info->is_link = inst_ARM_is_branch_and_link(instr_info->opcode);
instr_info->is_link = inst_ARM_is_branch_and_link(instr_info->opcode, info);
}
else if((barrier = inst_ARM_barrier(instr_info->opcode)) != ARM_BARRIER_NONE)
{
@ -137,7 +123,7 @@ ocsd_err_t TrcIDecode::DecodeA32(ocsd_instr_info *instr_info)
return OCSD_OK;
}
ocsd_err_t TrcIDecode::DecodeA64(ocsd_instr_info *instr_info)
ocsd_err_t TrcIDecode::DecodeA64(ocsd_instr_info *instr_info, struct decode_info *info)
{
uint64_t branchAddr = 0;
arm_barrier_t barrier;
@ -147,12 +133,12 @@ ocsd_err_t TrcIDecode::DecodeA64(ocsd_instr_info *instr_info)
instr_info->next_isa = instr_info->isa; // assume same ISA
instr_info->is_link = 0;
if(inst_A64_is_indirect_branch_link(instr_info->opcode, &instr_info->is_link))
if(inst_A64_is_indirect_branch_link(instr_info->opcode, &instr_info->is_link, info))
{
instr_info->type = OCSD_INSTR_BR_INDIRECT;
// instr_info->is_link = inst_A64_is_branch_and_link(instr_info->opcode);
}
else if(inst_A64_is_direct_branch_link(instr_info->opcode, &instr_info->is_link))
else if(inst_A64_is_direct_branch_link(instr_info->opcode, &instr_info->is_link, info))
{
inst_A64_branch_destination(instr_info->instr_addr,instr_info->opcode,&branchAddr);
instr_info->type = OCSD_INSTR_BR;
@ -187,7 +173,7 @@ ocsd_err_t TrcIDecode::DecodeA64(ocsd_instr_info *instr_info)
return OCSD_OK;
}
ocsd_err_t TrcIDecode::DecodeT32(ocsd_instr_info *instr_info)
ocsd_err_t TrcIDecode::DecodeT32(ocsd_instr_info *instr_info, struct decode_info *info)
{
uint32_t branchAddr = 0;
arm_barrier_t barrier;
@ -206,7 +192,7 @@ ocsd_err_t TrcIDecode::DecodeT32(ocsd_instr_info *instr_info)
instr_info->is_conditional = 0;
if(inst_Thumb_is_direct_branch_link(instr_info->opcode,&instr_info->is_link, &instr_info->is_conditional))
if(inst_Thumb_is_direct_branch_link(instr_info->opcode,&instr_info->is_link, &instr_info->is_conditional, info))
{
inst_Thumb_branch_destination((uint32_t)instr_info->instr_addr,instr_info->opcode,&branchAddr);
instr_info->type = OCSD_INSTR_BR;
@ -214,7 +200,7 @@ ocsd_err_t TrcIDecode::DecodeT32(ocsd_instr_info *instr_info)
if((branchAddr & 0x1) == 0)
instr_info->next_isa = ocsd_isa_arm;
}
else if (inst_Thumb_is_indirect_branch_link(instr_info->opcode, &instr_info->is_link))
else if (inst_Thumb_is_indirect_branch_link(instr_info->opcode, &instr_info->is_link, info))
{
instr_info->type = OCSD_INSTR_BR_INDIRECT;
}
@ -246,5 +232,4 @@ ocsd_err_t TrcIDecode::DecodeT32(ocsd_instr_info *instr_info)
return OCSD_OK;
}
/* End of File trc_i_decode.cpp */

View File

@ -42,27 +42,6 @@ block identification and trace decode.
#include <stddef.h> /* for NULL */
#include <assert.h>
static ocsd_instr_subtype instr_sub_type = OCSD_S_INSTR_NONE;
/* need to spot the architecture version for certain instructions */
static uint16_t arch_version = 0x70;
ocsd_instr_subtype get_instr_subtype()
{
return instr_sub_type;
}
void clear_instr_subtype()
{
instr_sub_type = OCSD_S_INSTR_NONE;
}
void set_arch_version(uint16_t version)
{
arch_version = version;
}
int inst_ARM_is_direct_branch(uint32_t inst)
{
int is_direct_branch = 1;
@ -91,7 +70,7 @@ int inst_ARM_wfiwfe(uint32_t inst)
return 0;
}
int inst_ARM_is_indirect_branch(uint32_t inst)
int inst_ARM_is_indirect_branch(uint32_t inst, struct decode_info *info)
{
int is_indirect_branch = 1;
if ((inst & 0xf0000000) == 0xf0000000) {
@ -104,23 +83,23 @@ int inst_ARM_is_indirect_branch(uint32_t inst)
} else if ((inst & 0x0ff000d0) == 0x01200010) {
/* BLX (register), BX */
if ((inst & 0xFF) == 0x1E)
instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* BX LR */
info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* BX LR */
} else if ((inst & 0x0ff000f0) == 0x01200020) {
/* BXJ: in v8 this behaves like BX */
} else if ((inst & 0x0e108000) == 0x08108000) {
/* POP {...,pc} or LDMxx {...,pc} */
if ((inst & 0x0FFFA000) == 0x08BD8000) /* LDMIA SP!,{...,pc} */
instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET;
info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET;
} else if ((inst & 0x0e50f000) == 0x0410f000) {
/* LDR PC,imm... inc. POP {PC} */
if ( (inst & 0x01ff0000) == 0x009D0000)
instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* LDR PC, [SP], #imm */
info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* LDR PC, [SP], #imm */
} else if ((inst & 0x0e50f010) == 0x0610f000) {
/* LDR PC,reg */
} else if ((inst & 0x0fe0f000) == 0x01a0f000) {
/* MOV PC,rx */
if ((inst & 0x00100FFF) == 0x00E) /* ensure the S=0, LSL #0 variant - i.e plain MOV */
instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* MOV PC, R14 */
info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* MOV PC, R14 */
} else if ((inst & 0x0f900080) == 0x01000000) {
/* "Miscellaneous instructions" - in DP space */
is_indirect_branch = 0;
@ -144,13 +123,13 @@ int inst_ARM_is_indirect_branch(uint32_t inst)
return is_indirect_branch;
}
int inst_Thumb_is_direct_branch(uint32_t inst)
int inst_Thumb_is_direct_branch(uint32_t inst, struct decode_info *info)
{
uint8_t link, cond;
return inst_Thumb_is_direct_branch_link(inst, &link, &cond);
return inst_Thumb_is_direct_branch_link(inst, &link, &cond, info);
}
int inst_Thumb_is_direct_branch_link(uint32_t inst, uint8_t *is_link, uint8_t *is_cond)
int inst_Thumb_is_direct_branch_link(uint32_t inst, uint8_t *is_link, uint8_t *is_cond, struct decode_info *info)
{
int is_direct_branch = 1;
@ -166,12 +145,12 @@ int inst_Thumb_is_direct_branch_link(uint32_t inst, uint8_t *is_link, uint8_t *i
/* B (encoding T4); BL (encoding T1) */
if (inst & 0x00004000) {
*is_link = 1;
instr_sub_type = OCSD_S_INSTR_BR_LINK;
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
}
} else if ((inst & 0xf800d001) == 0xf000c000) {
/* BLX (imm) (encoding T2) */
*is_link = 1;
instr_sub_type = OCSD_S_INSTR_BR_LINK;
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
} else if ((inst & 0xf5000000) == 0xb1000000) {
/* CB(NZ) */
*is_cond = 1;
@ -197,13 +176,13 @@ int inst_Thumb_wfiwfe(uint32_t inst)
return is_wfiwfe;
}
int inst_Thumb_is_indirect_branch(uint32_t inst)
int inst_Thumb_is_indirect_branch(uint32_t inst, struct decode_info *info)
{
uint8_t link;
return inst_Thumb_is_indirect_branch_link(inst, &link);
return inst_Thumb_is_indirect_branch_link(inst, &link, info);
}
int inst_Thumb_is_indirect_branch_link(uint32_t inst, uint8_t *is_link)
int inst_Thumb_is_indirect_branch_link(uint32_t inst, uint8_t *is_link, struct decode_info *info)
{
/* See e.g. PFT Table 2-3 and Table 2-5 */
int is_branch = 1;
@ -212,20 +191,20 @@ int inst_Thumb_is_indirect_branch_link(uint32_t inst, uint8_t *is_link)
/* BX, BLX (reg) [v8M includes BXNS, BLXNS] */
if (inst & 0x00800000) {
*is_link = 1;
instr_sub_type = OCSD_S_INSTR_BR_LINK;
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
}
else if ((inst & 0x00780000) == 0x00700000) {
instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* BX LR */
info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* BX LR */
}
} else if ((inst & 0xfff0d000) == 0xf3c08000) {
/* BXJ: in v8 this behaves like BX */
} else if ((inst & 0xff000000) == 0xbd000000) {
/* POP {pc} */
instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET;
info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET;
} else if ((inst & 0xfd870000) == 0x44870000) {
/* MOV PC,reg or ADD PC,reg */
if ((inst & 0xffff0000) == 0x46f700000)
instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* MOV PC,LR */
if ((inst & 0xffff0000) == 0x46f70000)
info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* MOV PC,LR */
} else if ((inst & 0xfff0ffe0) == 0xe8d0f000) {
/* TBB/TBH */
} else if ((inst & 0xffd00000) == 0xe8100000) {
@ -241,26 +220,26 @@ int inst_Thumb_is_indirect_branch_link(uint32_t inst, uint8_t *is_link)
} else if ((inst & 0xfff0f800) == 0xf850f800) {
/* LDR PC,imm (T4) */
if((inst & 0x000f0f00) == 0x000d0b00)
instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* LDR PC, [SP], #imm*/
info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* LDR PC, [SP], #imm*/
} else if ((inst & 0xfff0ffc0) == 0xf850f000) {
/* LDR PC,reg (T2) */
} else if ((inst & 0xfe508000) == 0xe8108000) {
/* LDM PC */
if ((inst & 0x0FFF0000) == 0x08BD0000) /* LDMIA [SP]!, */
instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* POP {...,pc} */
info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* POP {...,pc} */
} else {
is_branch = 0;
}
return is_branch;
}
int inst_A64_is_direct_branch(uint32_t inst)
int inst_A64_is_direct_branch(uint32_t inst, struct decode_info *info)
{
uint8_t link = 0;
return inst_A64_is_direct_branch_link(inst, &link);
return inst_A64_is_direct_branch_link(inst, &link, info);
}
int inst_A64_is_direct_branch_link(uint32_t inst, uint8_t *is_link)
int inst_A64_is_direct_branch_link(uint32_t inst, uint8_t *is_link, struct decode_info *info)
{
int is_direct_branch = 1;
if ((inst & 0x7c000000) == 0x34000000) {
@ -271,7 +250,7 @@ int inst_A64_is_direct_branch_link(uint32_t inst, uint8_t *is_link)
/* B, BL imm */
if (inst & 0x80000000) {
*is_link = 1;
instr_sub_type = OCSD_S_INSTR_BR_LINK;
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
}
} else {
is_direct_branch = 0;
@ -287,13 +266,13 @@ int inst_A64_wfiwfe(uint32_t inst)
return 0;
}
int inst_A64_is_indirect_branch(uint32_t inst)
int inst_A64_is_indirect_branch(uint32_t inst, struct decode_info *info)
{
uint8_t link = 0;
return inst_A64_is_indirect_branch_link(inst, &link);
return inst_A64_is_indirect_branch_link(inst, &link, info);
}
int inst_A64_is_indirect_branch_link(uint32_t inst, uint8_t *is_link)
int inst_A64_is_indirect_branch_link(uint32_t inst, uint8_t *is_link, struct decode_info *info)
{
int is_indirect_branch = 1;
@ -301,34 +280,34 @@ int inst_A64_is_indirect_branch_link(uint32_t inst, uint8_t *is_link)
/* BR, BLR */
if (inst & 0x00200000) {
*is_link = 1;
instr_sub_type = OCSD_S_INSTR_BR_LINK;
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
}
} else if ((inst & 0xfffffc1f) == 0xd65f0000) {
instr_sub_type = OCSD_S_INSTR_V8_RET;
info->instr_sub_type = OCSD_S_INSTR_V8_RET;
/* RET */
} else if ((inst & 0xffffffff) == 0xd69f03e0) {
/* ERET */
instr_sub_type = OCSD_S_INSTR_V8_ERET;
} else if (arch_version >= 0x0803) {
info->instr_sub_type = OCSD_S_INSTR_V8_ERET;
} else if (info->arch_version >= 0x0803) {
/* new pointer auth instr for v8.3 arch */
if ((inst & 0xffdff800) == 0xd61f0800) {
if ((inst & 0xffdff800) == 0xd71f0800) {
/* BRAA, BRAB, BLRAA, BLRBB */
if (inst & 0x00200000) {
*is_link = 1;
instr_sub_type = OCSD_S_INSTR_BR_LINK;
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
}
} else if ((inst & 0xffdff81F) == 0xd71f081F) {
} else if ((inst & 0xffdff81F) == 0xd61f081F) {
/* BRAAZ, BRABZ, BLRAAZ, BLRBBZ */
if (inst & 0x00200000) {
*is_link = 1;
instr_sub_type = OCSD_S_INSTR_BR_LINK;
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
}
} else if ((inst & 0xfffffbff) == 0xd69f0bff) {
/* ERETAA, ERETAB */
instr_sub_type = OCSD_S_INSTR_V8_ERET;
info->instr_sub_type = OCSD_S_INSTR_V8_ERET;
} else if ((inst & 0xfffffbff) == 0xd65f0bff) {
/* RETAA, RETAB */
instr_sub_type = OCSD_S_INSTR_V8_RET;
info->instr_sub_type = OCSD_S_INSTR_V8_RET;
} else {
is_indirect_branch = 0;
}
@ -441,39 +420,39 @@ int inst_A64_branch_destination(uint64_t addr, uint32_t inst, uint64_t *pnpc)
return is_direct_branch;
}
int inst_ARM_is_branch(uint32_t inst)
int inst_ARM_is_branch(uint32_t inst, struct decode_info *info)
{
return inst_ARM_is_indirect_branch(inst) ||
return inst_ARM_is_indirect_branch(inst, info) ||
inst_ARM_is_direct_branch(inst);
}
int inst_Thumb_is_branch(uint32_t inst)
int inst_Thumb_is_branch(uint32_t inst, struct decode_info *info)
{
return inst_Thumb_is_indirect_branch(inst) ||
inst_Thumb_is_direct_branch(inst);
return inst_Thumb_is_indirect_branch(inst, info) ||
inst_Thumb_is_direct_branch(inst, info);
}
int inst_A64_is_branch(uint32_t inst)
int inst_A64_is_branch(uint32_t inst, struct decode_info *info)
{
return inst_A64_is_indirect_branch(inst) ||
inst_A64_is_direct_branch(inst);
return inst_A64_is_indirect_branch(inst, info) ||
inst_A64_is_direct_branch(inst, info);
}
int inst_ARM_is_branch_and_link(uint32_t inst)
int inst_ARM_is_branch_and_link(uint32_t inst, struct decode_info *info)
{
int is_branch = 1;
if ((inst & 0xf0000000) == 0xf0000000) {
if ((inst & 0xfe000000) == 0xfa000000){
instr_sub_type = OCSD_S_INSTR_BR_LINK;
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
/* BLX (imm) */
} else {
is_branch = 0;
}
} else if ((inst & 0x0f000000) == 0x0b000000) {
instr_sub_type = OCSD_S_INSTR_BR_LINK;
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
/* BL */
} else if ((inst & 0x0ff000f0) == 0x01200030) {
instr_sub_type = OCSD_S_INSTR_BR_LINK;
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
/* BLX (reg) */
} else {
is_branch = 0;
@ -481,14 +460,14 @@ int inst_ARM_is_branch_and_link(uint32_t inst)
return is_branch;
}
int inst_Thumb_is_branch_and_link(uint32_t inst)
int inst_Thumb_is_branch_and_link(uint32_t inst, struct decode_info *info)
{
int is_branch = 1;
if ((inst & 0xff800000) == 0x47800000) {
instr_sub_type = OCSD_S_INSTR_BR_LINK;
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
/* BLX (reg) */
} else if ((inst & 0xf800c000) == 0xf000c000) {
instr_sub_type = OCSD_S_INSTR_BR_LINK;
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
/* BL, BLX (imm) */
} else {
is_branch = 0;
@ -496,23 +475,23 @@ int inst_Thumb_is_branch_and_link(uint32_t inst)
return is_branch;
}
int inst_A64_is_branch_and_link(uint32_t inst)
int inst_A64_is_branch_and_link(uint32_t inst, struct decode_info *info)
{
int is_branch = 1;
if ((inst & 0xfffffc1f) == 0xd63f0000) {
/* BLR */
instr_sub_type = OCSD_S_INSTR_BR_LINK;
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
} else if ((inst & 0xfc000000) == 0x94000000) {
/* BL */
instr_sub_type = OCSD_S_INSTR_BR_LINK;
} else if (arch_version >= 0x0803) {
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
} else if (info->arch_version >= 0x0803) {
/* new pointer auth instr for v8.3 arch */
if ((inst & 0xfffff800) == 0xd73f0800) {
/* BLRAA, BLRBB */
instr_sub_type = OCSD_S_INSTR_BR_LINK;
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
} else if ((inst & 0xfffff81F) == 0xd63f081F) {
/* BLRAAZ, BLRBBZ */
instr_sub_type = OCSD_S_INSTR_BR_LINK;
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
} else {
is_branch = 0;
}

View File

@ -37,8 +37,7 @@
TrcMemAccBufPtr::TrcMemAccBufPtr(const ocsd_vaddr_t s_address, const uint8_t *p_buffer, const uint32_t size) :
TrcMemAccessorBase(MEMACC_BUFPTR, s_address, s_address+size-1),
m_p_buffer(p_buffer),
m_size(size)
m_p_buffer(p_buffer)
{
}

View File

@ -111,6 +111,7 @@ DecodeTree::~DecodeTree()
destroyDecodeElement(i);
}
PktPrinterFact::destroyAllPrinters(m_printer_list);
delete m_frame_deformatter_root;
}

View File

@ -207,7 +207,7 @@ const std::string ocsdError::getErrorString(const ocsdError &error)
void ocsdError::appendErrorDetails(std::string &errStr, const ocsdError &error)
{
int numerrstr = ((sizeof(s_errorCodeDescs) / sizeof(const char *)) / 2);
int numerrstr = sizeof(s_errorCodeDescs) / sizeof(s_errorCodeDescs[0]);
int code = (int)error.getErrorCode();
ocsd_trc_index_t idx = error.getErrorIndex();
uint8_t chan_ID = error.getErrorChanID();

View File

@ -0,0 +1,196 @@
/*
* \file ocsd_gen_elem_stack.cpp
* \brief OpenCSD : List of Generic trace elements for output.
*
* \copyright Copyright (c) 2020, 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 "common/ocsd_gen_elem_stack.h"
OcsdGenElemStack::OcsdGenElemStack() :
m_pElemArray(0),
m_elemArraySize(0),
m_elem_to_send(0),
m_curr_elem_idx(0),
m_send_elem_idx(0),
m_CSID(0),
m_is_init(false)
{
}
OcsdGenElemStack::~OcsdGenElemStack()
{
for (int i = 0; i<m_elemArraySize; i++)
{
delete m_pElemArray[i].pElem;
}
delete [] m_pElemArray;
m_pElemArray = 0;
}
ocsd_err_t OcsdGenElemStack::addElem(const ocsd_trc_index_t trc_pkt_idx)
{
ocsd_err_t err = OCSD_OK;
if (((m_curr_elem_idx + 1) == m_elemArraySize) || !m_pElemArray)
{
err = growArray();
if (err)
return err;
}
// if there is a least one element then copy and increment
// otherwise we are at base of stack.
if (m_elem_to_send)
{
copyPersistentData(m_curr_elem_idx, m_curr_elem_idx + 1);
m_curr_elem_idx++;
}
m_pElemArray[m_curr_elem_idx].trc_pkt_idx = trc_pkt_idx;
m_elem_to_send++;
return err;
}
ocsd_err_t OcsdGenElemStack::addElemType(const ocsd_trc_index_t trc_pkt_idx, ocsd_gen_trc_elem_t elem_type)
{
ocsd_err_t err = addElem(trc_pkt_idx);
if (!err)
getCurrElem().setType(elem_type);
return err;
}
ocsd_err_t OcsdGenElemStack::resetElemStack()
{
ocsd_err_t err = OCSD_OK;
if (!m_pElemArray)
{
err = growArray();
if (err)
return err;
}
if (!isInit())
return OCSD_ERR_NOT_INIT;
resetIndexes();
return err;
}
void OcsdGenElemStack::resetIndexes()
{
// last time there was more than one element on stack
if (m_curr_elem_idx > 0)
copyPersistentData(m_curr_elem_idx, 0);
// indexes to bottom of stack, nothing in use at present
m_curr_elem_idx = 0;
m_send_elem_idx = 0;
m_elem_to_send = 0;
}
ocsd_datapath_resp_t OcsdGenElemStack::sendElements()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
if (!isInit())
return OCSD_RESP_FATAL_NOT_INIT;
while (m_elem_to_send && OCSD_DATA_RESP_IS_CONT(resp))
{
resp = m_sendIf->first()->TraceElemIn(m_pElemArray[m_send_elem_idx].trc_pkt_idx, m_CSID, *(m_pElemArray[m_send_elem_idx].pElem));
m_send_elem_idx++;
m_elem_to_send--;
}
// clear the indexes if we are done.
if (!m_elem_to_send)
resetIndexes();
return resp;
}
ocsd_err_t OcsdGenElemStack::growArray()
{
elemPtr_t *p_new_array = 0;
const int increment = 4;
p_new_array = new (std::nothrow) elemPtr_t[m_elemArraySize + increment];
if (p_new_array != 0)
{
OcsdTraceElement *pElem = 0;
// fill the last increment elements with new objects
for (int i = 0; i < increment; i++)
{
pElem = new (std::nothrow) OcsdTraceElement();
if (!pElem)
return OCSD_ERR_MEM;
pElem->init();
p_new_array[m_elemArraySize + i].pElem = pElem;
}
// copy the existing objects from the old array to the start of the new one
if (m_elemArraySize > 0)
{
for (int i = 0; i < m_elemArraySize; i++)
{
p_new_array[i].pElem = m_pElemArray[i].pElem;
p_new_array[i].trc_pkt_idx = m_pElemArray[i].trc_pkt_idx;
}
}
// delete the old pointer array.
delete[] m_pElemArray;
m_elemArraySize += increment;
m_pElemArray = p_new_array;
}
else
return OCSD_ERR_MEM;
return OCSD_OK;
}
void OcsdGenElemStack::copyPersistentData(int src, int dst)
{
m_pElemArray[dst].pElem->copyPersistentData(*(m_pElemArray[src].pElem));
}
const bool OcsdGenElemStack::isInit()
{
if (!m_is_init) {
if (m_elemArraySize && m_pElemArray && m_sendIf)
m_is_init = true;
}
return m_is_init;
}
/* End of File ocsd_gen_elem_stack.cpp */

View File

@ -67,6 +67,7 @@ ocsd_datapath_resp_t TrcPktDecodePtm::processPacket()
case NO_SYNC:
// no sync - output a no sync packet then transition to wait sync.
m_output_elem.elem_type = OCSD_GEN_TRC_ELEM_NO_SYNC;
m_output_elem.unsync_eot_info = m_unsync_info;
resp = outputTraceElement(m_output_elem);
m_curr_state = (m_curr_packet_in->getType() == PTM_PKT_A_SYNC) ? WAIT_ISYNC : WAIT_SYNC;
bPktDone = true;
@ -108,6 +109,7 @@ ocsd_datapath_resp_t TrcPktDecodePtm::onEOT()
// shouldn't be any packets left to be processed - flush shoudl have done this.
// just output the end of trace marker
m_output_elem.setType(OCSD_GEN_TRC_ELEM_EO_TRACE);
m_output_elem.setUnSyncEOTReason(UNSYNC_EOT);
resp = outputTraceElement(m_output_elem);
return resp;
}
@ -115,6 +117,7 @@ ocsd_datapath_resp_t TrcPktDecodePtm::onEOT()
ocsd_datapath_resp_t TrcPktDecodePtm::onReset()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
m_unsync_info = UNSYNC_RESET_DECODER;
resetDecoder();
return resp;
}
@ -191,6 +194,7 @@ void TrcPktDecodePtm::initDecoder()
m_instr_info.pe_type.profile = profile_Unknown;
m_instr_info.pe_type.arch = ARCH_UNKNOWN;
m_instr_info.dsb_dmb_waypoints = 0;
m_unsync_info = UNSYNC_INIT_DECODER;
resetDecoder();
}
@ -504,11 +508,15 @@ ocsd_datapath_resp_t TrcPktDecodePtm::processAtomRange(const ocsd_atm_val A, con
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
bool bWPFound = false;
std::ostringstream oss;
ocsd_err_t err = OCSD_OK;
m_instr_info.instr_addr = m_curr_pe_state.instr_addr;
m_instr_info.isa = m_curr_pe_state.isa;
ocsd_err_t err = traceInstrToWP(bWPFound,traceWPOp,nextAddrMatch);
// set type (which resets out-elem) before traceInstrToWP modifies out-elem values
m_output_elem.setType(OCSD_GEN_TRC_ELEM_INSTR_RANGE);
err = traceInstrToWP(bWPFound,traceWPOp,nextAddrMatch);
if(err != OCSD_OK)
{
if(err == OCSD_ERR_UNSUPPORTED_ISA)
@ -576,7 +584,6 @@ ocsd_datapath_resp_t TrcPktDecodePtm::processAtomRange(const ocsd_atm_val A, con
break;
}
m_output_elem.setType(OCSD_GEN_TRC_ELEM_INSTR_RANGE);
m_output_elem.setLastInstrInfo((A == ATOM_E),m_instr_info.type, m_instr_info.sub_type,m_instr_info.instr_size);
m_output_elem.setISA(m_curr_pe_state.isa);
if(m_curr_packet_in->hasCC())
@ -595,7 +602,6 @@ ocsd_datapath_resp_t TrcPktDecodePtm::processAtomRange(const ocsd_atm_val A, con
if(m_output_elem.st_addr != m_output_elem.en_addr)
{
// some trace before we were out of memory access range
m_output_elem.setType(OCSD_GEN_TRC_ELEM_INSTR_RANGE);
m_output_elem.setLastInstrInfo(true,m_instr_info.type, m_instr_info.sub_type,m_instr_info.instr_size);
m_output_elem.setISA(m_curr_pe_state.isa);
m_output_elem.setLastInstrCond(m_instr_info.is_conditional);

View File

@ -68,6 +68,7 @@ ocsd_datapath_resp_t TrcPktDecodeStm::processPacket()
{
case NO_SYNC:
m_output_elem.setType(OCSD_GEN_TRC_ELEM_NO_SYNC);
m_output_elem.setUnSyncEOTReason(m_unsync_info);
resp = outputTraceElement(m_output_elem);
m_curr_state = WAIT_SYNC;
break;
@ -90,6 +91,7 @@ ocsd_datapath_resp_t TrcPktDecodeStm::onEOT()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
m_output_elem.setType(OCSD_GEN_TRC_ELEM_EO_TRACE);
m_output_elem.setUnSyncEOTReason(UNSYNC_EOT);
resp = outputTraceElement(m_output_elem);
return resp;
}
@ -97,6 +99,7 @@ ocsd_datapath_resp_t TrcPktDecodeStm::onEOT()
ocsd_datapath_resp_t TrcPktDecodeStm::onReset()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
m_unsync_info = UNSYNC_RESET_DECODER;
resetDecoder();
return resp;
}
@ -127,7 +130,7 @@ void TrcPktDecodeStm::initDecoder()
// base decoder state - STM requires no memory and instruction decode.
setUsesMemAccess(false);
setUsesIDecode(false);
m_unsync_info = UNSYNC_INIT_DECODER;
resetDecoder();
}
@ -166,6 +169,7 @@ ocsd_datapath_resp_t TrcPktDecodeStm::decodePacket(bool &bPktDone)
case STM_PKT_BAD_SEQUENCE: /**< Incorrect protocol sequence */
case STM_PKT_RESERVED:
resp = OCSD_RESP_FATAL_INVALID_DATA;
m_unsync_info = UNSYNC_BAD_PACKET;
case STM_PKT_NOTSYNC:
resetDecoder();
break;

View File

@ -41,7 +41,13 @@ class errLogAttachMonitor : public IComponentAttachNotifier
{
m_pComp = 0;
};
virtual ~ errLogAttachMonitor() {};
virtual ~ errLogAttachMonitor()
{
if (m_pComp)
m_pComp->getErrorLogAttachPt()->set_notifier(0);
m_pComp = 0;
};
virtual void attachNotify(const int num_attached)
{
if(m_pComp)
@ -73,6 +79,8 @@ TraceComponent::TraceComponent(const std::string &name, int instIDNum)
TraceComponent::~TraceComponent()
{
if (m_pErrAttachMon)
delete m_pErrAttachMon;
}
void TraceComponent::Init(const std::string &name)
@ -140,9 +148,7 @@ void TraceComponent::updateErrorLogLevel()
ocsd_err_t TraceComponent::setComponentOpMode(uint32_t op_flags)
{
if( (~m_supported_op_flags & op_flags) != 0)
return OCSD_ERR_INVALID_PARAM_VAL;
m_op_flags = op_flags;
m_op_flags = op_flags & m_supported_op_flags;
return OCSD_OK;
}

View File

@ -34,10 +34,12 @@
#include "common/trc_core_arch_map.h"
static struct _ap_map_elements {
typedef struct _ap_map_elements {
const char *name;
ocsd_arch_profile_t ap;
} ap_map_array[] =
} ap_map_elem_t;
static ap_map_elem_t ap_map_array[] =
{
{ "Cortex-A77", { ARCH_V8r3, profile_CortexA } },
{ "Cortex-A76", { ARCH_V8r3, profile_CortexA } },
@ -70,12 +72,28 @@ static struct _ap_map_elements {
{ "Cortex-M4", { ARCH_V7, profile_CortexM } }
};
static ap_map_elem_t arch_map_array[] =
{
{ "ARMv7-A", { ARCH_V7, profile_CortexA } },
{ "ARMv7-R", { ARCH_V7, profile_CortexR } },
{ "ARMv7-M", { ARCH_V7, profile_CortexM } },
{ "ARMv8-A", { ARCH_V8, profile_CortexA } },
{ "ARMv8.3-A", { ARCH_V8r3, profile_CortexA } },
{ "ARMv8-R", { ARCH_V8, profile_CortexR } },
{ "ARMv8-M", { ARCH_V8, profile_CortexM } },
};
CoreArchProfileMap::CoreArchProfileMap()
{
for(unsigned i = 0; i < sizeof(ap_map_array)/sizeof(_ap_map_elements); i++)
unsigned i;
for (i = 0; i < sizeof(ap_map_array) / sizeof(_ap_map_elements); i++)
{
core_profiles[ap_map_array[i].name] = ap_map_array[i].ap;
}
for (i = 0; i < sizeof(arch_map_array) / sizeof(_ap_map_elements); i++)
{
arch_profiles[arch_map_array[i].name] = arch_map_array[i].ap;
}
}
/* End of File trc_core_arch_map.cpp */

View File

@ -46,6 +46,7 @@ static const char *s_elem_descs[][2] =
{"OCSD_GEN_TRC_ELEM_EO_TRACE","End of the available trace in the buffer."},
{"OCSD_GEN_TRC_ELEM_PE_CONTEXT","PE status update / change (arch, ctxtid, vmid etc)."},
{"OCSD_GEN_TRC_ELEM_INSTR_RANGE","Traced N consecutive instructions from addr (no intervening events or data elements), may have data assoc key"},
{"OCSD_GEN_TRC_ELEM_I_RANGE_NOPATH","Traced N instructions in a range, but incomplete information as to program execution path from start to end of range"},
{"OCSD_GEN_TRC_ELEM_ADDR_NACC","Tracing in inaccessible memory area."},
{"OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN","Tracing unknown address area."},
{"OCSD_GEN_TRC_ELEM_EXCEPTION","Exception"},
@ -62,7 +63,8 @@ static const char *instr_type[] = {
"BR ",
"iBR ",
"ISB ",
"DSB.DMB"
"DSB.DMB",
"WFI.WFE"
};
#define T_SIZE (sizeof(instr_type) / sizeof(const char *))
@ -94,10 +96,20 @@ static const char *s_isa_str[] = {
"Unk" /**< ISA not yet known */
};
static const char *s_unsync_reason[] = {
"undefined", // UNSYNC_UNKNOWN - unknown /undefined
"init-decoder", // UNSYNC_INIT_DECODER - decoder intialisation - start of trace.
"reset-decoder", // UNSYNC_RESET_DECODER - decoder reset.
"overflow", // UNSYNC_OVERFLOW - overflow packet - need to re-sync
"discard", // UNSYNC_DISCARD - specl trace discard - need to re-sync
"bad-packet", // UNSYNC_BAD_PACKET - bad packet at input - resync to restart.
"end-of-trace", // UNSYNC_EOT - end of trace info.
};
void OcsdTraceElement::toString(std::string &str) const
{
std::ostringstream oss;
int num_str = ((sizeof(s_elem_descs) / sizeof(const char *)) / 2);
int num_str = sizeof(s_elem_descs) / sizeof(s_elem_descs[0]);
int typeIdx = (int)this->elem_type;
if(typeIdx < num_str)
{
@ -122,6 +134,11 @@ void OcsdTraceElement::toString(std::string &str) const
oss << " 0x" << std::hex << st_addr << " ";
break;
case OCSD_GEN_TRC_ELEM_I_RANGE_NOPATH:
oss << "first 0x" << std::hex << st_addr << ":[next 0x" << en_addr << "] ";
oss << "num_i(" << std::dec << num_instr_range << ") ";
break;
case OCSD_GEN_TRC_ELEM_EXCEPTION:
if (excep_ret_addr == 1)
{
@ -167,6 +184,12 @@ void OcsdTraceElement::toString(std::string &str) const
oss << " Numbered:" << std::dec << trace_event.ev_number << "; ";
break;
case OCSD_GEN_TRC_ELEM_EO_TRACE:
case OCSD_GEN_TRC_ELEM_NO_SYNC:
if (unsync_eot_info <= UNSYNC_EOT)
oss << " [" << s_unsync_reason[unsync_eot_info] << "]";
break;
default: break;
}
if(has_cc)

View File

@ -40,10 +40,8 @@ SRCS+= \
trc_cmp_cfg_etmv4.cpp \
trc_etmv4_stack_elem.cpp \
trc_pkt_decode_etmv4i.cpp \
trc_pkt_elem_etmv4d.cpp \
trc_pkt_elem_etmv4i.cpp \
trc_pkt_proc_etmv4.cpp \
trc_pkt_proc_etmv4i_impl.cpp
trc_pkt_proc_etmv4i.cpp
# PKT_PRINTERS
SRCS+= \
@ -75,6 +73,7 @@ SRCS+= \
ocsd_error.cpp \
ocsd_error_logger.cpp \
ocsd_gen_elem_list.cpp \
ocsd_gen_elem_stack.cpp \
ocsd_lib_dcd_register.cpp \
ocsd_msg_logger.cpp \
ocsd_version.cpp \
@ -126,9 +125,9 @@ ETMV4INCS= \
trc_dcd_mngr_etmv4i.h \
trc_etmv4_stack_elem.h \
trc_pkt_decode_etmv4i.h \
trc_pkt_elem_etmv4d.h \
trc_pkt_elem_etmv4i.h \
trc_pkt_proc_etmv4.h \
trc_pkt_proc_etmv4i.h \
trc_pkt_types_etmv4.h
ETMV4INCSDIR=${INCLUDEDIR}/opencsd/etmv4/