Update opencsd to 0.14.2
Sponsored by: Innovate UK
This commit is contained in:
commit
b6aadd183a
@ -36,6 +36,9 @@
|
|||||||
# xargs -n1 | sort | uniq -d;
|
# xargs -n1 | sort | uniq -d;
|
||||||
# done
|
# done
|
||||||
|
|
||||||
|
# 20200617: update opencsd to 0.14.2
|
||||||
|
OLD_FILES+=usr/include/opencsd/etmv4/trc_pkt_elem_etmv4d.h
|
||||||
|
|
||||||
# 20200606: retire binutils build infrastructure
|
# 20200606: retire binutils build infrastructure
|
||||||
.if !defined(WITH_PORT_BASE_BINUTILS)
|
.if !defined(WITH_PORT_BASE_BINUTILS)
|
||||||
OLD_FILES+=usr/bin/as
|
OLD_FILES+=usr/bin/as
|
||||||
|
@ -115,6 +115,9 @@ ocsd_err_t DecoderMngrBase<P,Pt,Pc>::createDecoder(const int create_flags, cons
|
|||||||
if(!pkt_proc)
|
if(!pkt_proc)
|
||||||
return OCSD_ERR_MEM;
|
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
|
// set the configuration
|
||||||
TrcPktProcBase<P,Pt,Pc> *pProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> *>(pkt_proc);
|
TrcPktProcBase<P,Pt,Pc> *pProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> *>(pkt_proc);
|
||||||
if(pProcBase == 0)
|
if(pProcBase == 0)
|
||||||
@ -133,6 +136,9 @@ ocsd_err_t DecoderMngrBase<P,Pt,Pc>::createDecoder(const int create_flags, cons
|
|||||||
if(!pkt_dcd)
|
if(!pkt_dcd)
|
||||||
return OCSD_ERR_MEM;
|
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
|
// get the decoder base
|
||||||
TrcPktDecodeBase<P,Pc> *pBase = dynamic_cast< TrcPktDecodeBase<P,Pc> *>(pkt_dcd);
|
TrcPktDecodeBase<P,Pc> *pBase = dynamic_cast< TrcPktDecodeBase<P,Pc> *>(pkt_dcd);
|
||||||
if(pBase == 0)
|
if(pBase == 0)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* \file ocsd_gen_elem_stack.h
|
* \file ocsd_gen_elem_list.h
|
||||||
* \brief OpenCSD : Generic element output stack.
|
* \brief OpenCSD : Generic element output list.
|
||||||
*
|
*
|
||||||
* \copyright Copyright (c) 2016, ARM Limited. All Rights Reserved.
|
* \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,
|
* This should remove some of the requirement on the packet processing to be re-enterant,
|
||||||
* simplifying this code.
|
* 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).
|
* (This required for cancel element in ETMv3 exeception branch).
|
||||||
*
|
*
|
||||||
* The "list" is actually a ring buffer - maintaining pointers to indicate current valid elements.
|
* 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;
|
m_sendIf = pGenElemIf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End of File ocsd_gen_elem_stack.h */
|
/* End of File ocsd_gen_elem_list.h */
|
||||||
|
109
contrib/opencsd/decoder/include/common/ocsd_gen_elem_stack.h
Normal file
109
contrib/opencsd/decoder/include/common/ocsd_gen_elem_stack.h
Normal 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 */
|
@ -39,6 +39,23 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include "opencsd/ocsd_if_types.h"
|
#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
|
class CoreArchProfileMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -50,16 +67,31 @@ class CoreArchProfileMap
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::map<std::string, ocsd_arch_profile_t> core_profiles;
|
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)
|
inline ocsd_arch_profile_t CoreArchProfileMap::getArchProfile(const std::string &coreName)
|
||||||
{
|
{
|
||||||
ocsd_arch_profile_t ap = { ARCH_UNKNOWN, profile_Unknown };
|
ocsd_arch_profile_t ap = { ARCH_UNKNOWN, profile_Unknown };
|
||||||
|
bool bFound = false;
|
||||||
|
|
||||||
std::map<std::string, ocsd_arch_profile_t>::const_iterator it;
|
std::map<std::string, ocsd_arch_profile_t>::const_iterator it;
|
||||||
|
|
||||||
|
/* match against the core name map. */
|
||||||
it = core_profiles.find(coreName);
|
it = core_profiles.find(coreName);
|
||||||
if(it != core_profiles.end())
|
if (it != core_profiles.end())
|
||||||
|
{
|
||||||
ap = it->second;
|
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;
|
return ap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ class OcsdTraceElement : public trcPrintableElem, public ocsd_generic_trace_elem
|
|||||||
|
|
||||||
|
|
||||||
void setTraceOnReason(const trace_on_reason_t reason);
|
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 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);
|
void setLastInstrInfo(const bool exec, const ocsd_instr_type last_i_type, const ocsd_instr_subtype last_i_subtype, const uint8_t size);
|
||||||
@ -94,7 +95,8 @@ class OcsdTraceElement : public trcPrintableElem, public ocsd_generic_trace_elem
|
|||||||
// return current context
|
// return current context
|
||||||
const ocsd_pe_context &getContext() const { return context; };
|
const ocsd_pe_context &getContext() const { return context; };
|
||||||
|
|
||||||
|
void copyPersistentData(const OcsdTraceElement &src);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void printSWInfoPkt(std::ostringstream &oss) const;
|
void printSWInfoPkt(std::ostringstream &oss) const;
|
||||||
void clearPerPktData(); //!< clear flags that indicate validity / have values on a per packet basis
|
void clearPerPktData(); //!< clear flags that indicate validity / have values on a per packet basis
|
||||||
@ -171,8 +173,8 @@ inline void OcsdTraceElement::init()
|
|||||||
|
|
||||||
inline void OcsdTraceElement::clearPerPktData()
|
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
|
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;
|
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)
|
inline void OcsdTraceElement::setISA(const ocsd_isa isa_update)
|
||||||
{
|
{
|
||||||
isa = isa_update;
|
isa = isa_update;
|
||||||
@ -201,6 +208,12 @@ inline void OcsdTraceElement::setExtendedDataPtr(const void *data_ptr)
|
|||||||
ptr_extended_data = 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;
|
||||||
|
}
|
||||||
|
|
||||||
/** @}*/
|
/** @}*/
|
||||||
|
|
||||||
|
@ -85,7 +85,10 @@ class TrcPktDecodeI : public TraceComponent
|
|||||||
virtual ocsd_err_t onProtocolConfig() = 0;
|
virtual ocsd_err_t onProtocolConfig() = 0;
|
||||||
virtual const uint8_t getCoreSightTraceID() = 0;
|
virtual const uint8_t getCoreSightTraceID() = 0;
|
||||||
|
|
||||||
|
/* init handling */
|
||||||
const bool checkInit();
|
const bool checkInit();
|
||||||
|
/* Called on first init confirmation */
|
||||||
|
virtual void onFirstInitOK() {};
|
||||||
|
|
||||||
/* data output */
|
/* data output */
|
||||||
ocsd_datapath_resp_t outputTraceElement(const OcsdTraceElement &elem); // use current index
|
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";
|
init_err_msg = "No instruction decoder interface attached and enabled";
|
||||||
else
|
else
|
||||||
m_decode_init_ok = true;
|
m_decode_init_ok = true;
|
||||||
|
if (m_decode_init_ok)
|
||||||
|
onFirstInitOK();
|
||||||
}
|
}
|
||||||
return m_decode_init_ok;
|
return m_decode_init_ok;
|
||||||
}
|
}
|
||||||
|
96
contrib/opencsd/decoder/include/common/trc_raw_buffer.h
Normal file
96
contrib/opencsd/decoder/include/common/trc_raw_buffer.h
Normal 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
|
||||||
|
|
@ -46,10 +46,9 @@ class TrcIDecode : public IInstrDecode
|
|||||||
virtual ocsd_err_t DecodeInstruction(ocsd_instr_info *instr_info);
|
virtual ocsd_err_t DecodeInstruction(ocsd_instr_info *instr_info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ocsd_err_t DecodeA32(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);
|
ocsd_err_t DecodeA64(ocsd_instr_info *instr_info, struct decode_info *info);
|
||||||
ocsd_err_t DecodeT32(ocsd_instr_info *instr_info);
|
ocsd_err_t DecodeT32(ocsd_instr_info *instr_info, struct decode_info *info);
|
||||||
void SetArchVersion(ocsd_instr_info *instr_info);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ARM_TRC_I_DECODE_H_INCLUDED
|
#endif // ARM_TRC_I_DECODE_H_INCLUDED
|
||||||
|
@ -42,6 +42,12 @@
|
|||||||
#include "opencsd/ocsd_if_types.h"
|
#include "opencsd/ocsd_if_types.h"
|
||||||
#include <cstdint>
|
#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,
|
For Thumb2, test if a halfword is the first half of a 32-bit instruction,
|
||||||
as opposed to a complete 16-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.
|
instructions such as SVC, HVC and SMC.
|
||||||
(Performance event 0x0C includes these.)
|
(Performance event 0x0C includes these.)
|
||||||
*/
|
*/
|
||||||
int inst_ARM_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);
|
int inst_Thumb_is_branch(uint32_t inst, struct decode_info *info);
|
||||||
int inst_A64_is_branch(uint32_t inst);
|
int inst_A64_is_branch(uint32_t inst, struct decode_info *info);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Test whether an instruction is a direct (aka immediate) branch.
|
Test whether an instruction is a direct (aka immediate) branch.
|
||||||
Performance event 0x0D counts these.
|
Performance event 0x0D counts these.
|
||||||
*/
|
*/
|
||||||
int inst_ARM_is_direct_branch(uint32_t inst);
|
int inst_ARM_is_direct_branch(uint32_t inst);
|
||||||
int inst_Thumb_is_direct_branch(uint32_t inst);
|
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);
|
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);
|
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);
|
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.
|
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_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_A64_branch_destination(uint64_t addr, uint32_t inst, uint64_t *pnpc);
|
||||||
|
|
||||||
int inst_ARM_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);
|
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);
|
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);
|
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);
|
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_ARM_is_branch_and_link(uint32_t inst, struct decode_info *info);
|
||||||
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 inst_A64_is_branch_and_link(uint32_t inst);
|
int inst_A64_is_branch_and_link(uint32_t inst, struct decode_info *info);
|
||||||
|
|
||||||
int inst_ARM_is_conditional(uint32_t inst);
|
int inst_ARM_is_conditional(uint32_t inst);
|
||||||
int inst_Thumb_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_Thumb_is_UDF(uint32_t inst);
|
||||||
int inst_A64_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
|
#endif // ARM_TRC_IDEC_ARMINST_H_INCLUDED
|
||||||
|
|
||||||
/* End of File trc_idec_arminst.h */
|
/* End of File trc_idec_arminst.h */
|
||||||
|
@ -68,7 +68,6 @@ class TrcMemAccBufPtr: public TrcMemAccessorBase
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const uint8_t *m_p_buffer; /**< pointer to the memory buffer */
|
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
|
#endif // ARM_TRC_MEM_ACC_BUFPTR_H_INCLUDED
|
||||||
|
@ -264,6 +264,7 @@ class TrcPktDecodeEtmV3 : public TrcPktDecodeBase<EtmV3TrcPacket, EtmV3Config>
|
|||||||
} processor_state_t;
|
} processor_state_t;
|
||||||
|
|
||||||
processor_state_t m_curr_state;
|
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.
|
uint8_t m_CSID; //!< Coresight trace ID for this decoder.
|
||||||
};
|
};
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
|
|
||||||
#include "trc_cmp_cfg_etmv4.h"
|
#include "trc_cmp_cfg_etmv4.h"
|
||||||
#include "trc_pkt_elem_etmv4i.h"
|
#include "trc_pkt_elem_etmv4i.h"
|
||||||
#include "trc_pkt_elem_etmv4d.h"
|
|
||||||
#include "trc_pkt_proc_etmv4.h"
|
#include "trc_pkt_proc_etmv4.h"
|
||||||
#include "trc_pkt_types_etmv4.h"
|
#include "trc_pkt_types_etmv4.h"
|
||||||
#include "trc_pkt_decode_etmv4i.h"
|
#include "trc_pkt_decode_etmv4i.h"
|
||||||
|
@ -56,6 +56,7 @@ typedef enum _p0_elem_t
|
|||||||
P0_TS,
|
P0_TS,
|
||||||
P0_CC,
|
P0_CC,
|
||||||
P0_TS_CC,
|
P0_TS_CC,
|
||||||
|
P0_Q,
|
||||||
P0_OVERFLOW,
|
P0_OVERFLOW,
|
||||||
P0_FUNC_RET,
|
P0_FUNC_RET,
|
||||||
} p0_elem_t;
|
} p0_elem_t;
|
||||||
@ -119,6 +120,44 @@ inline TrcStackElemAddr::TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt,
|
|||||||
m_addr_val.isa = 0;
|
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 */
|
/** Context element */
|
||||||
|
|
||||||
@ -133,9 +172,12 @@ class TrcStackElemCtxt : public TrcStackElem
|
|||||||
public:
|
public:
|
||||||
void setContext(const etmv4_context_t &ctxt) { m_context = ctxt; };
|
void setContext(const etmv4_context_t &ctxt) { m_context = ctxt; };
|
||||||
const etmv4_context_t &getContext() const { return m_context; };
|
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:
|
private:
|
||||||
etmv4_context_t m_context;
|
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) :
|
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();
|
const ocsd_atm_val commitOldest();
|
||||||
int cancelNewest(const int nCancel);
|
int cancelNewest(const int nCancel);
|
||||||
|
void mispredictNewest();
|
||||||
const bool isEmpty() const { return (m_atom.num == 0); };
|
const bool isEmpty() const { return (m_atom.num == 0); };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -217,6 +260,16 @@ inline int TrcStackElemAtom::cancelNewest(const int nCancel)
|
|||||||
return nRemove;
|
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 */
|
/** Generic param element */
|
||||||
|
|
||||||
@ -252,12 +305,20 @@ class EtmV4P0Stack
|
|||||||
|
|
||||||
void push_front(TrcStackElem *pElem);
|
void push_front(TrcStackElem *pElem);
|
||||||
void push_back(TrcStackElem *pElem); // insert element when processing
|
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 *back();
|
||||||
|
TrcStackElem *front();
|
||||||
size_t size();
|
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_all();
|
||||||
void delete_back();
|
void delete_back();
|
||||||
|
void delete_front();
|
||||||
void delete_popped();
|
void delete_popped();
|
||||||
|
|
||||||
// creation functions - create and push if successful.
|
// 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);
|
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);
|
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);
|
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);
|
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:
|
private:
|
||||||
std::deque<TrcStackElem *> m_P0_stack; //!< P0 decode element stack
|
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::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()
|
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
|
// 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();
|
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
|
// pop last element pointer off the stack and delete immediately
|
||||||
inline void EtmV4P0Stack::delete_back()
|
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
|
// get a pointer to the last element on the stack
|
||||||
inline TrcStackElem *EtmV4P0Stack::back()
|
inline TrcStackElem *EtmV4P0Stack::back()
|
||||||
{
|
{
|
||||||
return m_P0_stack.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
|
// remove and delete all the elements left on the stack
|
||||||
inline void EtmV4P0Stack::delete_all()
|
inline void EtmV4P0Stack::delete_all()
|
||||||
{
|
{
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include "opencsd/etmv4/trc_cmp_cfg_etmv4.h"
|
#include "opencsd/etmv4/trc_cmp_cfg_etmv4.h"
|
||||||
#include "common/trc_gen_elem.h"
|
#include "common/trc_gen_elem.h"
|
||||||
#include "common/trc_ret_stack.h"
|
#include "common/trc_ret_stack.h"
|
||||||
|
#include "common/ocsd_gen_elem_stack.h"
|
||||||
#include "opencsd/etmv4/trc_etmv4_stack_elem.h"
|
#include "opencsd/etmv4/trc_etmv4_stack_elem.h"
|
||||||
|
|
||||||
class TrcStackElem;
|
class TrcStackElem;
|
||||||
@ -65,35 +66,69 @@ class TrcPktDecodeEtmV4I : public TrcPktDecodeBase<EtmV4ITrcPacket, EtmV4Config>
|
|||||||
/* local decode methods */
|
/* local decode methods */
|
||||||
void initDecoder(); // initial state on creation (zeros all config)
|
void initDecoder(); // initial state on creation (zeros all config)
|
||||||
void resetDecoder(); // reset state to start of decode. (moves state, retains 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_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 commitElements(bool &Complete); // commit elements - may get wait response, or flag completion.
|
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_datapath_resp_t flushEOT();
|
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 doTraceInfoPacket();
|
||||||
void updateContext(TrcStackElemCtxt *pCtxtElem);
|
void updateContext(TrcStackElemCtxt *pCtxtElem, OcsdTraceElement &elem);
|
||||||
|
|
||||||
// process atom will output instruction trace, or no memory access trace elements.
|
// process atom will create instruction trace, or no memory access trace output elements.
|
||||||
ocsd_datapath_resp_t processAtom(const ocsd_atm_val, bool &bCont);
|
ocsd_err_t processAtom(const ocsd_atm_val atom);
|
||||||
|
|
||||||
// process an exception element - output instruction trace + exception generic type.
|
// 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
|
// 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_err_t addElemCC(TrcStackElemParam *pParamElem);
|
||||||
ocsd_datapath_resp_t outputTS(TrcStackElemParam *pParamElem, bool withCC);
|
ocsd_err_t addElemTS(TrcStackElemParam *pParamElem, bool withCC);
|
||||||
ocsd_datapath_resp_t outputEvent(TrcStackElemParam *pParamElem);
|
ocsd_err_t addElemEvent(TrcStackElemParam *pParamElem);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetInstrInfoInAddrISA(const ocsd_vaddr_t addr_val, const uint8_t isa);
|
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);
|
//** 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
|
uint32_t m_vmid_id; // most recent VMID
|
||||||
bool m_is_secure; // true if Secure
|
bool m_is_secure; // true if Secure
|
||||||
bool m_is_64bit; // true if 64 bit
|
bool m_is_64bit; // true if 64 bit
|
||||||
|
uint8_t m_last_IS; // last instruction set value from address packet.
|
||||||
|
|
||||||
// cycle counts
|
// cycle counts
|
||||||
int m_cc_threshold;
|
int m_cc_threshold;
|
||||||
|
|
||||||
// speculative trace (unsupported at present in the decoder).
|
// speculative trace
|
||||||
int m_curr_spec_depth;
|
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).
|
// data trace associative elements (unsupported at present in the decoder).
|
||||||
int m_p0_key;
|
int m_p0_key;
|
||||||
int m_p0_key_max;
|
int m_p0_key_max;
|
||||||
@ -121,6 +160,7 @@ class TrcPktDecodeEtmV4I : public TrcPktDecodeBase<EtmV4ITrcPacket, EtmV4Config>
|
|||||||
int m_cond_c_key;
|
int m_cond_c_key;
|
||||||
int m_cond_r_key;
|
int m_cond_r_key;
|
||||||
int m_cond_key_max_incr;
|
int m_cond_key_max_incr;
|
||||||
|
#endif
|
||||||
|
|
||||||
uint8_t m_CSID; //!< Coresight trace ID for this decoder.
|
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_SYNC, //!< waiting for sync packet.
|
||||||
WAIT_TINFO, //!< waiting for trace info packet.
|
WAIT_TINFO, //!< waiting for trace info packet.
|
||||||
DECODE_PKTS, //!< processing packets - creating decode elements on stack
|
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;
|
||||||
|
|
||||||
processor_state_t m_curr_state;
|
processor_state_t m_curr_state;
|
||||||
|
unsync_info_t m_unsync_eot_info; //!< addition info when / why unsync / eot
|
||||||
|
|
||||||
//** P0 element stack
|
//** P0 element stack
|
||||||
EtmV4P0Stack m_P0_stack; //!< P0 decode 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
|
// packet decode state
|
||||||
bool m_need_ctxt; //!< need context to continue
|
bool m_need_ctxt; //!< need context to continue
|
||||||
bool m_need_addr; //!< need an address to continue
|
bool m_need_addr; //!< need an address to continue
|
||||||
bool m_except_pending_addr; //!< next address packet is part of exception.
|
bool m_elem_pending_addr; //!< next address packet is needed for prev element.
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
ocsd_instr_info m_instr_info; //!< instruction info for code follower - in address is the next to be decoded.
|
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.
|
etmv4_trace_info_t m_trace_info; //!< trace info for this trace run.
|
||||||
|
|
||||||
bool m_prev_overflow;
|
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; //!< the address return stack.
|
||||||
|
|
||||||
TrcAddrReturnStack m_return_stack;
|
|
||||||
|
|
||||||
//** output element
|
|
||||||
OcsdTraceElement m_output_elem;
|
|
||||||
|
|
||||||
|
//** 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
|
#endif // ARM_TRC_PKT_DECODE_ETMV4I_H_INCLUDED
|
||||||
|
@ -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 */
|
|
@ -57,14 +57,7 @@ class Etmv4PktAddrStack
|
|||||||
public:
|
public:
|
||||||
Etmv4PktAddrStack()
|
Etmv4PktAddrStack()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 3; i++)
|
reset_stack();
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
~Etmv4PktAddrStack() {};
|
~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:
|
private:
|
||||||
ocsd_pkt_vaddr m_v_addr[3]; //!< most recently broadcast address packet
|
ocsd_pkt_vaddr m_v_addr[3]; //!< most recently broadcast address packet
|
||||||
uint8_t m_v_addr_ISA[3];
|
uint8_t m_v_addr_ISA[3];
|
||||||
@ -172,6 +179,7 @@ class EtmV4ITrcPacket : public TrcPacketBase, public ocsd_etmv4_i_pkt, public t
|
|||||||
|
|
||||||
// atom
|
// atom
|
||||||
const ocsd_pkt_atom &getAtom() const { return atom; };
|
const ocsd_pkt_atom &getAtom() const { return atom; };
|
||||||
|
const int getNumAtoms() const { return atom.num; };
|
||||||
|
|
||||||
// context
|
// context
|
||||||
const etmv4_context_t &getContext() const { return 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
|
// cc
|
||||||
const uint32_t getCC() const { return pkt_valid.bits.cc_valid ? cycle_count : 0; };
|
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
|
// packet type
|
||||||
const bool isBadPacket() const;
|
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.
|
// set these as defaults - if they don't appear in TINFO this is the state.
|
||||||
setTraceInfo(0);
|
setTraceInfo(0);
|
||||||
setTraceInfoSpec(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)
|
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)
|
if (pkt_valid.bits.context_valid && context.SF)
|
||||||
{
|
{
|
||||||
v_addr.size = VA_64BIT;
|
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);
|
v_addr.val = (v_addr.val & ~mask) | (addr & mask);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
v_addr.val = addr;
|
v_addr.val = addr;
|
||||||
v_addr.size = VA_32BIT;
|
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;
|
v_addr_ISA = IS;
|
||||||
push_vaddr();
|
push_vaddr();
|
||||||
}
|
}
|
||||||
|
@ -35,70 +35,13 @@
|
|||||||
#ifndef ARM_TRC_PKT_PROC_ETMV4_H_INCLUDED
|
#ifndef ARM_TRC_PKT_PROC_ETMV4_H_INCLUDED
|
||||||
#define 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_types_etmv4.h"
|
||||||
|
#include "trc_pkt_proc_etmv4i.h"
|
||||||
#include "common/trc_pkt_proc_base.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
|
#endif // ARM_TRC_PKT_PROC_ETMV4_H_INCLUDED
|
||||||
|
|
||||||
/* End of File trc_pkt_proc_etmv4.h */
|
/* End of File trc_pkt_proc_etmv4.h */
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* \file trc_pkt_proc_etmv4i_impl.h
|
* \file trc_pkt_proc_etmv4i.h
|
||||||
* \brief OpenCSD : Implementation of ETMv4 packet processing
|
* \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
|
#ifndef ARM_TRC_PKT_PROC_ETMV4I_IMPL_H_INCLUDED
|
||||||
#define 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_pkt_proc_etmv4.h"
|
||||||
#include "opencsd/etmv4/trc_cmp_cfg_etmv4.h"
|
#include "opencsd/etmv4/trc_cmp_cfg_etmv4.h"
|
||||||
#include "opencsd/etmv4/trc_pkt_elem_etmv4i.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:
|
public:
|
||||||
TraceRawBuffer();
|
TrcPktProcEtmV4I();
|
||||||
~TraceRawBuffer() {};
|
TrcPktProcEtmV4I(int instIDNum);
|
||||||
|
virtual ~TrcPktProcEtmV4I();
|
||||||
|
|
||||||
// init the buffer
|
protected:
|
||||||
void init(const uint32_t size, const uint8_t *rawtrace, std::vector<uint8_t> *out_packet);
|
/* implementation packet processing interface */
|
||||||
void copyByteToPkt(); // move a byte to the packet buffer
|
virtual ocsd_datapath_resp_t processData( const ocsd_trc_index_t index,
|
||||||
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,
|
|
||||||
const uint32_t dataBlockSize,
|
const uint32_t dataBlockSize,
|
||||||
const uint8_t *pDataBlock,
|
const uint8_t *pDataBlock,
|
||||||
uint32_t *numBytesProcessed);
|
uint32_t *numBytesProcessed);
|
||||||
ocsd_datapath_resp_t onEOT();
|
virtual ocsd_datapath_resp_t onEOT();
|
||||||
ocsd_datapath_resp_t onReset();
|
virtual ocsd_datapath_resp_t onReset();
|
||||||
ocsd_datapath_resp_t onFlush();
|
virtual ocsd_datapath_resp_t onFlush();
|
||||||
const bool isBadPacket() const;
|
virtual ocsd_err_t onProtocolConfig();
|
||||||
|
virtual const bool isBadPacket() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef enum _process_state {
|
typedef enum _process_state {
|
||||||
@ -100,7 +83,6 @@ class EtmV4IPktProcImpl
|
|||||||
|
|
||||||
/** packet processor configuration **/
|
/** packet processor configuration **/
|
||||||
bool m_isInit;
|
bool m_isInit;
|
||||||
TrcPktProcEtmV4I *m_interface; /**< The interface to the other decode components */
|
|
||||||
|
|
||||||
// etmv4 hardware configuration
|
// etmv4 hardware configuration
|
||||||
EtmV4Config m_config;
|
EtmV4Config m_config;
|
||||||
@ -111,7 +93,6 @@ class EtmV4IPktProcImpl
|
|||||||
int m_currPktIdx; // index into raw packet when expanding
|
int m_currPktIdx; // index into raw packet when expanding
|
||||||
EtmV4ITrcPacket m_curr_packet; // expanded packet
|
EtmV4ITrcPacket m_curr_packet; // expanded packet
|
||||||
ocsd_trc_index_t m_packet_index; // index of the start of the current 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
|
ocsd_trc_index_t m_blockIndex; // index at the start of the current data block being processed
|
||||||
|
|
||||||
// searching for sync
|
// 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);
|
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.
|
// packet processing is table driven.
|
||||||
typedef void (EtmV4IPktProcImpl::*PPKTFN)(uint8_t);
|
typedef void (TrcPktProcEtmV4I::*PPKTFN)(uint8_t);
|
||||||
PPKTFN m_pIPktFn;
|
PPKTFN m_pIPktFn;
|
||||||
|
|
||||||
struct _pkt_i_table_t {
|
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();
|
return m_curr_packet.isBadPacket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @}*/
|
||||||
|
|
||||||
#endif // ARM_TRC_PKT_PROC_ETMV4I_IMPL_H_INCLUDED
|
#endif // ARM_TRC_PKT_PROC_ETMV4I_IMPL_H_INCLUDED
|
||||||
|
|
||||||
/* End of File trc_pkt_proc_etmv4i_impl.h */
|
/* End of File trc_pkt_proc_etmv4i_impl.h */
|
@ -85,7 +85,8 @@ typedef enum _ocsd_etmv4_i_pkt_type
|
|||||||
|
|
||||||
// speculation
|
// speculation
|
||||||
ETM4_PKT_I_COMMIT = 0x2D, /*!< b00101101 */
|
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_MISPREDICT = 0x30, /*!< b001100xx */
|
||||||
ETM4_PKT_I_CANCEL_F2 = 0x34, /*!< b001101xx */
|
ETM4_PKT_I_CANCEL_F2 = 0x34, /*!< b001101xx */
|
||||||
ETM4_PKT_I_CANCEL_F3 = 0x38, /*!< b00111xxx */
|
ETM4_PKT_I_CANCEL_F3 = 0x38, /*!< b00111xxx */
|
||||||
|
@ -273,11 +273,11 @@ typedef enum _ocsd_dcd_tree_src_t {
|
|||||||
|
|
||||||
/** Core Architecture Version */
|
/** Core Architecture Version */
|
||||||
typedef enum _ocsd_arch_version {
|
typedef enum _ocsd_arch_version {
|
||||||
ARCH_UNKNOWN, /**< unknown architecture */
|
ARCH_UNKNOWN = 0x0000, /**< unknown architecture */
|
||||||
ARCH_CUSTOM, /**< None ARM, custom architecture */
|
ARCH_CUSTOM = 0x0001, /**< None ARM, custom architecture */
|
||||||
ARCH_V7, /**< V7 architecture */
|
ARCH_V7 = 0x0700, /**< V7 architecture */
|
||||||
ARCH_V8, /**< V8 architecture */
|
ARCH_V8 = 0x0800, /**< V8 architecture */
|
||||||
ARCH_V8r3, /**< V8.3 architecture */
|
ARCH_V8r3 = 0x0803, /**< V8.3 architecture */
|
||||||
} ocsd_arch_version_t;
|
} ocsd_arch_version_t;
|
||||||
|
|
||||||
// macros for arch version comparisons.
|
// 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_EL1N = 0x2, /**< NS EL1/0 */
|
||||||
OCSD_MEM_SPACE_EL2 = 0x4, /**< NS EL2 */
|
OCSD_MEM_SPACE_EL2 = 0x4, /**< NS EL2 */
|
||||||
OCSD_MEM_SPACE_EL3 = 0x8, /**< S EL3 */
|
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_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;
|
} ocsd_mem_space_acc_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -494,13 +495,14 @@ typedef struct _ocsd_file_mem_region {
|
|||||||
|
|
||||||
/** @name Packet Processor Operation Control Flags
|
/** @name Packet Processor Operation Control Flags
|
||||||
common operational flags - bottom 16 bits,
|
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_NOFWD_BAD_PKTS 0x00000010 /**< 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_NOMON_BAD_PKTS 0x00000020 /**< 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_ERR_BAD_PKTS 0x00000040 /**< 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_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 */
|
/** mask to combine all common packet processor operational control flags */
|
||||||
#define OCSD_OPFLG_PKTPROC_COMMON (OCSD_OPFLG_PKTPROC_NOFWD_BAD_PKTS | \
|
#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_ERR_BAD_PKTS | \
|
||||||
OCSD_OPFLG_PKTPROC_UNSYNC_ON_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
|
/** @name Packet Decoder Operation Control Flags
|
||||||
common operational flags - bottom 16 bits,
|
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 */
|
/** mask to combine all common packet processor operational control flags */
|
||||||
#define OCSD_OPFLG_PKTDEC_COMMON (OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS)
|
#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
|
/** @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.
|
Builtin decoder names.
|
||||||
|
|
||||||
|
@ -43,8 +43,8 @@
|
|||||||
/** @name Library Versioning
|
/** @name Library Versioning
|
||||||
@{*/
|
@{*/
|
||||||
#define OCSD_VER_MAJOR 0x0 /**< Library Major Version */
|
#define OCSD_VER_MAJOR 0x0 /**< Library Major Version */
|
||||||
#define OCSD_VER_MINOR 0xC /**< Library Minor Version */
|
#define OCSD_VER_MINOR 0xE /**< Library Minor Version */
|
||||||
#define OCSD_VER_PATCH 0x0 /**< Library Patch Version */
|
#define OCSD_VER_PATCH 0x2 /**< Library Patch Version */
|
||||||
|
|
||||||
/** Library version number - MMMMnnpp format.
|
/** Library version number - MMMMnnpp format.
|
||||||
MMMM = major version,
|
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_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_NAME "OpenCSD Library" /**< Library name string */
|
||||||
#define OCSD_LIB_SHORT_NAME "OCSD" /**< Library Short name string */
|
#define OCSD_LIB_SHORT_NAME "OCSD" /**< Library Short name string */
|
||||||
/** @}*/
|
/** @}*/
|
||||||
|
@ -154,6 +154,7 @@ class TrcPktDecodePtm : public TrcPktDecodeBase<PtmTrcPacket, PtmConfig>
|
|||||||
} processor_state_t;
|
} processor_state_t;
|
||||||
|
|
||||||
processor_state_t m_curr_state;
|
processor_state_t m_curr_state;
|
||||||
|
unsync_info_t m_unsync_info;
|
||||||
|
|
||||||
const bool processStateIsCont() const;
|
const bool processStateIsCont() const;
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ class TrcPktDecodeStm : public TrcPktDecodeBase<StmTrcPacket, STMConfig>
|
|||||||
} processor_state_t;
|
} processor_state_t;
|
||||||
|
|
||||||
processor_state_t m_curr_state;
|
processor_state_t m_curr_state;
|
||||||
|
unsync_info_t m_unsync_info;
|
||||||
|
|
||||||
ocsd_swt_info_t m_swt_packet_info;
|
ocsd_swt_info_t m_swt_packet_info;
|
||||||
|
|
||||||
|
@ -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_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_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_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_NACC, /*!< tracing in inaccessible memory area */
|
||||||
OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN, /*!< address currently unknown - need address packet update */
|
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. */
|
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 */
|
uint16_t ev_number; /**< event number if numbered event type */
|
||||||
} trace_event_t;
|
} 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 {
|
typedef struct _ocsd_generic_trace_elem {
|
||||||
ocsd_gen_trc_elem_t elem_type; /**< Element type - remaining data interpreted according to this value */
|
ocsd_gen_trc_elem_t elem_type; /**< Element type - remaining data interpreted according to this value */
|
||||||
ocsd_isa isa; /**< instruction set for executed instructions */
|
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 */
|
trace_on_reason_t trace_on_reason; /**< reason for the trace on packet */
|
||||||
ocsd_swt_info_t sw_trace_info; /**< software trace packet info */
|
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) */
|
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 */
|
const void *ptr_extended_data; /**< pointer to extended data buffer (data trace, sw trace payload) / custom structure */
|
||||||
|
@ -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))
|
if(!m_bRawPrint && (m_last_resp == OCSD_RESP_WAIT))
|
||||||
{
|
{
|
||||||
// expect a flush or a complete reset after a 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";
|
m_oss <<"ID:"<< std::hex << (uint32_t)m_trcID << "\tERROR: FLUSH operation expected after wait on trace decode path\n";
|
||||||
itemPrintLine(m_oss.str());
|
itemPrintLine(m_oss.str());
|
||||||
|
@ -130,6 +130,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV3::onEOT()
|
|||||||
try {
|
try {
|
||||||
pElem = GetNextOpElem(resp);
|
pElem = GetNextOpElem(resp);
|
||||||
pElem->setType(OCSD_GEN_TRC_ELEM_EO_TRACE);
|
pElem->setType(OCSD_GEN_TRC_ELEM_EO_TRACE);
|
||||||
|
pElem->setUnSyncEOTReason(UNSYNC_EOT);
|
||||||
m_outputElemList.commitAllPendElem();
|
m_outputElemList.commitAllPendElem();
|
||||||
m_curr_state = SEND_PKTS;
|
m_curr_state = SEND_PKTS;
|
||||||
resp = m_outputElemList.sendElements();
|
resp = m_outputElemList.sendElements();
|
||||||
@ -147,6 +148,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV3::onEOT()
|
|||||||
ocsd_datapath_resp_t TrcPktDecodeEtmV3::onReset()
|
ocsd_datapath_resp_t TrcPktDecodeEtmV3::onReset()
|
||||||
{
|
{
|
||||||
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
|
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
|
||||||
|
m_unsync_info = UNSYNC_RESET_DECODER;
|
||||||
resetDecoder();
|
resetDecoder();
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
@ -199,6 +201,7 @@ void TrcPktDecodeEtmV3::initDecoder()
|
|||||||
{
|
{
|
||||||
m_CSID = 0;
|
m_CSID = 0;
|
||||||
resetDecoder();
|
resetDecoder();
|
||||||
|
m_unsync_info = UNSYNC_INIT_DECODER;
|
||||||
m_code_follower.initInterfaces(getMemoryAccessAttachPt(),getInstrDecodeAttachPt());
|
m_code_follower.initInterfaces(getMemoryAccessAttachPt(),getInstrDecodeAttachPt());
|
||||||
m_outputElemList.initSendIf(getTraceElemOutAttachPt());
|
m_outputElemList.initSendIf(getTraceElemOutAttachPt());
|
||||||
}
|
}
|
||||||
@ -355,6 +358,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV3::decodePacket(bool &pktDone)
|
|||||||
catch(ocsdError &err)
|
catch(ocsdError &err)
|
||||||
{
|
{
|
||||||
LogError(err);
|
LogError(err);
|
||||||
|
m_unsync_info = UNSYNC_BAD_PACKET;
|
||||||
resetDecoder(); // mark decoder as unsynced - dump any current state.
|
resetDecoder(); // mark decoder as unsynced - dump any current state.
|
||||||
pktDone = true;
|
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."));
|
LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_FAIL,m_index_curr_pkt,m_CSID,"Bad Packet sequence."));
|
||||||
resp = OCSD_RESP_FATAL_SYS_ERR;
|
resp = OCSD_RESP_FATAL_SYS_ERR;
|
||||||
|
m_unsync_info = UNSYNC_BAD_PACKET;
|
||||||
resetDecoder(); // mark decoder as unsynced - dump any current state.
|
resetDecoder(); // mark decoder as unsynced - dump any current state.
|
||||||
pktDone = true;
|
pktDone = true;
|
||||||
}
|
}
|
||||||
@ -375,11 +380,13 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV3::sendUnsyncPacket()
|
|||||||
try {
|
try {
|
||||||
pElem = GetNextOpElem(resp);
|
pElem = GetNextOpElem(resp);
|
||||||
pElem->setType(OCSD_GEN_TRC_ELEM_NO_SYNC);
|
pElem->setType(OCSD_GEN_TRC_ELEM_NO_SYNC);
|
||||||
|
pElem->setUnSyncEOTReason(m_unsync_info);
|
||||||
resp = m_outputElemList.sendElements();
|
resp = m_outputElemList.sendElements();
|
||||||
}
|
}
|
||||||
catch(ocsdError &err)
|
catch(ocsdError &err)
|
||||||
{
|
{
|
||||||
LogError(err);
|
LogError(err);
|
||||||
|
m_unsync_info = UNSYNC_BAD_PACKET;
|
||||||
resetDecoder(); // mark decoder as unsynced - dump any current state.
|
resetDecoder(); // mark decoder as unsynced - dump any current state.
|
||||||
}
|
}
|
||||||
return resp;
|
return resp;
|
||||||
@ -464,6 +471,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV3::processISync(const bool withCC, const bo
|
|||||||
catch(ocsdError &err)
|
catch(ocsdError &err)
|
||||||
{
|
{
|
||||||
LogError(err);
|
LogError(err);
|
||||||
|
m_unsync_info = UNSYNC_BAD_PACKET;
|
||||||
resetDecoder(); // mark decoder as unsynced - dump any current state.
|
resetDecoder(); // mark decoder as unsynced - dump any current state.
|
||||||
}
|
}
|
||||||
return resp;
|
return resp;
|
||||||
@ -531,6 +539,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV3::processBranchAddr()
|
|||||||
catch(ocsdError &err)
|
catch(ocsdError &err)
|
||||||
{
|
{
|
||||||
LogError(err);
|
LogError(err);
|
||||||
|
m_unsync_info = UNSYNC_BAD_PACKET;
|
||||||
resetDecoder(); // mark decoder as unsynced - dump any current state.
|
resetDecoder(); // mark decoder as unsynced - dump any current state.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -647,6 +656,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV3::processPHdr()
|
|||||||
catch(ocsdError &err)
|
catch(ocsdError &err)
|
||||||
{
|
{
|
||||||
LogError(err);
|
LogError(err);
|
||||||
|
m_unsync_info = UNSYNC_BAD_PACKET;
|
||||||
resetDecoder(); // mark decoder as unsynced - dump any current state.
|
resetDecoder(); // mark decoder as unsynced - dump any current state.
|
||||||
}
|
}
|
||||||
return resp;
|
return resp;
|
||||||
|
@ -90,13 +90,17 @@ TrcStackElemExcept *EtmV4P0Stack::createExceptElem(const ocsd_etmv4_i_pkt_type r
|
|||||||
return pElem;
|
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);
|
TrcStackElemCtxt *pElem = new (std::nothrow) TrcStackElemCtxt(root_pkt, root_index);
|
||||||
if (pElem)
|
if (pElem)
|
||||||
{
|
{
|
||||||
pElem->setContext(context);
|
pElem->setContext(context);
|
||||||
push_front(pElem);
|
pElem->setIS(IS);
|
||||||
|
if (back)
|
||||||
|
push_back(pElem);
|
||||||
|
else
|
||||||
|
push_front(pElem);
|
||||||
}
|
}
|
||||||
return pElem;
|
return pElem;
|
||||||
|
|
||||||
@ -113,4 +117,40 @@ TrcStackElemAddr *EtmV4P0Stack::createAddrElem(const ocsd_etmv4_i_pkt_type root_
|
|||||||
return pElem;
|
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 */
|
/* End of file trc_etmv4_stack_elem.cpp */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -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 */
|
|
@ -161,6 +161,7 @@ void EtmV4ITrcPacket::toString(std::string &str) const
|
|||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "; INFO=" << std::hex << "0x" << trace_info.val;
|
oss << "; INFO=" << std::hex << "0x" << trace_info.val;
|
||||||
|
oss << " { CC." << std::dec << trace_info.bits.cc_enabled << " }";
|
||||||
if (trace_info.bits.cc_enabled)
|
if (trace_info.bits.cc_enabled)
|
||||||
oss << "; CC_THRESHOLD=" << std::hex << "0x" << cc_threshold;
|
oss << "; CC_THRESHOLD=" << std::hex << "0x" << cc_threshold;
|
||||||
str += oss.str();
|
str += oss.str();
|
||||||
@ -176,8 +177,96 @@ void EtmV4ITrcPacket::toString(std::string &str) const
|
|||||||
str += oss.str();
|
str += oss.str();
|
||||||
}
|
}
|
||||||
break;
|
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
|
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.";
|
pDesc = "Cancel Format 1.";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ETM4_PKT_I_CANCEL_F1_MISPRED:
|
||||||
|
pName = "I_CANCEL_F1_MISPRED";
|
||||||
|
pDesc = "Cancel Format 1 + Mispredict.";
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
case ETM4_PKT_I_MISPREDICT:
|
case ETM4_PKT_I_MISPREDICT:
|
||||||
pName = "I_MISPREDICT";
|
pName = "I_MISPREDICT";
|
||||||
pDesc = "Mispredict.";
|
pDesc = "Mispredict.";
|
||||||
|
@ -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 */
|
|
@ -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 */
|
|
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* \file trc_pkt_proc_etmv4i_impl.cpp
|
* \file trc_pkt_proc_etmv4i.cpp
|
||||||
* \brief OpenCSD :
|
* \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.
|
* 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 */
|
#ifdef __GNUC__
|
||||||
TraceRawBuffer::TraceRawBuffer()
|
// G++ doesn't like the ## pasting
|
||||||
{
|
#define ETMV4I_PKTS_NAME "PKTP_ETMV4I"
|
||||||
m_bufSize = 0;
|
#else
|
||||||
m_bufProcessed = 0;
|
// VC++ is fine
|
||||||
m_pBuffer = 0;
|
#define ETMV4I_PKTS_NAME OCSD_CMPNAME_PREFIX_PKTPROC##"_ETMV4I"
|
||||||
pkt = 0;
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
// init the buffer
|
static const uint32_t ETMV4_SUPPORTED_OP_FLAGS = OCSD_OPFLG_PKTPROC_COMMON;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* trace etmv4 packet processing class */
|
/* trace etmv4 packet processing class */
|
||||||
EtmV4IPktProcImpl::EtmV4IPktProcImpl() :
|
TrcPktProcEtmV4I::TrcPktProcEtmV4I() : TrcPktProcBase(ETMV4I_PKTS_NAME),
|
||||||
m_isInit(false),
|
m_isInit(false),
|
||||||
m_interface(0),
|
|
||||||
m_first_trace_info(false)
|
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)
|
InitProcessorState();
|
||||||
{
|
m_config = *TrcPktProcBase::getProtocolConfig();
|
||||||
m_interface = p_interface;
|
BuildIPacketTable(); // packet table based on config
|
||||||
m_isInit = true;
|
m_isInit = true;
|
||||||
}
|
return OCSD_OK;
|
||||||
InitProcessorState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ocsd_err_t EtmV4IPktProcImpl::Configure(const EtmV4Config *p_config)
|
ocsd_datapath_resp_t TrcPktProcEtmV4I::processData( const ocsd_trc_index_t index,
|
||||||
{
|
|
||||||
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,
|
|
||||||
const uint32_t dataBlockSize,
|
const uint32_t dataBlockSize,
|
||||||
const uint8_t *pDataBlock,
|
const uint8_t *pDataBlock,
|
||||||
uint32_t *numBytesProcessed)
|
uint32_t *numBytesProcessed)
|
||||||
{
|
{
|
||||||
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
|
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_trcIn.init(dataBlockSize, pDataBlock, &m_currPacketData);
|
||||||
m_blockIndex = index;
|
m_blockIndex = index;
|
||||||
bool done = false;
|
bool done = false;
|
||||||
@ -122,9 +93,6 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::processData( const ocsd_trc_index_t ind
|
|||||||
{
|
{
|
||||||
try
|
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)) &&
|
while ( (!m_trcIn.empty() || (m_process_state == SEND_PKT)) &&
|
||||||
OCSD_DATA_RESP_IS_CONT(resp)
|
OCSD_DATA_RESP_IS_CONT(resp)
|
||||||
)
|
)
|
||||||
@ -142,7 +110,7 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::processData( const ocsd_trc_index_t ind
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// unsynced - process data until we see a sync point
|
// 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_curr_packet.type = ETM4_PKT_I_NOTSYNC;
|
||||||
}
|
}
|
||||||
m_process_state = PROC_DATA;
|
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();
|
nextByte = m_trcIn.peekNextByte();
|
||||||
m_trcIn.copyByteToPkt(); // move next byte into the packet
|
m_trcIn.copyByteToPkt(); // move next byte into the packet
|
||||||
// m_currPacketData.push_back(pDataBlock[m_blockBytesProcessed]);
|
|
||||||
// m_blockBytesProcessed++;
|
|
||||||
(this->*m_pIPktFn)(nextByte);
|
(this->*m_pIPktFn)(nextByte);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -181,7 +147,7 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::processData( const ocsd_trc_index_t ind
|
|||||||
catch(ocsdError &err)
|
catch(ocsdError &err)
|
||||||
{
|
{
|
||||||
done = true;
|
done = true;
|
||||||
m_interface->LogError(err);
|
LogError(err);
|
||||||
if( (err.getErrorCode() == OCSD_ERR_BAD_PACKET_SEQ) ||
|
if( (err.getErrorCode() == OCSD_ERR_BAD_PACKET_SEQ) ||
|
||||||
(err.getErrorCode() == OCSD_ERR_INVALID_PCKT_HDR))
|
(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.
|
/// vv bad at this point.
|
||||||
resp = OCSD_RESP_FATAL_SYS_ERR;
|
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.");
|
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);
|
} while (!done);
|
||||||
|
|
||||||
@ -209,9 +175,12 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::processData( const ocsd_trc_index_t ind
|
|||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
ocsd_datapath_resp_t EtmV4IPktProcImpl::onEOT()
|
ocsd_datapath_resp_t TrcPktProcEtmV4I::onEOT()
|
||||||
{
|
{
|
||||||
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
|
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 we have a partial packet then send to attached sinks
|
||||||
if(m_currPacketData.size() != 0)
|
if(m_currPacketData.size() != 0)
|
||||||
{
|
{
|
||||||
@ -222,31 +191,37 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::onEOT()
|
|||||||
return resp;
|
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
|
// prepare for new decoding session
|
||||||
InitProcessorState();
|
InitProcessorState();
|
||||||
return OCSD_RESP_CONT;
|
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,
|
// packet processor never holds on to flushable data (may have partial packet,
|
||||||
// but any full packets are immediately sent)
|
// but any full packets are immediately sent)
|
||||||
return OCSD_RESP_CONT;
|
return OCSD_RESP_CONT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EtmV4IPktProcImpl::InitPacketState()
|
void TrcPktProcEtmV4I::InitPacketState()
|
||||||
{
|
{
|
||||||
m_currPacketData.clear();
|
m_currPacketData.clear();
|
||||||
m_curr_packet.initNextPacket(); // clear for next packet.
|
m_curr_packet.initNextPacket(); // clear for next packet.
|
||||||
m_update_on_unsync_packet_index = 0;
|
m_update_on_unsync_packet_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EtmV4IPktProcImpl::InitProcessorState()
|
void TrcPktProcEtmV4I::InitProcessorState()
|
||||||
{
|
{
|
||||||
InitPacketState();
|
InitPacketState();
|
||||||
m_pIPktFn = &EtmV4IPktProcImpl::iNotSync;
|
m_pIPktFn = &TrcPktProcEtmV4I::iNotSync;
|
||||||
m_packet_index = 0;
|
m_packet_index = 0;
|
||||||
m_is_sync = false;
|
m_is_sync = false;
|
||||||
m_first_trace_info = false;
|
m_first_trace_info = false;
|
||||||
@ -255,23 +230,23 @@ void EtmV4IPktProcImpl::InitProcessorState()
|
|||||||
m_curr_packet.initStartState();
|
m_curr_packet.initStartState();
|
||||||
}
|
}
|
||||||
|
|
||||||
ocsd_datapath_resp_t EtmV4IPktProcImpl::outputPacket()
|
ocsd_datapath_resp_t TrcPktProcEtmV4I::outputPacket()
|
||||||
{
|
{
|
||||||
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
|
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;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
ocsd_datapath_resp_t EtmV4IPktProcImpl::outputUnsyncedRawPacket()
|
ocsd_datapath_resp_t TrcPktProcEtmV4I::outputUnsyncedRawPacket()
|
||||||
{
|
{
|
||||||
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
|
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)
|
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;
|
m_sent_notsync_packet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +258,7 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::outputUnsyncedRawPacket()
|
|||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EtmV4IPktProcImpl::iNotSync(const uint8_t lastByte)
|
void TrcPktProcEtmV4I::iNotSync(const uint8_t lastByte)
|
||||||
{
|
{
|
||||||
// is it an extension byte?
|
// is it an extension byte?
|
||||||
if (lastByte == 0x00) // TBD : add check for forced sync in here?
|
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...
|
// some expansion may be required...
|
||||||
switch(m_curr_packet.type)
|
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....
|
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
|
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());
|
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
|
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());
|
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)
|
if(m_currPacketData.size() == 2)
|
||||||
{
|
{
|
||||||
// not sync and not next by 0x00 - not sync sequence
|
// not sync and not next by 0x00 - not sync sequence
|
||||||
if(!m_is_sync && (lastByte != 0x00))
|
if(!m_is_sync && (lastByte != 0x00))
|
||||||
{
|
{
|
||||||
m_pIPktFn = &EtmV4IPktProcImpl::iNotSync;
|
m_pIPktFn = &TrcPktProcEtmV4I::iNotSync;
|
||||||
m_curr_packet.type = ETM4_PKT_I_NOTSYNC;
|
m_curr_packet.type = ETM4_PKT_I_NOTSYNC;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -376,7 +351,7 @@ void EtmV4IPktProcImpl::iPktExtension(const uint8_t lastByte)
|
|||||||
|
|
||||||
case 0x00:
|
case 0x00:
|
||||||
m_curr_packet.type = ETM4_PKT_I_ASYNC;
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
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)
|
if(lastByte != 0x00)
|
||||||
{
|
{
|
||||||
// not sync and not next by 0x00 - not sync sequence if < 12
|
// not sync and not next by 0x00 - not sync sequence if < 12
|
||||||
if(!m_is_sync && m_currPacketData.size() != 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;
|
m_curr_packet.type = ETM4_PKT_I_NOTSYNC;
|
||||||
return;
|
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
|
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
|
// process the header byte
|
||||||
if(m_currPacketData.size() == 1)
|
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;
|
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;
|
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)
|
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 0x2: m_curr_packet.setAtomPacket(ATOM_PATTERN, 0x3, 2); break; // EE
|
||||||
case 0x3: m_curr_packet.setAtomPacket(ATOM_PATTERN, 0x0, 1); break; // N
|
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);
|
m_curr_packet.setCancelElements(1);
|
||||||
|
else
|
||||||
|
m_curr_packet.setCancelElements(0);
|
||||||
m_process_state = SEND_PKT;
|
m_process_state = SEND_PKT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -694,13 +671,12 @@ void EtmV4IPktProcImpl::iPktSpeclRes(const uint8_t lastByte)
|
|||||||
m_curr_packet.setCommitElements(field_val);
|
m_curr_packet.setCommitElements(field_val);
|
||||||
else
|
else
|
||||||
m_curr_packet.setCancelElements(field_val);
|
m_curr_packet.setCancelElements(field_val);
|
||||||
// TBD: sanity check with max spec depth here?
|
|
||||||
m_process_state = SEND_PKT;
|
m_process_state = SEND_PKT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EtmV4IPktProcImpl::iPktCondInstr(const uint8_t lastByte)
|
void TrcPktProcEtmV4I::iPktCondInstr(const uint8_t lastByte)
|
||||||
{
|
{
|
||||||
bool bF1Done = false;
|
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)
|
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;
|
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
|
// on input, buffer index points at the info byte - always present
|
||||||
uint8_t infoByte = m_currPacketData[st_idx];
|
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)
|
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)
|
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 IS_shift = (IS == 0) ? 2 : 1;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
@ -1000,7 +976,7 @@ int EtmV4IPktProcImpl::extractShortAddr(const std::vector<uint8_t> &buffer, cons
|
|||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EtmV4IPktProcImpl::iPktLongAddr(const uint8_t lastByte)
|
void TrcPktProcEtmV4I::iPktLongAddr(const uint8_t lastByte)
|
||||||
{
|
{
|
||||||
if(m_currPacketData.size() == 1)
|
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)
|
if(m_currPacketData.size() == 1)
|
||||||
{
|
{
|
||||||
@ -1096,7 +1072,7 @@ void EtmV4IPktProcImpl::iPktQ(const uint8_t lastByte)
|
|||||||
default:
|
default:
|
||||||
m_curr_packet.err_type = m_curr_packet.type;
|
m_curr_packet.err_type = m_curr_packet.type;
|
||||||
m_curr_packet.type = ETM4_PKT_I_BAD_SEQUENCE;
|
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;
|
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.
|
// patterns lsbit = oldest atom, ms bit = newest.
|
||||||
static const uint32_t f4_patterns[] = {
|
static const uint32_t f4_patterns[] = {
|
||||||
@ -1228,32 +1204,32 @@ void EtmV4IPktProcImpl::iAtom(const uint8_t lastByte)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// header byte processing is table driven.
|
// header byte processing is table driven.
|
||||||
void EtmV4IPktProcImpl::BuildIPacketTable()
|
void TrcPktProcEtmV4I::BuildIPacketTable()
|
||||||
{
|
{
|
||||||
// initialise everything as reserved.
|
// initialise everything as reserved.
|
||||||
for(int i = 0; i < 256; i++)
|
for(int i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
m_i_table[i].pkt_type = ETM4_PKT_I_RESERVED;
|
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
|
// 0x00 - extension
|
||||||
m_i_table[0x00].pkt_type = ETM4_PKT_I_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
|
// 0x01 - Trace info
|
||||||
m_i_table[0x01].pkt_type = ETM4_PKT_I_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
|
// b0000001x - timestamp
|
||||||
m_i_table[0x02].pkt_type = ETM4_PKT_I_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].pkt_type = ETM4_PKT_I_TIMESTAMP;
|
||||||
m_i_table[0x03].pptkFn = &EtmV4IPktProcImpl::iPktTimestamp;
|
m_i_table[0x03].pptkFn = &TrcPktProcEtmV4I::iPktTimestamp;
|
||||||
|
|
||||||
// b0000 0100 - trace on
|
// b0000 0100 - trace on
|
||||||
m_i_table[0x04].pkt_type = ETM4_PKT_I_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
|
// b0000 0101 - Funct ret V8M
|
||||||
@ -1262,30 +1238,30 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
|
|||||||
(OCSD_IS_V8_ARCH(m_config.archVersion())) &&
|
(OCSD_IS_V8_ARCH(m_config.archVersion())) &&
|
||||||
(m_config.FullVersion() >= 0x42))
|
(m_config.FullVersion() >= 0x42))
|
||||||
{
|
{
|
||||||
m_i_table[0x05].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
|
m_i_table[0x05].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
|
||||||
}
|
}
|
||||||
|
|
||||||
// b0000 0110 - exception
|
// b0000 0110 - exception
|
||||||
m_i_table[0x06].pkt_type = ETM4_PKT_I_EXCEPT;
|
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
|
// b0000 0111 - exception return
|
||||||
m_i_table[0x07].pkt_type = ETM4_PKT_I_EXCEPT_RTN;
|
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 110x - cycle count f2
|
||||||
// b0000 111x - cycle count f1
|
// b0000 111x - cycle count f1
|
||||||
for(int i = 0; i < 4; i++)
|
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].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
|
// b0001 xxxx - cycle count f3
|
||||||
for(int i = 0; i < 16; i++)
|
for(int i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
m_i_table[0x10+i].pkt_type = ETM4_PKT_I_CCNT_F3;
|
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
|
// b0010 0xxx - NDSM
|
||||||
@ -1293,9 +1269,9 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
|
|||||||
{
|
{
|
||||||
m_i_table[0x20 + i].pkt_type = ETM4_PKT_I_NUM_DS_MKR;
|
m_i_table[0x20 + i].pkt_type = ETM4_PKT_I_NUM_DS_MKR;
|
||||||
if (m_config.enabledDataTrace())
|
if (m_config.enabledDataTrace())
|
||||||
m_i_table[0x20+i].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
|
m_i_table[0x20+i].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
|
||||||
else
|
else
|
||||||
m_i_table[0x20+i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
|
m_i_table[0x20+i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// b0010 10xx, b0010 1100 - UDSM
|
// 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;
|
m_i_table[0x28+i].pkt_type = ETM4_PKT_I_UNNUM_DS_MKR;
|
||||||
if (m_config.enabledDataTrace())
|
if (m_config.enabledDataTrace())
|
||||||
m_i_table[0x28+i].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
|
m_i_table[0x28+i].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
|
||||||
else
|
else
|
||||||
m_i_table[0x28+i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
|
m_i_table[0x28+i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// b0010 1101 - commit
|
// b0010 1101 - commit
|
||||||
m_i_table[0x2D].pkt_type = ETM4_PKT_I_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
|
// b0010 111x - cancel f1 (mis pred)
|
||||||
for(int i = 0; i < 2; i++)
|
m_i_table[0x2E].pkt_type = ETM4_PKT_I_CANCEL_F1;
|
||||||
{
|
m_i_table[0x2E].pptkFn = &TrcPktProcEtmV4I::iPktSpeclRes;
|
||||||
// G++ doesn't understand [0x2E+i] so...
|
m_i_table[0x2F].pkt_type = ETM4_PKT_I_CANCEL_F1_MISPRED;
|
||||||
int idx = i + 0x2E;
|
m_i_table[0x2F].pptkFn = &TrcPktProcEtmV4I::iPktSpeclRes;
|
||||||
m_i_table[idx].pkt_type = ETM4_PKT_I_CANCEL_F1;
|
|
||||||
m_i_table[idx].pptkFn = &EtmV4IPktProcImpl::iPktSpeclRes;
|
|
||||||
}
|
|
||||||
|
|
||||||
// b0011 00xx - mis predict
|
// b0011 00xx - mis predict
|
||||||
for(int i = 0; i < 4; i++)
|
for(int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
m_i_table[0x30+i].pkt_type = ETM4_PKT_I_MISPREDICT;
|
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
|
// b0011 01xx - cancel f2
|
||||||
for(int i = 0; i < 4; i++)
|
for(int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
m_i_table[0x34+i].pkt_type = ETM4_PKT_I_CANCEL_F2;
|
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
|
// b0011 1xxx - cancel f3
|
||||||
for(int i = 0; i < 8; i++)
|
for(int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
m_i_table[0x38+i].pkt_type = ETM4_PKT_I_CANCEL_F3;
|
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();
|
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;
|
m_i_table[0x40 + i].pkt_type = ETM4_PKT_I_COND_I_F2;
|
||||||
if (bCondValid)
|
if (bCondValid)
|
||||||
m_i_table[0x40 + i].pptkFn = &EtmV4IPktProcImpl::iPktCondInstr;
|
m_i_table[0x40 + i].pptkFn = &TrcPktProcEtmV4I::iPktCondInstr;
|
||||||
else
|
else
|
||||||
m_i_table[0x40 + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
|
m_i_table[0x40 + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// b0100 0011 - cond flush
|
// b0100 0011 - cond flush
|
||||||
m_i_table[0x43].pkt_type = ETM4_PKT_I_COND_FLUSH;
|
m_i_table[0x43].pkt_type = ETM4_PKT_I_COND_FLUSH;
|
||||||
if (bCondValid)
|
if (bCondValid)
|
||||||
m_i_table[0x43].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
|
m_i_table[0x43].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
|
||||||
else
|
else
|
||||||
m_i_table[0x43].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
|
m_i_table[0x43].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
|
||||||
|
|
||||||
// b0100 010x, b0100 0110 - cond res f4
|
// b0100 010x, b0100 0110 - cond res f4
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
m_i_table[0x44 + i].pkt_type = ETM4_PKT_I_COND_RES_F4;
|
m_i_table[0x44 + i].pkt_type = ETM4_PKT_I_COND_RES_F4;
|
||||||
if (bCondValid)
|
if (bCondValid)
|
||||||
m_i_table[0x44 + i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
|
m_i_table[0x44 + i].pptkFn = &TrcPktProcEtmV4I::iPktCondResult;
|
||||||
else
|
else
|
||||||
m_i_table[0x44 + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
|
m_i_table[0x44 + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// b0100 100x, b0100 0110 - cond res f2
|
// 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;
|
m_i_table[0x48 + i].pkt_type = ETM4_PKT_I_COND_RES_F2;
|
||||||
if (bCondValid)
|
if (bCondValid)
|
||||||
m_i_table[0x48 + i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
|
m_i_table[0x48 + i].pptkFn = &TrcPktProcEtmV4I::iPktCondResult;
|
||||||
else
|
else
|
||||||
m_i_table[0x48 + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
|
m_i_table[0x48 + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
m_i_table[0x4C + i].pkt_type = ETM4_PKT_I_COND_RES_F2;
|
m_i_table[0x4C + i].pkt_type = ETM4_PKT_I_COND_RES_F2;
|
||||||
if (bCondValid)
|
if (bCondValid)
|
||||||
m_i_table[0x4C + i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
|
m_i_table[0x4C + i].pptkFn = &TrcPktProcEtmV4I::iPktCondResult;
|
||||||
else
|
else
|
||||||
m_i_table[0x4C + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
|
m_i_table[0x4C + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// b0101xxxx - cond res f3
|
// b0101xxxx - cond res f3
|
||||||
@ -1395,9 +1368,9 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
|
|||||||
{
|
{
|
||||||
m_i_table[0x50 + i].pkt_type = ETM4_PKT_I_COND_RES_F3;
|
m_i_table[0x50 + i].pkt_type = ETM4_PKT_I_COND_RES_F3;
|
||||||
if (bCondValid)
|
if (bCondValid)
|
||||||
m_i_table[0x50 + i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
|
m_i_table[0x50 + i].pptkFn = &TrcPktProcEtmV4I::iPktCondResult;
|
||||||
else
|
else
|
||||||
m_i_table[0x50 + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
|
m_i_table[0x50 + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// b011010xx - cond res f1
|
// b011010xx - cond res f1
|
||||||
@ -1405,24 +1378,24 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
|
|||||||
{
|
{
|
||||||
m_i_table[0x68 + i].pkt_type = ETM4_PKT_I_COND_RES_F1;
|
m_i_table[0x68 + i].pkt_type = ETM4_PKT_I_COND_RES_F1;
|
||||||
if (bCondValid)
|
if (bCondValid)
|
||||||
m_i_table[0x68 + i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
|
m_i_table[0x68 + i].pptkFn = &TrcPktProcEtmV4I::iPktCondResult;
|
||||||
else
|
else
|
||||||
m_i_table[0x68 + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
|
m_i_table[0x68 + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// b0110 1100 - cond instr f1
|
// b0110 1100 - cond instr f1
|
||||||
m_i_table[0x6C].pkt_type = ETM4_PKT_I_COND_I_F1;
|
m_i_table[0x6C].pkt_type = ETM4_PKT_I_COND_I_F1;
|
||||||
if (bCondValid)
|
if (bCondValid)
|
||||||
m_i_table[0x6C].pptkFn = &EtmV4IPktProcImpl::iPktCondInstr;
|
m_i_table[0x6C].pptkFn = &TrcPktProcEtmV4I::iPktCondInstr;
|
||||||
else
|
else
|
||||||
m_i_table[0x6C].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
|
m_i_table[0x6C].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
|
||||||
|
|
||||||
// b0110 1101 - cond instr f3
|
// b0110 1101 - cond instr f3
|
||||||
m_i_table[0x6D].pkt_type = ETM4_PKT_I_COND_I_F3;
|
m_i_table[0x6D].pkt_type = ETM4_PKT_I_COND_I_F3;
|
||||||
if (bCondValid)
|
if (bCondValid)
|
||||||
m_i_table[0x6D].pptkFn = &EtmV4IPktProcImpl::iPktCondInstr;
|
m_i_table[0x6D].pptkFn = &TrcPktProcEtmV4I::iPktCondInstr;
|
||||||
else
|
else
|
||||||
m_i_table[0x6D].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
|
m_i_table[0x6D].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
|
||||||
|
|
||||||
// b0110111x - cond res f1
|
// b0110111x - cond res f1
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
@ -1430,30 +1403,30 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
|
|||||||
// G++ cannot understand [0x6E+i] so change these round
|
// G++ cannot understand [0x6E+i] so change these round
|
||||||
m_i_table[i + 0x6E].pkt_type = ETM4_PKT_I_COND_RES_F1;
|
m_i_table[i + 0x6E].pkt_type = ETM4_PKT_I_COND_RES_F1;
|
||||||
if (bCondValid)
|
if (bCondValid)
|
||||||
m_i_table[i + 0x6E].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
|
m_i_table[i + 0x6E].pptkFn = &TrcPktProcEtmV4I::iPktCondResult;
|
||||||
else
|
else
|
||||||
m_i_table[i + 0x6E].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
|
m_i_table[i + 0x6E].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ETM 4.3 introduces ignore packets
|
// ETM 4.3 introduces ignore packets
|
||||||
if (m_config.FullVersion() >= 0x43)
|
if (m_config.FullVersion() >= 0x43)
|
||||||
{
|
{
|
||||||
m_i_table[0x70].pkt_type = ETM4_PKT_I_IGNORE;
|
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
|
// b01110001 - b01111111 - event trace
|
||||||
for(int i = 0; i < 15; i++)
|
for(int i = 0; i < 15; i++)
|
||||||
{
|
{
|
||||||
m_i_table[0x71+i].pkt_type = ETM4_PKT_I_EVENT;
|
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
|
// 0b1000 000x - context
|
||||||
for(int i = 0; i < 2; i++)
|
for(int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
m_i_table[0x80+i].pkt_type = ETM4_PKT_I_CTXT;
|
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
|
// 0b1000 0010 to b1000 0011 - addr with ctxt
|
||||||
@ -1461,27 +1434,27 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
|
|||||||
for(int i = 0; i < 2; i++)
|
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].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++)
|
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].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
|
// 0b1001 0000 to b1001 0010 - exact match addr
|
||||||
for(int i = 0; i < 3; i++)
|
for(int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
m_i_table[0x90+i].pkt_type = ETM4_PKT_I_ADDR_MATCH;
|
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
|
// b1001 0101 - b1001 0110 - addr short address
|
||||||
for(int i = 0; i < 2; i++)
|
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].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
|
// b10011010 - b10011011 - addr long address
|
||||||
@ -1489,12 +1462,12 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
|
|||||||
for(int i = 0; i < 2; i++)
|
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].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++)
|
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].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
|
// b1010xxxx - Q packet
|
||||||
@ -1515,7 +1488,7 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
|
|||||||
default:
|
default:
|
||||||
// if this config supports Q elem - otherwise reserved again.
|
// if this config supports Q elem - otherwise reserved again.
|
||||||
if (m_config.hasQElem())
|
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
|
for(int i = 0xC0; i <= 0xD4; i++) // atom f6
|
||||||
{
|
{
|
||||||
m_i_table[i].pkt_type = ETM4_PKT_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
|
for(int i = 0xD5; i <= 0xD7; i++) // atom f5
|
||||||
{
|
{
|
||||||
m_i_table[i].pkt_type = ETM4_PKT_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
|
for(int i = 0xD8; i <= 0xDB; i++) // atom f2
|
||||||
{
|
{
|
||||||
m_i_table[i].pkt_type = ETM4_PKT_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
|
for(int i = 0xDC; i <= 0xDF; i++) // atom f4
|
||||||
{
|
{
|
||||||
m_i_table[i].pkt_type = ETM4_PKT_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
|
for(int i = 0xE0; i <= 0xF4; i++) // atom f6
|
||||||
{
|
{
|
||||||
m_i_table[i].pkt_type = ETM4_PKT_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
|
// atom f5
|
||||||
m_i_table[0xF5].pkt_type = ETM4_PKT_I_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
|
for(int i = 0xF6; i <= 0xF7; i++) // atom f1
|
||||||
{
|
{
|
||||||
m_i_table[i].pkt_type = ETM4_PKT_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
|
for(int i = 0xF8; i <= 0xFF; i++) // atom f3
|
||||||
{
|
{
|
||||||
m_i_table[i].pkt_type = ETM4_PKT_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;
|
unsigned idx = 0;
|
||||||
bool lastByte = false;
|
bool lastByte = false;
|
||||||
@ -1586,7 +1559,7 @@ void EtmV4IPktProcImpl::BuildIPacketTable()
|
|||||||
return idx;
|
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;
|
unsigned idx = 0;
|
||||||
bool lastByte = false;
|
bool lastByte = false;
|
||||||
@ -1610,7 +1583,7 @@ unsigned EtmV4IPktProcImpl::extractContField64(const std::vector<uint8_t> &buffe
|
|||||||
return idx;
|
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;
|
unsigned idx = 0;
|
||||||
bool lastByte = false;
|
bool lastByte = false;
|
||||||
@ -1644,7 +1617,7 @@ unsigned EtmV4IPktProcImpl::extractContField64(const std::vector<uint8_t> &buffe
|
|||||||
return idx;
|
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;
|
value = 0;
|
||||||
if(IS == 0)
|
if(IS == 0)
|
||||||
@ -1666,7 +1639,7 @@ int EtmV4IPktProcImpl::extract64BitLongAddr(const std::vector<uint8_t> &buffer,
|
|||||||
return 8;
|
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;
|
value = 0;
|
||||||
if(IS == 0)
|
if(IS == 0)
|
||||||
@ -1684,11 +1657,11 @@ int EtmV4IPktProcImpl::extract32BitLongAddr(const std::vector<uint8_t> &buffer,
|
|||||||
return 4;
|
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
|
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);
|
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 */
|
@ -39,21 +39,23 @@
|
|||||||
ocsd_err_t TrcIDecode::DecodeInstruction(ocsd_instr_info *instr_info)
|
ocsd_err_t TrcIDecode::DecodeInstruction(ocsd_instr_info *instr_info)
|
||||||
{
|
{
|
||||||
ocsd_err_t err = OCSD_OK;
|
ocsd_err_t err = OCSD_OK;
|
||||||
clear_instr_subtype();
|
struct decode_info info;
|
||||||
SetArchVersion(instr_info);
|
|
||||||
|
info.instr_sub_type = OCSD_S_INSTR_NONE;
|
||||||
|
info.arch_version = (uint16_t)(instr_info->pe_type.arch);
|
||||||
|
|
||||||
switch(instr_info->isa)
|
switch(instr_info->isa)
|
||||||
{
|
{
|
||||||
case ocsd_isa_arm:
|
case ocsd_isa_arm:
|
||||||
err = DecodeA32(instr_info);
|
err = DecodeA32(instr_info, &info);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ocsd_isa_thumb2:
|
case ocsd_isa_thumb2:
|
||||||
err = DecodeT32(instr_info);
|
err = DecodeT32(instr_info, &info);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ocsd_isa_aarch64:
|
case ocsd_isa_aarch64:
|
||||||
err = DecodeA64(instr_info);
|
err = DecodeA64(instr_info, &info);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ocsd_isa_tee:
|
case ocsd_isa_tee:
|
||||||
@ -63,27 +65,11 @@ ocsd_err_t TrcIDecode::DecodeInstruction(ocsd_instr_info *instr_info)
|
|||||||
err = OCSD_ERR_UNSUPPORTED_ISA;
|
err = OCSD_ERR_UNSUPPORTED_ISA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
instr_info->sub_type = get_instr_subtype();
|
instr_info->sub_type = info.instr_sub_type;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrcIDecode::SetArchVersion(ocsd_instr_info *instr_info)
|
ocsd_err_t TrcIDecode::DecodeA32(ocsd_instr_info *instr_info, struct decode_info *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)
|
|
||||||
{
|
{
|
||||||
uint32_t branchAddr = 0;
|
uint32_t branchAddr = 0;
|
||||||
arm_barrier_t barrier;
|
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->next_isa = instr_info->isa; // assume same ISA
|
||||||
instr_info->is_link = 0;
|
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->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))
|
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;
|
branchAddr &= ~0x1;
|
||||||
}
|
}
|
||||||
instr_info->branch_addr = (ocsd_vaddr_t)branchAddr;
|
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)
|
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;
|
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;
|
uint64_t branchAddr = 0;
|
||||||
arm_barrier_t barrier;
|
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->next_isa = instr_info->isa; // assume same ISA
|
||||||
instr_info->is_link = 0;
|
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->type = OCSD_INSTR_BR_INDIRECT;
|
||||||
// instr_info->is_link = inst_A64_is_branch_and_link(instr_info->opcode);
|
// 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);
|
inst_A64_branch_destination(instr_info->instr_addr,instr_info->opcode,&branchAddr);
|
||||||
instr_info->type = OCSD_INSTR_BR;
|
instr_info->type = OCSD_INSTR_BR;
|
||||||
@ -187,7 +173,7 @@ ocsd_err_t TrcIDecode::DecodeA64(ocsd_instr_info *instr_info)
|
|||||||
return OCSD_OK;
|
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;
|
uint32_t branchAddr = 0;
|
||||||
arm_barrier_t barrier;
|
arm_barrier_t barrier;
|
||||||
@ -206,7 +192,7 @@ ocsd_err_t TrcIDecode::DecodeT32(ocsd_instr_info *instr_info)
|
|||||||
instr_info->is_conditional = 0;
|
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);
|
inst_Thumb_branch_destination((uint32_t)instr_info->instr_addr,instr_info->opcode,&branchAddr);
|
||||||
instr_info->type = OCSD_INSTR_BR;
|
instr_info->type = OCSD_INSTR_BR;
|
||||||
@ -214,7 +200,7 @@ ocsd_err_t TrcIDecode::DecodeT32(ocsd_instr_info *instr_info)
|
|||||||
if((branchAddr & 0x1) == 0)
|
if((branchAddr & 0x1) == 0)
|
||||||
instr_info->next_isa = ocsd_isa_arm;
|
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;
|
instr_info->type = OCSD_INSTR_BR_INDIRECT;
|
||||||
}
|
}
|
||||||
@ -246,5 +232,4 @@ ocsd_err_t TrcIDecode::DecodeT32(ocsd_instr_info *instr_info)
|
|||||||
return OCSD_OK;
|
return OCSD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* End of File trc_i_decode.cpp */
|
/* End of File trc_i_decode.cpp */
|
||||||
|
@ -42,27 +42,6 @@ block identification and trace decode.
|
|||||||
#include <stddef.h> /* for NULL */
|
#include <stddef.h> /* for NULL */
|
||||||
#include <assert.h>
|
#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 inst_ARM_is_direct_branch(uint32_t inst)
|
||||||
{
|
{
|
||||||
int is_direct_branch = 1;
|
int is_direct_branch = 1;
|
||||||
@ -91,7 +70,7 @@ int inst_ARM_wfiwfe(uint32_t inst)
|
|||||||
return 0;
|
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;
|
int is_indirect_branch = 1;
|
||||||
if ((inst & 0xf0000000) == 0xf0000000) {
|
if ((inst & 0xf0000000) == 0xf0000000) {
|
||||||
@ -104,23 +83,23 @@ int inst_ARM_is_indirect_branch(uint32_t inst)
|
|||||||
} else if ((inst & 0x0ff000d0) == 0x01200010) {
|
} else if ((inst & 0x0ff000d0) == 0x01200010) {
|
||||||
/* BLX (register), BX */
|
/* BLX (register), BX */
|
||||||
if ((inst & 0xFF) == 0x1E)
|
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) {
|
} else if ((inst & 0x0ff000f0) == 0x01200020) {
|
||||||
/* BXJ: in v8 this behaves like BX */
|
/* BXJ: in v8 this behaves like BX */
|
||||||
} else if ((inst & 0x0e108000) == 0x08108000) {
|
} else if ((inst & 0x0e108000) == 0x08108000) {
|
||||||
/* POP {...,pc} or LDMxx {...,pc} */
|
/* POP {...,pc} or LDMxx {...,pc} */
|
||||||
if ((inst & 0x0FFFA000) == 0x08BD8000) /* LDMIA SP!,{...,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) {
|
} else if ((inst & 0x0e50f000) == 0x0410f000) {
|
||||||
/* LDR PC,imm... inc. POP {PC} */
|
/* LDR PC,imm... inc. POP {PC} */
|
||||||
if ( (inst & 0x01ff0000) == 0x009D0000)
|
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) {
|
} else if ((inst & 0x0e50f010) == 0x0610f000) {
|
||||||
/* LDR PC,reg */
|
/* LDR PC,reg */
|
||||||
} else if ((inst & 0x0fe0f000) == 0x01a0f000) {
|
} else if ((inst & 0x0fe0f000) == 0x01a0f000) {
|
||||||
/* MOV PC,rx */
|
/* MOV PC,rx */
|
||||||
if ((inst & 0x00100FFF) == 0x00E) /* ensure the S=0, LSL #0 variant - i.e plain MOV */
|
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) {
|
} else if ((inst & 0x0f900080) == 0x01000000) {
|
||||||
/* "Miscellaneous instructions" - in DP space */
|
/* "Miscellaneous instructions" - in DP space */
|
||||||
is_indirect_branch = 0;
|
is_indirect_branch = 0;
|
||||||
@ -144,13 +123,13 @@ int inst_ARM_is_indirect_branch(uint32_t inst)
|
|||||||
return is_indirect_branch;
|
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;
|
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;
|
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) */
|
/* B (encoding T4); BL (encoding T1) */
|
||||||
if (inst & 0x00004000) {
|
if (inst & 0x00004000) {
|
||||||
*is_link = 1;
|
*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) {
|
} else if ((inst & 0xf800d001) == 0xf000c000) {
|
||||||
/* BLX (imm) (encoding T2) */
|
/* BLX (imm) (encoding T2) */
|
||||||
*is_link = 1;
|
*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) {
|
} else if ((inst & 0xf5000000) == 0xb1000000) {
|
||||||
/* CB(NZ) */
|
/* CB(NZ) */
|
||||||
*is_cond = 1;
|
*is_cond = 1;
|
||||||
@ -197,13 +176,13 @@ int inst_Thumb_wfiwfe(uint32_t inst)
|
|||||||
return is_wfiwfe;
|
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;
|
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 */
|
/* See e.g. PFT Table 2-3 and Table 2-5 */
|
||||||
int is_branch = 1;
|
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] */
|
/* BX, BLX (reg) [v8M includes BXNS, BLXNS] */
|
||||||
if (inst & 0x00800000) {
|
if (inst & 0x00800000) {
|
||||||
*is_link = 1;
|
*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) {
|
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) {
|
} else if ((inst & 0xfff0d000) == 0xf3c08000) {
|
||||||
/* BXJ: in v8 this behaves like BX */
|
/* BXJ: in v8 this behaves like BX */
|
||||||
} else if ((inst & 0xff000000) == 0xbd000000) {
|
} else if ((inst & 0xff000000) == 0xbd000000) {
|
||||||
/* POP {pc} */
|
/* 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) {
|
} else if ((inst & 0xfd870000) == 0x44870000) {
|
||||||
/* MOV PC,reg or ADD PC,reg */
|
/* MOV PC,reg or ADD PC,reg */
|
||||||
if ((inst & 0xffff0000) == 0x46f700000)
|
if ((inst & 0xffff0000) == 0x46f70000)
|
||||||
instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* MOV PC,LR */
|
info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* MOV PC,LR */
|
||||||
} else if ((inst & 0xfff0ffe0) == 0xe8d0f000) {
|
} else if ((inst & 0xfff0ffe0) == 0xe8d0f000) {
|
||||||
/* TBB/TBH */
|
/* TBB/TBH */
|
||||||
} else if ((inst & 0xffd00000) == 0xe8100000) {
|
} 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) {
|
} else if ((inst & 0xfff0f800) == 0xf850f800) {
|
||||||
/* LDR PC,imm (T4) */
|
/* LDR PC,imm (T4) */
|
||||||
if((inst & 0x000f0f00) == 0x000d0b00)
|
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) {
|
} else if ((inst & 0xfff0ffc0) == 0xf850f000) {
|
||||||
/* LDR PC,reg (T2) */
|
/* LDR PC,reg (T2) */
|
||||||
} else if ((inst & 0xfe508000) == 0xe8108000) {
|
} else if ((inst & 0xfe508000) == 0xe8108000) {
|
||||||
/* LDM PC */
|
/* LDM PC */
|
||||||
if ((inst & 0x0FFF0000) == 0x08BD0000) /* LDMIA [SP]!, */
|
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 {
|
} else {
|
||||||
is_branch = 0;
|
is_branch = 0;
|
||||||
}
|
}
|
||||||
return is_branch;
|
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;
|
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;
|
int is_direct_branch = 1;
|
||||||
if ((inst & 0x7c000000) == 0x34000000) {
|
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 */
|
/* B, BL imm */
|
||||||
if (inst & 0x80000000) {
|
if (inst & 0x80000000) {
|
||||||
*is_link = 1;
|
*is_link = 1;
|
||||||
instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
is_direct_branch = 0;
|
is_direct_branch = 0;
|
||||||
@ -287,13 +266,13 @@ int inst_A64_wfiwfe(uint32_t inst)
|
|||||||
return 0;
|
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;
|
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;
|
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 */
|
/* BR, BLR */
|
||||||
if (inst & 0x00200000) {
|
if (inst & 0x00200000) {
|
||||||
*is_link = 1;
|
*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) {
|
} else if ((inst & 0xfffffc1f) == 0xd65f0000) {
|
||||||
instr_sub_type = OCSD_S_INSTR_V8_RET;
|
info->instr_sub_type = OCSD_S_INSTR_V8_RET;
|
||||||
/* RET */
|
/* RET */
|
||||||
} else if ((inst & 0xffffffff) == 0xd69f03e0) {
|
} else if ((inst & 0xffffffff) == 0xd69f03e0) {
|
||||||
/* ERET */
|
/* ERET */
|
||||||
instr_sub_type = OCSD_S_INSTR_V8_ERET;
|
info->instr_sub_type = OCSD_S_INSTR_V8_ERET;
|
||||||
} else if (arch_version >= 0x0803) {
|
} else if (info->arch_version >= 0x0803) {
|
||||||
/* new pointer auth instr for v8.3 arch */
|
/* new pointer auth instr for v8.3 arch */
|
||||||
if ((inst & 0xffdff800) == 0xd61f0800) {
|
if ((inst & 0xffdff800) == 0xd71f0800) {
|
||||||
/* BRAA, BRAB, BLRAA, BLRBB */
|
/* BRAA, BRAB, BLRAA, BLRBB */
|
||||||
if (inst & 0x00200000) {
|
if (inst & 0x00200000) {
|
||||||
*is_link = 1;
|
*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 */
|
/* BRAAZ, BRABZ, BLRAAZ, BLRBBZ */
|
||||||
if (inst & 0x00200000) {
|
if (inst & 0x00200000) {
|
||||||
*is_link = 1;
|
*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) {
|
} else if ((inst & 0xfffffbff) == 0xd69f0bff) {
|
||||||
/* ERETAA, ERETAB */
|
/* ERETAA, ERETAB */
|
||||||
instr_sub_type = OCSD_S_INSTR_V8_ERET;
|
info->instr_sub_type = OCSD_S_INSTR_V8_ERET;
|
||||||
} else if ((inst & 0xfffffbff) == 0xd65f0bff) {
|
} else if ((inst & 0xfffffbff) == 0xd65f0bff) {
|
||||||
/* RETAA, RETAB */
|
/* RETAA, RETAB */
|
||||||
instr_sub_type = OCSD_S_INSTR_V8_RET;
|
info->instr_sub_type = OCSD_S_INSTR_V8_RET;
|
||||||
} else {
|
} else {
|
||||||
is_indirect_branch = 0;
|
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;
|
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);
|
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) ||
|
return inst_Thumb_is_indirect_branch(inst, info) ||
|
||||||
inst_Thumb_is_direct_branch(inst);
|
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) ||
|
return inst_A64_is_indirect_branch(inst, info) ||
|
||||||
inst_A64_is_direct_branch(inst);
|
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;
|
int is_branch = 1;
|
||||||
if ((inst & 0xf0000000) == 0xf0000000) {
|
if ((inst & 0xf0000000) == 0xf0000000) {
|
||||||
if ((inst & 0xfe000000) == 0xfa000000){
|
if ((inst & 0xfe000000) == 0xfa000000){
|
||||||
instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
||||||
/* BLX (imm) */
|
/* BLX (imm) */
|
||||||
} else {
|
} else {
|
||||||
is_branch = 0;
|
is_branch = 0;
|
||||||
}
|
}
|
||||||
} else if ((inst & 0x0f000000) == 0x0b000000) {
|
} else if ((inst & 0x0f000000) == 0x0b000000) {
|
||||||
instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
||||||
/* BL */
|
/* BL */
|
||||||
} else if ((inst & 0x0ff000f0) == 0x01200030) {
|
} else if ((inst & 0x0ff000f0) == 0x01200030) {
|
||||||
instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
||||||
/* BLX (reg) */
|
/* BLX (reg) */
|
||||||
} else {
|
} else {
|
||||||
is_branch = 0;
|
is_branch = 0;
|
||||||
@ -481,14 +460,14 @@ int inst_ARM_is_branch_and_link(uint32_t inst)
|
|||||||
return is_branch;
|
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;
|
int is_branch = 1;
|
||||||
if ((inst & 0xff800000) == 0x47800000) {
|
if ((inst & 0xff800000) == 0x47800000) {
|
||||||
instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
||||||
/* BLX (reg) */
|
/* BLX (reg) */
|
||||||
} else if ((inst & 0xf800c000) == 0xf000c000) {
|
} 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) */
|
/* BL, BLX (imm) */
|
||||||
} else {
|
} else {
|
||||||
is_branch = 0;
|
is_branch = 0;
|
||||||
@ -496,23 +475,23 @@ int inst_Thumb_is_branch_and_link(uint32_t inst)
|
|||||||
return is_branch;
|
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;
|
int is_branch = 1;
|
||||||
if ((inst & 0xfffffc1f) == 0xd63f0000) {
|
if ((inst & 0xfffffc1f) == 0xd63f0000) {
|
||||||
/* BLR */
|
/* BLR */
|
||||||
instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
||||||
} else if ((inst & 0xfc000000) == 0x94000000) {
|
} else if ((inst & 0xfc000000) == 0x94000000) {
|
||||||
/* BL */
|
/* BL */
|
||||||
instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
||||||
} else if (arch_version >= 0x0803) {
|
} else if (info->arch_version >= 0x0803) {
|
||||||
/* new pointer auth instr for v8.3 arch */
|
/* new pointer auth instr for v8.3 arch */
|
||||||
if ((inst & 0xfffff800) == 0xd73f0800) {
|
if ((inst & 0xfffff800) == 0xd73f0800) {
|
||||||
/* BLRAA, BLRBB */
|
/* BLRAA, BLRBB */
|
||||||
instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
||||||
} else if ((inst & 0xfffff81F) == 0xd63f081F) {
|
} else if ((inst & 0xfffff81F) == 0xd63f081F) {
|
||||||
/* BLRAAZ, BLRBBZ */
|
/* BLRAAZ, BLRBBZ */
|
||||||
instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
|
||||||
} else {
|
} else {
|
||||||
is_branch = 0;
|
is_branch = 0;
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,7 @@
|
|||||||
|
|
||||||
TrcMemAccBufPtr::TrcMemAccBufPtr(const ocsd_vaddr_t s_address, const uint8_t *p_buffer, const uint32_t size) :
|
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),
|
TrcMemAccessorBase(MEMACC_BUFPTR, s_address, s_address+size-1),
|
||||||
m_p_buffer(p_buffer),
|
m_p_buffer(p_buffer)
|
||||||
m_size(size)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,6 +111,7 @@ DecodeTree::~DecodeTree()
|
|||||||
destroyDecodeElement(i);
|
destroyDecodeElement(i);
|
||||||
}
|
}
|
||||||
PktPrinterFact::destroyAllPrinters(m_printer_list);
|
PktPrinterFact::destroyAllPrinters(m_printer_list);
|
||||||
|
delete m_frame_deformatter_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ const std::string ocsdError::getErrorString(const ocsdError &error)
|
|||||||
|
|
||||||
void ocsdError::appendErrorDetails(std::string &errStr, 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();
|
int code = (int)error.getErrorCode();
|
||||||
ocsd_trc_index_t idx = error.getErrorIndex();
|
ocsd_trc_index_t idx = error.getErrorIndex();
|
||||||
uint8_t chan_ID = error.getErrorChanID();
|
uint8_t chan_ID = error.getErrorChanID();
|
||||||
|
196
contrib/opencsd/decoder/source/ocsd_gen_elem_stack.cpp
Normal file
196
contrib/opencsd/decoder/source/ocsd_gen_elem_stack.cpp
Normal 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 */
|
@ -67,6 +67,7 @@ ocsd_datapath_resp_t TrcPktDecodePtm::processPacket()
|
|||||||
case NO_SYNC:
|
case NO_SYNC:
|
||||||
// no sync - output a no sync packet then transition to wait 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.elem_type = OCSD_GEN_TRC_ELEM_NO_SYNC;
|
||||||
|
m_output_elem.unsync_eot_info = m_unsync_info;
|
||||||
resp = outputTraceElement(m_output_elem);
|
resp = outputTraceElement(m_output_elem);
|
||||||
m_curr_state = (m_curr_packet_in->getType() == PTM_PKT_A_SYNC) ? WAIT_ISYNC : WAIT_SYNC;
|
m_curr_state = (m_curr_packet_in->getType() == PTM_PKT_A_SYNC) ? WAIT_ISYNC : WAIT_SYNC;
|
||||||
bPktDone = true;
|
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.
|
// shouldn't be any packets left to be processed - flush shoudl have done this.
|
||||||
// just output the end of trace marker
|
// just output the end of trace marker
|
||||||
m_output_elem.setType(OCSD_GEN_TRC_ELEM_EO_TRACE);
|
m_output_elem.setType(OCSD_GEN_TRC_ELEM_EO_TRACE);
|
||||||
|
m_output_elem.setUnSyncEOTReason(UNSYNC_EOT);
|
||||||
resp = outputTraceElement(m_output_elem);
|
resp = outputTraceElement(m_output_elem);
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
@ -115,6 +117,7 @@ ocsd_datapath_resp_t TrcPktDecodePtm::onEOT()
|
|||||||
ocsd_datapath_resp_t TrcPktDecodePtm::onReset()
|
ocsd_datapath_resp_t TrcPktDecodePtm::onReset()
|
||||||
{
|
{
|
||||||
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
|
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
|
||||||
|
m_unsync_info = UNSYNC_RESET_DECODER;
|
||||||
resetDecoder();
|
resetDecoder();
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
@ -191,6 +194,7 @@ void TrcPktDecodePtm::initDecoder()
|
|||||||
m_instr_info.pe_type.profile = profile_Unknown;
|
m_instr_info.pe_type.profile = profile_Unknown;
|
||||||
m_instr_info.pe_type.arch = ARCH_UNKNOWN;
|
m_instr_info.pe_type.arch = ARCH_UNKNOWN;
|
||||||
m_instr_info.dsb_dmb_waypoints = 0;
|
m_instr_info.dsb_dmb_waypoints = 0;
|
||||||
|
m_unsync_info = UNSYNC_INIT_DECODER;
|
||||||
resetDecoder();
|
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;
|
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
|
||||||
bool bWPFound = false;
|
bool bWPFound = false;
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
|
ocsd_err_t err = OCSD_OK;
|
||||||
|
|
||||||
m_instr_info.instr_addr = m_curr_pe_state.instr_addr;
|
m_instr_info.instr_addr = m_curr_pe_state.instr_addr;
|
||||||
m_instr_info.isa = m_curr_pe_state.isa;
|
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_OK)
|
||||||
{
|
{
|
||||||
if(err == OCSD_ERR_UNSUPPORTED_ISA)
|
if(err == OCSD_ERR_UNSUPPORTED_ISA)
|
||||||
@ -576,7 +584,6 @@ ocsd_datapath_resp_t TrcPktDecodePtm::processAtomRange(const ocsd_atm_val A, con
|
|||||||
break;
|
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.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);
|
m_output_elem.setISA(m_curr_pe_state.isa);
|
||||||
if(m_curr_packet_in->hasCC())
|
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)
|
if(m_output_elem.st_addr != m_output_elem.en_addr)
|
||||||
{
|
{
|
||||||
// some trace before we were out of memory access range
|
// 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.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.setISA(m_curr_pe_state.isa);
|
||||||
m_output_elem.setLastInstrCond(m_instr_info.is_conditional);
|
m_output_elem.setLastInstrCond(m_instr_info.is_conditional);
|
||||||
|
@ -68,6 +68,7 @@ ocsd_datapath_resp_t TrcPktDecodeStm::processPacket()
|
|||||||
{
|
{
|
||||||
case NO_SYNC:
|
case NO_SYNC:
|
||||||
m_output_elem.setType(OCSD_GEN_TRC_ELEM_NO_SYNC);
|
m_output_elem.setType(OCSD_GEN_TRC_ELEM_NO_SYNC);
|
||||||
|
m_output_elem.setUnSyncEOTReason(m_unsync_info);
|
||||||
resp = outputTraceElement(m_output_elem);
|
resp = outputTraceElement(m_output_elem);
|
||||||
m_curr_state = WAIT_SYNC;
|
m_curr_state = WAIT_SYNC;
|
||||||
break;
|
break;
|
||||||
@ -90,6 +91,7 @@ ocsd_datapath_resp_t TrcPktDecodeStm::onEOT()
|
|||||||
{
|
{
|
||||||
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
|
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
|
||||||
m_output_elem.setType(OCSD_GEN_TRC_ELEM_EO_TRACE);
|
m_output_elem.setType(OCSD_GEN_TRC_ELEM_EO_TRACE);
|
||||||
|
m_output_elem.setUnSyncEOTReason(UNSYNC_EOT);
|
||||||
resp = outputTraceElement(m_output_elem);
|
resp = outputTraceElement(m_output_elem);
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
@ -97,6 +99,7 @@ ocsd_datapath_resp_t TrcPktDecodeStm::onEOT()
|
|||||||
ocsd_datapath_resp_t TrcPktDecodeStm::onReset()
|
ocsd_datapath_resp_t TrcPktDecodeStm::onReset()
|
||||||
{
|
{
|
||||||
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
|
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
|
||||||
|
m_unsync_info = UNSYNC_RESET_DECODER;
|
||||||
resetDecoder();
|
resetDecoder();
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
@ -127,7 +130,7 @@ void TrcPktDecodeStm::initDecoder()
|
|||||||
// base decoder state - STM requires no memory and instruction decode.
|
// base decoder state - STM requires no memory and instruction decode.
|
||||||
setUsesMemAccess(false);
|
setUsesMemAccess(false);
|
||||||
setUsesIDecode(false);
|
setUsesIDecode(false);
|
||||||
|
m_unsync_info = UNSYNC_INIT_DECODER;
|
||||||
resetDecoder();
|
resetDecoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,6 +169,7 @@ ocsd_datapath_resp_t TrcPktDecodeStm::decodePacket(bool &bPktDone)
|
|||||||
case STM_PKT_BAD_SEQUENCE: /**< Incorrect protocol sequence */
|
case STM_PKT_BAD_SEQUENCE: /**< Incorrect protocol sequence */
|
||||||
case STM_PKT_RESERVED:
|
case STM_PKT_RESERVED:
|
||||||
resp = OCSD_RESP_FATAL_INVALID_DATA;
|
resp = OCSD_RESP_FATAL_INVALID_DATA;
|
||||||
|
m_unsync_info = UNSYNC_BAD_PACKET;
|
||||||
case STM_PKT_NOTSYNC:
|
case STM_PKT_NOTSYNC:
|
||||||
resetDecoder();
|
resetDecoder();
|
||||||
break;
|
break;
|
||||||
|
@ -41,7 +41,13 @@ class errLogAttachMonitor : public IComponentAttachNotifier
|
|||||||
{
|
{
|
||||||
m_pComp = 0;
|
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)
|
virtual void attachNotify(const int num_attached)
|
||||||
{
|
{
|
||||||
if(m_pComp)
|
if(m_pComp)
|
||||||
@ -73,6 +79,8 @@ TraceComponent::TraceComponent(const std::string &name, int instIDNum)
|
|||||||
|
|
||||||
TraceComponent::~TraceComponent()
|
TraceComponent::~TraceComponent()
|
||||||
{
|
{
|
||||||
|
if (m_pErrAttachMon)
|
||||||
|
delete m_pErrAttachMon;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TraceComponent::Init(const std::string &name)
|
void TraceComponent::Init(const std::string &name)
|
||||||
@ -140,9 +148,7 @@ void TraceComponent::updateErrorLogLevel()
|
|||||||
|
|
||||||
ocsd_err_t TraceComponent::setComponentOpMode(uint32_t op_flags)
|
ocsd_err_t TraceComponent::setComponentOpMode(uint32_t op_flags)
|
||||||
{
|
{
|
||||||
if( (~m_supported_op_flags & op_flags) != 0)
|
m_op_flags = op_flags & m_supported_op_flags;
|
||||||
return OCSD_ERR_INVALID_PARAM_VAL;
|
|
||||||
m_op_flags = op_flags;
|
|
||||||
return OCSD_OK;
|
return OCSD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,10 +34,12 @@
|
|||||||
|
|
||||||
#include "common/trc_core_arch_map.h"
|
#include "common/trc_core_arch_map.h"
|
||||||
|
|
||||||
static struct _ap_map_elements {
|
typedef struct _ap_map_elements {
|
||||||
const char *name;
|
const char *name;
|
||||||
ocsd_arch_profile_t ap;
|
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-A77", { ARCH_V8r3, profile_CortexA } },
|
||||||
{ "Cortex-A76", { 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 } }
|
{ "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()
|
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;
|
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 */
|
/* End of File trc_core_arch_map.cpp */
|
||||||
|
@ -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_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_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_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_NACC","Tracing in inaccessible memory area."},
|
||||||
{"OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN","Tracing unknown address area."},
|
{"OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN","Tracing unknown address area."},
|
||||||
{"OCSD_GEN_TRC_ELEM_EXCEPTION","Exception"},
|
{"OCSD_GEN_TRC_ELEM_EXCEPTION","Exception"},
|
||||||
@ -62,7 +63,8 @@ static const char *instr_type[] = {
|
|||||||
"BR ",
|
"BR ",
|
||||||
"iBR ",
|
"iBR ",
|
||||||
"ISB ",
|
"ISB ",
|
||||||
"DSB.DMB"
|
"DSB.DMB",
|
||||||
|
"WFI.WFE"
|
||||||
};
|
};
|
||||||
|
|
||||||
#define T_SIZE (sizeof(instr_type) / sizeof(const char *))
|
#define T_SIZE (sizeof(instr_type) / sizeof(const char *))
|
||||||
@ -94,10 +96,20 @@ static const char *s_isa_str[] = {
|
|||||||
"Unk" /**< ISA not yet known */
|
"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
|
void OcsdTraceElement::toString(std::string &str) const
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
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;
|
int typeIdx = (int)this->elem_type;
|
||||||
if(typeIdx < num_str)
|
if(typeIdx < num_str)
|
||||||
{
|
{
|
||||||
@ -122,6 +134,11 @@ void OcsdTraceElement::toString(std::string &str) const
|
|||||||
oss << " 0x" << std::hex << st_addr << " ";
|
oss << " 0x" << std::hex << st_addr << " ";
|
||||||
break;
|
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:
|
case OCSD_GEN_TRC_ELEM_EXCEPTION:
|
||||||
if (excep_ret_addr == 1)
|
if (excep_ret_addr == 1)
|
||||||
{
|
{
|
||||||
@ -167,6 +184,12 @@ void OcsdTraceElement::toString(std::string &str) const
|
|||||||
oss << " Numbered:" << std::dec << trace_event.ev_number << "; ";
|
oss << " Numbered:" << std::dec << trace_event.ev_number << "; ";
|
||||||
break;
|
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;
|
default: break;
|
||||||
}
|
}
|
||||||
if(has_cc)
|
if(has_cc)
|
||||||
|
@ -40,10 +40,8 @@ SRCS+= \
|
|||||||
trc_cmp_cfg_etmv4.cpp \
|
trc_cmp_cfg_etmv4.cpp \
|
||||||
trc_etmv4_stack_elem.cpp \
|
trc_etmv4_stack_elem.cpp \
|
||||||
trc_pkt_decode_etmv4i.cpp \
|
trc_pkt_decode_etmv4i.cpp \
|
||||||
trc_pkt_elem_etmv4d.cpp \
|
|
||||||
trc_pkt_elem_etmv4i.cpp \
|
trc_pkt_elem_etmv4i.cpp \
|
||||||
trc_pkt_proc_etmv4.cpp \
|
trc_pkt_proc_etmv4i.cpp
|
||||||
trc_pkt_proc_etmv4i_impl.cpp
|
|
||||||
|
|
||||||
# PKT_PRINTERS
|
# PKT_PRINTERS
|
||||||
SRCS+= \
|
SRCS+= \
|
||||||
@ -75,6 +73,7 @@ SRCS+= \
|
|||||||
ocsd_error.cpp \
|
ocsd_error.cpp \
|
||||||
ocsd_error_logger.cpp \
|
ocsd_error_logger.cpp \
|
||||||
ocsd_gen_elem_list.cpp \
|
ocsd_gen_elem_list.cpp \
|
||||||
|
ocsd_gen_elem_stack.cpp \
|
||||||
ocsd_lib_dcd_register.cpp \
|
ocsd_lib_dcd_register.cpp \
|
||||||
ocsd_msg_logger.cpp \
|
ocsd_msg_logger.cpp \
|
||||||
ocsd_version.cpp \
|
ocsd_version.cpp \
|
||||||
@ -126,9 +125,9 @@ ETMV4INCS= \
|
|||||||
trc_dcd_mngr_etmv4i.h \
|
trc_dcd_mngr_etmv4i.h \
|
||||||
trc_etmv4_stack_elem.h \
|
trc_etmv4_stack_elem.h \
|
||||||
trc_pkt_decode_etmv4i.h \
|
trc_pkt_decode_etmv4i.h \
|
||||||
trc_pkt_elem_etmv4d.h \
|
|
||||||
trc_pkt_elem_etmv4i.h \
|
trc_pkt_elem_etmv4i.h \
|
||||||
trc_pkt_proc_etmv4.h \
|
trc_pkt_proc_etmv4.h \
|
||||||
|
trc_pkt_proc_etmv4i.h \
|
||||||
trc_pkt_types_etmv4.h
|
trc_pkt_types_etmv4.h
|
||||||
|
|
||||||
ETMV4INCSDIR=${INCLUDEDIR}/opencsd/etmv4/
|
ETMV4INCSDIR=${INCLUDEDIR}/opencsd/etmv4/
|
||||||
|
Loading…
Reference in New Issue
Block a user