Import OpenCSD -- an ARM CoreSight(tm) Trace Decode Library.

Sponsored by:	DARPA, AFRL
This commit is contained in:
br 2018-04-04 12:55:31 +00:00
commit 0c2c623a27
140 changed files with 31535 additions and 0 deletions

View File

@ -0,0 +1,63 @@
/*!
* \file comp_attach_notifier_i.h
* \brief OpenCSD : Component attach point notifier interface.
*
* \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_COMP_ATTACH_NOTIFIER_I_H_INCLUDED
#define ARM_COMP_ATTACH_NOTIFIER_I_H_INCLUDED
/*!
* @class IComponentAttachNotifier
* @addtogroup ocsd_infrastructure
* @brief Notification interface for attachment.
*
* Interface to the componentAttachPt classes that allow notification on component
* connect and disconnect.
*/
class IComponentAttachNotifier {
public:
IComponentAttachNotifier() {}; /**< Default interface constructor */
virtual ~IComponentAttachNotifier() {}; /**< Default interface destructor */
/*!
* Callback called by the componentAttachPt() classes when a component is attached
* to or detached from the attach point.
*
* @param num_attached : number of remaining components attached to the point after the
* operation that triggered the notification.
*/
virtual void attachNotify(const int num_attached) = 0;
};
#endif // ARM_COMP_ATTACH_NOTIFIER_I_H_INCLUDED
/* End of File comp_attach_notifier_i.h */

View File

@ -0,0 +1,240 @@
/*!
* \file comp_attach_pt_t.h
* \brief OpenCSD : Component attachment point interface class.
*
* \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_COMP_ATTACH_PT_T_H_INCLUDED
#define ARM_COMP_ATTACH_PT_T_H_INCLUDED
#include <vector>
#include "opencsd/ocsd_if_types.h"
/** @defgroup ocsd_infrastructure OpenCSD Library : Library Component Infrastructure
@brief Classes providing library infrastructure and auxilary functionality
@{*/
#include "comp_attach_notifier_i.h"
/*!
* @class componentAttachPt
* @brief Single component interface pointer attachment point.
*
* This is a class template to standardise the connections between decode components.
*
* An attachment point connects a component interface pointer to the component providing the
* attachment point.
*
* This attachment point implementation allows a single interface to be connected.
*
*/
template <class T>
class componentAttachPt {
public:
componentAttachPt(); /**< Default constructor */
virtual ~componentAttachPt(); /**< Default destructor */
/*!
* Attach an interface of type T to the attachment point.
*
* @param component : interface to attach.
*
* @return ocsd_err_t : OCSD_OK if successful, OCSD_ERR_ATTACH_TOO_MANY if too many connections.
*/
virtual ocsd_err_t attach(T* component);
/*!
* Detach component from the attachment point.
*
* @param component : Component to detach.
*
* @return virtual ocsd_err_t : OCSD_OK if successful, OCSD_ERR_ATTACH_COMP_NOT_FOUND if no match to component.
*/
virtual ocsd_err_t detach(T* component);
// detach current first if anything attached, connect supplied pointer, remain unattached if pointer 0
virtual ocsd_err_t replace_first(T* component);
/*!
* Detach all components.
*/
virtual void detach_all();
/*!
* Return the current (first) attached interface pointer.
* Will return 0 if nothing attached or the attachment point is disabled.
*
* @return T* : Current Interface pointer of type T or 0.
*/
virtual T* first();
/*!
* Return the next attached interface.
* The componentAttachPt base implmentation will always return 0 as only a single attachment is possible
*
* @return T* : Always returns 0.
*/
virtual T* next();
/*!
* Returns the number of interface pointers attached to this attachment point.
*
* @return int : number of component interfaces attached.
*/
virtual int num_attached();
/*!
* Attach a notifier interface to the attachment point. Will call back on this interface whenever
* a component is attached or detached.
*
* @param *notifier : pointer to the IComponentAttachNotifier interface.
*/
void set_notifier(IComponentAttachNotifier *notifier);
/* enable state does not affect attach / detach, but can be used to filter access to interfaces */
const bool enabled() const; /**< return the enabled flag. */
void set_enabled(const bool enable);
/*!
* Check to see if any attachements. Will return attach state independent of enable state.
*
* @return const bool : true if attachment.
*/
const bool hasAttached() const { return m_hasAttached; };
/*!
* Return both the attachment and enabled state.
*
* @return const bool : true if both has attachment and is enabled.
*/
const bool hasAttachedAndEnabled() const { return m_hasAttached && m_enabled; };
protected:
bool m_enabled; /**< Flag to indicate if the attachment point is enabled. */
bool m_hasAttached; /**< Flag indicating at least one attached interface */
IComponentAttachNotifier *m_notifier; /**< Optional attachement notifier interface. */
T *m_comp; /**< pointer to the single attached interface */
};
template<class T> componentAttachPt<T>::componentAttachPt()
{
m_comp = 0;
m_notifier = 0;
m_enabled = true;
m_hasAttached = false;
}
template<class T> componentAttachPt<T>::~componentAttachPt()
{
detach_all();
}
template<class T> ocsd_err_t componentAttachPt<T>::attach(T* component)
{
if(m_comp != 0)
return OCSD_ERR_ATTACH_TOO_MANY;
m_comp = component;
if(m_notifier) m_notifier->attachNotify(1);
m_hasAttached = true;
return OCSD_OK;
}
template<class T> ocsd_err_t componentAttachPt<T>::replace_first(T* component)
{
if(m_hasAttached)
detach(m_comp);
if(component == 0)
return OCSD_OK;
return attach(component);
}
template<class T> ocsd_err_t componentAttachPt<T>::detach(T* component)
{
if(m_comp != component)
return OCSD_ERR_ATTACH_COMP_NOT_FOUND;
m_comp = 0;
m_hasAttached = false;
if(m_notifier) m_notifier->attachNotify(0);
return OCSD_OK;
}
template<class T> T* componentAttachPt<T>::first()
{
return (m_enabled) ? m_comp : 0;
}
template<class T> T* componentAttachPt<T>::next()
{
return 0;
}
template<class T> int componentAttachPt<T>::num_attached()
{
return ((m_comp != 0) ? 1 : 0);
}
template<class T> void componentAttachPt<T>::detach_all()
{
m_comp = 0;
m_hasAttached = false;
if(m_notifier) m_notifier->attachNotify(0);
}
template<class T> void componentAttachPt<T>::set_notifier(IComponentAttachNotifier *notifier)
{
m_notifier = notifier;
}
template<class T> const bool componentAttachPt<T>::enabled() const
{
return m_enabled;
}
template<class T> void componentAttachPt<T>::set_enabled(const bool enable)
{
m_enabled = enable;
}
/** @}*/
#endif // ARM_COMP_ATTACH_PT_T_H_INCLUDED
/* End of File comp_attach_pt_t.h */

View File

@ -0,0 +1,231 @@
/*
* \file ocsd_code_follower.h
* \brief OpenCSD : Code follower for instruction trace decode
*
* \copyright Copyright (c) 2016, 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_OCSD_CODE_FOLLOWER_H_INCLUDED
#define ARM_OCSD_CODE_FOLLOWER_H_INCLUDED
#include "opencsd/ocsd_if_types.h"
#include "opencsd/trc_pkt_types.h"
#include "comp_attach_pt_t.h"
#include "interfaces/trc_tgt_mem_access_i.h"
#include "interfaces/trc_instr_decode_i.h"
/*!
* @class OcsdCodeFollower
* @brief The code follower looks for waypoints or addresses.
*
* Code follower used to determine the trace ranges for Atom or other waypoint
* elements. Uses memory accessor and I decoder to follow the code path.
*
*/
class OcsdCodeFollower
{
public:
OcsdCodeFollower();
~OcsdCodeFollower();
//*********** setup API
void initInterfaces(componentAttachPt<ITargetMemAccess> *pMemAccess, componentAttachPt<IInstrDecode> *pIDecode);
// set information for decode operation - static or occasionally changing settings
// per decode values are passed as parameters into the decode API calls.
void setArchProfile(const ocsd_arch_profile_t profile); //!< core profile
void setMemSpaceAccess(const ocsd_mem_space_acc_t mem_acc_rule); //!< memory space to use for access (filtered by S/NS, EL etc).
void setMemSpaceCSID(const uint8_t csid); //!< memory spaces might be partitioned by CSID
void setISA(const ocsd_isa isa); //!< set the ISA for the decode.
void setDSBDMBasWP(); //!< DSB and DMB can be treated as WP in some archs.
//********** code following API
// standard WP search - for program flow trace
//ocsd_err_t followToAtomWP(idec_res_t &op_result, const ocsd_vaddr_t addrStart, const ocsd_atm_val A);
// PTM exception code may require follow to an address
//ocsd_err_t followToAddress(idec_res_t &op_result, const ocsd_vaddr_t addrStart, const ocsd_atm_val A, const ocsd_vaddr_t addrMatch);
// single instruction atom format such as ETMv3
ocsd_err_t followSingleAtom(const ocsd_vaddr_t addrStart, const ocsd_atm_val A);
// follow N instructions
// ocsd_err_t followNInstructions(idec_res_t &op_result) // ETMv4 Q elements
//*********************** results API
const ocsd_vaddr_t getRangeSt() const; //!< inclusive start address of decoded range (value passed in)
const ocsd_vaddr_t getRangeEn() const; //!< exclusive end address of decoded range (first instruction _not_ executed / potential next instruction).
const bool hasRange() const; //!< we have a valid range executed (may be false if nacc).
const bool hasNextAddr() const; //!< we have calulated the next address - otherwise this is needed from trace packets.
const ocsd_vaddr_t getNextAddr() const; //!< next address - valid if hasNextAddr() true.
// information on last instruction executed in range.
const ocsd_instr_type getInstrType() const; //!< last instruction type
const ocsd_instr_subtype getInstrSubType() const; //!< last instruction sub-type
const bool isCondInstr() const; //!< is a conditional instruction
const bool isLink() const; //!< is a link (branch with link etc)
const bool ISAChanged() const; //!< next ISA different from input ISA.
const ocsd_isa nextISA() const; //!< ISA for next instruction
// information on error conditions
const bool isNacc() const; //!< true if Memory Not Accessible (nacc) error occurred
void clearNacc(); //!< clear the nacc error flag
const ocsd_vaddr_t getNaccAddr() const; //!< get the nacc error address.
private:
bool initFollowerState(); //!< clear all the o/p data and flags, check init valid.
ocsd_err_t decodeSingleOpCode(); //!< decode single opcode address from current m_inst_info packet
ocsd_instr_info m_instr_info;
ocsd_vaddr_t m_st_range_addr; //!< start of excuted range - inclusive address.
ocsd_vaddr_t m_en_range_addr; //!< end of executed range - exclusive address.
ocsd_vaddr_t m_next_addr; //!< calcuated next address (could be eo range of branch address, not set for indirect branches)
bool m_b_next_valid; //!< true if next address valid, false if need address from trace packets.
//! memory space rule to use when accessing memory.
ocsd_mem_space_acc_t m_mem_acc_rule;
//! memory space csid to use when accessing memory.
uint8_t m_mem_space_csid;
ocsd_vaddr_t m_nacc_address; //!< memory address that was inaccessible - failed read @ start, or during follow operation
bool m_b_nacc_err; //!< memory NACC error - required address was unavailable.
//! pointers to the memory access and i decode interfaces.
componentAttachPt<ITargetMemAccess> *m_pMemAccess;
componentAttachPt<IInstrDecode> *m_pIDecode;
};
#endif // ARM_OCSD_CODE_FOLLOWER_H_INCLUDED
//*********** setup API
inline void OcsdCodeFollower::setArchProfile(const ocsd_arch_profile_t profile)
{
m_instr_info.pe_type = profile;
}
inline void OcsdCodeFollower::setMemSpaceAccess(const ocsd_mem_space_acc_t mem_acc_rule)
{
m_mem_acc_rule = mem_acc_rule;
}
inline void OcsdCodeFollower::setMemSpaceCSID(const uint8_t csid)
{
m_mem_space_csid = csid;
}
inline void OcsdCodeFollower::setISA(const ocsd_isa isa)
{
m_instr_info.isa = isa;
}
inline void OcsdCodeFollower::setDSBDMBasWP()
{
m_instr_info.dsb_dmb_waypoints = 1;
}
//**************************************** results API
inline const ocsd_vaddr_t OcsdCodeFollower::getRangeSt() const
{
return m_st_range_addr;
}
inline const ocsd_vaddr_t OcsdCodeFollower::getRangeEn() const
{
return m_en_range_addr;
}
inline const bool OcsdCodeFollower::hasRange() const
{
return m_st_range_addr < m_en_range_addr;
}
inline const bool OcsdCodeFollower::hasNextAddr() const
{
return m_b_next_valid;
}
inline const ocsd_vaddr_t OcsdCodeFollower::getNextAddr() const
{
return m_next_addr;
}
// information on last instruction executed in range.
inline const ocsd_instr_type OcsdCodeFollower::getInstrType() const
{
return m_instr_info.type;
}
inline const ocsd_instr_subtype OcsdCodeFollower::getInstrSubType() const
{
return m_instr_info.sub_type;
}
inline const bool OcsdCodeFollower::isCondInstr() const
{
return (bool)(m_instr_info.is_conditional == 1);
}
inline const bool OcsdCodeFollower::isLink() const
{
return (bool)(m_instr_info.is_link == 1);
}
inline const bool OcsdCodeFollower::ISAChanged() const
{
return (bool)(m_instr_info.isa != m_instr_info.next_isa);
}
inline const ocsd_isa OcsdCodeFollower::nextISA() const
{
return m_instr_info.next_isa;
}
// information on error conditions
inline const bool OcsdCodeFollower::isNacc() const
{
return m_b_nacc_err;
}
inline void OcsdCodeFollower::clearNacc()
{
m_b_nacc_err = false;
}
inline const ocsd_vaddr_t OcsdCodeFollower::getNaccAddr() const
{
return m_nacc_address;
}
/* End of File ocsd_code_follower.h */

View File

@ -0,0 +1,396 @@
/*
* \file ocsd_dcd_mngr.h
* \brief OpenCSD : Decoder manager base class.
*
* \copyright Copyright (c) 2016, 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_OCSD_DCD_MNGR_H_INCLUDED
#define ARM_OCSD_DCD_MNGR_H_INCLUDED
#include "opencsd/ocsd_if_types.h"
#include "common/ocsd_dcd_mngr_i.h"
#include "common/ocsd_lib_dcd_register.h"
#include "common/trc_pkt_decode_base.h"
#include "common/trc_pkt_proc_base.h"
template <class P, class Pt, class Pc>
class DecoderMngrBase : public IDecoderMngr
{
public:
DecoderMngrBase(const std::string &decoderTypeName, ocsd_trace_protocol_t builtInProtocol);
virtual ~DecoderMngrBase() {};
// create decoder interface.
virtual ocsd_err_t createDecoder(const int create_flags, const int instID, const CSConfig *p_config, TraceComponent **p_component);
virtual ocsd_err_t destroyDecoder(TraceComponent *p_component);
virtual const ocsd_trace_protocol_t getProtocolType() const { return m_builtInProtocol; }
// common
virtual ocsd_err_t attachErrorLogger(TraceComponent *pComponent, ITraceErrorLog *pIErrorLog);
// pkt decoder
virtual ocsd_err_t attachInstrDecoder(TraceComponent *pComponent, IInstrDecode *pIInstrDec);
virtual ocsd_err_t attachMemAccessor(TraceComponent *pComponent, ITargetMemAccess *pMemAccessor);
virtual ocsd_err_t attachOutputSink(TraceComponent *pComponent, ITrcGenElemIn *pOutSink);
// pkt processor
virtual ocsd_err_t attachPktMonitor(TraceComponent *pComponent, ITrcTypedBase *pPktRawDataMon);
virtual ocsd_err_t attachPktIndexer(TraceComponent *pComponent, ITrcTypedBase *pPktIndexer);
virtual ocsd_err_t attachPktSink(TraceComponent *pComponent, ITrcTypedBase *pPktDataInSink);
// data input connection interface
virtual ocsd_err_t getDataInputI(TraceComponent *pComponent, ITrcDataIn **ppDataIn);
// generate a Config object from opaque config struct pointer.
virtual ocsd_err_t createConfigFromDataStruct(CSConfig **pConfigBase, const void *pDataStruct);
// implemented by decoder handler derived classes
virtual TraceComponent *createPktProc(const bool useInstID, const int instID) = 0;
virtual TraceComponent *createPktDecode(const bool useInstID, const int instID) { return 0; };
virtual CSConfig *createConfig(const void *pDataStruct) = 0;
private:
ocsd_trace_protocol_t m_builtInProtocol; //!< Protocol ID if built in type.
};
template <class P, class Pt, class Pc>
DecoderMngrBase<P,Pt,Pc>::DecoderMngrBase(const std::string &decoderTypeName, ocsd_trace_protocol_t builtInProtocol)
{
OcsdLibDcdRegister *pDcdReg = OcsdLibDcdRegister::getDecoderRegister();
if(pDcdReg)
pDcdReg->registerDecoderTypeByName(decoderTypeName,this);
m_builtInProtocol = builtInProtocol;
}
template <class P, class Pt, class Pc>
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::createDecoder(const int create_flags, const int instID, const CSConfig *pConfig, TraceComponent **ppTrcComp)
{
TraceComponent *pkt_proc = 0;
TraceComponent *pkt_dcd = 0;
bool bUseInstID = (create_flags & OCSD_CREATE_FLG_INST_ID) != 0;
bool bDecoder = (create_flags & OCSD_CREATE_FLG_FULL_DECODER) != 0;
bool bUnConfigured = (pConfig == 0);
const Pc *pConf = dynamic_cast< const Pc * >(pConfig);
// check inputs valid...
if((pConf == 0) && !bUnConfigured)
return OCSD_ERR_INVALID_PARAM_TYPE;
if((create_flags & (OCSD_CREATE_FLG_PACKET_PROC | OCSD_CREATE_FLG_FULL_DECODER)) == 0)
return OCSD_ERR_INVALID_PARAM_VAL;
// always need a packet processor
pkt_proc = createPktProc(bUseInstID, instID);
if(!pkt_proc)
return OCSD_ERR_MEM;
// set the configuration
TrcPktProcBase<P,Pt,Pc> *pProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> *>(pkt_proc);
if(pProcBase == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
if(!bUnConfigured)
pProcBase->setProtocolConfig(pConf);
*ppTrcComp = pkt_proc;
// may need a packet decoder
if(bDecoder)
{
// create the decoder
pkt_dcd = createPktDecode(bUseInstID, instID);
if(!pkt_dcd)
return OCSD_ERR_MEM;
// get the decoder base
TrcPktDecodeBase<P,Pc> *pBase = dynamic_cast< TrcPktDecodeBase<P,Pc> *>(pkt_dcd);
if(pBase == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
if(!bUnConfigured)
pBase->setProtocolConfig(pConf);
// associate decoder with packet processor
// -> this means a TraceComponent with an associated component is a packet decoder.
// the associated component is the connected packet processor.
pkt_dcd->setAssocComponent(pkt_proc);
// connect packet processor and decoder
pProcBase->getPacketOutAttachPt()->attach(pBase);
*ppTrcComp = pkt_dcd;
}
return OCSD_OK;
}
template <class P, class Pt, class Pc>
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::destroyDecoder(TraceComponent *pComponent)
{
if(pComponent->getAssocComponent() != 0)
delete pComponent->getAssocComponent();
delete pComponent;
return OCSD_OK;
}
template <class P, class Pt, class Pc>
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachErrorLogger(TraceComponent *pComponent, ITraceErrorLog *pIErrorLog)
{
return pComponent->getErrorLogAttachPt()->replace_first(pIErrorLog);
}
template <class P, class Pt, class Pc>
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachInstrDecoder(TraceComponent *pComponent, IInstrDecode *pIInstrDec)
{
ocsd_err_t err = OCSD_ERR_DCD_INTERFACE_UNUSED;
if(pComponent->getAssocComponent() == 0) // no associated component - so this is a packet processor
return OCSD_ERR_INVALID_PARAM_TYPE;
TrcPktDecodeI *pDcdI = dynamic_cast< TrcPktDecodeI * >(pComponent);
if(pDcdI == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
if(pDcdI->getUsesIDecode())
err = pDcdI->getInstrDecodeAttachPt()->replace_first(pIInstrDec);
return err;
}
template <class P, class Pt, class Pc>
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachMemAccessor(TraceComponent *pComponent, ITargetMemAccess *pMemAccessor)
{
ocsd_err_t err = OCSD_ERR_DCD_INTERFACE_UNUSED;
if(pComponent->getAssocComponent() == 0) // no associated component - so this is a packet processor
return OCSD_ERR_INVALID_PARAM_TYPE;
TrcPktDecodeI *pDcdI = dynamic_cast< TrcPktDecodeI * >(pComponent);
if(pDcdI == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
if(pDcdI->getUsesMemAccess())
err = pDcdI->getMemoryAccessAttachPt()->replace_first(pMemAccessor);
return err;
}
template <class P, class Pt, class Pc>
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachOutputSink(TraceComponent *pComponent, ITrcGenElemIn *pOutSink)
{
ocsd_err_t err = OCSD_ERR_INVALID_PARAM_TYPE;
if(pComponent->getAssocComponent() == 0) // no associated component - so this is a packet processor
return err;
TrcPktDecodeI *pDcdI = dynamic_cast< TrcPktDecodeI * >(pComponent);
if(pDcdI == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
err = pDcdI->getTraceElemOutAttachPt()->replace_first(pOutSink);
return err;
}
template <class P, class Pt, class Pc>
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::getDataInputI(TraceComponent *pComponent, ITrcDataIn **ppDataIn)
{
// find the packet processor
TraceComponent *pPktProc = pComponent;
if(pComponent->getAssocComponent() != 0)
pPktProc = pComponent->getAssocComponent();
TrcPktProcI *pPPI = dynamic_cast< TrcPktProcI * >(pPktProc);
if(pPPI == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
*ppDataIn = pPPI;
return OCSD_OK;
}
template <class P, class Pt, class Pc>
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachPktMonitor(TraceComponent *pComponent, ITrcTypedBase *pPktRawDataMon)
{
// find the packet processor
TraceComponent *pPktProc = pComponent;
if(pComponent->getAssocComponent() != 0)
pPktProc = pComponent->getAssocComponent();
// get the packet processor
TrcPktProcBase<P,Pt,Pc> *pPktProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> * >(pPktProc);
if(pPktProcBase == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
// get the interface
IPktRawDataMon<P> *p_If = dynamic_cast< IPktRawDataMon<P> * >(pPktRawDataMon);
if(p_If == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
return pPktProcBase->getRawPacketMonAttachPt()->replace_first(p_If);
}
template <class P, class Pt, class Pc>
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachPktIndexer(TraceComponent *pComponent, ITrcTypedBase *pPktIndexer)
{
// find the packet processor
TraceComponent *pPktProc = pComponent;
if(pComponent->getAssocComponent() != 0)
pPktProc = pComponent->getAssocComponent();
// get the packet processor
TrcPktProcBase<P,Pt,Pc> *pPktProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> * >(pPktProc);
if(pPktProcBase == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
// get the interface
ITrcPktIndexer<Pt> *p_If = dynamic_cast< ITrcPktIndexer<Pt> * >(pPktIndexer);
if(p_If == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
return pPktProcBase->getTraceIDIndexerAttachPt()->replace_first(p_If);
}
template <class P, class Pt, class Pc>
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachPktSink(TraceComponent *pComponent, ITrcTypedBase *pPktDataInSink)
{
// must be solo packet processor
if(pComponent->getAssocComponent() != 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
// interface must be the correct one.
IPktDataIn<P> *pkt_in_i = dynamic_cast< IPktDataIn<P> * >(pPktDataInSink);
if(pkt_in_i == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
// get the packet processor
TrcPktProcBase<P,Pt,Pc> *pPktProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> * >(pComponent);
if(pPktProcBase == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
// attach
return pPktProcBase->getPacketOutAttachPt()->replace_first(pkt_in_i);
}
template <class P, class Pt, class Pc>
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::createConfigFromDataStruct(CSConfig **pConfigBase, const void *pDataStruct)
{
CSConfig *pConfig = createConfig(pDataStruct);
if(!pConfig)
return OCSD_ERR_MEM;
*pConfigBase = pConfig;
return OCSD_OK;
}
/****************************************************************************************************/
/* Full decoder / packet process pair, templated base for creating decoder objects */
/****************************************************************************************************/
template< class P, // Packet class.
class Pt, // Packet enum type ID.
class Pc, // Processor config class.
class PcSt, // Processor config struct type
class PktProc, // Packet processor class.
class PktDcd> // Packet decoder class.
class DecodeMngrFullDcd : public DecoderMngrBase<P,Pt,Pc>
{
public:
DecodeMngrFullDcd (const std::string &name, ocsd_trace_protocol_t builtInProtocol)
: DecoderMngrBase<P,Pt,Pc>(name,builtInProtocol) {};
virtual ~DecodeMngrFullDcd() {};
virtual TraceComponent *createPktProc(const bool useInstID, const int instID)
{
TraceComponent *pComp;
if(useInstID)
pComp = new (std::nothrow) PktProc(instID);
else
pComp = new (std::nothrow) PktProc();
return pComp;
}
virtual TraceComponent *createPktDecode(const bool useInstID, const int instID)
{
TraceComponent *pComp;
if(useInstID)
pComp = new (std::nothrow)PktDcd(instID);
else
pComp = new (std::nothrow)PktDcd();
return pComp;
}
virtual CSConfig *createConfig(const void *pDataStruct)
{
return new (std::nothrow) Pc((PcSt *)pDataStruct);
}
};
/****************************************************************************************************/
/* Packet processor only, templated base for creating decoder objects */
/****************************************************************************************************/
template< class P, // Packet class.
class Pt, // Packet enum type ID.
class Pc, // Processor config class.
class PcSt, // Processor config struct type
class PktProc> // Packet processor class.
class DecodeMngrPktProc : public DecoderMngrBase<P,Pt,Pc>
{
public:
DecodeMngrPktProc (const std::string &name, ocsd_trace_protocol_t builtInProtocol)
: DecoderMngrBase<P,Pt,Pc>(name,builtInProtocol) {};
virtual ~DecodeMngrPktProc() {};
virtual TraceComponent *createPktProc(const bool useInstID, const int instID)
{
TraceComponent *pComp;
if(useInstID)
pComp = new (std::nothrow) PktProc(instID);
else
pComp = new (std::nothrow) PktProc();
return pComp;
}
virtual CSConfig *createConfig(const void *pDataStruct)
{
return new (std::nothrow) Pc((PcSt *)pDataStruct);
}
};
#endif // ARM_OCSD_DCD_MNGR_H_INCLUDED
/* End of File ocsd_dcd_mngr.h */

View File

@ -0,0 +1,98 @@
/*
* \file ocsd_dcd_mngr_i.h
* \brief OpenCSD : Decoder manager interface.
*
* \copyright Copyright (c) 2016, 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_OCSD_DCD_MNGR_I_H_INCLUDED
#define ARM_OCSD_DCD_MNGR_I_H_INCLUDED
#include "opencsd/ocsd_if_types.h"
#include "common/trc_cs_config.h"
#include "common/trc_component.h"
#include "interfaces/trc_error_log_i.h"
#include "interfaces/trc_data_raw_in_i.h"
#include "interfaces/trc_instr_decode_i.h"
#include "interfaces/trc_tgt_mem_access_i.h"
#include "interfaces/trc_gen_elem_in_i.h"
#include "interfaces/trc_abs_typed_base_i.h"
class IDecoderMngr
{
public:
IDecoderMngr() {};
virtual ~IDecoderMngr() {};
// create and destroy decoders
virtual ocsd_err_t createDecoder(const int create_flags, const int instID, const CSConfig *p_config, TraceComponent **ppComponent) = 0;
virtual ocsd_err_t destroyDecoder(TraceComponent *pComponent) = 0;
//! Get the built in protocol type ID managed by this instance - extern for custom decoders
virtual const ocsd_trace_protocol_t getProtocolType() const = 0;
// connect decoders to other components - (replace current / 0 pointer value to detach );
// compatible with all decoders
//!attach error logger to ptk-processor, or both of pkt processor and pkt decoder pair
virtual ocsd_err_t attachErrorLogger(TraceComponent *pComponent, ITraceErrorLog *pIErrorLog) = 0;
// pkt decoder only
//! attach instruction decoder to pkt decoder
virtual ocsd_err_t attachInstrDecoder(TraceComponent *pComponent, IInstrDecode *pIInstrDec) = 0;
//! attach memory accessor to pkt decoder
virtual ocsd_err_t attachMemAccessor(TraceComponent *pComponent, ITargetMemAccess *pMemAccessor) = 0;
//! attach generic output interface to pkt decoder
virtual ocsd_err_t attachOutputSink(TraceComponent *pComponent, ITrcGenElemIn *pOutSink) = 0;
// pkt processor only
//! attach a raw packet monitor to pkt processor (solo pkt processor, or pkt processor part of pair)
virtual ocsd_err_t attachPktMonitor(TraceComponent *pComponent, ITrcTypedBase *pPktRawDataMon) = 0;
//! attach a packet indexer to pkt processor (solo pkt processor, or pkt processor part of pair)
virtual ocsd_err_t attachPktIndexer(TraceComponent *pComponent, ITrcTypedBase *pPktIndexer) = 0;
//! attach a packet data sink to pkt processor output (solo pkt processor only - instead of decoder when pkt processor only created.)
virtual ocsd_err_t attachPktSink(TraceComponent *pComponent, ITrcTypedBase *pPktDataInSink) = 0;
// data input connection interface
//! get raw data input interface from packet processor
virtual ocsd_err_t getDataInputI(TraceComponent *pComponent, ITrcDataIn **ppDataIn) = 0;
// create configuration from data structure
virtual ocsd_err_t createConfigFromDataStruct(CSConfig **pConfigBase, const void *pDataStruct) = 0;
};
#endif // ARM_OCSD_DCD_MNGR_I_H_INCLUDED
/* End of File ocsd_dcd_mngr.h */

View File

@ -0,0 +1,406 @@
/*!
* \file ocsd_dcd_tree.h
* \brief OpenCSD : Trace Decode Tree.
*
* \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_OCSD_DCD_TREE_H_INCLUDED
#define ARM_OCSD_DCD_TREE_H_INCLUDED
#include <vector>
#include <list>
#include "opencsd.h"
#include "ocsd_dcd_tree_elem.h"
/** @defgroup dcd_tree OpenCSD Library : Trace Decode Tree.
@brief Create a multi source decode tree for a single trace capture buffer.
Use to create a connected set of decoder objects to decode a trace buffer.
There may be multiple trace sources within the capture buffer.
@{*/
/*!
* @class DecodeTree
* @brief Class to manage the decoding of data from a single trace sink .
*
* Provides functionality to build a tree of decode objects capable of decoding
* multiple trace sources within a single trace sink (capture buffer).
*
*/
class DecodeTree : public ITrcDataIn
{
public:
/** @name Creation and Destruction
@{*/
DecodeTree(); //!< default constructor
~DecodeTree(); //!< default destructor
/*!
* @brief Create a decode tree.
* Automatically creates a trace frame deformatter if required and a default error log component.
*
* @param src_type : Data stream source type, can be CoreSight frame formatted trace, or single demuxed trace data stream,
* @param formatterCfgFlags : Configuration flags for trace de-formatter.
*
* @return DecodeTree * : pointer to the decode tree, 0 if creation failed.
*/
static DecodeTree *CreateDecodeTree(const ocsd_dcd_tree_src_t src_type, const uint32_t formatterCfgFlags);
/** @brief Destroy a decode tree */
static void DestroyDecodeTree(DecodeTree *p_dcd_tree);
/** @}*/
/** @name Error and element Logging
@{*/
/** @brief The library default error logger */
static ocsdDefaultErrorLogger* getDefaultErrorLogger() { return &s_error_logger; };
/** the current error logging interface in use */
static ITraceErrorLog *getCurrentErrorLogI() { return s_i_error_logger; };
/** set an alternate error logging interface. */
static void setAlternateErrorLogger(ITraceErrorLog *p_error_logger);
/** get the list of packet printers for this decode tree */
std::vector<ItemPrinter *> &getPrinterList() { return m_printer_list; };
/** add a protocol packet printer */
ocsd_err_t addPacketPrinter(uint8_t CSID, bool bMonitor, ItemPrinter **ppPrinter);
/** add a raw frame printer */
ocsd_err_t addRawFramePrinter(RawFramePrinter **ppPrinter, uint32_t flags);
/** add a generic element output printer */
ocsd_err_t addGenElemPrinter(TrcGenericElementPrinter **ppPrinter);
/** @}*/
/** @name Trace Data Path
@{*/
/** @brief Trace Data input interface (ITrcDataIn)
Decode tree implements the data in interface : ITrcDataIn .
Captured raw trace data is passed into the deformatter and decoders via this method.
*/
virtual ocsd_datapath_resp_t TraceDataIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed);
/*!
* @brief Decoded Trace output.
*
* Client trace analysis program attaches a generic trace element interface to
* receive the output from the trace decode operations.
*
* @param *i_gen_trace_elem : Pointer to the interface.
*/
void setGenTraceElemOutI(ITrcGenElemIn *i_gen_trace_elem);
/*! @brief Return the connected generic element interface */
ITrcGenElemIn *getGenTraceElemOutI() const { return m_i_gen_elem_out; };
/** @}*/
/** @name Decoder Management
@{*/
/*!
* Creates a decoder that is registered with the library under the supplied name.
* createFlags determine if a full packet processor / packet decoder pair or
* packet processor only is created.
* Uses the supplied configuration structure.
*
* @param &decoderName : registered name of decoder
* @param createFlags : Decoder creation options.
* @param *pConfig : Pointer to a valid configuration structure for the named decoder.
*
* @return ocsd_err_t : Library error code or OCSD_OK if successful.
*/
ocsd_err_t createDecoder(const std::string &decoderName, const int createFlags, const CSConfig *pConfig);
/* */
/*!
* Remove a decoder / packet processor attached to an Trace ID output on the frame de-mux.
*
* Once removed another decoder can be created that has a CSConfig using that ID.
*
* @param CSID : Trace ID to remove.
*
* @return ocsd_err_t : Library error code or OCSD_OK if successful.
*/
ocsd_err_t removeDecoder(const uint8_t CSID);
/* get decoder elements currently in use */
/*!
* Find a decode tree element associated with a specific CoreSight trace ID. *
*/
DecodeTreeElement *getDecoderElement(const uint8_t CSID) const;
/* iterate decoder elements */
/*!
* Decode tree iteration. Return the first tree element 0 if no elements avaiable.
*
* @param &elemID : CoreSight Trace ID associated with this element
*/
DecodeTreeElement *getFirstElement(uint8_t &elemID);
/*!
* Return the next tree element - or 0 if no futher elements avaiable.
*
* @param &elemID : CoreSight Trace ID associated with this element
*/
DecodeTreeElement *getNextElement(uint8_t &elemID);
/* set key interfaces - attach / replace on any existing tree components */
/*!
* Set an ARM instruction opcode decoder.
*
* @param *i_instr_decode : Pointer to the interface.
*/
void setInstrDecoder(IInstrDecode *i_instr_decode);
/*!
* Set a target memory access interface - used to access program image memory for instruction
* trace decode.
*
* @param *i_mem_access : Pointer to the interface.
*/
void setMemAccessI(ITargetMemAccess *i_mem_access);
/** @}*/
/** @name Memory Access Mapper
A memory mapper is used to organise a collection of memory accessor objects that contain the
memory images for different areas of traced instruction memory. These areas could be the executed
program and a set of loaded .so libraries for example - each of which would have code sections in
different memory locations.
A memory accessor represents a snapshot of an area of memory as it appeared during trace capture,
for a given memory space. Memory spaces are described by the ocsd_mem_space_acc_t enum. The most
general memory space is OCSD_MEM_SPACE_ANY. This represents memory that can be secure or none-secure,
available at any exception level.
The memory mapper will not allow two accessors to overlap in the same memory space.
The trace decdoer will access memory with a memory space parameter that represents the current core
state - the mapper will find the closest memory space match for the address.
e.g. if the core is accessing secure EL3, then the most specialised matching space will be accessed.
If an EL3 space matches that will be used, otherwise the any secure, and finally _ANY.
It is no necessary for clients to register memory accessors for all spaces - _ANY will be sufficient
in many cases.
@{*/
/* */
/*!
* This creates a memory mapper within the decode tree.
*
* @param type : defaults to MEMACC_MAP_GLOBAL (only type available at present)
*
* @return ocsd_err_t : Library error code or OCSD_OK if successful.
*/
ocsd_err_t createMemAccMapper(memacc_mapper_t type = MEMACC_MAP_GLOBAL);
/*!
* Get a pointer to the memory mapper. Allows a client to add memory accessors directly to the mapper.
* @return TrcMemAccMapper : Pointer to the mapper.
*/
TrcMemAccMapper *getMemAccMapper() const { return m_default_mapper; };
/*!
* Set an external mapper rather than create a mapper in the decode tree.
* Setting this will also destroy any internal mapper that was previously created.
*
* @param pMapper : pointer to the mapper to add.
*/
void setExternMemAccMapper(TrcMemAccMapper * pMapper);
/*!
* Return true if a mapper has been set (internal or external
*/
const bool hasMemAccMapper() const { return (bool)(m_default_mapper != 0); };
void logMappedRanges(); //!< Log the mapped memory ranges to the default message logger.
/** @}*/
/** @name Memory Accessors
A memory accessor represents a snapshot of an area of memory as it appeared during trace capture.
Memory spaces represent either common global memory, or Secure / none-secure and EL specific spaces.
@{*/
/*!
* Creates a memory accessor for a memory block in the supplied buffer and adds to the current mapper.
*
* @param address : Start address for the memory block in the memory map.
* @param mem_space : Memory space
* @param *p_mem_buffer : start of the buffer.
* @param mem_length : length of the buffer.
*
* @return ocsd_err_t : Library error code or OCSD_OK if successful.
*/
ocsd_err_t addBufferMemAcc(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t *p_mem_buffer, const uint32_t mem_length);
/*!
* Creates a memory accessor for a memory block supplied as a contiguous binary data file, and adds to the current mapper.
*
* @param address : Start address for the memory block in the memory map.
* @param mem_space : Memory space
* @param &filepath : Path to the binary data file
*
* @return ocsd_err_t : Library error code or OCSD_OK if successful.
*/
ocsd_err_t addBinFileMemAcc(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const std::string &filepath);
/*!
* Creates a memory accessor for a memory block supplied as a one or more memory regions in a binary file.
* Region structures are created that describe the memory start address, the offset within the binary file
* for that address, and the length of the region. This accessor can be used to point to the code section
* in a program file for example.
*
* @param *region_array : array of valid memory regions in the file.
* @param num_regions : number of regions
* @param mem_space : Memory space
* @param &filepath : Path to the binary data file
*
* @return ocsd_err_t : Library error code or OCSD_OK if successful.
*/
ocsd_err_t addBinFileRegionMemAcc(const ocsd_file_mem_region_t *region_array, const int num_regions, const ocsd_mem_space_acc_t mem_space, const std::string &filepath);
/*!
* This memory accessor allows the client to supply a callback function for the region
* defined by the start and end addresses. This can be used to supply a custom memory accessor,
* or to directly access memory if the decode is running live on a target system.
*
* @param st_address : start address of region.
* @param en_address : end address of region.
* @param mem_space : Memory space
* @param p_cb_func : Callback function
* @param *p_context : client supplied context information
*
* @return ocsd_err_t : Library error code or OCSD_OK if successful.
*/
ocsd_err_t addCallbackMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, const ocsd_mem_space_acc_t mem_space, Fn_MemAcc_CB p_cb_func, const void *p_context);
/*!
* Remove the memory accessor from the map, that begins at the given address, for the memory space provided.
*
* @param address : Start address of the memory accessor.
* @param mem_space : Memory space for the memory accessor.
*
* @return ocsd_err_t : Library error code or OCSD_OK if successful.
*/
ocsd_err_t removeMemAccByAddress(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space);
/** @}*/
/** @name CoreSight Trace Frame De-mux
@{*/
//! Get the Trace Frame de-mux.
TraceFormatterFrameDecoder *getFrameDeformatter() const { return m_frame_deformatter_root; };
/*! @brief ID filtering - sets the output filter on the trace deformatter.
Only supplied IDs will be decoded.
No effect if no decoder attached for the ID
@param ids : Vector of CS Trace IDs
*/
ocsd_err_t setIDFilter(std::vector<uint8_t> &ids); // only supplied IDs will be decoded
ocsd_err_t clearIDFilter(); //!< remove filter, all IDs will be decoded
/** @}*/
private:
bool initialise(const ocsd_dcd_tree_src_t type, uint32_t formatterCfgFlags);
const bool usingFormatter() const { return (bool)(m_dcd_tree_type == OCSD_TRC_SRC_FRAME_FORMATTED); };
void setSingleRoot(TrcPktProcI *pComp);
ocsd_err_t createDecodeElement(const uint8_t CSID);
void destroyDecodeElement(const uint8_t CSID);
void destroyMemAccMapper();
ocsd_dcd_tree_src_t m_dcd_tree_type;
IInstrDecode *m_i_instr_decode;
ITargetMemAccess *m_i_mem_access;
ITrcGenElemIn *m_i_gen_elem_out; //!< Output interface for generic elements from decoder.
ITrcDataIn* m_i_decoder_root; /*!< root decoder object interface - either deformatter or single packet processor */
TraceFormatterFrameDecoder *m_frame_deformatter_root;
DecodeTreeElement *m_decode_elements[0x80];
uint8_t m_decode_elem_iter;
TrcMemAccMapper *m_default_mapper; //!< the mem acc mapper to use
bool m_created_mapper; //!< true if created by decode tree object
std::vector<ItemPrinter *> m_printer_list; //!< list of packet printers.
/* global error logger - all sources */
static ITraceErrorLog *s_i_error_logger;
static std::list<DecodeTree *> s_trace_dcd_trees;
/**! default error logger */
static ocsdDefaultErrorLogger s_error_logger;
/**! default instruction decoder */
static TrcIDecode s_instruction_decoder;
};
/** @}*/
#endif // ARM_OCSD_DCD_TREE_H_INCLUDED
/* End of File ocsd_dcd_tree.h */

View File

@ -0,0 +1,112 @@
/*!
* \file ocsd_dcd_tree_elem.h
* \brief OpenCSD : Decode tree element.
*
* \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_OCSD_DCD_TREE_ELEM_H_INCLUDED
#define ARM_OCSD_DCD_TREE_ELEM_H_INCLUDED
#include "common/ocsd_dcd_mngr_i.h"
#include "common/trc_component.h"
/** @addtogroup dcd_tree
@{*/
/*! @struct _decoder_elements
* @brief Decode tree element base structure.
*
* Element describes the protocol supported for this element and
* contains pointers to the decoder manager interface and component handle.
*/
typedef struct _decoder_elements
{
std::string dcd_name; //!< Registered name of the decoder
TraceComponent *dcd_handle; //!< handle to the decoder object
IDecoderMngr *dcd_mngr; //!< pointer to the decoder manager interface for the decodcer
ocsd_trace_protocol_t protocol;//!< protocol type
bool created; /**< decode tree created this element (destroy it on tree destruction) */
} decoder_element;
/*!
* @class DecodeTreeElement
* @brief Decode tree element
*
* Decoder tree elements are references to individual decoders in the tree.
* These allow iteration of all decoders in the tree to perform common operations.
*
* The DecodeTree contains a list of elements.
*/
class DecodeTreeElement : protected decoder_element
{
public:
DecodeTreeElement();
~DecodeTreeElement() {};
void SetDecoderElement(const std::string &name, IDecoderMngr *dcdMngr, TraceComponent *pHandle, bool bCreated);
void DestroyElem();
const std::string &getDecoderTypeName() { return dcd_name; };
IDecoderMngr *getDecoderMngr() { return dcd_mngr; };
ocsd_trace_protocol_t getProtocol() const { return protocol; };
TraceComponent *getDecoderHandle() { return dcd_handle; };
};
inline DecodeTreeElement::DecodeTreeElement()
{
dcd_name = "unknown";
dcd_mngr = 0;
dcd_handle = 0;
protocol = OCSD_PROTOCOL_END;
created = false;
}
inline void DecodeTreeElement::SetDecoderElement(const std::string &name, IDecoderMngr *dcdMngr, TraceComponent *pHandle, bool bCreated)
{
dcd_name = name;
dcd_mngr = dcdMngr;
dcd_handle = pHandle;
protocol = OCSD_PROTOCOL_UNKNOWN;
if(dcd_mngr)
protocol = dcd_mngr->getProtocolType();
created = bCreated;
}
inline void DecodeTreeElement::DestroyElem()
{
if(created && (dcd_mngr != 0) && (dcd_handle != 0))
dcd_mngr->destroyDecoder(dcd_handle);
}
/** @}*/
#endif // ARM_OCSD_DCD_TREE_ELEM_H_INCLUDED
/* End of File ocsd_dcd_tree_elem.h */

View File

@ -0,0 +1,116 @@
/*!
* \file ocsd_error.h
* \brief OpenCSD : Library Error class
*
* \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_OCSD_ERROR_H_INCLUDED
#define ARM_OCSD_ERROR_H_INCLUDED
#include "opencsd/ocsd_if_types.h"
#include <string>
/** @ingroup ocsd_infrastructure
@{*/
/*!
* @class ocsdError
*
* This class is the error object for the Ocsd.
*
* Errors are created with a severity (ocsd_err_severity_t) and a standard ocsd_err_t error code.
* Errors can optionally be created with a trace index (offset from start of capture buffer), and
* trace CoreSight source channel ID.
*
* A custom error message can be appended to the error.
*
* The ocsdError class contains a static function to output a formatted string representation of an error.
*
*/
class ocsdError {
public:
ocsdError(const ocsd_err_severity_t sev_type, const ocsd_err_t code); /**< Default error constructor with severity and error code. */
ocsdError(const ocsd_err_severity_t sev_type, const ocsd_err_t code, const ocsd_trc_index_t idx); /**< Constructor with optional trace index. */
ocsdError(const ocsd_err_severity_t sev_type, const ocsd_err_t code, const ocsd_trc_index_t idx, const uint8_t chan_id); /**< Constructor with optional trace index and channel ID. */
ocsdError(const ocsd_err_severity_t sev_type, const ocsd_err_t code, const std::string &msg); /**< Default error constructor with severity and error code - plus message. */
ocsdError(const ocsd_err_severity_t sev_type, const ocsd_err_t code, const ocsd_trc_index_t idx, const std::string &msg); /**< Constructor with optional trace index - plus message. */
ocsdError(const ocsd_err_severity_t sev_type, const ocsd_err_t code, const ocsd_trc_index_t idx, const uint8_t chan_id, const std::string &msg); /**< Constructor with optional trace index and channel ID - plus message. */
ocsdError(const ocsdError *pError); /**< Copy constructor */
ocsdError(const ocsdError &Error); /**< Copy constructor */
~ocsdError(); /**< Destructor */
ocsdError& operator=(const ocsdError *p_err);
ocsdError& operator=(const ocsdError &err);
void setMessage(const std::string &msg) { m_err_message = msg; }; /**< Set custom error message */
const std::string &getMessage() const { return m_err_message; }; /**< Get custom error message */
const ocsd_err_t getErrorCode() const { return m_error_code; }; /**< Get error code. */
const ocsd_err_severity_t getErrorSeverity() const { return m_sev; }; /**< Get error severity. */
const ocsd_trc_index_t getErrorIndex() const { return m_idx; }; /**< Get trace index associated with the error. */
const uint8_t getErrorChanID() const { return m_chan_ID; }; /**< Get the trace source channel ID associated with the error. */
static const std::string getErrorString(const ocsdError &error); /**< Generate a formatted error string for the supplied error. */
private:
static void appendErrorDetails(std::string &errStr, const ocsdError &error); /**< build the error string. */
ocsdError(); /**< Make no parameter default constructor inaccessible. */
ocsd_err_t m_error_code; /**< Error code for this error */
ocsd_err_severity_t m_sev; /**< severity for this error */
ocsd_trc_index_t m_idx; /**< Trace buffer index associated with this error (optional) */
uint8_t m_chan_ID; /**< trace source ID associated with this error (optional) */
std::string m_err_message; /**< Additional text associated with this error (optional) */
};
inline ocsdError& ocsdError::operator=(const ocsdError *p_err)
{
this->m_error_code = p_err->getErrorCode();
this->m_sev = p_err->getErrorSeverity();
this->m_idx = p_err->getErrorIndex();
this->m_chan_ID = p_err->getErrorChanID();
this->m_err_message = p_err->getMessage();
return *this;
}
inline ocsdError& ocsdError::operator=(const ocsdError &err)
{
return (*this = &err);
}
/** @}*/
#endif // ARM_OCSD_ERROR_H_INCLUDED
/* End of File ocsd_error.h */

View File

@ -0,0 +1,89 @@
/*!
* \file ocsd_error_logger.h
* \brief OpenCSD : Library error logger.
*
* \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_OCSD_ERROR_LOGGER_H_INCLUDED
#define ARM_OCSD_ERROR_LOGGER_H_INCLUDED
#include <string>
#include <vector>
#include <fstream>
#include "interfaces/trc_error_log_i.h"
#include "ocsd_error.h"
#include "ocsd_msg_logger.h"
class ocsdDefaultErrorLogger : public ITraceErrorLog
{
public:
ocsdDefaultErrorLogger();
virtual ~ocsdDefaultErrorLogger();
bool initErrorLogger(const ocsd_err_severity_t verbosity, bool bCreateOutputLogger = false);
virtual ocsdMsgLogger *getOutputLogger() { return m_output_logger; };
virtual void setOutputLogger(ocsdMsgLogger *pLogger);
virtual const ocsd_hndl_err_log_t RegisterErrorSource(const std::string &component_name);
virtual void LogError(const ocsd_hndl_err_log_t handle, const ocsdError *Error);
virtual void LogMessage(const ocsd_hndl_err_log_t handle, const ocsd_err_severity_t filter_level, const std::string &msg );
virtual const ocsd_err_severity_t GetErrorLogVerbosity() const { return m_Verbosity; };
virtual ocsdError *GetLastError() { return m_lastErr; };
virtual ocsdError *GetLastIDError(const uint8_t chan_id)
{
if(OCSD_IS_VALID_CS_SRC_ID(chan_id))
return m_lastErrID[chan_id];
return 0;
};
private:
void CreateErrorObj(ocsdError **ppErr, const ocsdError *p_from);
ocsdError *m_lastErr;
ocsdError *m_lastErrID[0x80];
ocsd_err_severity_t m_Verbosity;
ocsdMsgLogger *m_output_logger; // pointer to a standard message output logger;
bool m_created_output_logger; // true if this class created it's own logger;
std::vector<std::string> m_error_sources;
};
#endif // ARM_OCSD_ERROR_LOGGER_H_INCLUDED
/* End of File ocsd_error_logger.h */

View File

@ -0,0 +1,153 @@
/*
* \file ocsd_gen_elem_stack.h
* \brief OpenCSD : Generic element output stack.
*
* \copyright Copyright (c) 2016, 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 <list>
#include "trc_gen_elem.h"
#include "comp_attach_pt_t.h"
#include "interfaces/trc_gen_elem_in_i.h"
/*!
* @class OcsdGenElemList
* @brief Maintain a list of elements to be output
*
* Each incoming packet can result in multiple output elements.
* These are stacked in this class prior to entering the output phase of processing.
*
* This should remove some of the requirement on the packet processing to be re-enterant,
* simplifying this code.
*
* Last element(s) on this stack can be marked pending to allow for later cancellation.
* (This required for cancel element in ETMv3 exeception branch).
*
* The "list" is actually a ring buffer - maintaining pointers to indicate current valid elements.
* This buffer can increase on demand, but will only be released at the end of a decode session.
*/
class OcsdGenElemList
{
public:
OcsdGenElemList();
~OcsdGenElemList();
void initSendIf(componentAttachPt<ITrcGenElemIn> *pGenElemIf);
void initCSID(const uint8_t CSID) { m_CSID = CSID; };
void reset(); //!< reset the element list.
OcsdTraceElement *getNextElem(const ocsd_trc_index_t trc_pkt_idx); //!< get next free element on the stack (add one to the output)
const int getNumElem() const; //!< return the total number of elements on the stack (inlcuding any pended ones).
const ocsd_gen_trc_elem_t getElemType(const int entryN) const; //!< get the type for the nth element in the stack (0 indexed)
void pendLastNElem(int numPend); //!< Last element to be pended prior to cancel/commit decision.
void commitAllPendElem(); //!< commit all pended elements.
void cancelPendElem(); //!< cancel the last pended element on the stack.
const int numPendElem() const; //!< return the number of pended elements.
/*! Send all of the none pended elements
Stop sending when all sent or _CONT response.
*/
ocsd_datapath_resp_t sendElements();
const bool elemToSend() const; //!< true if any none-pending elements left to send.
private:
void growArray();
const int getAdjustedIdx(int idxIn) const; //!< get adjusted index into circular buffer.
// list element contains pointer and byte index in trace stream
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;
elemPtr_t *m_pElemArray; //!< an array of pointers to elements.
int m_elemArraySize; //!< number of element pointers in the array
int m_firstElemIdx; //!< internal index in array of first element in use.
int m_numUsed; //!< number of elements in use
int m_numPend; //!< internal count of pended elements.
uint8_t m_CSID;
componentAttachPt<ITrcGenElemIn> *m_sendIf; //!< element send interface.
};
inline const int OcsdGenElemList::getAdjustedIdx(int idxIn) const
{
if(idxIn >= m_elemArraySize)
idxIn -= m_elemArraySize;
return idxIn;
}
inline const int OcsdGenElemList::getNumElem() const
{
return m_numUsed;
}
inline const int OcsdGenElemList::numPendElem() const
{
return m_numPend;
}
inline void OcsdGenElemList::pendLastNElem(int numPend)
{
if(numPend >= getNumElem())
m_numPend = numPend;
}
inline void OcsdGenElemList::commitAllPendElem()
{
m_numPend = 0;
}
inline void OcsdGenElemList::cancelPendElem()
{
if(m_numPend > 0)
{
m_numUsed -= m_numPend;
}
}
inline const bool OcsdGenElemList::elemToSend() const
{
return ((getNumElem() - m_numPend) > 0);
}
inline void OcsdGenElemList::initSendIf(componentAttachPt<ITrcGenElemIn> *pGenElemIf)
{
m_sendIf = pGenElemIf;
}
/* End of File ocsd_gen_elem_stack.h */

View File

@ -0,0 +1,131 @@
/*
* \file ocsd_lib_dcd_register.h
* \brief OpenCSD : Library decoder registration and management.
*
* \copyright Copyright (c) 2016, ARM Limited. All Rights Reserved.
*/
#ifndef ARM_OCSD_LIB_DCD_REGISTER_H_INCLUDED
#define ARM_OCSD_LIB_DCD_REGISTER_H_INCLUDED
/*
* 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 <map>
#include "opencsd/ocsd_if_types.h"
#include "common/ocsd_dcd_mngr_i.h"
/*!
* @class OcsdLibDcdRegister : Registers decoders with the library
*
* library decoder register class allows decoders to be registered by name, and the register allows clients to access
* the list of names of registerd decoders.
*
* The decoders in the library are accessed through the decoder manager interface. This provides a set of functions to allow
* the creation, manipulation and destruction of registered decoders
*
*/
class OcsdLibDcdRegister
{
public:
static OcsdLibDcdRegister *getDecoderRegister();
static void deregisterAllDecoders(); //!< library cleanup - deregisters decoder managers and destroys the register object.
static const ocsd_trace_protocol_t getNextCustomProtocolID();
static void releaseLastCustomProtocolID();
const ocsd_err_t registerDecoderTypeByName(const std::string &name, IDecoderMngr *p_decoder_fact); //!< register a decoder manager interface
const ocsd_err_t getDecoderMngrByName(const std::string &name, IDecoderMngr **p_decoder_mngr);
const ocsd_err_t getDecoderMngrByType(const ocsd_trace_protocol_t decoderType, IDecoderMngr **p_decoder_mngr);
const bool isRegisteredDecoder(const std::string &name);
const bool getFirstNamedDecoder(std::string &name);
const bool getNextNamedDecoder(std::string &name);
const bool isRegisteredDecoderType(const ocsd_trace_protocol_t decoderType);
private:
void registerBuiltInDecoders(); //!< register the list of build in decoder managers on first access of getDecoderMngrByName.
void deRegisterCustomDecoders(); //!< delete all custom decoders registered with the library.
std::map<const std::string, IDecoderMngr *> m_decoder_mngrs; //!< map linking names to decoder manager interfaces.
std::map<const std::string, IDecoderMngr *>::const_iterator m_iter; //!< iterator for name search.
std::map<const ocsd_trace_protocol_t, IDecoderMngr *> m_typed_decoder_mngrs; //!< map linking decoder managers to protocol type ID
// cache last found by type to speed up repeated quries on same object.
IDecoderMngr *m_pLastTypedDecoderMngr; //!< last manager we found by type
// singleton pattern - need just one of these in the library - ensure all default constructors are private.
OcsdLibDcdRegister();
OcsdLibDcdRegister(OcsdLibDcdRegister const &) {};
OcsdLibDcdRegister& operator=(OcsdLibDcdRegister const &){ return *this; };
~OcsdLibDcdRegister();
static OcsdLibDcdRegister *m_p_libMngr;
static bool m_b_registeredBuiltins;
static ocsd_trace_protocol_t m_nextCustomProtocolID;
};
/*!
* Typedef of function signature to create a decoder manager.
*
* @param *name : Registered name of the decoder.
*/
typedef IDecoderMngr *(*CreateMngr)(const std::string &name);
/*!
* Template function to create a specific decoder manager class object.
*
* @param &name : Registered name of the decoder.
*
* @return IDecoderMngr * : pointer to the decoder manager base class interface.
*/
template <typename T> IDecoderMngr *createManagerInst(const std::string &name)
{
return new (std::nothrow)T(name);
}
/*! Structure to contain the information needed to create and register a builtin decoder
* manager with the library
*/
typedef struct built_in_decoder_info {
IDecoderMngr *pMngr; //!< pointer to created decoder manager
CreateMngr PFn; //!< function to create the decoder manager.
const char *name; //!< registered name of the decoder.
} built_in_decoder_info_t;
//! Define to use to fill in an array of built_in_decoder_info_t structures.
#define CREATE_BUILTIN_ENTRY(C,N) { 0, createManagerInst<C>, N }
#endif // ARM_OCSD_LIB_DCD_REGISTER_H_INCLUDED
/* End of File ocsd_lib_dcd_register.h */

View File

@ -0,0 +1,84 @@
/*!
* \file ocsd_msg_logger.h
* \brief OpenCSD : Generic Message logger / printer
*
* \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_OCSD_MSG_LOGGER_H_INCLUDED
#define ARM_OCSD_MSG_LOGGER_H_INCLUDED
#include <string>
#include <fstream>
class ocsdMsgLogStrOutI
{
public:
ocsdMsgLogStrOutI() {};
virtual ~ocsdMsgLogStrOutI() {};
virtual void printOutStr(const std::string &outStr) = 0;
};
class ocsdMsgLogger
{
public:
ocsdMsgLogger();
~ocsdMsgLogger();
typedef enum {
OUT_NONE = 0,
OUT_FILE = 1,
OUT_STDERR = 2,
OUT_STDOUT = 4,
OUT_STR_CB = 8 /* output to external string callback interface */
} output_dest;
void setLogOpts(int logOpts);
const int getLogOpts() const { return m_outFlags; };
void setLogFileName(const char *fileName);
void setStrOutFn(ocsdMsgLogStrOutI *p_IstrOut);
void LogMsg(const std::string &msg);
const bool isLogging() const;
private:
int m_outFlags;
std::string m_logFileName;
std::fstream m_out_file;
ocsdMsgLogStrOutI *m_pOutStrI;
};
#endif // ARM_OCSD_MSG_LOGGER_H_INCLUDED
/* End of File ocsd_msg_logger.h */

View File

@ -0,0 +1,116 @@
/*
* \file ocsd_pe_context.h
* \brief OpenCSD : Wrapper class for PE context
*
* \copyright Copyright (c) 2016, 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_OCSD_PE_CONTEXT_H_INCLUDED
#define ARM_OCSD_PE_CONTEXT_H_INCLUDED
#include "opencsd/ocsd_if_types.h"
/*! @class OcsdPeContext
* @brief Handler for the ocsd_pe_context structure.
*
* Reads and writes structure values, enforcing interaction rules between values
* and flags.
*/
class OcsdPeContext
{
public:
OcsdPeContext();
OcsdPeContext(const ocsd_pe_context *context);
~OcsdPeContext() {};
OcsdPeContext &operator =(const OcsdPeContext &ctxt);
OcsdPeContext &operator =(const ocsd_pe_context *context);
void resetCtxt();
void setSecLevel(const ocsd_sec_level sl) { m_context.security_level = sl; };
void setEL(const ocsd_ex_level el) { m_context.exception_level = el; m_context.el_valid = el > ocsd_EL_unknown ? 1 : 0; };
void setCtxtID(const uint32_t id) { m_context.context_id = id; m_context.ctxt_id_valid = 1; };
void setVMID(const uint32_t id) { m_context.vmid = id; m_context.vmid_valid = 1; };
void set64bit(const bool is64bit) { m_context.bits64 = is64bit ? 1 : 0; };
const ocsd_sec_level getSecLevel() const { return m_context.security_level; };
const ocsd_ex_level getEL() const { return m_context.exception_level; };
const bool ELvalid() const { return (m_context.el_valid == 1); };
const uint32_t getCtxtID() const { return (m_context.ctxt_id_valid == 1) ? m_context.context_id : 0; };
const bool ctxtIDvalid() const { return (m_context.ctxt_id_valid == 1); };
const uint32_t getVMID() const { return (m_context.vmid_valid == 1) ? m_context.vmid : 0; };
const bool VMIDvalid() const { return (m_context.vmid_valid == 1); };
// only allow an immutable copy of the structure out to C-API land.
operator const ocsd_pe_context &() const { return m_context; };
private:
ocsd_pe_context m_context;
};
inline OcsdPeContext::OcsdPeContext()
{
resetCtxt();
}
inline OcsdPeContext::OcsdPeContext(const ocsd_pe_context *context)
{
m_context = *context;
}
inline void OcsdPeContext::resetCtxt()
{
// initialise the context
m_context.bits64 = 0;
m_context.context_id = 0;
m_context.ctxt_id_valid = 0;
m_context.el_valid = 0;
m_context.exception_level = ocsd_EL_unknown;
m_context.security_level = ocsd_sec_secure;
m_context.vmid = 0;
m_context.vmid_valid = 0;
}
inline OcsdPeContext & OcsdPeContext::operator =(const OcsdPeContext &ctxt)
{
m_context = ctxt;
return *this;
}
inline OcsdPeContext & OcsdPeContext::operator =(const ocsd_pe_context *context)
{
m_context = *context;
return *this;
}
#endif // ARM_OCSD_PE_CONTEXT_H_INCLUDED
/* End of File ocsd_pe_context.h */

View File

@ -0,0 +1,46 @@
/*
* \file ocsd_version.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_OCSD_VERSION_H_INCLUDED
#define ARM_OCSD_VERSION_H_INCLUDED
class ocsdVersion
{
public:
static const uint32_t vers_num();
static const char *vers_str();
};
#endif // ARM_OCSD_VERSION_H_INCLUDED
/* End of File ocsd_version.h */

View File

@ -0,0 +1,149 @@
/*!
* \file trc_component.h
* \brief OpenCSD : Base trace decode component.
*
* \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_COMPONENT_H_INCLUDED
#define ARM_TRC_COMPONENT_H_INCLUDED
#include <string>
#include "comp_attach_pt_t.h"
#include "interfaces/trc_error_log_i.h"
#include "ocsd_error.h"
class errLogAttachMonitor;
/** @addtogroup ocsd_infrastructure
@{*/
/*!
* @class TraceComponent
* @brief Base class for all decode components in the library.
*
* Provides error logging attachment point and component type and instance naming
* Interface for handling of component operational mode.
*/
class TraceComponent
{
public:
TraceComponent(const std::string &name);
TraceComponent(const std::string &name, int instIDNum);
virtual ~TraceComponent(); /**< Default Destructor */
const std::string &getComponentName() const { return m_name; };
void setComponentName(const std::string &name) { m_name = name; };
/** Error logger attachment point.*/
componentAttachPt<ITraceErrorLog> *getErrorLogAttachPt() { return &m_error_logger; };
/*!
* Set the operational mode for the component.
* This controls the way the component behaves under error conditions etc.
* These flags may also control output formats or data.
* Operation mode flags used are component specific and defined by derived classes.
*
* @param op_flags : Set of operation mode flags.
*
* @return ocsd_err_t : OCSD_OK if flags supported by this component, error if unsuppored
*/
ocsd_err_t setComponentOpMode(uint32_t op_flags);
/*!
* Return the current operational mode flags values
*
* @return const uint32_t : Op Mode flags.
*/
const uint32_t getComponentOpMode() const { return m_op_flags; };
/*!
* Get the supported operational mode flags for this component.
* Base class will return nothing supported.
* Derived class must set the value correctly for the component.
*
* @return const uint32_t : Supported flags values.
*/
const uint32_t getSupportedOpModes() const { return m_supported_op_flags; };
/*!
* Set associated trace component - used by generic code to track
* packet processor / packet decoder pairs.
*
* @param *assocComp : pointer to the associated component
*/
void setAssocComponent(TraceComponent *assocComp) { m_assocComp = assocComp; };
/*!
* get associated trace component pointer
*
* @return TraceComponent *: associated component.
*/
TraceComponent *getAssocComponent() { return m_assocComp; };
/*!
* Log a message at the default severity on this component.
*/
void LogDefMessage(const std::string &msg)
{
LogMessage(m_errVerbosity, msg);
}
protected:
friend class errLogAttachMonitor;
void LogError(const ocsdError &Error);
void LogMessage(const ocsd_err_severity_t filter_level, const std::string &msg);
const ocsd_err_severity_t getErrorLogLevel() const { return m_errVerbosity; };
const bool isLoggingErrorLevel(const ocsd_err_severity_t level) const { return level <= m_errVerbosity; };
void updateErrorLogLevel();
void do_attach_notify(const int num_attached);
void Init(const std::string &name);
uint32_t m_op_flags; //!< current component operational mode flags.
uint32_t m_supported_op_flags; //!< supported component operational mode flags - derived class to intialise.
private:
componentAttachPt<ITraceErrorLog> m_error_logger;
ocsd_hndl_err_log_t m_errLogHandle;
ocsd_err_severity_t m_errVerbosity;
errLogAttachMonitor *m_pErrAttachMon;
std::string m_name;
TraceComponent *m_assocComp; //!< associated component -> if this is a pkt decoder, associated pkt processor.
};
/** @}*/
#endif // ARM_TRC_COMPONENT_H_INCLUDED
/* End of File trc_component.h */

View File

@ -0,0 +1,68 @@
/*!
* \file trc_core_arch_map.h
* \brief OpenCSD : Map core name strings to architecture profile constants.
*
* \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_CORE_ARCH_MAP_H_INCLUDED
#define ARM_TRC_CORE_ARCH_MAP_H_INCLUDED
#include <map>
#include <string>
#include "opencsd/ocsd_if_types.h"
class CoreArchProfileMap
{
public:
CoreArchProfileMap();
~CoreArchProfileMap() {};
ocsd_arch_profile_t getArchProfile(const std::string &coreName);
private:
std::map<std::string, ocsd_arch_profile_t> core_profiles;
};
inline ocsd_arch_profile_t CoreArchProfileMap::getArchProfile(const std::string &coreName)
{
ocsd_arch_profile_t ap = { ARCH_UNKNOWN, profile_Unknown };
std::map<std::string, ocsd_arch_profile_t>::const_iterator it;
it = core_profiles.find(coreName);
if(it != core_profiles.end())
ap = it->second;
return ap;
}
#endif // ARM_TRC_CORE_ARCH_MAP_H_INCLUDED
/* End of File trc_core_arch_map.h */

View File

@ -0,0 +1,62 @@
/*
* \file trc_cs_config.h
* \brief OpenCSD : Trace component config base class.
*
* \copyright Copyright (c) 2016, ARM Limited. All Rights Reserved.
*/
#ifndef ARM_TRC_CS_CONFIG_H_INCLUDED
#define ARM_TRC_CS_CONFIG_H_INCLUDED
/*
* 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.
*/
/** @addtogroup ocsd_protocol_cfg
@{*/
/*!
* @class CSConfig
* @brief Base class for configuration data on CoreSight trace component.
*
* Defines common access functionality, common to all components.
* (e.g. trace ID).
*
*/
class CSConfig
{
public:
CSConfig() {};
virtual ~CSConfig() {};
virtual const uint8_t getTraceID() const = 0; //!< CoreSight Trace ID for this device.
};
/** @}*/
#endif // ARM_TRC_CS_CONFIG_H_INCLUDED
/* End of File trc_cs_config.h */

View File

@ -0,0 +1,97 @@
/*!
* \file trc_frame_deformatter.h
* \brief OpenCSD : De-format CoreSight formatted trace frame.
*
* \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_FRAME_DEFORMATTER_H_INCLUDED
#define ARM_TRC_FRAME_DEFORMATTER_H_INCLUDED
#include "opencsd/ocsd_if_types.h"
#include "interfaces/trc_data_raw_in_i.h"
#include "comp_attach_pt_t.h"
class ITrcRawFrameIn;
class ITrcDataMixIDIn;
class ITrcSrcIndexCreator;
class ITraceErrorLog;
class TraceFmtDcdImpl;
/** @defgroup ocsd_deformatter OpenCSD Library : Trace Frame Deformatter
@brief CoreSight Formatted Trace Frame - deformatting functionality.
@{*/
class TraceFormatterFrameDecoder : public ITrcDataIn
{
public:
TraceFormatterFrameDecoder();
TraceFormatterFrameDecoder(int instNum);
virtual ~TraceFormatterFrameDecoder();
/* the data input interface from the reader */
virtual ocsd_datapath_resp_t TraceDataIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed);
/* attach a data processor to a stream ID output */
componentAttachPt<ITrcDataIn> *getIDStreamAttachPt(uint8_t ID);
/* attach a data processor to the raw frame output */
componentAttachPt<ITrcRawFrameIn> *getTrcRawFrameAttachPt();
componentAttachPt<ITrcSrcIndexCreator> *getTrcSrcIndexAttachPt();
componentAttachPt<ITraceErrorLog> *getErrLogAttachPt();
/* configuration - set operational mode for incoming stream (has FSYNCS etc) */
ocsd_err_t Configure(uint32_t cfg_flags);
const uint32_t getConfigFlags() const;
/* enable / disable ID streams - default as all enabled */
ocsd_err_t OutputFilterIDs(std::vector<uint8_t> &id_list, bool bEnable);
ocsd_err_t OutputFilterAllIDs(bool bEnable);
/* decode control */
ocsd_datapath_resp_t Reset(); /* reset the decode to the start state, drop partial data - propogate to attached components */
ocsd_datapath_resp_t Flush(); /* flush existing data if possible, retain state - propogate to attached components */
private:
TraceFmtDcdImpl *m_pDecoder;
int m_instNum;
};
/** @}*/
#endif // ARM_TRC_FRAME_DEFORMATTER_H_INCLUDED
/* End of File trc_frame_deformatter.h */

View File

@ -0,0 +1,206 @@
/*!
* \file trc_gen_elem.h
* \brief OpenCSD : Decoder Generic trace element output class.
*
* \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_GEN_ELEM_H_INCLUDED
#define ARM_TRC_GEN_ELEM_H_INCLUDED
#include "opencsd/trc_gen_elem_types.h"
#include "trc_printable_elem.h"
#include "ocsd_pe_context.h"
/** @addtogroup gen_trc_elem
@{*/
/*!
* @class OcsdTraceElement
* @brief Generic trace element class
*
*/
class OcsdTraceElement : public trcPrintableElem, public ocsd_generic_trace_elem
{
public:
OcsdTraceElement();
OcsdTraceElement(ocsd_gen_trc_elem_t type);
virtual ~OcsdTraceElement() {};
void init();
// set elements API
void setType(const ocsd_gen_trc_elem_t type); //!< set type and init flags
void updateType(const ocsd_gen_trc_elem_t type); //!< change type only - no init
void setContext(const ocsd_pe_context &new_context) { context = new_context; };
void setISA(const ocsd_isa isa_update);
void setCycleCount(const uint32_t cycleCount);
void setEvent(const event_t ev_type, const uint16_t number);
void setTS(const uint64_t ts, const bool freqChange = false);
void setExcepMarker() { excep_data_marker = 1; };
void setExceptionNum(uint32_t excepNum) { exception_number = excepNum; };
void setTraceOnReason(const trace_on_reason_t reason);
void setAddrRange(const ocsd_vaddr_t st_addr, const ocsd_vaddr_t en_addr);
void setLastInstrInfo(const bool exec, const ocsd_instr_type last_i_type, const ocsd_instr_subtype last_i_subtype);
void setAddrStart(const ocsd_vaddr_t st_addr) { this->st_addr = st_addr; };
void setSWTInfo(const ocsd_swt_info_t swt_info) { sw_trace_info = swt_info; };
void setExtendedDataPtr(const void *data_ptr);
// stringize the element
virtual void toString(std::string &str) const;
// get elements API
OcsdTraceElement &operator =(const ocsd_generic_trace_elem* p_elem);
const ocsd_gen_trc_elem_t getType() const { return elem_type; };
// return current context
const ocsd_pe_context &getContext() const { return context; };
private:
void printSWInfoPkt(std::ostringstream &oss) const;
void clearPerPktData(); //!< clear flags that indicate validity / have values on a per packet basis
};
inline OcsdTraceElement::OcsdTraceElement(ocsd_gen_trc_elem_t type)
{
elem_type = type;
}
inline OcsdTraceElement::OcsdTraceElement()
{
elem_type = OCSD_GEN_TRC_ELEM_UNKNOWN;
}
inline void OcsdTraceElement::setCycleCount(const uint32_t cycleCount)
{
cycle_count = cycleCount;
has_cc = 1;
}
inline void OcsdTraceElement::setEvent(const event_t ev_type, const uint16_t number)
{
trace_event.ev_type = (uint16_t)ev_type;
trace_event.ev_number = ev_type == EVENT_NUMBERED ? number : 0;
}
inline void OcsdTraceElement::setAddrRange(const ocsd_vaddr_t st_addr, const ocsd_vaddr_t en_addr)
{
this->st_addr = st_addr;
this->en_addr = en_addr;
}
inline void OcsdTraceElement::setLastInstrInfo(const bool exec, const ocsd_instr_type last_i_type, const ocsd_instr_subtype last_i_subtype)
{
last_instr_exec = exec ? 1 : 0;
this->last_i_type = last_i_type;
this->last_i_subtype = last_i_subtype;
}
inline void OcsdTraceElement::setType(const ocsd_gen_trc_elem_t type)
{
// set the type and clear down the per element flags
elem_type = type;
clearPerPktData();
}
inline void OcsdTraceElement::updateType(const ocsd_gen_trc_elem_t type)
{
elem_type = type;
}
inline void OcsdTraceElement::init()
{
st_addr = en_addr = (ocsd_vaddr_t)-1;
isa = ocsd_isa_unknown;
cycle_count = 0;
timestamp = 0;
context.ctxt_id_valid = 0;
context.vmid_valid = 0;
context.el_valid = 0;
last_i_type = OCSD_INSTR_OTHER;
last_i_subtype = OCSD_S_INSTR_NONE;
clearPerPktData();
}
inline void OcsdTraceElement::clearPerPktData()
{
flag_bits = 0; // union with trace_on_reason / trace_event
ptr_extended_data = 0; // extended data pointer
}
inline void OcsdTraceElement::setTraceOnReason(const trace_on_reason_t reason)
{
trace_on_reason = reason;
}
inline void OcsdTraceElement::setISA(const ocsd_isa isa_update)
{
isa = isa_update;
if(isa > ocsd_isa_unknown)
isa = ocsd_isa_unknown;
}
inline void OcsdTraceElement::setTS(const uint64_t ts, const bool freqChange /*= false*/)
{
timestamp = ts;
cpu_freq_change = freqChange ? 1 : 0;
has_ts = 1;
}
inline void OcsdTraceElement::setExtendedDataPtr(const void *data_ptr)
{
extended_data = 1;
ptr_extended_data = data_ptr;
}
/** @}*/
#endif // ARM_TRC_GEN_ELEM_H_INCLUDED
/* End of File trc_gen_elem.h */

View File

@ -0,0 +1,303 @@
/*!
* \file trc_pkt_decode_base.h
* \brief OpenCSD : Trace Packet decoder base class.
*
* \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_DECODE_BASE_H_INCLUDED
#define ARM_TRC_PKT_DECODE_BASE_H_INCLUDED
#include "trc_component.h"
#include "comp_attach_pt_t.h"
#include "interfaces/trc_pkt_in_i.h"
#include "interfaces/trc_gen_elem_in_i.h"
#include "interfaces/trc_tgt_mem_access_i.h"
#include "interfaces/trc_instr_decode_i.h"
/** @defgroup ocsd_pkt_decode OpenCSD Library : Packet Decoders.
@brief Classes providing Protocol Packet Decoding capability.
Packet decoders convert incoming protocol packets from a packet processor,
into generic trace elements to be output to an analysis program.
Packet decoders can be:-
- PE decoders - converting ETM or PTM packets into instruction and data trace elements
- SW stimulus decoder - converting STM or ITM packets into software generated trace elements.
- Bus decoders - converting HTM packets into bus transaction elements.
@{*/
class TrcPktDecodeI : public TraceComponent
{
public:
TrcPktDecodeI(const char *component_name);
TrcPktDecodeI(const char *component_name, int instIDNum);
virtual ~TrcPktDecodeI() {};
componentAttachPt<ITrcGenElemIn> *getTraceElemOutAttachPt() { return &m_trace_elem_out; };
componentAttachPt<ITargetMemAccess> *getMemoryAccessAttachPt() { return &m_mem_access; };
componentAttachPt<IInstrDecode> *getInstrDecodeAttachPt() { return &m_instr_decode; };
void setUsesMemAccess(bool bUsesMemaccess) { m_uses_memaccess = bUsesMemaccess; };
const bool getUsesMemAccess() const { return m_uses_memaccess; };
void setUsesIDecode(bool bUsesIDecode) { m_uses_idecode = bUsesIDecode; };
const bool getUsesIDecode() const { return m_uses_idecode; };
protected:
/* implementation packet decoding interface */
virtual ocsd_datapath_resp_t processPacket() = 0;
virtual ocsd_datapath_resp_t onEOT() = 0;
virtual ocsd_datapath_resp_t onReset() = 0;
virtual ocsd_datapath_resp_t onFlush() = 0;
virtual ocsd_err_t onProtocolConfig() = 0;
virtual const uint8_t getCoreSightTraceID() = 0;
const bool checkInit();
/* data output */
ocsd_datapath_resp_t outputTraceElement(const OcsdTraceElement &elem); // use current index
ocsd_datapath_resp_t outputTraceElementIdx(ocsd_trc_index_t idx, const OcsdTraceElement &elem); // use supplied index (where decoder caches elements)
/* target access */
ocsd_err_t accessMemory(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, uint32_t *num_bytes, uint8_t *p_buffer);
/* instruction decode */
ocsd_err_t instrDecode(ocsd_instr_info *instr_info);
componentAttachPt<ITrcGenElemIn> m_trace_elem_out;
componentAttachPt<ITargetMemAccess> m_mem_access;
componentAttachPt<IInstrDecode> m_instr_decode;
ocsd_trc_index_t m_index_curr_pkt;
bool m_decode_init_ok; //!< set true if all attachments in place for decode. (remove checks in main throughput paths)
bool m_config_init_ok; //!< set true if config set.
std::string init_err_msg; //!< error message for init error
bool m_uses_memaccess;
bool m_uses_idecode;
};
inline TrcPktDecodeI::TrcPktDecodeI(const char *component_name) :
TraceComponent(component_name),
m_index_curr_pkt(0),
m_decode_init_ok(false),
m_config_init_ok(false),
m_uses_memaccess(true),
m_uses_idecode(true)
{
}
inline TrcPktDecodeI::TrcPktDecodeI(const char *component_name, int instIDNum) :
TraceComponent(component_name, instIDNum),
m_index_curr_pkt(0),
m_decode_init_ok(false),
m_config_init_ok(false),
m_uses_memaccess(true),
m_uses_idecode(true)
{
}
inline const bool TrcPktDecodeI::checkInit()
{
if(!m_decode_init_ok)
{
if(!m_config_init_ok)
init_err_msg = "No decoder configuration information";
else if(!m_trace_elem_out.hasAttachedAndEnabled())
init_err_msg = "No element output interface attached and enabled";
else if(m_uses_memaccess && !m_mem_access.hasAttachedAndEnabled())
init_err_msg = "No memory access interface attached and enabled";
else if(m_uses_idecode && !m_instr_decode.hasAttachedAndEnabled())
init_err_msg = "No instruction decoder interface attached and enabled";
else
m_decode_init_ok = true;
}
return m_decode_init_ok;
}
inline ocsd_datapath_resp_t TrcPktDecodeI::outputTraceElement(const OcsdTraceElement &elem)
{
return m_trace_elem_out.first()->TraceElemIn(m_index_curr_pkt,getCoreSightTraceID(), elem);
}
inline ocsd_datapath_resp_t TrcPktDecodeI::outputTraceElementIdx(ocsd_trc_index_t idx, const OcsdTraceElement &elem)
{
return m_trace_elem_out.first()->TraceElemIn(idx, getCoreSightTraceID(), elem);
}
inline ocsd_err_t TrcPktDecodeI::instrDecode(ocsd_instr_info *instr_info)
{
if(m_uses_idecode)
return m_instr_decode.first()->DecodeInstruction(instr_info);
return OCSD_ERR_DCD_INTERFACE_UNUSED;
}
inline ocsd_err_t TrcPktDecodeI::accessMemory(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, uint32_t *num_bytes, uint8_t *p_buffer)
{
if(m_uses_memaccess)
return m_mem_access.first()->ReadTargetMemory(address,getCoreSightTraceID(),mem_space, num_bytes,p_buffer);
return OCSD_ERR_DCD_INTERFACE_UNUSED;
}
/**********************************************************************/
template <class P, class Pc>
class TrcPktDecodeBase : public TrcPktDecodeI, public IPktDataIn<P>
{
public:
TrcPktDecodeBase(const char *component_name);
TrcPktDecodeBase(const char *component_name, int instIDNum);
virtual ~TrcPktDecodeBase();
virtual ocsd_datapath_resp_t PacketDataIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const P *p_packet_in);
/* protocol configuration */
ocsd_err_t setProtocolConfig(const Pc *config);
const Pc * getProtocolConfig() const { return m_config; };
protected:
void ClearConfigObj();
/* the protocol configuration */
Pc * m_config;
/* the current input packet */
const P * m_curr_packet_in;
};
template <class P, class Pc> TrcPktDecodeBase<P, Pc>::TrcPktDecodeBase(const char *component_name) :
TrcPktDecodeI(component_name),
m_config(0)
{
}
template <class P, class Pc> TrcPktDecodeBase<P, Pc>::TrcPktDecodeBase(const char *component_name, int instIDNum) :
TrcPktDecodeI(component_name,instIDNum),
m_config(0)
{
}
template <class P, class Pc> TrcPktDecodeBase<P, Pc>::~TrcPktDecodeBase()
{
ClearConfigObj();
}
template <class P, class Pc> ocsd_datapath_resp_t TrcPktDecodeBase<P, Pc>::PacketDataIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const P *p_packet_in)
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
if(!checkInit())
{
LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_NOT_INIT,init_err_msg));
return OCSD_RESP_FATAL_NOT_INIT;
}
switch(op)
{
case OCSD_OP_DATA:
if(p_packet_in == 0)
{
LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PARAM_VAL));
resp = OCSD_RESP_FATAL_INVALID_PARAM;
}
else
{
m_curr_packet_in = p_packet_in;
m_index_curr_pkt = index_sop;
resp = processPacket();
}
break;
case OCSD_OP_EOT:
resp = onEOT();
break;
case OCSD_OP_FLUSH:
resp = onFlush();
break;
case OCSD_OP_RESET:
resp = onReset();
break;
default:
LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PARAM_VAL));
resp = OCSD_RESP_FATAL_INVALID_OP;
break;
}
return resp;
}
/* protocol configuration */
template <class P, class Pc> ocsd_err_t TrcPktDecodeBase<P, Pc>::setProtocolConfig(const Pc *config)
{
ocsd_err_t err = OCSD_ERR_INVALID_PARAM_VAL;
if(config != 0)
{
ClearConfigObj(); // remove any current config
m_config = new (std::nothrow) Pc(*config); // make a copy of the config - don't rely on the object passed in being valid outside the context of the call.
if(m_config != 0)
{
err = onProtocolConfig();
if(err == OCSD_OK)
m_config_init_ok = true;
}
else
err = OCSD_ERR_MEM;
}
return err;
}
template <class P, class Pc> void TrcPktDecodeBase<P, Pc>::ClearConfigObj()
{
if(m_config)
{
delete m_config;
m_config = 0;
}
}
/** @}*/
#endif // ARM_TRC_PKT_DECODE_BASE_H_INCLUDED
/* End of File trc_pkt_decode_base.h */

View File

@ -0,0 +1,49 @@
/*
* \file trc_pkt_elem_base.h
* \brief Reference CoreSight Trace Decoder :
*
* \copyright Copyright (c) 2016, ARM Limited. All Rights Reserved.
*/
#ifndef ARM_TRC_PKT_ELEM_BASE_H_INCLUDED
#define ARM_TRC_PKT_ELEM_BASE_H_INCLUDED
/*
* 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.
*/
class TrcPacketBase
{
public:
TrcPacketBase() {};
virtual ~TrcPacketBase() {}
//! return the underlying C API packet structure
virtual const void *c_pkt() const = 0;
};
#endif // ARM_TRC_PKT_ELEM_BASE_H_INCLUDED
/* End of File trc_pkt_elem_base.h */

View File

@ -0,0 +1,412 @@
/*!
* \file trc_pkt_proc_base.h
* \brief OpenCSD : Trace packet processor base class.
*
* \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_BASE_H_INCLUDED
#define ARM_TRC_PKT_PROC_BASE_H_INCLUDED
#include "interfaces/trc_data_raw_in_i.h"
#include "interfaces/trc_pkt_in_i.h"
#include "interfaces/trc_pkt_raw_in_i.h"
#include "interfaces/trc_indexer_pkt_i.h"
#include "trc_component.h"
#include "comp_attach_pt_t.h"
/** @defgroup ocsd_pkt_proc OpenCSD Library : Packet Processors.
@brief Classes providing Protocol Packet Processing capability.
Packet processors take an incoming byte stream and convert into discrete packets for the
required trace protocol.
@{*/
/*!
* @class TrcPktProcI
* @brief Base Packet processing interface
*
* Defines the packet processing methods that protocol specific processors must
* implement.
*
*/
class TrcPktProcI : public TraceComponent, public ITrcDataIn
{
public:
TrcPktProcI(const char *component_name);
TrcPktProcI(const char *component_name, int instIDNum);
virtual ~TrcPktProcI() {};
/** Trace byte data input interface - from ITrcDataIn.
*/
virtual ocsd_datapath_resp_t TraceDataIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed) = 0;
protected:
/* implementation packet processing interface */
/*! @brief Implementation function for the OCSD_OP_DATA operation */
virtual ocsd_datapath_resp_t processData( const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed) = 0;
virtual ocsd_datapath_resp_t onEOT() = 0; //!< Implementation function for the OCSD_OP_EOT operation
virtual ocsd_datapath_resp_t onReset() = 0; //!< Implementation function for the OCSD_OP_RESET operation
virtual ocsd_datapath_resp_t onFlush() = 0; //!< Implementation function for the OCSD_OP_FLUSH operation
virtual ocsd_err_t onProtocolConfig() = 0; //!< Called when the configuration object is passed to the decoder.
virtual const bool isBadPacket() const = 0; //!< check if the current packet is an error / bad packet
};
inline TrcPktProcI::TrcPktProcI(const char *component_name) :
TraceComponent(component_name)
{
}
inline TrcPktProcI::TrcPktProcI(const char *component_name, int instIDNum) :
TraceComponent(component_name,instIDNum)
{
}
/*!
* @class TrcPktProcBase
* @brief Packet Processor base class. Provides common infrastructure and interconnections for packet processors.
*
* The class is a templated base class.
* - P - this is the packet object class.
* - Pt - this is the packet type class.
* - Pc - this is the packet configuration class.
*
* implementations will provide concrete classes for each of these to operate under the common infrastructures.
* The base provides the trace data in (ITrcDataIn) interface and operates on the incoming operation type.
*
* Implementions override the 'onFn()' and data process functions defined in TrcPktProcI,
* with the base class ensuring consistent ordering of operations.
*
*/
template <class P, class Pt, class Pc>
class TrcPktProcBase : public TrcPktProcI
{
public:
TrcPktProcBase(const char *component_name);
TrcPktProcBase(const char *component_name, int instIDNum);
virtual ~TrcPktProcBase();
/** Byte trace data input interface defined in ITrcDataIn
The base class implementation processes the operation to call the
interface functions on TrcPktProcI.
*/
virtual ocsd_datapath_resp_t TraceDataIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed);
/* component attachment points */
//! Attachement point for the protocol packet output
componentAttachPt<IPktDataIn<P>> *getPacketOutAttachPt() { return &m_pkt_out_i; };
//! Attachment point for the protocol packet monitor
componentAttachPt<IPktRawDataMon<P>> *getRawPacketMonAttachPt() { return &m_pkt_raw_mon_i; };
//! Attachment point for a packet indexer
componentAttachPt<ITrcPktIndexer<Pt>> *getTraceIDIndexerAttachPt() { return &m_pkt_indexer_i; };
/* protocol configuration */
//!< Set the protocol specific configuration for the decoder.
virtual ocsd_err_t setProtocolConfig(const Pc *config);
//!< Get the configuration for the decoder.
virtual const Pc *getProtocolConfig() const { return m_config; };
protected:
/* data output functions */
ocsd_datapath_resp_t outputDecodedPacket(const ocsd_trc_index_t index_sop, const P *pkt);
void outputRawPacketToMonitor( const ocsd_trc_index_t index_sop,
const P *pkt,
const uint32_t size,
const uint8_t *p_data);
void indexPacket(const ocsd_trc_index_t index_sop, const Pt *packet_type);
ocsd_datapath_resp_t outputOnAllInterfaces(const ocsd_trc_index_t index_sop, const P *pkt, const Pt *pkt_type, std::vector<uint8_t> &pktdata);
ocsd_datapath_resp_t outputOnAllInterfaces(const ocsd_trc_index_t index_sop, const P *pkt, const Pt *pkt_type, const uint8_t *pktdata, uint32_t pktlen);
/*! Let the derived class figure out if it needs to collate and send raw data.
can improve wait for sync performance if we do not need to save and send unsynced data.
*/
const bool hasRawMon() const;
/* the protocol configuration */
const Pc *m_config;
void ClearConfigObj(); // remove our copy of the config
const bool checkInit(); // return true if init (configured and at least one output sink attached), false otherwise.
private:
/* decode control */
ocsd_datapath_resp_t Reset(const ocsd_trc_index_t index);
ocsd_datapath_resp_t Flush();
ocsd_datapath_resp_t EOT();
componentAttachPt<IPktDataIn<P>> m_pkt_out_i;
componentAttachPt<IPktRawDataMon<P>> m_pkt_raw_mon_i;
componentAttachPt<ITrcPktIndexer<Pt>> m_pkt_indexer_i;
bool m_b_is_init;
};
template<class P,class Pt, class Pc> TrcPktProcBase<P, Pt, Pc>::TrcPktProcBase(const char *component_name) :
TrcPktProcI(component_name),
m_config(0),
m_b_is_init(false)
{
}
template<class P,class Pt, class Pc> TrcPktProcBase<P, Pt, Pc>::TrcPktProcBase(const char *component_name, int instIDNum) :
TrcPktProcI(component_name, instIDNum),
m_config(0),
m_b_is_init(false)
{
}
template<class P,class Pt, class Pc> TrcPktProcBase<P, Pt, Pc>::~TrcPktProcBase()
{
ClearConfigObj();
}
template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::TraceDataIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed)
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
switch(op)
{
case OCSD_OP_DATA:
if((dataBlockSize == 0) || (pDataBlock == 0) || (numBytesProcessed == 0))
{
if(numBytesProcessed)
*numBytesProcessed = 0; // ensure processed bytes value set to 0.
LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PARAM_VAL,"Packet Processor: Zero length data block or NULL pointer error\n"));
resp = OCSD_RESP_FATAL_INVALID_PARAM;
}
else
resp = processData(index,dataBlockSize,pDataBlock,numBytesProcessed);
break;
case OCSD_OP_EOT:
resp = EOT();
break;
case OCSD_OP_FLUSH:
resp = Flush();
break;
case OCSD_OP_RESET:
resp = Reset(index);
break;
default:
LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PARAM_VAL,"Packet Processor : Unknown Datapath operation\n"));
resp = OCSD_RESP_FATAL_INVALID_OP;
break;
}
return resp;
}
template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::Reset(const ocsd_trc_index_t index)
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
// reset the trace decoder attachment on main data path.
if(m_pkt_out_i.hasAttachedAndEnabled())
resp = m_pkt_out_i.first()->PacketDataIn(OCSD_OP_RESET,index,0);
// reset the packet processor implmentation
if(!OCSD_DATA_RESP_IS_FATAL(resp))
resp = onReset();
// packet monitor
if(m_pkt_raw_mon_i.hasAttachedAndEnabled())
m_pkt_raw_mon_i.first()->RawPacketDataMon(OCSD_OP_RESET,index,0,0,0);
return resp;
}
template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::Flush()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
ocsd_datapath_resp_t resplocal = OCSD_RESP_CONT;
// the trace decoder attachment on main data path.
if(m_pkt_out_i.hasAttachedAndEnabled())
resp = m_pkt_out_i.first()->PacketDataIn(OCSD_OP_FLUSH,0,0); // flush up the data path first.
// if the connected components are flushed, not flush this one.
if(OCSD_DATA_RESP_IS_CONT(resp))
resplocal = onFlush(); // local flush
return (resplocal > resp) ? resplocal : resp;
}
template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::EOT()
{
ocsd_datapath_resp_t resp = onEOT(); // local EOT - mark any part packet as incomplete type and prepare to send
// the trace decoder attachment on main data path.
if(m_pkt_out_i.hasAttachedAndEnabled() && !OCSD_DATA_RESP_IS_FATAL(resp))
resp = m_pkt_out_i.first()->PacketDataIn(OCSD_OP_EOT,0,0);
// packet monitor
if(m_pkt_raw_mon_i.hasAttachedAndEnabled())
m_pkt_raw_mon_i.first()->RawPacketDataMon(OCSD_OP_EOT,0,0,0,0);
return resp;
}
template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::outputDecodedPacket(const ocsd_trc_index_t index, const P *pkt)
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
// bad packet filter.
if((getComponentOpMode() & OCSD_OPFLG_PKTPROC_NOFWD_BAD_PKTS) && isBadPacket())
return resp;
// send a complete packet over the primary data path
if(m_pkt_out_i.hasAttachedAndEnabled())
resp = m_pkt_out_i.first()->PacketDataIn(OCSD_OP_DATA,index,pkt);
return resp;
}
template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::outputRawPacketToMonitor(
const ocsd_trc_index_t index_sop,
const P *pkt,
const uint32_t size,
const uint8_t *p_data)
{
// never output 0 sized packets.
if(size == 0)
return;
// bad packet filter.
if((getComponentOpMode() & OCSD_OPFLG_PKTPROC_NOMON_BAD_PKTS) && isBadPacket())
return;
// packet monitor - this cannot return CONT / WAIT, but does get the raw packet data.
if(m_pkt_raw_mon_i.hasAttachedAndEnabled())
m_pkt_raw_mon_i.first()->RawPacketDataMon(OCSD_OP_DATA,index_sop,pkt,size,p_data);
}
template<class P,class Pt, class Pc> const bool TrcPktProcBase<P, Pt, Pc>::hasRawMon() const
{
return m_pkt_raw_mon_i.hasAttachedAndEnabled();
}
template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::indexPacket(const ocsd_trc_index_t index_sop, const Pt *packet_type)
{
// packet indexer - cannot return CONT / WAIT, just gets the current index and type.
if(m_pkt_indexer_i.hasAttachedAndEnabled())
m_pkt_indexer_i.first()->TracePktIndex(index_sop,packet_type);
}
template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::outputOnAllInterfaces(const ocsd_trc_index_t index_sop, const P *pkt, const Pt *pkt_type, std::vector<uint8_t> &pktdata)
{
indexPacket(index_sop,pkt_type);
if(pktdata.size() > 0) // prevent out of range errors for 0 length vector.
outputRawPacketToMonitor(index_sop,pkt,(uint32_t)pktdata.size(),&pktdata[0]);
return outputDecodedPacket(index_sop,pkt);
}
template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::outputOnAllInterfaces(const ocsd_trc_index_t index_sop, const P *pkt, const Pt *pkt_type, const uint8_t *pktdata, uint32_t pktlen)
{
indexPacket(index_sop,pkt_type);
outputRawPacketToMonitor(index_sop,pkt,pktlen,pktdata);
return outputDecodedPacket(index_sop,pkt);
}
template<class P,class Pt, class Pc> ocsd_err_t TrcPktProcBase<P, Pt, Pc>::setProtocolConfig(const Pc *config)
{
ocsd_err_t err = OCSD_ERR_INVALID_PARAM_VAL;
if(config != 0)
{
ClearConfigObj();
m_config = new (std::nothrow) Pc(*config);
if(m_config != 0)
err = onProtocolConfig();
else
err = OCSD_ERR_MEM;
}
return err;
}
template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::ClearConfigObj()
{
if(m_config)
{
delete m_config;
m_config = 0;
}
}
template<class P,class Pt, class Pc> const bool TrcPktProcBase<P, Pt, Pc>::checkInit()
{
if(!m_b_is_init)
{
if( (m_config != 0) &&
(m_pkt_out_i.hasAttached() || m_pkt_raw_mon_i.hasAttached())
)
m_b_is_init = true;
}
return m_b_is_init;
}
/** @}*/
#endif // ARM_TRC_PKT_PROC_BASE_H_INCLUDED
/* End of File trc_pkt_proc_base.h */

View File

@ -0,0 +1,91 @@
/*!
* \file trc_printable_elem.h
* \brief OpenCSD : Standard printable element base class.
*
* \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_PRINTABLE_ELEM_H_INCLUDED
#define ARM_TRC_PRINTABLE_ELEM_H_INCLUDED
#include <string>
#include <cstdint>
/** @addtogroup ocsd_infrastructure
@{*/
/*!
* @class trcPrintableElem
* @brief Class to provide trace element strings for printing
*
* Provide a standard interface to the trace packet classes to allow the packets
* to be printed in logging or tools.
*
* Provides some standard formatting functionality
*
*/
class trcPrintableElem
{
public:
trcPrintableElem() {};
virtual ~trcPrintableElem() {};
virtual void toString(std::string &str) const;
virtual void toStringFmt(const uint32_t fmtFlags, std::string &str) const;
// print formatting utilities
static void getValStr(std::string &valStr, const int valTotalBitSize, const int valValidBits, const uint64_t value, const bool asHex = true, const int updateBits = 0);
};
inline void trcPrintableElem::toString(std::string &str) const
{
str = "Trace Element : print not implemented";
}
inline void trcPrintableElem::toStringFmt(const uint32_t /*fmtFlags*/, std::string &str) const
{
toString(str);
}
/** static template string function - used in "C" API to provide generic printing */
template<class Pc, class Pt>
void trcPrintElemToString(const void *p_pkt, std::string &str)
{
Pc pktClass;
pktClass = static_cast<const Pt *>(p_pkt);
pktClass.toString(str);
}
/** @}*/
#endif // ARM_TRC_PRINTABLE_ELEM_H_INCLUDED
/* End of File trc_printable_elem.h */

View File

@ -0,0 +1,114 @@
/*
* \file trc_ret_stack.h
* \brief OpenCSD : trace decoder return stack feature.
*
* \copyright Copyright (c) 2017, 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_RET_STACK_H_INCLUDED
#define ARM_TRC_RET_STACK_H_INCLUDED
#include "opencsd/ocsd_if_types.h"
// uncomment below for return stack logging
// #define TRC_RET_STACK_DEBUG
#ifdef TRC_RET_STACK_DEBUG
class TraceComponent;
#endif
typedef struct _retStackElement
{
ocsd_vaddr_t ret_addr;
ocsd_isa ret_isa;
} retStackElement;
class TrcAddrReturnStack
{
public:
TrcAddrReturnStack();
~TrcAddrReturnStack() {};
void set_active(bool active)
{
m_active = active;
};
bool is_active() const
{
return m_active;
};
void push(const ocsd_vaddr_t addr, const ocsd_isa isa);
ocsd_vaddr_t pop(ocsd_isa &isa);
void flush();
bool overflow() const
{
return (bool)(num_entries < 0);
};
void set_pop_pending()
{
if (m_active)
m_pop_pending = true;
}
void clear_pop_pending()
{
m_pop_pending = false;
}
bool pop_pending() const
{
return m_pop_pending;
};
private:
bool m_active;
bool m_pop_pending; // flag for decoder to indicate a pop might be needed depending on the next packet (ETMv4)
int head_idx;
int num_entries;
retStackElement m_stack[16];
#ifdef TRC_RET_STACK_DEBUG
public:
void set_dbg_logger(TraceComponent *pLogger) { m_p_debug_logger = pLogger; };
private:
void LogOp(const char *pszOpString, ocsd_vaddr_t addr, int head_off, ocsd_isa isa);
TraceComponent *m_p_debug_logger;
#endif // TRC_RET_STACK_DEBUG
};
#endif // ARM_TRC_RET_STACK_H_INCLUDED
/* End of File trc_ret_stack.h */

View File

@ -0,0 +1,56 @@
/*
* \file trc_i_decode.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_I_DECODE_H_INCLUDED
#define ARM_TRC_I_DECODE_H_INCLUDED
#include "interfaces/trc_instr_decode_i.h"
#include "opencsd/ocsd_if_types.h"
class TrcIDecode : public IInstrDecode
{
public:
TrcIDecode() {};
virtual ~TrcIDecode() {};
virtual ocsd_err_t DecodeInstruction(ocsd_instr_info *instr_info);
private:
ocsd_err_t DecodeA32(ocsd_instr_info *instr_info);
ocsd_err_t DecodeA64(ocsd_instr_info *instr_info);
ocsd_err_t DecodeT32(ocsd_instr_info *instr_info);
};
#endif // ARM_TRC_I_DECODE_H_INCLUDED
/* End of File trc_i_decode.h */

View File

@ -0,0 +1,130 @@
/*
* \file trc_idec_arminst.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_IDEC_ARMINST_H_INCLUDED
#define ARM_TRC_IDEC_ARMINST_H_INCLUDED
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS 1
#endif
#include "opencsd/ocsd_if_types.h"
#include <cstdint>
/*
For Thumb2, test if a halfword is the first half of a 32-bit instruction,
as opposed to a complete 16-bit instruction.
*/
inline int is_wide_thumb(uint16_t insthw)
{
return (insthw & 0xF800) >= 0xE800;
}
/*
In the following queries, 16-bit Thumb2 instructions should be
passed in as the high halfword, e.g. xxxx0000.
*/
/*
Test whether an instruction is a branch (software change of the PC).
This includes branch instructions and all loads and data-processing
instructions that write to the PC. It does not include exception
instructions such as SVC, HVC and SMC.
(Performance event 0x0C includes these.)
*/
int inst_ARM_is_branch(uint32_t inst);
int inst_Thumb_is_branch(uint32_t inst);
int inst_A64_is_branch(uint32_t inst);
/*
Test whether an instruction is a direct (aka immediate) branch.
Performance event 0x0D counts these.
*/
int inst_ARM_is_direct_branch(uint32_t inst);
int inst_Thumb_is_direct_branch(uint32_t inst);
int inst_A64_is_direct_branch(uint32_t inst);
/*
Get branch destination for a direct branch.
*/
int inst_ARM_branch_destination(uint32_t addr, uint32_t inst, uint32_t *pnpc);
int inst_Thumb_branch_destination(uint32_t addr, uint32_t inst, uint32_t *pnpc);
int inst_A64_branch_destination(uint64_t addr, uint32_t inst, uint64_t *pnpc);
int inst_ARM_is_indirect_branch(uint32_t inst);
int inst_Thumb_is_indirect_branch(uint32_t inst);
int inst_A64_is_indirect_branch(uint32_t inst);
int inst_ARM_is_branch_and_link(uint32_t inst);
int inst_Thumb_is_branch_and_link(uint32_t inst);
int inst_A64_is_branch_and_link(uint32_t inst);
int inst_ARM_is_conditional(uint32_t inst);
int inst_Thumb_is_conditional(uint32_t inst);
int inst_A64_is_conditional(uint32_t inst);
/* For an IT instruction, return the number of instructions conditionalized
(from 1 to 4). For other instructions, return zero. */
unsigned int inst_Thumb_is_IT(uint32_t inst);
typedef enum {
ARM_BARRIER_NONE,
ARM_BARRIER_ISB,
ARM_BARRIER_DMB,
ARM_BARRIER_DSB
} arm_barrier_t;
arm_barrier_t inst_ARM_barrier(uint32_t inst);
arm_barrier_t inst_Thumb_barrier(uint32_t inst);
arm_barrier_t inst_A64_barrier(uint32_t inst);
/*
Test whether an instruction is definitely undefined, e.g. because
allocated to a "permanently UNDEFINED" space (UDF mnemonic).
Other instructions besides the ones indicated, may always or
sometimes cause an undefined instruction trap. This call is
intended to be helpful in 'runaway decode' prevention.
*/
int inst_ARM_is_UDF(uint32_t inst);
int inst_Thumb_is_UDF(uint32_t inst);
int inst_A64_is_UDF(uint32_t inst);
/* access sub-type information */
ocsd_instr_subtype get_instr_subtype();
void clear_instr_subtype();
#endif // ARM_TRC_IDEC_ARMINST_H_INCLUDED
/* End of File trc_idec_arminst.h */

View File

@ -0,0 +1,58 @@
/*
* \file trc_abs_typed_base_i.h
* \brief OpenCSD :
*
* \copyright Copyright (c) 2016, 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_ABS_TYPED_BASE_I_H_INCLUDED
#define ARM_TRC_ABS_TYPED_BASE_I_H_INCLUDED
/*!
* @class ITrcTypedBase
* @brief Abstract base class to for interfaces templated types.
*
* This class is used as an abstract base for any interfaces that are specialised using
* template<> types.
*
* Designed to allow interface objects to be passed through generic interfaces into type
* specific templated implmentation handlers and converted/checked using RTTI.
*/
class ITrcTypedBase
{
public:
ITrcTypedBase() {};
virtual ~ITrcTypedBase() {};
};
#endif // ARM_TRC_ABS_TYPED_BASE_I_H_INCLUDED
/* End of File trc_abs_typed_base_i.h */

View File

@ -0,0 +1,84 @@
/*
* \file trc_data_raw_in_i.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_TRCDATA_RAW_IN_I_H_INCLUDED
#define ARM_TRCDATA_RAW_IN_I_H_INCLUDED
#include "opencsd/ocsd_if_types.h"
/** @class ITrcDataIn
*
* @brief Interface to either trace data frame deformatter or packet processor.
*
* @ingroup ocsd_interfaces
*
* Interface class to a processor that can consume raw formatted trace byte stream from a trace reader
* or raw source buffer into a deformatter object.
*
* Also used to interface a single trace source ID data stream into a packet processor.
*
*/
class ITrcDataIn {
public:
ITrcDataIn() {}; /**< Default constructor. */
virtual ~ITrcDataIn() {}; /**< Default destructor. */
/*!
* Data input method for a component on the Trace decode datapath.
* Datapath operations passed to the component, which responds with data path response codes.
*
* This API is for raw trace data, which can be:-
* - CoreSight formatted frame data for input to the frame deformatter.
* - Single binary source data for input to a packet decoder.
*
* @param op : Data path operation.
* @param index : Byte index of start of pDataBlock data as offset from start of captured data. May be zero for none-data operation
* @param dataBlockSize : Size of data block. Zero for none-data operation.
* @param *pDataBlock : pointer to data block. Null for none-data operation
* @param *numBytesProcessed : Pointer to count of data used by processor. Set by processor on data operation. Null for none-data operation
*
* @return ocsd_datapath_resp_t : Standard data path response code.
*/
virtual ocsd_datapath_resp_t TraceDataIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed) = 0;
};
#endif // ARM_TRCDATA_RAW_IN_I_H_INCLUDED
/* End of File trc_data_raw_in_i.h */

View File

@ -0,0 +1,81 @@
/*
* \file trc_data_rawframe_in_i.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_TRCDATA_RAWFRAME_IN_I_H_INCLUDED
#define ARM_TRCDATA_RAWFRAME_IN_I_H_INCLUDED
#include "opencsd/ocsd_if_types.h"
/*!
* @class ITrcRawFrameIn
*
* @brief Interface to monitor the raw frame decode progress..
*
* @ingroup ocsd_interfaces
*
* This interface allows a program to monitor the contents of the CoreSight frames passing through the
* frame deformatter.
*
*
*/
class ITrcRawFrameIn {
public:
ITrcRawFrameIn() {}; /**< Default constructor. */
virtual ~ITrcRawFrameIn() {}; /**< Default destructor. */
/*!
* Interface to monitor CoreSight frame data. Output as blocks of data.
*
* @param op : Data path operation.
* @param index : Byte index of start of pDataBlock data as offset from start of captured data. May be zero for none-data operation
* @param frame_element : Type of frame element being output.
* @param dataBlockSize : size of frame element.
* @param *pDataBlock : pointer to frame data.
* @param traceID : Trace ID when element type ID data.
*
* @return ocsd_err_t : Standard library erroc code. Monitor only, not on data path.
*/
virtual ocsd_err_t TraceRawFrameIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index,
const ocsd_rawframe_elem_t frame_element,
const int dataBlockSize,
const uint8_t *pDataBlock,
const uint8_t traceID) = 0;
};
#endif // ARM_TRCDATA_RAWFRAME_IN_I_H_INCLUDED
/* End of File trc_data_rawframe_in_i.h */

View File

@ -0,0 +1,134 @@
/*!
* \file trc_error_log_i.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_ERROR_LOG_I_H_INCLUDED
#define ARM_TRC_ERROR_LOG_I_H_INCLUDED
#include "opencsd/ocsd_if_types.h"
#include <string>
class ocsdError;
class ocsdMsgLogger;
/*!
* @class ITraceErrorLog
* @brief Error logging interface.
* @ingroup ocsd_interfaces
*
* This class provides a standard interface to the decoder error logger for all trace decode and
* reader components.
*
* Implementation will determine if and how the errors and messages are logged.
*
*/
class ITraceErrorLog
{
public:
ITraceErrorLog() {}; /**< default constructor */
virtual ~ITraceErrorLog() {}; /**< default destructor */
/*!
* Register a named component error source. Allows the logger to associate errors with components.
* returned handle to be used with subsequent error log calls.
*
* @param &component_name : name of the component.
*
* @return virtual const : Handle associated with the component.
*/
virtual const ocsd_hndl_err_log_t RegisterErrorSource(const std::string &component_name) = 0;
/*!
* Return the verbosity level of the logger. Errors of the returned ocsd_err_severity_t severity
* or lower will be logged, others are ignored.
*
* @return ocsd_err_severity_t : Current logging severity level.
*/
virtual const ocsd_err_severity_t GetErrorLogVerbosity() const = 0;
/*!
* Log an error.
* Pass an error object and the component or generic handle to associate with the error.
* Error will be saved for access by GetLastError().
*
* If logger implementation has output print logging enabled then this may be printed to file or screen.
*
* @param handle : Component handle or standard generic handle
* @param *Error : Pointer to an error object.
*/
virtual void LogError(const ocsd_hndl_err_log_t handle, const ocsdError *Error) = 0;
/*!
* Log a general message. Associated with component or use generic handle.
* Message logged to same output as errors if output enabled, but not saved for GetLastError()
*
* @param handle : Component handle or standard generic handle.
* @param filter_level : Verbosity filter.
* @param msg : Pointer to an error object.
*/
virtual void LogMessage(const ocsd_hndl_err_log_t handle, const ocsd_err_severity_t filter_level, const std::string &msg ) = 0;
/*!
* Get a pointer to the last logged error.
* Returns 0 if no errors have been logged.
*
* @return ocsdError *: last error pointer.
*/
virtual ocsdError *GetLastError() = 0;
/*!
* Get the last error associated with the given Trace source channel ID.
* returns a pointer to the error or 0 if no errors associated with the ID.
*
* @param chan_id : ID.
*
* @return ocsdError *: last error pointer for ID or 0.
*/
virtual ocsdError *GetLastIDError(const uint8_t chan_id) = 0;
virtual ocsdMsgLogger *getOutputLogger() = 0;
virtual void setOutputLogger(ocsdMsgLogger *pLogger) = 0;
enum generic_handles {
HANDLE_GEN_ERR = 0,
HANDLE_GEN_WARN,
HANDLE_GEN_INFO,
/* last value in list */
HANDLE_FIRST_REGISTERED_COMPONENT /**< 1st valid handle value for components registered with logger */
};
};
#endif // ARM_TRC_ERROR_LOG_I_H_INCLUDED
/* End of File trc_error_log_i.h */

View File

@ -0,0 +1,77 @@
/*
* \file trc_gen_elem_in_i.h
* \brief OpenCSD : Generic Trace Element interface.
*
* \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_GEN_ELEM_IN_I_H_INCLUDED
#define ARM_TRC_GEN_ELEM_IN_I_H_INCLUDED
class OcsdTraceElement;
/*!
* @class ITrcGenElemIn
* @brief Interface for the input of generic trace elements.
*
* @ingroup ocsd_interfaces
*
* This interface is the principal output attachment point for the trace packet decoders.
*
*/
class ITrcGenElemIn
{
public:
ITrcGenElemIn() {}; /**< Default constructor. */
virtual ~ITrcGenElemIn() {}; /**< Default destructor. */
/*!
* Interface for analysis blocks that take generic trace elements as their input.
* Final interface on the decode data path. The index provided is that for the generating
* trace packet. Multiple generic elements may be produced from a single packet so they will
* all have the same start index.
*
* @param index_sop : Trace index for start of packet generating this element.
* @param trc_chan_id : CoreSight Trace ID for this source.
* @param &elem : Generic trace element generated from the deocde data path
*
* @return ocsd_datapath_resp_t : Standard data path response.
*/
virtual ocsd_datapath_resp_t TraceElemIn(const ocsd_trc_index_t index_sop,
const uint8_t trc_chan_id,
const OcsdTraceElement &elem) = 0;
};
#endif // ARM_TRC_GEN_ELEM_IN_I_H_INCLUDED
/* End of File trc_gen_elem_in_i.h */

View File

@ -0,0 +1,77 @@
/*
* \file trc_indexer_pkt_i.h
* \brief OpenCSD : Trace packet indexer
*
* \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_INDEXER_PKT_I_H_INCLUDED
#define ARM_TRC_INDEXER_PKT_I_H_INCLUDED
#include "trc_abs_typed_base_i.h"
/*!
* @class ITrcPktIndexer
* @brief Templated interface class to index packet types.
*
* @ingroup ocsd_interfaces
*
* Each protocol version will have an associated indexer that will index significant
* packets such as synchronisation points, timestamps, trigger events.
*
* Creating an index is optional at runtime, but will allow any analysis program to synchronise the
* different trace streams.
*
* Indexes need to be created only once and can be saved for re-use.
*
* Packet processors should be created to support the attachment of an indexer.
*
*/
template <class Pt>
class ITrcPktIndexer : public ITrcTypedBase
{
public:
ITrcPktIndexer() {}; /**< Default constructor. */
virtual ~ITrcPktIndexer() {}; /**< Default destructor. */
/*!
* Interface method for trace packet indexing. Implementated by a channel packet indexer.
*
* @param index_sop : trace index at the start of the packet.
* @param *packet_type : The packet type being indexed.
*/
virtual void TracePktIndex(const ocsd_trc_index_t index_sop, const Pt *packet_type) = 0;
};
#endif // ARM_TRC_INDEXER_PKT_I_H_INCLUDED
/* End of File trc_indexer_pkt_i.h */

View File

@ -0,0 +1,124 @@
/*
* \file trc_indexer_src_i.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_INDEXER_SRC_I_H_INCLUDED
#define ARM_TRC_INDEXER_SRC_I_H_INCLUDED
#include <vector>
#include "opencsd/ocsd_if_types.h"
/*!
* @class ITrcSrcIndexCreator
*
* @brief Interface class to index the frame formatted trace stream
*
* @ingroup ocsd_interfaces
*
* This indexer creates an index of trace IDs present in the frame formatted trace stream.
* It will also index any trigger point markers indicated in the frame format.
*
* Indexing is optional at runtime. Indexes can be saved and re-used.
*/
class ITrcSrcIndexCreator
{
public:
ITrcSrcIndexCreator() {}; /**< Default constructor. */
virtual ~ITrcSrcIndexCreator() {}; /**< Default destructor. */
/*!
* The size of block that the indexer will split trace into - this is effectively the
* index granularity. The indexing will indicate if an indexed element - e.g. a source
* ID - is present in the block. Smaller granularity will mean a larger index but more
* resolution in IDs and event positions.
*
* Block sizes will be power of 2 aligned, not less 256 bytes (16 frames).
* Indexer will choose block size based on total trace size and desired granularity.
*
* @return uint32_t : Size of indexing block.
*/
virtual const uint32_t IndexBlockSize() const;
/*!
* Index a single ID
*
* @param src_idx : trace index of source ID
* @param ID : The source ID.
*
* @return virtual ocsd_err_t : OCSD_OK if successful.
*/
virtual ocsd_err_t TrcIDIndex(const ocsd_trc_index_t src_idx, const uint8_t ID) = 0;
/*!
* Index a set of IDs in a block.
* Block is assumed to be one of size IndexBlockSize()
*
* May be used by the deformatter to collate IDs and reduce indexing calls.
* May be used by hardware capture source that has its own index of IDs, to transfer
* indexing information into the decoder indexer.
*
* @param src_idx_start : Index of start of block.
* @param IDs : IDs within the block.
*
* @return virtual ocsd_err_t : OCSD_OK if successful.
*/
virtual ocsd_err_t TrcIDBlockMap(const ocsd_trc_index_t src_idx_start, const std::vector<uint8_t> IDs) = 0;
/*!
* The CoreSight frame format can use a reserved ID to indicate trigger or other
* events programmed into the trace protocol generator.
* This call indexes these events.
*
* @param src_idx : trace index of the event.
* @param event_type : type of event.
*
* @return ocsd_err_t : OCSD_OK if indexed correctly, OCSD_ERR_INVALID_PARAM_VAL if incorrect value used.
*/
virtual ocsd_err_t TrcEventIndex(const ocsd_trc_index_t src_idx, const int event_type) = 0;
/*!
* When the frame formatter is using frame syncs (typically TPIU output captured on off chip capture
* device), this index call notes the position of these elements.
*
* @param src_idx : trace index of sync point.
*/
virtual void TrcSyncIndex(const ocsd_trc_index_t src_idx);
};
#endif // ARM_TRC_INDEXER_SRC_I_H_INCLUDED
/* End of File trc_indexer_src_i.h */

View File

@ -0,0 +1,66 @@
/*
* \file trc_instr_decode_i.h
* \brief OpenCSD : Interface for instruction decode.
*
* \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_INSTR_DECODE_I_H_INCLUDED
#define ARM_TRC_INSTR_DECODE_I_H_INCLUDED
/*!
* @class IInstrDecode
* @ingroup ocsd_interfaces
* @brief Interface class to an instruction opcode decoder.
*
* The opcode decoder needs to be capable of limited decode required for trace
* execution flow determination.
*
*/
class IInstrDecode
{
public:
IInstrDecode() {}; /**< Default constructor. */
virtual ~IInstrDecode() {}; /**< Default destructor. */
/*!
* Instruction opcode decode for the packet trace decoder to follow the
* instruction execution flow.
*
* @param *instr_info : Structure to pass current opcode, and receive required decode information.
*
* @return ocsd_err_t : OCSD_OK if successful.
*/
virtual ocsd_err_t DecodeInstruction(ocsd_instr_info *instr_info) = 0;
};
#endif // ARM_TRC_INSTR_DECODE_I_H_INCLUDED
/* End of File trc_instr_decode_i.h */

View File

@ -0,0 +1,80 @@
/*
* \file trc_pkt_in_i.h
* \brief OpenCSD : Interface for trace protocol packet input
*
* \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_IN_I_H_INCLUDED
#define ARM_TRC_PKT_IN_I_H_INCLUDED
#include "trc_abs_typed_base_i.h"
/*!
* @class IPktDataIn
* @ingroup ocsd_interfaces
* @brief Interface class providing an input for discrete protocol packets.
*
* Implemented by trace protocol packet decoders to convert packets into
* generic trace elements.
*
* Packet class used will contain information on the latest packet,
* and any intra-packet state.
*
*/
template<class P>
class IPktDataIn : public ITrcTypedBase
{
public:
IPktDataIn() {}; /**< Default constructor. */
virtual ~IPktDataIn() {}; /**< Default destructor. */
/*!
* Interface function to process a single protocol packet.
* Pass a trace index for the start of packet and a pointer to a packet when the
* datapath operation is OCSD_OP_DATA.
*
* @param op : Datapath operation.
* @param index_sop : Trace index for the start of the packet, 0 if not OCSD_OP_DATA.
* @param *p_packet_in : Protocol Packet - when data path operation is OCSD_OP_DATA. null otherwise.
*
* @return ocsd_datapath_resp_t : Standard data path response.
*/
virtual ocsd_datapath_resp_t PacketDataIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const P *p_packet_in) = 0;
};
#endif // ARM_TRC_PKT_IN_I_H_INCLUDED
/* End of File trc_proc_pkt_in_i.h */

View File

@ -0,0 +1,83 @@
/*
* \file trc_pkt_raw_in_i.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_RAW_IN_I_H_INCLUDED
#define ARM_TRC_PKT_RAW_IN_I_H_INCLUDED
#include "trc_abs_typed_base_i.h"
/*!
* @class IPktRawDataMon
*
* @brief Interface class for packet processor monitor.
*
* @addtogroup ocsd_interfaces
*
* This interface provides a monitor point for the packet processor block.
* The templated interface is called with a complete packet of the given
* type, plus the raw packet bytes. Use for tools which need to display compplete
* packets or require additional processing on raw packet data.
*
* This interface is not part of the data decode path and cannot provide feedback.
*
*/
template<class P>
class IPktRawDataMon : public ITrcTypedBase
{
public:
IPktRawDataMon() {}; /**< Default constructor. */
virtual ~IPktRawDataMon() {}; /**< Default destructor. */
/*!
* Interface monitor function called with a complete packet, or other
* data path operation.
*
* @param op : Datapath operation
* @param index_sop : start of packet index
* @param *pkt : The expanded packet
* @param size : size of packet data bytes
* @param *p_data : the packet data bytes.
*
*/
virtual void RawPacketDataMon( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const P *pkt,
const uint32_t size,
const uint8_t *p_data) = 0;
};
#endif // ARM_TRC_PKT_RAW_IN_I_H_INCLUDED
/* End of File trc_pkt_raw_in_i.h */

View File

@ -0,0 +1,91 @@
/*
* \file trc_tgt_mem_access_i.h
* \brief OpenCSD : Target memory read interface.
*
* \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_TGT_MEM_ACCESS_I_H_INCLUDED
#define ARM_TRC_TGT_MEM_ACCESS_I_H_INCLUDED
/*!
* @class ITargetMemAccess
*
* @brief Interface to target memory access.
*
* @ingroup ocsd_interfaces
*
* Read Target memory call is used by the decoder to access the memory location in the
* target memory space for the next instruction(s) to be traced.
*
* Memory data returned is to be little-endian.
*
* The implementator of this interface could either use file(s) containing dumps of memory
* locations from the target, be an elf file reader extracting code, or a live target
* connection, depending on the tool execution context.
*
*
*/
class ITargetMemAccess
{
public:
ITargetMemAccess() {}; /**< default interface constructor */
virtual ~ITargetMemAccess() {}; /**< default interface destructor */
/*!
* Read a block of target memory into supplied buffer.
*
* Bytes read set less than bytes required, along with a success return code indicates full memory
* location not accessible. Function will return all accessible bytes from the address up to the point
* where the first inaccessible location appears.
*
* The cs_trace_id associates a memory read with a core. Different cores may have different memory spaces,
* the memory access may take this into account. Access will first look in the registered memory areas
* associated with the ID, failing that will look into any global memory spaces.
*
* @param address : Address to access.
* @param cs_trace_id : protocol source trace ID.
* @param mem_space : Memory space to access, (secure, non-secure, optionally with EL, or any).
* @param num_bytes : [in] Number of bytes required. [out] Number of bytes actually read.
* @param *p_buffer : Buffer to fill with the bytes.
*
* @return ocsd_err_t : OCSD_OK on successful access (including memory not available)
*/
virtual ocsd_err_t ReadTargetMemory( const ocsd_vaddr_t address,
const uint8_t cs_trace_id,
const ocsd_mem_space_acc_t mem_space,
uint32_t *num_bytes,
uint8_t *p_buffer) = 0;
};
#endif // ARM_TRC_TGT_MEM_ACCESS_I_H_INCLUDED
/* End of File trc_tgt_mem_access_i.h */

View File

@ -0,0 +1,47 @@
/*
* \file trc_mem_acc.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_MEM_ACC_H_INCLUDED
#define ARM_TRC_MEM_ACC_H_INCLUDED
#include "trc_mem_acc_base.h"
#include "trc_mem_acc_bufptr.h"
#include "trc_mem_acc_file.h"
#include "trc_mem_acc_mapper.h"
#include "trc_mem_acc_cb.h"
#endif // ARM_TRC_MEM_ACC_H_INCLUDED
/* End of File trc_mem_acc.h */

View File

@ -0,0 +1,244 @@
/*!
* \file trc_mem_acc_base.h
* \brief OpenCSD : Memory accessor base class.
*
* \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_MEM_ACC_BASE_H_INCLUDED
#define ARM_TRC_MEM_ACC_BASE_H_INCLUDED
#include "opencsd/ocsd_if_types.h"
#include <string>
/*!
* @class TrcMemAccessorBase
* @brief Memory range to access by trace decoder.
*
* Represents a memory access range for the trace decoder.
* Range inclusive from m_startAddress to m_endAddress.
* e.g. a 1k range from 0x1000 has start of 0x1000 and end of 0x13FF
*
* Derived classes provide specific access types such as binary files and memory buffers.
*
*/
class TrcMemAccessorBase
{
public:
/** Describes the storage type of the underlying memory accessor */
enum MemAccTypes {
MEMACC_UNKNOWN,
MEMACC_FILE, //<! Binary data file accessor
MEMACC_BUFPTR, //<! memory buffer accessor
MEMACC_CB_IF, //<! callback interface accessor - use for live memory access
};
/** default constructor */
TrcMemAccessorBase(MemAccTypes type);
/** costruct with address range values */
TrcMemAccessorBase(MemAccTypes type, ocsd_vaddr_t startAddr, ocsd_vaddr_t endAddr);
/** default desctructor */
virtual ~TrcMemAccessorBase() {};
/*!
* Set the inclusive address range of this accessor.
*
* @param startAddr : start address of the range.
* @param endAddr : end address of the range.
*/
void setRange(ocsd_vaddr_t startAddr, ocsd_vaddr_t endAddr);
/*!
* test if an address is in the inclusive range for this accessor
*
* @param s_address : Address to test.
*
* @return const bool : true if the address is in range.
*/
virtual const bool addrInRange(const ocsd_vaddr_t s_address) const;
/*!
* test if an address is the start of range for this accessor
*
* @param s_address : Address to test.
*
* @return const bool : true if the address is start of range.
*/
virtual const bool addrStartOfRange(const ocsd_vaddr_t s_address) const;
/*!
* Test number of bytes available from the start address, up to the number of requested bytes.
* Tests if all the requested bytes are available from the supplied start address.
* Returns the number available up to full requested amount.
*
* @param s_address : Start address within the range.
* @param reqBytes : Number of bytes needed from the start address.
*
* @return const uint32_t : Bytes available, up to reqBytes. 0 is s_address not in range.
*/
virtual const uint32_t bytesInRange(const ocsd_vaddr_t s_address, const uint32_t reqBytes) const;
/*!
* test is supplied range accessor overlaps this range.
*
* @param *p_test_acc : Accessor to test for overlap.
*
* @return bool : true if overlap, false if not.
*/
virtual const bool overLapRange(const TrcMemAccessorBase *p_test_acc) const;
/*!
* Read bytes from via the accessor from the memory range.
*
* @param s_address : Start address of the read.
* @param memSpace : memory space for this access.
* @param reqBytes : Number of bytes required.
* @param *byteBuffer : Buffer to copy the bytes into.
*
* @return uint32_t : Number of bytes read, 0 if s_address out of range, or mem space not accessible.
*/
virtual const uint32_t readBytes(const ocsd_vaddr_t s_address, const ocsd_mem_space_acc_t memSpace, const uint32_t reqBytes, uint8_t *byteBuffer) = 0;
/*!
* Validate the address range - ensure addresses aligned, different, st < en etc.
*
* @return bool : true if valid range.
*/
virtual const bool validateRange();
const enum MemAccTypes getType() const { return m_type; };
/* handle memory spaces */
void setMemSpace(ocsd_mem_space_acc_t memSpace) { m_mem_space = memSpace; };
const ocsd_mem_space_acc_t getMemSpace() const { return m_mem_space; };
const bool inMemSpace(const ocsd_mem_space_acc_t mem_space) const { return (bool)(((uint8_t)m_mem_space & (uint8_t)mem_space) != 0); };
/* memory access info logging */
virtual void getMemAccString(std::string &accStr) const;
protected:
ocsd_vaddr_t m_startAddress; /**< accessible range start address */
ocsd_vaddr_t m_endAddress; /**< accessible range end address */
const MemAccTypes m_type; /**< memory accessor type */
ocsd_mem_space_acc_t m_mem_space;
};
inline TrcMemAccessorBase::TrcMemAccessorBase(MemAccTypes accType, ocsd_vaddr_t startAddr, ocsd_vaddr_t endAddr) :
m_startAddress(startAddr),
m_endAddress(endAddr),
m_type(accType),
m_mem_space(OCSD_MEM_SPACE_ANY)
{
}
inline TrcMemAccessorBase::TrcMemAccessorBase(MemAccTypes accType) :
m_startAddress(0),
m_endAddress(0),
m_type(accType),
m_mem_space(OCSD_MEM_SPACE_ANY)
{
}
inline void TrcMemAccessorBase::setRange(ocsd_vaddr_t startAddr, ocsd_vaddr_t endAddr)
{
m_startAddress = startAddr;
m_endAddress = endAddr;
}
inline const bool TrcMemAccessorBase::addrInRange(const ocsd_vaddr_t s_address) const
{
return (s_address >= m_startAddress) && (s_address <= m_endAddress);
}
inline const bool TrcMemAccessorBase::addrStartOfRange(const ocsd_vaddr_t s_address) const
{
return (s_address == m_startAddress);
}
inline const uint32_t TrcMemAccessorBase::bytesInRange(const ocsd_vaddr_t s_address, const uint32_t reqBytes) const
{
ocsd_vaddr_t bytesInRange = 0;
if(addrInRange(s_address)) // start not in range, return 0.
{
// bytes available till end address.
bytesInRange = m_endAddress - s_address + 1;
if(bytesInRange > reqBytes)
bytesInRange = reqBytes;
}
return (uint32_t)bytesInRange;
}
inline const bool TrcMemAccessorBase::overLapRange(const TrcMemAccessorBase *p_test_acc) const
{
if( addrInRange(p_test_acc->m_startAddress) ||
addrInRange(p_test_acc->m_endAddress)
)
return true;
return false;
}
inline const bool TrcMemAccessorBase::validateRange()
{
if(m_startAddress & 0x1) // at least hword aligned for thumb
return false;
if((m_endAddress + 1) & 0x1)
return false;
if(m_startAddress == m_endAddress) // zero length range.
return false;
if(m_startAddress > m_endAddress) // values bakcwards / invalid
return false;
return true;
}
class TrcMemAccFactory
{
public:
/** Accessor Creation */
static ocsd_err_t CreateBufferAccessor(TrcMemAccessorBase **pAccessor, const ocsd_vaddr_t s_address, const uint8_t *p_buffer, const uint32_t size);
static ocsd_err_t CreateFileAccessor(TrcMemAccessorBase **pAccessor, const std::string &pathToFile, ocsd_vaddr_t startAddr, size_t offset = 0, size_t size = 0);
static ocsd_err_t CreateCBAccessor(TrcMemAccessorBase **pAccessor, const ocsd_vaddr_t s_address, const ocsd_vaddr_t e_address, const ocsd_mem_space_acc_t mem_space);
/** Accessor Destruction */
static void DestroyAccessor(TrcMemAccessorBase *pAccessor);
private:
TrcMemAccFactory() {};
~TrcMemAccFactory() {};
};
#endif // ARM_TRC_MEM_ACC_BASE_H_INCLUDED
/* End of File trc_mem_acc_base.h */

View File

@ -0,0 +1,76 @@
/*
* \file trc_mem_acc_bufptr.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_MEM_ACC_BUFPTR_H_INCLUDED
#define ARM_TRC_MEM_ACC_BUFPTR_H_INCLUDED
#include "mem_acc/trc_mem_acc_base.h"
/*!
* @class TrcMemAccBufPtr:
* @brief Trace memory accessor for a memory buffer.
*
* Wraps a memory buffer in an memory range accessor object.
* Takes a copy of the buffer pointer which must remain valid
* for the lifetime of the object.
*
*/
class TrcMemAccBufPtr: public TrcMemAccessorBase
{
public:
/*!
* Construct the accessor.
* uses the start address as the start of range and calculates the end address
* according to the buffer size
*
* @param s_address : Start address in memory map represented by the data in the buffer.
* @param *p_buffer : pointer to a buffer of binary data.
* @param size : size of the buffer.
*
*/
TrcMemAccBufPtr(const ocsd_vaddr_t s_address, const uint8_t *p_buffer, const uint32_t size);
virtual ~TrcMemAccBufPtr() {}; /**< default destructor */
/** Memory access override - allow decoder to read bytes from the buffer. */
virtual const uint32_t readBytes(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t memSpace, const uint32_t reqBytes, uint8_t *byteBuffer);
private:
const uint8_t *m_p_buffer; /**< pointer to the memory buffer */
const uint32_t m_size; /**< size of the memory buffer. */
};
#endif // ARM_TRC_MEM_ACC_BUFPTR_H_INCLUDED
/* End of File trc_mem_acc_bufptr.h */

View File

@ -0,0 +1,81 @@
/*!
* \file trc_mem_acc_cb.h
* \brief OpenCSD : Callback trace memory accessor.
*
* \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_MEM_ACC_CB_H_INCLUDED
#define ARM_TRC_MEM_ACC_CB_H_INCLUDED
#include "mem_acc/trc_mem_acc_base.h"
#include "mem_acc/trc_mem_acc_cb_if.h"
class TrcMemAccCB : public TrcMemAccessorBase
{
public:
TrcMemAccCB(const ocsd_vaddr_t s_address,
const ocsd_vaddr_t e_address,
const ocsd_mem_space_acc_t mem_space);
virtual ~TrcMemAccCB() {};
/** Memory access override - allow decoder to read bytes from the buffer. */
virtual const uint32_t readBytes(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t memSpace, const uint32_t reqBytes, uint8_t *byteBuffer);
void setCBIfClass(TrcMemAccCBIF *p_if);
void setCBIfFn(Fn_MemAcc_CB p_fn, const void *p_context);
private:
TrcMemAccCBIF *m_p_CBclass; //<! callback class.
Fn_MemAcc_CB m_p_CBfn; //<! callback function.
const void *m_p_cbfn_context; //<! context pointer for callback function.
};
inline void TrcMemAccCB::setCBIfClass(TrcMemAccCBIF *p_if)
{
m_p_CBclass = p_if;
m_p_CBfn = 0; // only one callback type per accessor.
m_p_cbfn_context = 0;
}
inline void TrcMemAccCB::setCBIfFn(Fn_MemAcc_CB p_fn, const void *p_context)
{
m_p_CBfn = p_fn;
m_p_cbfn_context = p_context;
m_p_CBclass = 0; // only one callback type per accessor.
}
#endif // ARM_TRC_MEM_ACC_CB_H_INCLUDED
/* End of File trc_mem_acc_cb.h */

View File

@ -0,0 +1,71 @@
/*!
* \file trc_mem_acc_cb_if.h
* \brief OpenCSD : Memory Accessor Callback Direct Interface
*
* \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_MEM_ACC_CB_IF_H_INCLUDED
#define ARM_TRC_MEM_ACC_CB_IF_H_INCLUDED
#include "opencsd/ocsd_if_types.h"
/*!
* @class TrcMemAccCBIF
* @brief Interface class to implement memory accessor callbacks
*
* Implement an object with this interface to use in a memory accessor callback type.
* Callback accesses the memory according to address and memory space.
* Use for trace decode memory access on live systems, or where the implemented accessor types
* are not suitable for the memory data being accessed.
*
*/
class TrcMemAccCBIF
{
public:
TrcMemAccCBIF() {};
virtual ~TrcMemAccCBIF() {};
/*!
* Read bytes from via the accessor from the memory range.
*
* @param s_address : Start address of the read.
* @param memSpace : memory space for this access.
* @param reqBytes : Number of bytes required.
* @param *byteBuffer : Buffer to copy the bytes into.
*
* @return uint32_t : Number of bytes read, 0 if s_address out of range, or mem space not accessible.
*/
virtual const uint32_t readBytes(const ocsd_vaddr_t s_address, const ocsd_mem_space_acc_t memSpace, const uint32_t reqBytes, uint8_t *byteBuffer) = 0;
};
#endif // ARM_TRC_MEM_ACC_CB_IF_H_INCLUDED
/* End of File trc_mem_acc_cb_if.h */

View File

@ -0,0 +1,234 @@
/*
* \file trc_mem_acc_file.h
* \brief OpenCSD : Access binary target memory file
*
* \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_MEM_ACC_FILE_H_INCLUDED
#define ARM_TRC_MEM_ACC_FILE_H_INCLUDED
#include <map>
#include <string>
#include <fstream>
#include <list>
#include "opencsd/ocsd_if_types.h"
#include "mem_acc/trc_mem_acc_base.h"
// an add-on region to a file - allows setting of a region at a none-zero offset for a file.
class FileRegionMemAccessor : public TrcMemAccessorBase
{
public:
FileRegionMemAccessor() : TrcMemAccessorBase(MEMACC_FILE) {};
virtual ~FileRegionMemAccessor() {};
void setOffset(const size_t offset) { m_file_offset = offset; };
const size_t getOffset() const { return m_file_offset; };
bool operator<(const FileRegionMemAccessor& rhs) { return this->m_startAddress < rhs.m_startAddress; };
// not going to use these objects to read bytes - defer to the file class for that.
virtual const uint32_t readBytes(const ocsd_vaddr_t s_address, const ocsd_mem_space_acc_t memSpace, const uint32_t reqBytes, uint8_t *byteBuffer) { return 0; };
const ocsd_vaddr_t regionStartAddress() const { return m_startAddress; };
private:
size_t m_file_offset;
};
/*!
* @class TrcMemAccessorFile
* @brief Memory accessor for a binary file.
*
* Memory accessor based on a binary file snapshot of some memory.
*
* Static creation code to allow reference counted accessor usable for
* multiple access maps attached to multiple source trees for the same system.
*/
class TrcMemAccessorFile : public TrcMemAccessorBase
{
public:
/** read bytes override - reads from file */
virtual const uint32_t readBytes(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t memSpace, const uint32_t reqBytes, uint8_t *byteBuffer);
protected:
TrcMemAccessorFile(); /**< protected default constructor */
virtual ~ TrcMemAccessorFile(); /**< protected default destructor */
/** increment reference counter */
void IncRefCount() { m_ref_count++; };
/** decrement reference counter */
void DecRefCount() { m_ref_count--; };
/** get current reference count */
const int getRefCount() const { return m_ref_count; };
/*!
* Initialise accessor with file name and path, and start address.
* File opened and length calculated to determine end address for the range.
*
* @param &pathToFile : Binary file path and name
* @param startAddr : system memory address associated with start of binary datain file.
*
* @return bool : true if set up successfully, false if file could not be opened.
*/
ocsd_err_t initAccessor(const std::string &pathToFile, ocsd_vaddr_t startAddr, size_t offset, size_t size);
/** get the file path */
const std::string &getFilePath() const { return m_file_path; };
/** get an offset region if extant for the address */
FileRegionMemAccessor *getRegionForAddress(const ocsd_vaddr_t startAddr) const;
/* validate ranges */
virtual const bool validateRange();
public:
/*!
* File may contain multiple none-overlapping ranges in a single file.
*
* @param startAddr : Address for beginning of byte data.
* @param size : size of range in bytes.
* @param offset : offset into file for that data.
*
* @return bool : true if set successfully.
*/
bool AddOffsetRange(const ocsd_vaddr_t startAddr, const size_t size, const size_t offset);
/*!
* Override in case we have multiple regions in the file.
*
* @param s_address : Address to test.
*
* @return const bool : true if the address is in range.
*/
virtual const bool addrInRange(const ocsd_vaddr_t s_address) const;
/*!
* test if an address is the start of range for this accessor
*
* @param s_address : Address to test.
*
* @return const bool : true if the address is start of range.
*/
virtual const bool addrStartOfRange(const ocsd_vaddr_t s_address) const;
/*!
* Test number of bytes available from the start address, up to the number of requested bytes.
* Tests if all the requested bytes are available from the supplied start address.
* Returns the number available up to full requested amount.
*
* @param s_address : Start address within the range.
* @param reqBytes : Number of bytes needed from the start address.
*
* @return const uint32_t : Bytes available, up to reqBytes. 0 is s_address not in range.
*/
virtual const uint32_t bytesInRange(const ocsd_vaddr_t s_address, const uint32_t reqBytes) const;
/*!
* test is supplied range accessor overlaps this range.
*
* @param *p_test_acc : Accessor to test for overlap.
*
* @return bool : true if overlap, false if not.
*/
virtual const bool overLapRange(const TrcMemAccessorBase *p_test_acc) const;
/*! Override to handle ranges and offset accessors plus add in file name. */
virtual void getMemAccString(std::string &accStr) const;
/*!
* Create a file accessor based on the supplied path and address.
* Keeps a list of file accessors created.
*
* File will be checked to ensure valid accessor can be created.
*
* If an accessor using the supplied file is currently in use then a reference to that
* accessor will be returned and the accessor reference counter updated.
*
* @param &pathToFile : Path to binary file
* @param startAddr : Start address of data represented by file.
*
* @return TrcMemAccessorFile * : pointer to accessor if successful, 0 if it could not be created.
*/
static ocsd_err_t createFileAccessor(TrcMemAccessorFile **p_acc, const std::string &pathToFile, ocsd_vaddr_t startAddr, size_t offset = 0, size_t size = 0);
/*!
* Destroy supplied accessor.
*
* Reference counter decremented and checked and accessor destroyed if no longer in use.
*
* @param *p_accessor : File Accessor to destroy.
*/
static void destroyFileAccessor(TrcMemAccessorFile *p_accessor);
/*!
* Test if any accessor is currently using the supplied file path
*
* @param &pathToFile : Path to test.
*
* @return bool : true if an accessor exists with this file path.
*/
static const bool isExistingFileAccessor(const std::string &pathToFile);
/*!
* Get the accessor using the supplied file path
* Use after createFileAccessor if additional memory ranges need
* adding to an exiting file accessor.
*
* @param &pathToFile : Path to test.
*
* @return TrcMemAccessorFile * : none 0 if an accessor exists with this file path.
*/
static TrcMemAccessorFile * getExistingFileAccessor(const std::string &pathToFile);
private:
static std::map<std::string, TrcMemAccessorFile *> s_FileAccessorMap; /**< map of file accessors in use. */
private:
std::ifstream m_mem_file; /**< input binary file stream */
ocsd_vaddr_t m_file_size; /**< size of the file */
int m_ref_count; /**< accessor reference count */
std::string m_file_path; /**< path to input file */
std::list<FileRegionMemAccessor *> m_access_regions; /**< additional regions in the file at non-zero offsets */
bool m_base_range_set; /**< true when offset 0 set */
bool m_has_access_regions; /**< true if single file contains multiple regions */
};
#endif // ARM_TRC_MEM_ACC_FILE_H_INCLUDED
/* End of File trc_mem_acc_file.h */

View File

@ -0,0 +1,128 @@
/*
* \file trc_mem_acc_mapper.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_MEM_ACC_MAPPER_H_INCLUDED
#define ARM_TRC_MEM_ACC_MAPPER_H_INCLUDED
#include <vector>
#include "opencsd/ocsd_if_types.h"
#include "interfaces/trc_tgt_mem_access_i.h"
#include "interfaces/trc_error_log_i.h"
#include "mem_acc/trc_mem_acc_base.h"
typedef enum _memacc_mapper_t {
MEMACC_MAP_GLOBAL,
} memacc_mapper_t;
class TrcMemAccMapper : public ITargetMemAccess
{
public:
TrcMemAccMapper();
TrcMemAccMapper(bool using_trace_id);
virtual ~TrcMemAccMapper();
// decoder memory access interface
virtual ocsd_err_t ReadTargetMemory( const ocsd_vaddr_t address,
const uint8_t cs_trace_id,
const ocsd_mem_space_acc_t mem_space,
uint32_t *num_bytes,
uint8_t *p_buffer);
// mapper memory area configuration interface
// add an accessor to this map
virtual ocsd_err_t AddAccessor(TrcMemAccessorBase *p_accessor, const uint8_t cs_trace_id) = 0;
// remove a specific accessor
virtual ocsd_err_t RemoveAccessor(const TrcMemAccessorBase *p_accessor) = 0;
// clear all attached accessors from the map
void RemoveAllAccessors();
// remove a single accessor based on address.
ocsd_err_t RemoveAccessorByAddress(const ocsd_vaddr_t st_address, const ocsd_mem_space_acc_t mem_space, const uint8_t cs_trace_id = 0);
// set the error log.
void setErrorLog(ITraceErrorLog *err_log_i) { m_err_log = err_log_i; };
// print out the ranges in this mapper.
virtual void logMappedRanges() = 0;
protected:
virtual bool findAccessor(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t cs_trace_id) = 0; // set m_acc_curr if found valid range, leave unchanged if not.
virtual bool readFromCurrent(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t cs_trace_id) = 0;
virtual TrcMemAccessorBase *getFirstAccessor() = 0;
virtual TrcMemAccessorBase *getNextAccessor() = 0;
virtual void clearAccessorList() = 0;
void LogMessage(const std::string &msg);
TrcMemAccessorBase *m_acc_curr; // most recently used - try this first.
uint8_t m_trace_id_curr; // trace ID for the current accessor
const bool m_using_trace_id; // true if we are using separate memory spaces by TraceID.
ITraceErrorLog *m_err_log; // error log to print out mappings on request.
};
// address spaces common to all sources using this mapper.
// trace id unused.
class TrcMemAccMapGlobalSpace : public TrcMemAccMapper
{
public:
TrcMemAccMapGlobalSpace();
virtual ~TrcMemAccMapGlobalSpace();
// mapper creation interface - prevent overlaps
virtual ocsd_err_t AddAccessor(TrcMemAccessorBase *p_accessor, const uint8_t cs_trace_id);
// print out the ranges in this mapper.
virtual void logMappedRanges();
protected:
virtual bool findAccessor(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t cs_trace_id);
virtual bool readFromCurrent(const ocsd_vaddr_t address,const ocsd_mem_space_acc_t mem_space, const uint8_t cs_trace_id);
virtual TrcMemAccessorBase *getFirstAccessor();
virtual TrcMemAccessorBase *getNextAccessor();
virtual void clearAccessorList();
virtual ocsd_err_t RemoveAccessor(const TrcMemAccessorBase *p_accessor);
std::vector<TrcMemAccessorBase *> m_acc_global;
std::vector<TrcMemAccessorBase *>::iterator m_acc_it;
};
#endif // ARM_TRC_MEM_ACC_MAPPER_H_INCLUDED
/* End of File trc_mem_acc_mapper.h */

View File

@ -0,0 +1,65 @@
/*
* \file ocsd_if_version.h
* \brief OpenCSD : Library API versioning
*
* \copyright Copyright (c) 2016, 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_OCSD_IF_VERSION_H_INCLUDED
#define ARM_OCSD_IF_VERSION_H_INCLUDED
#include <stdint.h>
/** @addtogroup ocsd_interfaces
@{*/
/** @name Library Versioning
@{*/
#define OCSD_VER_MAJOR 0x0 /**< Library Major Version */
#define OCSD_VER_MINOR 0x8 /**< Library Minor Version */
#define OCSD_VER_PATCH 0x2 /**< Library Patch Version */
/** Library version number - MMMMnnpp format.
MMMM = major version,
nn = minor version,
pp = patch version
*/
#define OCSD_VER_NUM (((uint32_t)OCSD_VER_MAJOR << 16) | ((uint32_t)OCSD_VER_MINOR << 8) | ((uint32_t)OCSD_VER_PATCH))
#define OCSD_VER_STRING "0.8.2" /**< Library Version string */
#define OCSD_LIB_NAME "OpenCSD Library" /**< Library name string */
#define OCSD_LIB_SHORT_NAME "OCSD" /**< Library Short name string */
/** @}*/
/** @}*/
#endif // ARM_OCSD_IF_VERSION_H_INCLUDED
/* End of File ocsd_if_version.h */

View File

@ -0,0 +1,84 @@
/*!
* \file opencsd.h
* \brief OpenCSD: Open CoreSight Trace Decoder -Master include file for C++ library
*
* \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_OPENCSD_H_INCLUDED
#define ARM_OPENCSD_H_INCLUDED
/** C interface types */
#include "opencsd/ocsd_if_types.h"
#include "opencsd/trc_pkt_types.h"
#include "opencsd/trc_gen_elem_types.h"
/* C++ abstract interfaces */
#include "interfaces/trc_data_raw_in_i.h"
#include "interfaces/trc_data_rawframe_in_i.h"
#include "interfaces/trc_error_log_i.h"
#include "interfaces/trc_gen_elem_in_i.h"
#include "interfaces/trc_instr_decode_i.h"
#include "interfaces/trc_pkt_in_i.h"
#include "interfaces/trc_pkt_raw_in_i.h"
#include "interfaces/trc_tgt_mem_access_i.h"
/* protocol base classes and generic elements */
#include "common/ocsd_version.h"
#include "common/ocsd_error.h"
#include "common/trc_gen_elem.h"
#include "common/trc_core_arch_map.h"
/** Implemented Protocol decoders */
#include "common/trc_frame_deformatter.h"
#include "opencsd/etmv3/etmv3_decoder.h"
#include "opencsd/etmv4/etmv4_decoder.h"
#include "opencsd/ptm/ptm_decoder.h"
#include "opencsd/stm/stm_decoder.h"
/** C++ library object types */
#include "common/ocsd_error_logger.h"
#include "common/ocsd_msg_logger.h"
#include "i_dec/trc_i_decode.h"
#include "mem_acc/trc_mem_acc.h"
/* printers for builtin packet elements */
#include "pkt_printers/trc_pkt_printers.h"
#include "pkt_printers/trc_print_fact.h"
/** The decode tree and decoder register*/
#include "common/ocsd_lib_dcd_register.h"
#include "common/ocsd_dcd_tree.h"
#endif // ARM_OPENCSD_H_INCLUDED
/* End of File opencsd.h */

View File

@ -0,0 +1,54 @@
/*
* \file ocsd_c_api_cust_fact.h
* \brief OpenCSD : Custom decoder factory API functions
*
* \copyright Copyright (c) 2016, 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_OCSD_C_API_CUST_FACT_H_INCLUDED
#define ARM_OCSD_C_API_CUST_FACT_H_INCLUDED
#include "ocsd_c_api_types.h"
#include "ocsd_c_api_custom.h"
/* Declarations for the functions implemented in the custom decoder factory. */
/** Required function to create a decoder instance - fills in the decoder struct supplied. */
ocsd_err_t CreateCustomDecoder(const int create_flags, const void *decoder_cfg, ocsd_extern_dcd_inst_t *p_decoder_inst);
/** Required Function to destroy a decoder instance - indicated by decoder handle */
ocsd_err_t DestroyCustomDecoder(const void *decoder_handle);
/** Required Function to extract the CoreSight Trace ID from the configuration structure */
ocsd_err_t GetCSIDFromConfig(const void *decoder_cfg, unsigned char *p_csid);
/** Optional Function to convert a protocol specific trace packet to human readable string */
ocsd_err_t PacketToString(const void *trc_pkt, char *buffer, const int buflen);
#endif /* ARM_OCSD_C_API_CUST_FACT_H_INCLUDED */

View File

@ -0,0 +1,158 @@
/*
* \file ocsd_c_api_cust_impl.h
* \brief OpenCSD : Custom decoder implementation common API definitions
*
* \copyright Copyright (c) 2016, 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_OCSD_C_API_CUST_IMPL_H_INCLUDED
#define ARM_OCSD_C_API_CUST_IMPL_H_INCLUDED
#include "opencsd/c_api/ocsd_c_api_types.h"
#include "opencsd/c_api/ocsd_c_api_custom.h"
/** @addtogroup ocsd_ext_dcd
@{*/
/**@name External decoder - Inline utility functions.
@brief inline functions used in decoders to call the various library callback functionality.
Functions manipulate and use the ocsd_extern_dcd_cb_fns structure to call into the library,
with appropriate checking for initialisation and usage flags.
@{*/
static inline ocsd_datapath_resp_t lib_cb_GenElemOp(const ocsd_extern_dcd_cb_fns *callbacks,
const ocsd_trc_index_t index_sop,
const uint8_t trc_chan_id,
const ocsd_generic_trace_elem *elem)
{
if (callbacks->fn_gen_elem_out)
return callbacks->fn_gen_elem_out(callbacks->lib_context, index_sop, trc_chan_id, elem);
return OCSD_RESP_FATAL_NOT_INIT;
}
static inline ocsd_err_t lib_cb_LogError(const ocsd_extern_dcd_cb_fns *callbacks,
const ocsd_err_severity_t filter_level,
const ocsd_err_t code,
const ocsd_trc_index_t idx,
const uint8_t chan_id,
const char *pMsg)
{
if (callbacks->fn_log_error)
{
callbacks->fn_log_error(callbacks->lib_context, filter_level, code, idx, chan_id, pMsg);
return OCSD_OK;
}
return OCSD_ERR_NOT_INIT;
}
static inline ocsd_err_t lib_cb_LogMsg(const ocsd_extern_dcd_cb_fns *callbacks,
const ocsd_err_severity_t filter_level,
const char *pMsg)
{
if (callbacks->fn_log_msg)
{
callbacks->fn_log_msg(callbacks->lib_context, filter_level, pMsg);
return OCSD_OK;
}
return OCSD_ERR_NOT_INIT;
}
static inline ocsd_err_t lib_cb_DecodeArmInst(const ocsd_extern_dcd_cb_fns *callbacks,
ocsd_instr_info *instr_info)
{
if (callbacks->fn_arm_instruction_decode)
return callbacks->fn_arm_instruction_decode(callbacks->lib_context, instr_info);
return OCSD_ERR_NOT_INIT;
}
static inline ocsd_err_t lib_cb_MemAccess(const ocsd_extern_dcd_cb_fns *callbacks,
const ocsd_vaddr_t address,
const uint8_t cs_trace_id,
const ocsd_mem_space_acc_t mem_space,
uint32_t *num_bytes,
uint8_t *p_buffer)
{
if (callbacks->fn_memory_access)
return callbacks->fn_memory_access(callbacks->lib_context, address, cs_trace_id, mem_space, num_bytes, p_buffer);
return OCSD_ERR_NOT_INIT;
}
static inline void lib_cb_PktMon(const ocsd_extern_dcd_cb_fns *callbacks,
const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const void *pkt,
const uint32_t size,
const uint8_t *p_data)
{
if (callbacks->packetCBFlags & OCSD_CUST_DCD_PKT_CB_USE_MON)
{
if (callbacks->fn_packet_mon)
callbacks->fn_packet_mon(callbacks->lib_context, op, index_sop, pkt, size, p_data);
}
}
static inline int lib_cb_usePktMon(const ocsd_extern_dcd_cb_fns *callbacks)
{
return (callbacks->packetCBFlags & OCSD_CUST_DCD_PKT_CB_USE_MON);
}
/* callback function to connect to the packet sink interface, on the main decode
data path - used if decoder created as packet processor only */
static inline ocsd_datapath_resp_t lib_cb_PktDataSink(const ocsd_extern_dcd_cb_fns *callbacks,
const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const void *pkt)
{
if (callbacks->packetCBFlags & OCSD_CUST_DCD_PKT_CB_USE_SINK)
{
if (callbacks->fn_packet_data_sink)
return callbacks->fn_packet_data_sink(callbacks->lib_context, op, index_sop, pkt);
else
return OCSD_RESP_FATAL_NOT_INIT;
}
return OCSD_RESP_CONT;
}
static inline int lib_cb_usePktSink(const ocsd_extern_dcd_cb_fns *callbacks)
{
return (callbacks->packetCBFlags & OCSD_CUST_DCD_PKT_CB_USE_SINK);
}
static inline void lib_cb_updatePktCBFlags(ocsd_extern_dcd_cb_fns *callbacks, const int newFlags)
{
callbacks->packetCBFlags = newFlags;
}
/** @}*/
/** @}*/
#endif /* ARM_OCSD_C_API_CUST_IMPL_H_INCLUDED */

View File

@ -0,0 +1,253 @@
/*
* \file ocsd_c_api_custom.h
* \brief OpenCSD : Custom decoder interface types and structures
*
* \copyright Copyright (c) 2016, 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_OCSD_C_API_CUSTOM_H_INCLUDED
#define ARM_OCSD_C_API_CUSTOM_H_INCLUDED
#include "ocsd_c_api_types.h"
/** @defgroup ocsd_ext_dcd OpenCSD Library : Custom External Decoder C-API
@brief Set of types, structures and interfaces for attaching custom decoders via the C-API
These types, functions and structures define the required API between a custom external decoder
and the library, which will allow the decoder to interact with the library and use library
resources in the same way as the built-in decoders.
The external decoder must implement:-
- A set of factory functions that allow the creation and destruction of decoder instances.
- A set of call-in and call-back functions plus data structures allowing interaction with the library.
@{*/
/**@name External decoder - Input Interfaces
@{*/
/* Custom decoder C-API interface types. */
/** Raw trace data input function - a decoder must have one of these
Implements ITrcDataIn with the addition of a decoder handle to provide context in the decoder.
*/
typedef ocsd_datapath_resp_t (* fnTraceDataIn)( const void *decoder_handle,
const ocsd_datapath_op_t op,
const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed);
/** Function to update the in-use flags for the packet sinks
Defines if the fnPktMonCB or fnPktDataSinkCB callbacks are in use by the library.
If so then it is expected that the decoder should call them when trace protocol packets are generated.
This function must be implemented in the decoder.
@param decoder_handle : handle for decoder accessed by this call.
@param flags: Values indicating interfaces in use / not in use. [ OCSD_CUST_DCD_PKT_CB_USE_MON or OCSD_CUST_DCD_PKT_CB_USE_SINK]
*/
typedef void (* fnUpdatePktMonFlags)(const void *decoder_handle, const int flags);
/** Flag to indicate the the packet monitor (fnPktMonCB) is in use in the library */
#define OCSD_CUST_DCD_PKT_CB_USE_MON 0x1
/** Flag to indicate the the packet sink (fnPktDataSinkCB) is in use in the library - only if trace packet processing only mode. */
#define OCSD_CUST_DCD_PKT_CB_USE_SINK 0x2
/** Owned by the library instance object, this structure is filled in by the ocsd_extern_dcd_fact_t createDecoder() function. */
typedef struct _ocsd_extern_dcd_inst {
/* Mandatory decoder call back functions - library initialisation will fail without these. */
fnTraceDataIn fn_data_in; /**< raw trace data input function to decoder */
fnUpdatePktMonFlags fn_update_pkt_mon; /**< update the packet monitor / sink usage flags */
/* Decoder instance data */
void *decoder_handle; /**< Instance handle for the decoder - used by library to call the decoder call in functions */
char *p_decoder_name; /**< type name of the decoder - may be used in logging */
uint8_t cs_id; /**< Coresight ID for the instance - extracted from the config on creation. */
} ocsd_extern_dcd_inst_t;
/** @}*/
/**@name External decoder - Callback Interfaces
@{*/
/** callback function to connect into the generic element output point
Implements ITrcGenElemIn::TraceElemIn with addition of library context pointer.
*/
typedef ocsd_datapath_resp_t (* fnGenElemOpCB)( const void *lib_context,
const ocsd_trc_index_t index_sop,
const uint8_t trc_chan_id,
const ocsd_generic_trace_elem *elem);
/** callback functions to connect into the library error logging mechanism
Implements ITraceErrorLog::LogError with addition of library context pointer.
*/
typedef void (* fnLogErrorCB)( const void *lib_context,
const ocsd_err_severity_t filter_level,
const ocsd_err_t code,
const ocsd_trc_index_t idx,
const uint8_t chan_id,
const char *pMsg);
/** callback functions to connect into the library error logging mechanism
Implements ITraceErrorLog::LogMessage with addition of library context pointer.
*/
typedef void (* fnLogMsgCB)(const void *lib_context, const ocsd_err_severity_t filter_level, const char *msg);
/** callback function to connect an ARM instruction decoder
Implements IInstrDecode::DecodeInstruction with addition of library context pointer.
*/
typedef ocsd_err_t (* fnDecodeArmInstCB)(const void *lib_context, ocsd_instr_info *instr_info);
/** callback function to connect the memory accessor interface
Implements ITargetMemAccess::ReadTargetMemory with addition of library context pointer.
*/
typedef ocsd_err_t (* fnMemAccessCB)(const void *lib_context,
const ocsd_vaddr_t address,
const uint8_t cs_trace_id,
const ocsd_mem_space_acc_t mem_space,
uint32_t *num_bytes,
uint8_t *p_buffer);
/** callback function to connect to the packet monitor interface of the packet processor
Implements IPktRawDataMon::RawPacketDataMon <void> with addition of library context pointer.
*/
typedef void (* fnPktMonCB)( const void *lib_context,
const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const void *pkt,
const uint32_t size,
const uint8_t *p_data);
/** callback function to connect to the packet sink interface, on the main decode
data path - use if decoder created as packet processor only
Implements IPktDataIn::PacketDataIn <void> with addition of library context pointer.
*/
typedef ocsd_datapath_resp_t (* fnPktDataSinkCB)( const void *lib_context,
const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const void *pkt);
/** an instance of this is owned by the decoder, filled in by the library - allows the CB fns in the library decode tree to be called. */
typedef struct _ocsd_extern_dcd_cb_fns {
/* Callback functions */
fnGenElemOpCB fn_gen_elem_out; /**< Callback to output a generic element. */
fnLogErrorCB fn_log_error; /**< Callback to output an error. */
fnLogMsgCB fn_log_msg; /**< Callback to output a message. */
fnDecodeArmInstCB fn_arm_instruction_decode; /**< Callback to decode an ARM instruction. */
fnMemAccessCB fn_memory_access; /**< Callback to access memory images related to the trace capture. */
fnPktMonCB fn_packet_mon; /**< Callback to output trace packet to packet monitor. */
fnPktDataSinkCB fn_packet_data_sink; /**< Callback to output trace packet to packet sink - if in pack processing only mode. */
/* CB in use flags. */
int packetCBFlags; /**< Flags to indicate if the packet sink / packet monitor callbacks are in use. ( OCSD_CUST_DCD_PKT_CB_USE_MON / OCSD_CUST_DCD_PKT_CB_USE_SINK) */
/* library context */
const void *lib_context; /**< library context pointer - use in callbacks to allow the library to load the correct context data. */
} ocsd_extern_dcd_cb_fns;
/** @}*/
/**@name External decoder - Decoder Factory
@{*/
/** Function to create a decoder instance
Create a decoder instance according to the create_flags parameter and the supplied decoder_cfg structure.
Fill in the p_decoder_inst structure, copy the p_lib_callbacks information for use in the decoder instance.
Create flags can be:
- OCSD_CREATE_FLG_PACKET_PROC: decoder will split the incoming trace into trace protocol packets and not further decode them. fnPktDataSinkCB likely to be in use.
- OCSD_CREATE_FLG_FULL_DECODER: decoder will split the incoming trace into trace protocol packets and further decode them to recreate program flow or other generic trace output.
@param create_flags : Sets the decoder operating mode.
@param *decoder_cfg : Hardware specific configuration for this trace element.
@param *p_lib_callbacks : Library callbacks plus context pointer.
@param *p_decoder_inst : Structure representing the new decoder instance being created. Filled in by create function to contain handle and call-in functions for the library.
@return ocsd_err_t : Library error code - RCDTL_OK if successful
*/
typedef ocsd_err_t (* fnCreateCustomDecoder)(const int create_flags, const void *decoder_cfg, const ocsd_extern_dcd_cb_fns *p_lib_callbacks, ocsd_extern_dcd_inst_t *p_decoder_inst);
/** Function to destroy a decoder instance indicated by decoder handle.
@param decoder_handle : Instance handle for decoder.
@return ocsd_err_t : Library error code - RCDTL_OK if successful
*/
typedef ocsd_err_t (* fnDestroyCustomDecoder)(const void *decoder_handle);
/** Function to extract the CoreSight Trace ID from the configuration structure.
@param *decoder_cfg : Hardware specific configuration for this trace element.
@parma *p_csid : location to write CoreSight Trace ID value.
@return ocsd_err_t : Library error code - RCDTL_OK if successful
*/
typedef ocsd_err_t (* fnGetCSIDFromConfig)(const void *decoder_cfg, unsigned char *p_csid);
/** Function to convert a protocol specific trace packet to human readable string
@param *trc_pkt : protocol specific packet structure.
@param *buffer : buffer to fill with string.
@param buflen : length of string buffer.
@return ocsd_err_t : Library error code - RCDTL_OK if successful
*/
typedef ocsd_err_t (* fnPacketToString)(const void *trc_pkt, char *buffer, const int buflen);
/** set of functions and callbacks to create an extern custom decoder in the library
via the C API interface. This structure is registered with the library by name and
then decoders of the type can be created on the decode tree.
*/
typedef struct _ocsd_extern_dcd_fact {
fnCreateCustomDecoder createDecoder; /**< Function pointer to create a decoder instance. */
fnDestroyCustomDecoder destroyDecoder; /**< Function pointer to destroy a decoder instance. */
fnGetCSIDFromConfig csidFromConfig; /**< Function pointer to extract the CSID from a config structure */
fnPacketToString pktToString; /**< Function pointer to print a trace protocol packet in this decoder */
ocsd_trace_protocol_t protocol_id; /**< protocol ID assigned during registration. */
} ocsd_extern_dcd_fact_t;
/** @}*/
/** @}*/
#endif // ARM_OCSD_C_API_CUSTOM_H_INCLUDED
/* End of File ocsd_c_api_custom.h */

View File

@ -0,0 +1,105 @@
/*!
* \file ocsd_c_api_types.h
* \brief OpenCSD : Trace Decoder "C" API types.
*
* \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_OCSD_C_API_TYPES_H_INCLUDED
#define ARM_OCSD_C_API_TYPES_H_INCLUDED
/* select the library types that are C compatible - the interface data types */
#include "opencsd/ocsd_if_types.h"
#include "opencsd/trc_gen_elem_types.h"
#include "opencsd/trc_pkt_types.h"
/* pull in the protocol decoder types. */
#include "opencsd/etmv3/trc_pkt_types_etmv3.h"
#include "opencsd/etmv4/trc_pkt_types_etmv4.h"
#include "opencsd/ptm/trc_pkt_types_ptm.h"
#include "opencsd/stm/trc_pkt_types_stm.h"
/** @ingroup lib_c_api
@{*/
/* Specific C-API only types */
/** Handle to decode tree */
typedef void * dcd_tree_handle_t;
/** define invalid handle value for decode tree handle */
#define C_API_INVALID_TREE_HANDLE (dcd_tree_handle_t)0
/** Logger output printer - no output. */
#define C_API_MSGLOGOUT_FLG_NONE 0x0
/** Logger output printer - output to file. */
#define C_API_MSGLOGOUT_FLG_FILE 0x1
/** Logger output printer - output to stderr. */
#define C_API_MSGLOGOUT_FLG_STDERR 0x2
/** Logger output printer - output to stdout. */
#define C_API_MSGLOGOUT_FLG_STDOUT 0x4
/** Logger output printer - mask of valid flags. */
#define C_API_MSGLOGOUT_MASK 0x7
/** function pointer type for decoder outputs. all protocols, generic data element input */
typedef ocsd_datapath_resp_t (* FnTraceElemIn)( const void *p_context,
const ocsd_trc_index_t index_sop,
const uint8_t trc_chan_id,
const ocsd_generic_trace_elem *elem);
/** function pointer type for packet processor packet output sink, packet analyser/decoder input - generic declaration */
typedef ocsd_datapath_resp_t (* FnDefPktDataIn)(const void *p_context,
const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const void *p_packet_in);
/** function pointer type for packet processor packet monitor sink, raw packet monitor / display input - generic declaration */
typedef void (* FnDefPktDataMon)(const void *p_context,
const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const void *p_packet_in,
const uint32_t size,
const uint8_t *p_data);
/** function pointer tyee for library default logger output to allow client to print zero terminated output string */
typedef void (* FnDefLoggerPrintStrCB)(const void *p_context, const char *psz_msg_str, const int str_len);
/** Callback interface type when attaching monitor/sink to packet processor */
typedef enum _ocsd_c_api_cb_types {
OCSD_C_API_CB_PKT_SINK, /** Attach to the packet processor primary packet output (CB fn is FnDefPktDataIn) */
OCSD_C_API_CB_PKT_MON, /** Attach to the packet processor packet monitor output (CB fn is FnDefPktDataMon) */
} ocsd_c_api_cb_types;
/** @}*/
#endif // ARM_OCSD_C_API_TYPES_H_INCLUDED
/* End of File ocsd_c_api_types.h */

View File

@ -0,0 +1,485 @@
/*!
* \file opencsd_c_api.h
* \brief OpenCSD : "C" API
*
* \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_OPENCSD_C_API_H_INCLUDED
#define ARM_OPENCSD_C_API_H_INCLUDED
/** @defgroup lib_c_api OpenCSD Library : Library "C" API.
@brief "C" API for the OpenCSD Library
Set of "C" wrapper functions for the OpenCSD library.
Defines API, functions and callback types.
@{*/
/* ensure C bindings */
#if defined(WIN32) /* windows bindings */
/** Building the C-API DLL **/
#ifdef _OCSD_C_API_DLL_EXPORT
#ifdef __cplusplus
#define OCSD_C_API extern "C" __declspec(dllexport)
#else
#define OCSD_C_API __declspec(dllexport)
#endif
#else
/** building or using the static C-API library **/
#if defined(_LIB) || defined(OCSD_USE_STATIC_C_API)
#ifdef __cplusplus
#define OCSD_C_API extern "C"
#else
#define OCSD_C_API
#endif
#else
/** using the C-API DLL **/
#ifdef __cplusplus
#define OCSD_C_API extern "C" __declspec(dllimport)
#else
#define OCSD_C_API __declspec(dllimport)
#endif
#endif
#endif
#else /* linux bindings */
#ifdef __cplusplus
#define OCSD_C_API extern "C"
#else
#define OCSD_C_API
#endif
#endif
#include "ocsd_c_api_types.h"
#include "ocsd_c_api_custom.h"
/** @name Library Version API
@{*/
/** Get Library version. Return a 32 bit version in form MMMMnnpp - MMMM = major verison, nn = minor version, pp = patch version */
OCSD_C_API uint32_t ocsd_get_version(void);
/** Get library version string */
OCSD_C_API const char * ocsd_get_version_str(void);
/** @}*/
/*---------------------- Trace Decode Tree ----------------------------------------------------------------------------------*/
/** @name Library Decode Tree API
@{*/
/*!
* Create a decode tree.
*
* @param src_type : Type of tree - formatted input, or single source input
* @param deformatterCfgFlags : Formatter flags - determine presence of frame syncs etc.
*
* @return dcd_tree_handle_t : Handle to the decode tree. Handle value set to 0 if creation failed.
*/
OCSD_C_API dcd_tree_handle_t ocsd_create_dcd_tree(const ocsd_dcd_tree_src_t src_type, const uint32_t deformatterCfgFlags);
/*!
* Destroy a decode tree.
*
* Also destroys all the associated processors and decoders for the tree.
*
* @param handle : Handle for decode tree to destroy.
*/
OCSD_C_API void ocsd_destroy_dcd_tree(const dcd_tree_handle_t handle);
/*!
* Input trace data into the decoder.
*
* Large trace source buffers can be broken down into smaller fragments.
*
* @param handle : Handle to decode tree.
* @param op : Datapath operation.
* @param index : Trace buffer byte index for the start of the supplied data block.
* @param dataBlockSize : Size of data block.
* @param *pDataBlock : Pointer to data block.
* @param *numBytesProcessed : Number of bytes actually processed by the decoder.
*
* @return ocsd_datapath_resp_t : Datapath response code (CONT/WAIT/FATAL)
*/
OCSD_C_API ocsd_datapath_resp_t ocsd_dt_process_data(const dcd_tree_handle_t handle,
const ocsd_datapath_op_t op,
const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed);
/*---------------------- Generic Trace Element Output --------------------------------------------------------------*/
/*!
* Set the trace element output callback function.
*
* This function will be called for each decoded generic trace element generated by
* any full trace decoder in the decode tree.
*
* A single function is used for all trace source IDs in the decode tree.
*
* @param handle : Handle to decode tree.
* @param pFn : Pointer to the callback function.
* @param p_context : opaque context pointer value used in callback function.
*
* @return ocsd_err_t : Library error code - OCSD_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_dt_set_gen_elem_outfn(const dcd_tree_handle_t handle, FnTraceElemIn pFn, const void *p_context);
/*---------------------- Trace Decoders ----------------------------------------------------------------------------------*/
/*!
* Creates a decoder that is registered with the library under the supplied name.
* Flags determine if a full packet processor / packet decoder pair or
* packet processor only is created.
* Uses the supplied configuration structure.
*
* @param handle : Handle to decode tree.
* @param *decoder_name : Registered name of the decoder to create.
* @param create_flags : Decoder creation options.
* @param *decoder_cfg : Pointer to a valid configuration structure for the named decoder.
* @param *pCSID : Pointer to location to return the configured CoreSight trace ID for the decoder.
*
* @return ocsd_err_t : Library error code - OCSD_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_dt_create_decoder(const dcd_tree_handle_t handle,
const char *decoder_name,
const int create_flags,
const void *decoder_cfg,
unsigned char *pCSID
);
/*!
* Remove a decoder from the tree and destroy it.
*
* @param handle : Handle to decode tree.
* @param CSID : Configured CoreSight trace ID for the decoder.
*
* @return ocsd_err_t : Library error code - OCSD_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_dt_remove_decoder( const dcd_tree_handle_t handle,
const unsigned char CSID);
/*!
* Attach a callback function to the packet processor.
*
* The callback_type defines the attachment point, either the main packet output
* (only if no decoder attached), or the packet monitor.
*
* @param handle : Handle to decode tree.
* @param CSID : Configured CoreSight trace ID for the decoder.
* @param callback_type : Attachment point
* @param p_fn_pkt_data_in : Pointer to the callback function.
* @param p_context : Opaque context pointer value used in callback function.
*
* @return ocsd_err_t : Library error code - OCSD_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_dt_attach_packet_callback( const dcd_tree_handle_t handle,
const unsigned char CSID,
const ocsd_c_api_cb_types callback_type,
void *p_fn_callback_data,
const void *p_context);
/** @}*/
/*---------------------- Memory Access for traced opcodes ----------------------------------------------------------------------------------*/
/** @name Library Memory Accessor configuration on decode tree.
@brief Configure the memory regions available for decode.
Full decode requires memory regions set up to allow access to the traced
opcodes. Add memory buffers or binary file regions to a map of regions.
@{*/
/*!
* Add a binary file based memory range accessor to the decode tree.
*
* Adds the entire binary file as a memory space to be accessed
*
* @param handle : Handle to decode tree.
* @param address : Start address of memory area.
* @param mem_space : Associated memory space.
* @param *filepath : Path to binary data file.
*
* @return ocsd_err_t : Library error code - RCDTL_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_dt_add_binfile_mem_acc(const dcd_tree_handle_t handle, const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const char *filepath);
/*!
* Add a binary file based memory range accessor to the decode tree.
*
* Add a binary file that contains multiple regions of memory with differing
* offsets wihtin the file.
*
* A linked list of file_mem_region_t structures is supplied. Each structure contains an
* offset into the binary file, the start address for this offset and the size of the region.
*
* @param handle : Handle to decode tree.
* @param region_list : Array of memory regions in the file.
* @param num_regions : Size of region array
* @param mem_space : Associated memory space.
* @param *filepath : Path to binary data file.
*
* @return ocsd_err_t : Library error code - RCDTL_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_dt_add_binfile_region_mem_acc(const dcd_tree_handle_t handle, const ocsd_file_mem_region_t *region_array, const int num_regions, const ocsd_mem_space_acc_t mem_space, const char *filepath);
/*!
* Add a memory buffer based memory range accessor to the decode tree.
*
* @param handle : Handle to decode tree.
* @param address : Start address of memory area.
* @param mem_space : Associated memory space.
* @param *p_mem_buffer : pointer to memory buffer.
* @param mem_length : Size of memory buffer.
*
* @return ocsd_err_t : Library error code - RCDTL_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_dt_add_buffer_mem_acc(const dcd_tree_handle_t handle, const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t *p_mem_buffer, const uint32_t mem_length);
/*!
* Add a memory access callback function. The decoder will call the function for opcode addresses in the
* address range supplied for the memory spaces covered.
*
* @param handle : Handle to decode tree.
* @param st_address : Start address of memory area covered by the callback.
* @param en_address : End address of the memory area covered by the callback. (inclusive)
* @param mem_space : Memory space(s) covered by the callback.
* @param p_cb_func : Callback function
* @param p_context : opaque context pointer value used in callback function.
*
* @return OCSD_C_API ocsd_err_t : Library error code - RCDTL_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_dt_add_callback_mem_acc(const dcd_tree_handle_t handle, const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, const ocsd_mem_space_acc_t mem_space, Fn_MemAcc_CB p_cb_func, const void *p_context);
/*!
* Remove a memory accessor by address and memory space.
*
* @param handle : Handle to decode tree.
* @param st_address : Start address of memory accessor.
* @param mem_space : Memory space(s) covered by the accessor.
*
* @return OCSD_C_API ocsd_err_t : Library error code - RCDTL_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_dt_remove_mem_acc(const dcd_tree_handle_t handle, const ocsd_vaddr_t st_address, const ocsd_mem_space_acc_t mem_space);
/*
* Print the mapped memory accessor ranges to the configured logger.
*
* @param handle : Handle to decode tree.
*/
OCSD_C_API void ocsd_tl_log_mapped_mem_ranges(const dcd_tree_handle_t handle);
/** @}*/
/** @name Library Default Error Log Object API
@brief Configure the default error logging object in the library.
Objects created by the decode trees will use this error logger. Configure for
desired error severity, and to enable print or logfile output.
@{*/
/*---------------------- Library Logging and debug ----------------------------------------------------------------------------------*/
/*!
* Initialise the library error logger.
*
* Choose severity of errors logger, and if the errors will be logged to screen and / or logfile.
*
* @param verbosity : Severity of errors that will be logged.
* @param create_output_logger : Set to none-zero to create an output printer.
*
* @return ocsd_err_t : Library error code - RCDTL_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_def_errlog_init(const ocsd_err_severity_t verbosity, const int create_output_logger);
/*!
* Configure the output logger. Choose STDOUT, STDERR and/or log to file.
* Optionally provide a log file name.
*
* @param output_flags : OR combination of required C_API_MSGLOGOUT_FLG_* flags.
* @param *log_file_name : optional filename if logging to file. Set to NULL if not needed.
*
* @return OCSD_C_API ocsd_err_t : Library error code - RCDTL_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_def_errlog_config_output(const int output_flags, const char *log_file_name);
/*!
* Configure the library default error logger to send all strings it is outputting back to the client
* to allow printing within the client application. This is in additional to any other log destinations
* set in ocsd_def_errlog_init().
*
* @param *p_context : opaque context pointer
* @param p_str_print_cb : client callback function to "print" logstring.
*/
OCSD_C_API ocsd_err_t ocsd_def_errlog_set_strprint_cb(const dcd_tree_handle_t handle, void *p_context, FnDefLoggerPrintStrCB p_str_print_cb);
/*!
* Print a message via the library output printer - if enabled.
*
* @param *msg : Message to output.
*
*/
OCSD_C_API void ocsd_def_errlog_msgout(const char *msg);
/** @}*/
/** @name Packet to string interface
@{*/
/*!
* Take a packet structure and render a string representation of the packet data.
*
* Returns a '0' terminated string of (buffer_size - 1) length or less.
*
* @param pkt_protocol : Packet protocol type - used to interpret the packet pointer
* @param *p_pkt : pointer to a valid packet structure of protocol type. cast to void *.
* @param *buffer : character buffer for string.
* @param buffer_size : size of character buffer.
*
* @return ocsd_err_t : Library error code - RCDTL_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_pkt_str(const ocsd_trace_protocol_t pkt_protocol, const void *p_pkt, char *buffer, const int buffer_size);
/*!
* Get a string representation of the generic trace element.
*
* @param *p_pkt : pointer to valid generic element structure.
* @param *buffer : character buffer for string.
* @param buffer_size : size of character buffer.
*
* @return ocsd_err_t : Library error code - RCDTL_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_gen_elem_str(const ocsd_generic_trace_elem *p_pkt, char *buffer, const int buffer_size);
/*!
* Init a generic element with type, clearing any flags etc.
*/
OCSD_C_API void ocsd_gen_elem_init(ocsd_generic_trace_elem *p_pkt, const ocsd_gen_trc_elem_t elem_type);
/** @}*/
/** @name Library packet and data printer control API
@brief Allows client to use libraries packet and data printers to log packets etc rather than attach callbacks
to packet output and use packet to string calls.
@{*/
/*!
* Set a raw frame printer on the trace frame demuxer. Allows inspection of raw trace data frames for debug.
* Prints via the library default error logging mechanisms.
*
* The flags input determines the data printed. OR combination of one or both of:
* OCSD_DFRMTR_PACKED_RAW_OUT : Output the undemuxed raw data frames.
* OCSD_DFRMTR_UNPACKED_RAW_OUT : Output the raw data by trace ID after unpacking the frame.
*
* @param handle : Handle to decode tree.
* @param flags : indicates type of raw frames to print.
*
* @return ocsd_err_t : Library error code - RCDTL_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_dt_set_raw_frame_printer(const dcd_tree_handle_t handle, int flags);
/*!
* Set a library printer on the generic element output of a full decoder.
*
* @param handle : Handle to decode tree.
*
* @return ocsd_err_t : Library error code - RCDTL_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_dt_set_gen_elem_printer(const dcd_tree_handle_t handle);
/*!
* Attach a library printer to the packet processor. May be attached to the main packet output, or the monitor
* output if the main packet output is to be attached to a packet decoder in the datapath.
*
* @param handle : Handle to decode tree.
* @param cs_id : Coresight trace ID for stream to print.
* @param monitor: 0 to attach printer directly to datapath packet output, 1 to attach to packet monitor output
*
* @return ocsd_err_t : Library error code - RCDTL_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_dt_set_pkt_protocol_printer(const dcd_tree_handle_t handle, uint8_t cs_id, int monitor);
/** @}*/
/** @name Custom Decoder API functions
@{*/
/** Register a custom decoder with the library
@param *name : Name under which to register the decoder.
@param *p_dcd_fact : Custom decoder factory structure.
@return ocsd_err_t : Library error code - RCDTL_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_register_custom_decoder(const char *name, ocsd_extern_dcd_fact_t *p_dcd_fact);
/** Clear all registered decoders - library cleanup
@return ocsd_err_t : Library error code - RCDTL_OK if successful.
*/
OCSD_C_API ocsd_err_t ocsd_deregister_decoders(void);
/** Get a string representation of a custom protocol packet.
Specific function to extract the packet string for a custom protocol ID only. Custom IDs are allocated to decoder factories
during the ocsd_register_custom_decoder() process.
This function is called by ocsd_pkt_str() when the incoming protocol is a custom ID.
@param pkt_protocol : Packet protocol type - must be in the custom ID range ( >= OCSD_PROTOCOL_CUSTOM_0, < OCSD_PROTOCOL_END)
@param *p_pkt : pointer to a valid packet structure of protocol type. cast to void *.
@param *buffer : character buffer for string.
@param buffer_size : size of character buffer.
@return ocsd_err_t : Library error code - RCDTL_OK if successful, OCSD_ERR_NO_PROTOCOL if input ID not in custom range or not in use.
*/
OCSD_C_API ocsd_err_t ocsd_cust_protocol_to_str(const ocsd_trace_protocol_t pkt_protocol, const void *trc_pkt, char *buffer, const int buflen);
/** @}*/
/** @}*/
#endif // ARM_OPENCSD_C_API_H_INCLUDED
/* End of File opencsd_c_api.h */

View File

@ -0,0 +1,47 @@
/*
* \file etmv3_decoder.h
* \brief OpenCSD : Top level header file for ETMv3 decoder
*
* \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_ETMV3_DECODER_H_INCLUDED
#define ARM_ETMV3_DECODER_H_INCLUDED
#include "opencsd/etmv3/trc_cmp_cfg_etmv3.h"
#include "opencsd/etmv3/trc_pkt_elem_etmv3.h"
#include "opencsd/etmv3/trc_pkt_proc_etmv3.h"
#include "opencsd/etmv3/trc_pkt_types_etmv3.h"
#include "opencsd/etmv3/trc_pkt_decode_etmv3.h"
#endif // ARM_ETMV3_DECODER_H_INCLUDED
/* End of File etmv3_decoder.h */

View File

@ -0,0 +1,235 @@
/*
* \file trc_cmp_cfg_etmv3.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_CMP_CFG_ETMV3_H_INCLUDED
#define ARM_TRC_CMP_CFG_ETMV3_H_INCLUDED
#include "trc_pkt_types_etmv3.h"
#include "common/trc_cs_config.h"
/** @addtogroup ocsd_protocol_cfg
@{*/
/** @name ETMV3 configuration
@{*/
/*!
* @class EtmV3Config
* @brief Interpreter class for etm v3 config structure.
*
* Provides quick value interpretation methods for the ETMv3 config register values.
* Primarily inlined for efficient code.
*
*/
class EtmV3Config : public CSConfig
{
public:
EtmV3Config(); /**< Default constructor */
EtmV3Config(const ocsd_etmv3_cfg *cfg_regs);
~EtmV3Config() {}; /**< Default destructor */
/* register bit constants. */
static const uint32_t CTRL_DATAVAL = 0x4;
static const uint32_t CTRL_DATAADDR = 0x8;
static const uint32_t CTRL_CYCLEACC = 0x1000;
static const uint32_t CTRL_DATAONLY = 0x100000;
static const uint32_t CTRL_TS_ENA = (0x1 << 28);
static const uint32_t CTRL_VMID_ENA = (0x1 << 30);
static const uint32_t CCER_HAS_TS = (0x1 << 22);
static const uint32_t CCER_VIRTEXT = (0x1 << 26);
static const uint32_t CCER_TS64BIT = (0x1 << 29);
static const uint32_t IDR_ALTBRANCH = 0x100000;
// operations to convert to and from C-API structure
//! copy assignment operator for C-API base structure into class.
EtmV3Config & operator=(const ocsd_etmv3_cfg *p_cfg);
//! cast operator returning struct const reference
operator const ocsd_etmv3_cfg &() const { return m_cfg; };
//! cast operator returning struct const pointer
operator const ocsd_etmv3_cfg *() const { return &m_cfg; };
//! combination enum to describe trace mode.
enum EtmTraceMode {
TM_INSTR_ONLY, //!< instruction only trace
TM_I_DATA_VAL, //!< instruction + data value
TM_I_DATA_ADDR, //!< instruction + data address
TM_I_DATA_VAL_ADDR, //!< instr + data value + data address
TM_DATAONLY_VAL, //!< data value trace
TM_DATAONLY_ADDR, //!< data address trace
TM_DATAONLY_VAL_ADDR //!< data value + address trace
};
EtmTraceMode const GetTraceMode() const; //!< return trace mode
const bool isInstrTrace() const; //!< instruction trace present.
const bool isDataValTrace() const; //!< data value trace present.
const bool isDataAddrTrace() const; //!< data address trace present.
const bool isDataTrace() const; //!< either or both data trace types present.
const bool isCycleAcc() const; //!< return true if cycle accurate tracing enabled.
const int MinorRev() const; //!< return X revision in 3.X
const bool isV7MArch() const; //!< source is V7M architecture
const bool isAltBranch() const; //!< Alternate branch packet encoding used.
const int CtxtIDBytes() const; //!< number of context ID bytes traced 1,2,4;
const bool hasVirtExt() const; //!< processor has virtualisation extensions.
const bool isVMIDTrace() const; //!< VMID tracing enabled.
const bool hasTS() const; //!< Timestamps implemented in trace.
const bool isTSEnabled() const; //!< Timestamp trace is enabled.
const bool TSPkt64() const; //!< timestamp packet is 64 bits in size.
virtual const uint8_t getTraceID() const; //!< CoreSight Trace ID for this device.
const ocsd_arch_version_t getArchVersion() const; //!< architecture version
const ocsd_core_profile_t getCoreProfile() const; //!< core profile.
private:
ocsd_etmv3_cfg m_cfg;
};
/* inlines for the bit interpretations */
inline EtmV3Config & EtmV3Config::operator=(const ocsd_etmv3_cfg *p_cfg)
{
m_cfg = *p_cfg;
return *this;
}
inline const bool EtmV3Config::isCycleAcc() const
{
return (bool)((m_cfg.reg_ctrl & CTRL_CYCLEACC) != 0);
}
//! return X revision in 3.X
inline const int EtmV3Config::MinorRev() const
{
return ((int)m_cfg.reg_idr & 0xF0) >> 4;
}
inline const bool EtmV3Config::isInstrTrace() const
{
return (bool)((m_cfg.reg_ctrl & CTRL_DATAONLY) == 0);
}
inline const bool EtmV3Config::isDataValTrace() const
{
return (bool)((m_cfg.reg_ctrl & CTRL_DATAVAL) != 0);
}
inline const bool EtmV3Config::isDataAddrTrace() const
{
return (bool)((m_cfg.reg_ctrl & CTRL_DATAADDR) != 0);
}
//! either or both data trace present
inline const bool EtmV3Config::isDataTrace() const
{
return (bool)((m_cfg.reg_ctrl & (CTRL_DATAADDR | CTRL_DATAVAL)) != 0);
}
inline const bool EtmV3Config::isV7MArch() const
{
return (bool)((m_cfg.arch_ver == ARCH_V7) && (m_cfg.core_prof == profile_CortexM));
}
//! has alternate branch encoding
inline const bool EtmV3Config::isAltBranch() const
{
return (bool)(((m_cfg.reg_idr & IDR_ALTBRANCH) != 0) && (MinorRev() >= 4));
}
//! processor implements virtualisation extensions.
inline const bool EtmV3Config::hasVirtExt() const
{
return (bool)((m_cfg.reg_ccer & CCER_VIRTEXT) != 0);
}
//! TS packet is 64 bit.
inline const bool EtmV3Config::TSPkt64() const
{
return (bool)((m_cfg.reg_ccer & CCER_TS64BIT) != 0);
}
//! TS implemented.
inline const bool EtmV3Config::hasTS() const
{
return (bool)((m_cfg.reg_ccer & CCER_HAS_TS) != 0);
}
//! TS is enabled in the trace
inline const bool EtmV3Config::isTSEnabled() const
{
return (bool)((m_cfg.reg_ctrl & CTRL_TS_ENA) != 0);
}
//! tracing VMID
inline const bool EtmV3Config::isVMIDTrace() const
{
return (bool)((m_cfg.reg_ctrl & CTRL_VMID_ENA) != 0);
}
inline const uint8_t EtmV3Config::getTraceID() const
{
return (uint8_t)(m_cfg.reg_trc_id & 0x7F);
}
inline const ocsd_arch_version_t EtmV3Config::getArchVersion() const
{
return m_cfg.arch_ver;
}
inline const ocsd_core_profile_t EtmV3Config::getCoreProfile() const
{
return m_cfg.core_prof;
}
/** @}*/
/** @}*/
#endif // ARM_TRC_CMP_CFG_ETMV3_H_INCLUDED
/* End of File trc_cmp_cfg_etmv3.h */

View File

@ -0,0 +1,57 @@
/*
* \file trc_dcd_mngr_etmv3.h
* \brief OpenCSD : ETMv3 decoder manager / handler specialisation
*
* \copyright Copyright (c) 2016, 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_DCD_MNGR_ETMV3_H_INCLUDED
#define ARM_TRC_DCD_MNGR_ETMV3_H_INCLUDED
#include "common/ocsd_dcd_mngr.h"
#include "trc_pkt_decode_etmv3.h"
#include "trc_pkt_proc_etmv3.h"
#include "trc_cmp_cfg_etmv3.h"
#include "trc_pkt_types_etmv3.h"
class DecoderMngrEtmV3 : public DecodeMngrFullDcd< EtmV3TrcPacket,
ocsd_etmv3_pkt_type,
EtmV3Config,
ocsd_etmv3_cfg,
TrcPktProcEtmV3,
TrcPktDecodeEtmV3>
{
public:
DecoderMngrEtmV3(const std::string &name) : DecodeMngrFullDcd(name,OCSD_PROTOCOL_ETMV3) {};
virtual ~DecoderMngrEtmV3() {};
};
#endif // ARM_TRC_DCD_MNGR_ETMV3_H_INCLUDED
/* End of File trc_dcd_mngr_etmv3.h */

View File

@ -0,0 +1,274 @@
/*!
* \file trc_pkt_decode_etmv3.h
* \brief OpenCSD : ETMv3 decode
*
* \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_DECODE_ETMV3_H_INCLUDED
#define ARM_TRC_PKT_DECODE_ETMV3_H_INCLUDED
#include "common/trc_pkt_decode_base.h"
#include "common/trc_gen_elem.h"
#include "common/ocsd_pe_context.h"
#include "common/ocsd_code_follower.h"
#include "common/ocsd_gen_elem_list.h"
#include "opencsd/etmv3/trc_pkt_elem_etmv3.h"
#include "opencsd/etmv3/trc_cmp_cfg_etmv3.h"
/**************** Atom handling class **************************************/
class Etmv3Atoms
{
public:
Etmv3Atoms(const bool isCycleAcc);
~Etmv3Atoms() {};
//! initialise the atom and index values
void initAtomPkt(const EtmV3TrcPacket *in_pkt, const ocsd_trc_index_t &root_index);
const ocsd_atm_val getCurrAtomVal() const;
const int numAtoms() const; //!< number of atoms
const ocsd_trc_index_t pktIndex() const; //!< originating packet index
const bool hasAtomCC() const; //!< cycle count for current atom?
const uint32_t getAtomCC() const; //!< cycle count for current atom
const uint32_t getRemainCC() const; //!< get residual cycle count for remaining atoms
void clearAtom(); //!< clear the current atom, set the next.
void clearAll(); //!< clear all
private:
// Atom PHDR packet formats from ETMv3 spec - defines content of header.
enum {
ATOM_PHDR_FMT_1 = 1,
ATOM_PHDR_FMT_2,
ATOM_PHDR_FMT_3,
ATOM_PHDR_FMT_4,
};
ocsd_pkt_atom m_atom; /**< atom elements - non zero number indicates valid atom count */
uint8_t m_p_hdr_fmt; /**< if atom elements, associated phdr format */
uint32_t m_cycle_count;
ocsd_trc_index_t m_root_index; //!< root index for the atom packet
bool m_isCCPacket;
};
inline Etmv3Atoms::Etmv3Atoms(const bool isCycleAcc)
{
m_isCCPacket = isCycleAcc;
}
//! initialise the atom and index values
inline void Etmv3Atoms::initAtomPkt(const EtmV3TrcPacket *in_pkt, const ocsd_trc_index_t &root_index)
{
m_atom = in_pkt->getAtom();
m_p_hdr_fmt = in_pkt->getPHdrFmt();
m_cycle_count = in_pkt->getCycleCount();
}
inline const ocsd_atm_val Etmv3Atoms::getCurrAtomVal() const
{
return (m_atom.En_bits & 0x1) ? ATOM_E : ATOM_N;
}
inline const int Etmv3Atoms::numAtoms() const
{
return m_atom.num;
}
inline const ocsd_trc_index_t Etmv3Atoms::pktIndex() const
{
return m_root_index;
}
inline const bool Etmv3Atoms::hasAtomCC() const
{
bool hasCC = false;
if(!m_isCCPacket)
return hasCC;
switch(m_p_hdr_fmt)
{
case ATOM_PHDR_FMT_4:
default:
break;
case ATOM_PHDR_FMT_3:
case ATOM_PHDR_FMT_1:
hasCC = true;
break;
case ATOM_PHDR_FMT_2:
hasCC = (m_atom.num > 1); // first of 2 has W state
break;
}
return hasCC;
}
inline const uint32_t Etmv3Atoms::getAtomCC() const
{
uint32_t CC = 0;
if(!m_isCCPacket)
return CC;
switch(m_p_hdr_fmt)
{
case ATOM_PHDR_FMT_4: // no CC in format 4
default:
break;
case ATOM_PHDR_FMT_3: // single CC with optional E atom
CC = m_cycle_count;
break;
case ATOM_PHDR_FMT_2: // single W on first of 2 atoms
CC = (m_atom.num > 1) ? 1: 0;
break;
case ATOM_PHDR_FMT_1: // each atom has 1 CC.
CC = 1;
break;
}
return CC;
}
inline const uint32_t Etmv3Atoms::getRemainCC() const
{
uint32_t CC = 0;
if(!m_isCCPacket)
return CC;
switch(m_p_hdr_fmt)
{
case ATOM_PHDR_FMT_4: // no CC in format 4
default:
break;
case ATOM_PHDR_FMT_3:
CC = m_cycle_count;
break;
case ATOM_PHDR_FMT_2:
CC = (m_atom.num > 1) ? 1: 0;
break;
case ATOM_PHDR_FMT_1:
CC = m_atom.num;
break;
}
return CC;
}
inline void Etmv3Atoms::clearAtom()
{
m_atom.En_bits >>=1;
if(m_atom.num)
m_atom.num--;
}
inline void Etmv3Atoms::clearAll()
{
m_atom.num = 0;
}
/********** Main decode class ****************************************************/
class TrcPktDecodeEtmV3 : public TrcPktDecodeBase<EtmV3TrcPacket, EtmV3Config>
{
public:
TrcPktDecodeEtmV3();
TrcPktDecodeEtmV3(int instIDNum);
virtual ~TrcPktDecodeEtmV3();
protected:
/* implementation packet decoding interface */
virtual ocsd_datapath_resp_t processPacket();
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 uint8_t getCoreSightTraceID() { return m_CSID; };
/* local decode methods */
void initDecoder(); //!< initial state on creation (zeros all config)
void resetDecoder(); //!< reset state to start of decode. (moves state, retains config)
ocsd_datapath_resp_t decodePacket(bool &pktDone); //!< decode a packet
ocsd_datapath_resp_t processISync(const bool withCC, const bool firstSync = false);
ocsd_datapath_resp_t processBranchAddr();
ocsd_datapath_resp_t processPHdr();
ocsd_datapath_resp_t sendUnsyncPacket(); //!< send an initial unsync packet when decoder starts
OcsdTraceElement *GetNextOpElem(ocsd_datapath_resp_t &resp); //!< get the next element from the element list.
private:
void setNeedAddr(bool bNeedAddr);
void pendExceptionReturn();
bool preISyncValid(ocsd_etmv3_pkt_type pkt_type);
//** intra packet state;
OcsdCodeFollower m_code_follower; //!< code follower for instruction trace
ocsd_vaddr_t m_IAddr; //!< next instruction address
bool m_bNeedAddr; //!< true if an address is needed (current out of date / invalid)
bool m_bSentUnknown; //!< true if we have sent an unknown address packet for this phase of needing an address.
bool m_bWaitISync; //!< true if waiting for first ISync packet
OcsdPeContext m_PeContext; //!< save context data before sending in output packet
OcsdGenElemList m_outputElemList; //!< list of output elements
//** Other packet decoder state;
// trace decode FSM
typedef enum {
NO_SYNC, //!< pre start trace - init state or after reset or overflow, loss of sync.
WAIT_ASYNC, //!< waiting for a-sync packet.
WAIT_ISYNC, //!< waiting for i-sync packet.
DECODE_PKTS, //!< processing a packet
SEND_PKTS, //!< sending packets.
} processor_state_t;
processor_state_t m_curr_state;
uint8_t m_CSID; //!< Coresight trace ID for this decoder.
};
#endif // ARM_TRC_PKT_DECODE_ETMV3_H_INCLUDED
/* End of File trc_pkt_decode_etmv3.h */

View File

@ -0,0 +1,261 @@
/*
* \file trc_pkt_elem_etmv3.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_ETMV3_H_INCLUDED
#define ARM_TRC_PKT_ELEM_ETMV3_H_INCLUDED
#include "trc_pkt_types_etmv3.h"
#include "common/trc_printable_elem.h"
#include "common/trc_pkt_elem_base.h"
/** @addtogroup trc_pkts
@{*/
/*!
* @class EtmV3TrcPacket
* @brief ETMv3 Trace Protocol Packet.
*
* This class represents a single ETMv3 trace packet, along with intra packet state.
*
*/
class EtmV3TrcPacket : public TrcPacketBase, public trcPrintableElem
{
public:
EtmV3TrcPacket();
~EtmV3TrcPacket();
// conversions between C-API struct and C++ object types
// assign from C-API struct
EtmV3TrcPacket &operator =(const ocsd_etmv3_pkt* p_pkt);
// allow const cast to C-API struct to pass C++ object
operator const ocsd_etmv3_pkt*() const { return &m_pkt_data; };
operator const ocsd_etmv3_pkt&() const { return m_pkt_data; };
// override c_pkt to pass out the packet data struct.
virtual const void *c_pkt() const { return &m_pkt_data; };
// update interface - set packet values
void Clear(); //!< clear update data in packet ready for new one.
void ResetState(); //!< reset intra packet state data -on full decoder reset.
void SetType(const ocsd_etmv3_pkt_type p_type);
void SetErrType(const ocsd_etmv3_pkt_type e_type);
void UpdateAddress(const ocsd_vaddr_t partAddrVal, const int updateBits);
void SetException( const ocsd_armv7_exception type,
const uint16_t number,
const bool cancel,
const bool cm_type,
const int irq_n = 0,
const int resume = 0);
void UpdateNS(const int NS);
void UpdateAltISA(const int AltISA);
void UpdateHyp(const int Hyp);
void UpdateISA(const ocsd_isa isa);
void UpdateContextID(const uint32_t contextID);
void UpdateVMID(const uint8_t VMID);
void UpdateTimestamp(const uint64_t tsVal, const uint8_t updateBits);
bool UpdateAtomFromPHdr(const uint8_t pHdr, const bool cycleAccurate); //!< Interpret P Hdr, return true if valid, false if not.
void SetDataOOOTag(const uint8_t tag);
void SetDataValue(const uint32_t value);
void UpdateDataAddress(const uint32_t value, const uint8_t valid_bits);
void UpdateDataEndian(const uint8_t BE_Val);
void SetCycleCount(const uint32_t cycleCount);
void SetISyncReason(const ocsd_iSync_reason reason);
void SetISyncHasCC();
void SetISyncIsLSiP();
void SetISyncNoAddr();
// packet status interface - get packet info.
const ocsd_etmv3_pkt_type getType() const { return m_pkt_data.type; };
const bool isBadPacket() const;
const int AltISA() const { return m_pkt_data.context.curr_alt_isa; };
const ocsd_isa ISA() const { return m_pkt_data.curr_isa; };
const bool changedISA() const { return m_pkt_data.curr_isa != m_pkt_data.prev_isa; };
// any of the context elements updated?
const bool isCtxtUpdated() const;
const bool isCtxtFlagsUpdated() const { return (m_pkt_data.context.updated == 1); };
const bool isNS() const { return m_pkt_data.context.curr_NS; };
const bool isHyp() const { return m_pkt_data.context.curr_Hyp; };
const bool isCtxtIDUpdated() const { return (m_pkt_data.context.updated_c == 1); }
const uint32_t getCtxtID() const { return m_pkt_data.context.ctxtID; };
const bool isVMIDUpdated() const { return (m_pkt_data.context.updated_v == 1); }
const uint32_t getVMID() const { return m_pkt_data.context.VMID; };
const uint32_t getCycleCount() const { return m_pkt_data.cycle_count; };
const uint64_t getTS() const { return m_pkt_data.timestamp; };
const bool isExcepPkt() const { return (m_pkt_data.exception.bits.present == 1); };
const ocsd_armv7_exception excepType() const { return m_pkt_data.exception.type; };
const uint16_t excepNum() const { return m_pkt_data.exception.number; };
const bool isExcepCancel() const { return (m_pkt_data.exception.bits.present == 1) && (m_pkt_data.exception.bits.cancel == 1); };
const ocsd_iSync_reason getISyncReason() const { return m_pkt_data.isync_info.reason; };
const bool getISyncHasCC() const { return m_pkt_data.isync_info.has_cycle_count; };
const bool getISyncIsLSiPAddr() const { return m_pkt_data.isync_info.has_LSipAddress; };
const bool getISyncNoAddr() const { return m_pkt_data.isync_info.no_address; };
const ocsd_vaddr_t getAddr() const { return m_pkt_data.addr.val; };
const ocsd_vaddr_t getDataAddr() const { return m_pkt_data.data.addr.val; };
const ocsd_pkt_atom &getAtom() const { return m_pkt_data.atom; };
const uint8_t getPHdrFmt() const { return m_pkt_data.p_hdr_fmt; };
// printing
virtual void toString(std::string &str) const;
virtual void toStringFmt(const uint32_t fmtFlags, std::string &str) const;
private:
const char *packetTypeName(const ocsd_etmv3_pkt_type type, const char **ppDesc) const;
void getBranchAddressStr(std::string &valStr) const;
void getAtomStr(std::string &valStr) const;
void getISyncStr(std::string &valStr) const;
void getISAStr(std::string &isaStr) const;
void getExcepStr(std::string &excepStr) const;
ocsd_etmv3_pkt m_pkt_data;
};
inline void EtmV3TrcPacket::UpdateNS(const int NS)
{
m_pkt_data.context.curr_NS = NS;
m_pkt_data.context.updated = 1;
};
inline void EtmV3TrcPacket::UpdateAltISA(const int AltISA)
{
m_pkt_data.context.curr_alt_isa = AltISA;
m_pkt_data.context.updated = 1;
}
inline void EtmV3TrcPacket::UpdateHyp(const int Hyp)
{
m_pkt_data.context.curr_Hyp = Hyp;
m_pkt_data.context.updated = 1;
}
inline void EtmV3TrcPacket::UpdateISA(const ocsd_isa isa)
{
m_pkt_data.prev_isa = m_pkt_data.curr_isa;
m_pkt_data.curr_isa = isa;
}
inline void EtmV3TrcPacket::SetType(const ocsd_etmv3_pkt_type p_type)
{
m_pkt_data.type = p_type;
}
inline void EtmV3TrcPacket::SetErrType(const ocsd_etmv3_pkt_type e_type)
{
m_pkt_data.err_type = m_pkt_data.type;
m_pkt_data.type = e_type;
}
inline const bool EtmV3TrcPacket::isBadPacket() const
{
return (m_pkt_data.type >= ETM3_PKT_BAD_SEQUENCE);
}
inline void EtmV3TrcPacket::SetDataOOOTag(const uint8_t tag)
{
m_pkt_data.data.ooo_tag = tag;
}
inline void EtmV3TrcPacket::SetDataValue(const uint32_t value)
{
m_pkt_data.data.value = value;
m_pkt_data.data.update_dval = 1;
}
inline void EtmV3TrcPacket::UpdateContextID(const uint32_t contextID)
{
m_pkt_data.context.updated_c = 1;
m_pkt_data.context.ctxtID = contextID;
}
inline void EtmV3TrcPacket::UpdateVMID(const uint8_t VMID)
{
m_pkt_data.context.updated_v = 1;
m_pkt_data.context.VMID = VMID;
}
inline void EtmV3TrcPacket::UpdateDataEndian(const uint8_t BE_Val)
{
m_pkt_data.data.be = BE_Val;
m_pkt_data.data.update_be = 1;
}
inline void EtmV3TrcPacket::SetCycleCount(const uint32_t cycleCount)
{
m_pkt_data.cycle_count = cycleCount;
}
inline void EtmV3TrcPacket::SetISyncReason(const ocsd_iSync_reason reason)
{
m_pkt_data.isync_info.reason = reason;
}
inline void EtmV3TrcPacket::SetISyncHasCC()
{
m_pkt_data.isync_info.has_cycle_count = 1;
}
inline void EtmV3TrcPacket::SetISyncIsLSiP()
{
m_pkt_data.isync_info.has_LSipAddress = 1;
}
inline void EtmV3TrcPacket::SetISyncNoAddr()
{
m_pkt_data.isync_info.no_address = 1;
}
inline const bool EtmV3TrcPacket::isCtxtUpdated() const
{
return (m_pkt_data.context.updated_v == 1) ||
(m_pkt_data.context.updated == 1) ||
(m_pkt_data.context.updated_c == 1);
}
/** @}*/
#endif // ARM_TRC_PKT_ELEM_ETMV3_H_INCLUDED
/* End of File trc_pkt_elem_etmv3.h */

View File

@ -0,0 +1,81 @@
/*
* \file trc_pkt_proc_etmv3.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_ETMV3_H_INCLUDED
#define ARM_TRC_PKT_PROC_ETMV3_H_INCLUDED
#include "trc_pkt_types_etmv3.h"
#include "common/trc_pkt_proc_base.h"
class EtmV3PktProcImpl;
class EtmV3TrcPacket;
class EtmV3Config;
/** @addtogroup ocsd_pkt_proc
@{*/
class TrcPktProcEtmV3 : public TrcPktProcBase< EtmV3TrcPacket, ocsd_etmv3_pkt_type, EtmV3Config>
{
public:
TrcPktProcEtmV3();
TrcPktProcEtmV3(int instIDNum);
virtual ~TrcPktProcEtmV3();
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 EtmV3PktProcImpl;
EtmV3PktProcImpl *m_pProcessor;
};
#define ETMV3_OPFLG_UNFORMATTED_SOURCE 0x00010000 /**< Single ETM source from bypassed formatter - need to check for EOT markers */
/** @}*/
#endif // ARM_TRC_PKT_PROC_ETMV3_H_INCLUDED
/* End of File trc_pkt_proc_etm.h */

View File

@ -0,0 +1,178 @@
/*
* \file trc_pkt_types_etmv3.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_ETM3_PKT_TYPES_ETMV3_H_INCLUDED
#define ARM_TRC_ETM3_PKT_TYPES_ETMV3_H_INCLUDED
#include "opencsd/trc_pkt_types.h"
/** @addtogroup trc_pkts
@{*/
/** @name ETMv3 Packet Types
@{*/
typedef enum _ocsd_etmv3_pkt_type
{
// markers for unknown packets
ETM3_PKT_NOERROR, //!< no error in packet - supplimentary data.
ETM3_PKT_NOTSYNC, //!< no sync found yet
ETM3_PKT_INCOMPLETE_EOT, //!< flushing incomplete/empty packet at end of trace.
// markers for valid packets
ETM3_PKT_BRANCH_ADDRESS,
ETM3_PKT_A_SYNC,
ETM3_PKT_CYCLE_COUNT,
ETM3_PKT_I_SYNC,
ETM3_PKT_I_SYNC_CYCLE,
ETM3_PKT_TRIGGER,
ETM3_PKT_P_HDR,
ETM3_PKT_STORE_FAIL,
ETM3_PKT_OOO_DATA,
ETM3_PKT_OOO_ADDR_PLC,
ETM3_PKT_NORM_DATA,
ETM3_PKT_DATA_SUPPRESSED,
ETM3_PKT_VAL_NOT_TRACED,
ETM3_PKT_IGNORE,
ETM3_PKT_CONTEXT_ID,
ETM3_PKT_VMID,
ETM3_PKT_EXCEPTION_ENTRY,
ETM3_PKT_EXCEPTION_EXIT,
ETM3_PKT_TIMESTAMP,
// internal processing types
ETM3_PKT_BRANCH_OR_BYPASS_EOT,
// packet errors
ETM3_PKT_BAD_SEQUENCE, //!< invalid sequence for packet type
ETM3_PKT_BAD_TRACEMODE, //!< invalid packet type for this trace mode.
ETM3_PKT_RESERVED //!< packet type reserved.
} ocsd_etmv3_pkt_type;
typedef struct _ocsd_etmv3_excep {
ocsd_armv7_exception type; /**< exception type. */
uint16_t number; /**< exception as number */
struct {
uint32_t present:1; /**< exception present in packet */
uint32_t cancel:1; /**< exception cancels prev instruction traced. */
uint32_t cm_type:1;
uint32_t cm_resume:4; /**< M class resume code */
uint32_t cm_irq_n:9; /**< M class IRQ n */
} bits;
} ocsd_etmv3_excep;
typedef struct _etmv3_context_t {
struct {
uint32_t curr_alt_isa:1; /**< current Alt ISA flag for Tee / T32 (used if not in present packet) */
uint32_t curr_NS:1; /**< current NS flag (used if not in present packet) */
uint32_t curr_Hyp:1; /**< current Hyp flag (used if not in present packet) */
uint32_t updated:1; /**< context updated */
uint32_t updated_c:1; /**< updated CtxtID */
uint32_t updated_v:1; /**< updated VMID */
};
uint32_t ctxtID; /**< Context ID */
uint8_t VMID; /**< VMID */
} etmv3_context_t;
typedef struct _etmv3_data_t {
uint32_t value; /**< Data value */
ocsd_pkt_vaddr addr; /**< current data address */
struct {
uint32_t ooo_tag:2; /**< Out of order data tag. */
uint32_t be:1; /**< data transfers big-endian */
uint32_t update_be:1; /**< updated Be flag */
uint32_t update_addr:1; /**< updated address */
uint32_t update_dval:1; /**< updated data value */
};
} etmv3_data_t;
typedef struct _etmv3_isync_t {
ocsd_iSync_reason reason;
struct {
uint32_t has_cycle_count:1; /**< updated cycle count */
uint32_t has_LSipAddress:1; /**< main address is load-store instuction, data address is overlapping instruction @ start of trace */
uint32_t no_address:1; /**< data only ISync */
};
} etmv3_isync_t;
typedef struct _ocsd_etmv3_pkt
{
ocsd_etmv3_pkt_type type; /**< Primary packet type. */
ocsd_isa curr_isa; /**< current ISA */
ocsd_isa prev_isa; /**< ISA in previous packet */
etmv3_context_t context; /**< current context */
ocsd_pkt_vaddr addr; /**< current Addr */
etmv3_isync_t isync_info;
ocsd_etmv3_excep exception;
ocsd_pkt_atom atom; /**< atom elements - non zerom number indicates valid atom count */
uint8_t p_hdr_fmt; /**< if atom elements, associated phdr format */
uint32_t cycle_count; /**< cycle count associated with this packet (ETMv3 has counts in atom packets and as individual packets */
uint64_t timestamp; /**< current timestamp value */
uint8_t ts_update_bits; /**< bits of ts updated this packet (if TS packet) */
etmv3_data_t data; /**< data transfer values */
ocsd_etmv3_pkt_type err_type; /**< Basic packet type if primary type indicates error or incomplete. (header type) */
} ocsd_etmv3_pkt;
typedef struct _ocsd_etmv3_cfg
{
uint32_t reg_idr; /**< ID register */
uint32_t reg_ctrl; /**< Control Register */
uint32_t reg_ccer; /**< CCER register */
uint32_t reg_trc_id; /**< Trace Stream ID register */
ocsd_arch_version_t arch_ver; /**< Architecture version */
ocsd_core_profile_t core_prof; /**< Core Profile */
} ocsd_etmv3_cfg;
#define DATA_ADDR_EXPECTED_FLAG 0x20 /**< Bit set for data trace headers if data address packets follow */
/** @}*/
/** @}*/
#endif // ARM_TRC_ETM3_PKT_TYPES_ETMV3_H_INCLUDED
/* End of File trc_pkt_types_etmv3.h */

View File

@ -0,0 +1,48 @@
/*
* \file etmv4_decoder.h
* \brief OpenCSD : Top level header file for ETMv4 decoders
*
* \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_ETMV4_DECODER_H_INCLUDED
#define ARM_ETMV4_DECODER_H_INCLUDED
#include "trc_cmp_cfg_etmv4.h"
#include "trc_pkt_elem_etmv4i.h"
#include "trc_pkt_elem_etmv4d.h"
#include "trc_pkt_proc_etmv4.h"
#include "trc_pkt_types_etmv4.h"
#include "trc_pkt_decode_etmv4i.h"
#endif // ARM_ETMV4_DECODER_H_INCLUDED
/* End of File etmv4_decoder.h */

View File

@ -0,0 +1,449 @@
/*
* \file trc_cmp_cfg_etmv4.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_CMP_CFG_ETMV4_H_INCLUDED
#define ARM_TRC_CMP_CFG_ETMV4_H_INCLUDED
#include "trc_pkt_types_etmv4.h"
#include "common/trc_cs_config.h"
/** @addtogroup ocsd_protocol_cfg
@{*/
/** @name ETMv4 configuration
@{*/
/*!
* @class EtmV4Config
* @brief Interpreter class for etm v4 config structure.
*
* Provides quick value interpretation methods for the ETMv4 config register values.
* Primarily inlined for efficient code.
*/
class EtmV4Config : public CSConfig // public ocsd_etmv4_cfg
{
public:
EtmV4Config(); /**< Default constructor */
EtmV4Config(const ocsd_etmv4_cfg *cfg_regs);
~EtmV4Config() {}; /**< Default destructor */
// operations to convert to and from C-API structure
//! copy assignment operator for base structure into class.
EtmV4Config & operator=(const ocsd_etmv4_cfg *p_cfg);
//! cast operator returning struct const reference
operator const ocsd_etmv4_cfg &() const { return m_cfg; };
//! cast operator returning struct const pointer
operator const ocsd_etmv4_cfg *() const { return &m_cfg; };
const ocsd_core_profile_t &coreProfile() const { return m_cfg.core_prof; };
const ocsd_arch_version_t &archVersion() const { return m_cfg.arch_ver; };
/* idr 0 */
const bool LSasInstP0() const;
const bool hasDataTrace() const;
const bool hasBranchBroadcast() const;
const bool hasCondTrace() const;
const bool hasCycleCountI() const;
const bool hasRetStack() const;
const uint8_t numEvents() const;
typedef enum _condType {
COND_PASS_FAIL,
COND_HAS_ASPR
} condType;
const condType hasCondType() const;
typedef enum _QSuppType {
Q_NONE,
Q_ICOUNT_ONLY,
Q_NO_ICOUNT_ONLY,
Q_FULL
} QSuppType;
const QSuppType getQSuppType();
const bool hasQElem();
const bool hasQFilter();
const bool hasTrcExcpData() const;
const uint32_t TimeStampSize() const;
const bool commitOpt1() const;
/* idr 1 */
const uint8_t MajVersion() const;
const uint8_t MinVersion() const;
/* idr 2 */
const uint32_t iaSizeMax() const;
const uint32_t cidSize() const;
const uint32_t vmidSize();
const uint32_t daSize() const;
const uint32_t dvSize() const;
const uint32_t ccSize() const;
const bool vmidOpt() const;
/* id regs 8-13*/
const uint32_t MaxSpecDepth() const;
const uint32_t P0_Key_Max() const;
const uint32_t P1_Key_Max() const;
const uint32_t P1_Spcl_Key_Max() const;
const uint32_t CondKeyMax() const;
const uint32_t CondSpecKeyMax() const;
const uint32_t CondKeyMaxIncr() const;
/* trace idr */
virtual const uint8_t getTraceID() const; //!< CoreSight Trace ID for this device.
/* config R */
const bool enabledDVTrace() const;
const bool enabledDATrace() const;
const bool enabledDataTrace() const;
typedef enum {
LSP0_NONE,
LSP0_L,
LSP0_S,
LSP0_LS
} LSP0_t;
const bool enabledLSP0Trace() const;
const LSP0_t LSP0Type() const;
const bool enabledBrBroad() const;
const bool enabledCCI() const;
const bool enabledCID() const;
const bool enabledVMID() const;
typedef enum {
COND_TR_DIS,
COND_TR_LD,
COND_TR_ST,
COND_TR_LDST,
COND_TR_ALL
} CondITrace_t;
const CondITrace_t enabledCondITrace();
const bool enabledTS() const;
const bool enabledRetStack() const;
const bool enabledQE() const;
private:
void PrivateInit();
void CalcQSupp();
void CalcVMIDSize();
bool m_QSuppCalc;
bool m_QSuppFilter;
QSuppType m_QSuppType;
bool m_VMIDSzCalc;
uint32_t m_VMIDSize;
bool m_condTraceCalc;
CondITrace_t m_CondTrace;
ocsd_etmv4_cfg m_cfg;
};
/* idr 0 */
inline const bool EtmV4Config::LSasInstP0() const
{
return (bool)((m_cfg.reg_idr0 & 0x6) == 0x6);
}
inline const bool EtmV4Config::hasDataTrace() const
{
return (bool)((m_cfg.reg_idr0 & 0x18) == 0x18);
}
inline const bool EtmV4Config::hasBranchBroadcast() const
{
return (bool)((m_cfg.reg_idr0 & 0x20) == 0x20);
}
inline const bool EtmV4Config::hasCondTrace() const
{
return (bool)((m_cfg.reg_idr0 & 0x40) == 0x40);
}
inline const bool EtmV4Config::hasCycleCountI() const
{
return (bool)((m_cfg.reg_idr0 & 0x80) == 0x80);
}
inline const bool EtmV4Config::hasRetStack() const
{
return (bool)((m_cfg.reg_idr0 & 0x200) == 0x200);
}
inline const uint8_t EtmV4Config::numEvents() const
{
return ((m_cfg.reg_idr0 >> 10) & 0x3) + 1;
}
inline const EtmV4Config::condType EtmV4Config::hasCondType() const
{
return ((m_cfg.reg_idr0 & 0x3000) == 0x1000) ? EtmV4Config::COND_HAS_ASPR : EtmV4Config::COND_PASS_FAIL;
}
inline const EtmV4Config::QSuppType EtmV4Config::getQSuppType()
{
if(!m_QSuppCalc) CalcQSupp();
return m_QSuppType;
}
inline const bool EtmV4Config::hasQElem()
{
if(!m_QSuppCalc) CalcQSupp();
return (bool)(m_QSuppType != Q_NONE);
}
inline const bool EtmV4Config::hasQFilter()
{
if(!m_QSuppCalc) CalcQSupp();
return m_QSuppFilter;
}
inline const bool EtmV4Config::hasTrcExcpData() const
{
return (bool)((m_cfg.reg_idr0 & 0x20000) == 0x20000);
}
inline const uint32_t EtmV4Config::TimeStampSize() const
{
uint32_t tsSizeF = (m_cfg.reg_idr0 >> 24) & 0x1F;
if(tsSizeF == 0x6)
return 48;
if(tsSizeF == 0x8)
return 64;
return 0;
}
inline const bool EtmV4Config::commitOpt1() const
{
return (bool)((m_cfg.reg_idr0 & 0x20000000) == 0x20000000) && hasCycleCountI();
}
/* idr 1 */
inline const uint8_t EtmV4Config::MajVersion() const
{
return (uint8_t)((m_cfg.reg_idr1 >> 8) & 0xF);
}
inline const uint8_t EtmV4Config::MinVersion() const
{
return (uint8_t)((m_cfg.reg_idr1 >> 4) & 0xF);
}
/* idr 2 */
inline const uint32_t EtmV4Config::iaSizeMax() const
{
return ((m_cfg.reg_idr2 & 0x1F) == 0x8) ? 64 : 32;
}
inline const uint32_t EtmV4Config::cidSize() const
{
return (((m_cfg.reg_idr2 >> 5) & 0x1F) == 0x4) ? 32 : 0;
}
inline const uint32_t EtmV4Config::vmidSize()
{
if(!m_VMIDSzCalc)
{
CalcVMIDSize();
}
return m_VMIDSize;
}
inline const uint32_t EtmV4Config::daSize() const
{
uint32_t daSizeF = ((m_cfg.reg_idr2 >> 15) & 0x1F);
if(daSizeF)
return (((m_cfg.reg_idr2 >> 15) & 0x1F) == 0x8) ? 64 : 32;
return 0;
}
inline const uint32_t EtmV4Config::dvSize() const
{
uint32_t dvSizeF = ((m_cfg.reg_idr2 >> 20) & 0x1F);
if(dvSizeF)
return (((m_cfg.reg_idr2 >> 20) & 0x1F) == 0x8) ? 64 : 32;
return 0;
}
inline const uint32_t EtmV4Config::ccSize() const
{
return ((m_cfg.reg_idr2 >> 25) & 0xF) + 12;
}
inline const bool EtmV4Config::vmidOpt() const
{
return (bool)((m_cfg.reg_idr2 & 0x20000000) == 0x20000000) && (MinVersion() > 0);
}
/* id regs 8-13*/
inline const uint32_t EtmV4Config::MaxSpecDepth() const
{
return m_cfg.reg_idr8;
}
inline const uint32_t EtmV4Config::P0_Key_Max() const
{
return (m_cfg.reg_idr9 == 0) ? 1 : m_cfg.reg_idr9;
}
inline const uint32_t EtmV4Config::P1_Key_Max() const
{
return m_cfg.reg_idr10;
}
inline const uint32_t EtmV4Config::P1_Spcl_Key_Max() const
{
return m_cfg.reg_idr11;
}
inline const uint32_t EtmV4Config::CondKeyMax() const
{
return m_cfg.reg_idr12;
}
inline const uint32_t EtmV4Config::CondSpecKeyMax() const
{
return m_cfg.reg_idr13;
}
inline const uint32_t EtmV4Config::CondKeyMaxIncr() const
{
return m_cfg.reg_idr12 - m_cfg.reg_idr13;
}
inline const uint8_t EtmV4Config::getTraceID() const
{
return (uint8_t)(m_cfg.reg_traceidr & 0x7F);
}
/* config R */
inline const bool EtmV4Config::enabledDVTrace() const
{
return hasDataTrace() && enabledLSP0Trace() && ((m_cfg.reg_configr & (0x1 << 17)) != 0);
}
inline const bool EtmV4Config::enabledDATrace() const
{
return hasDataTrace() && enabledLSP0Trace() && ((m_cfg.reg_configr & (0x1 << 16)) != 0);
}
inline const bool EtmV4Config::enabledDataTrace() const
{
return enabledDATrace() || enabledDVTrace();
}
inline const bool EtmV4Config::enabledLSP0Trace() const
{
return ((m_cfg.reg_configr & 0x6) != 0);
}
inline const EtmV4Config::LSP0_t EtmV4Config::LSP0Type() const
{
return (LSP0_t)((m_cfg.reg_configr & 0x6) >> 1);
}
inline const bool EtmV4Config::enabledBrBroad() const
{
return ((m_cfg.reg_configr & (0x1 << 3)) != 0);
}
inline const bool EtmV4Config::enabledCCI() const
{
return ((m_cfg.reg_configr & (0x1 << 4)) != 0);
}
inline const bool EtmV4Config::enabledCID() const
{
return ((m_cfg.reg_configr & (0x1 << 6)) != 0);
}
inline const bool EtmV4Config::enabledVMID() const
{
return ((m_cfg.reg_configr & (0x1 << 7)) != 0);
}
inline const EtmV4Config::CondITrace_t EtmV4Config::enabledCondITrace()
{
if(!m_condTraceCalc)
{
switch((m_cfg.reg_configr >> 8) & 0x7)
{
default:
case 0: m_CondTrace = COND_TR_DIS; break;
case 1: m_CondTrace = COND_TR_LD; break;
case 2: m_CondTrace = COND_TR_ST; break;
case 3: m_CondTrace = COND_TR_LDST; break;
case 7: m_CondTrace = COND_TR_ALL; break;
}
m_condTraceCalc = true;
}
return m_CondTrace;
}
inline const bool EtmV4Config::enabledTS() const
{
return ((m_cfg.reg_configr & (0x1 << 11)) != 0);
}
inline const bool EtmV4Config::enabledRetStack() const
{
return ((m_cfg.reg_configr & (0x1 << 12)) != 0);
}
inline const bool EtmV4Config::enabledQE() const
{
return ((m_cfg.reg_configr & (0x3 << 13)) != 0);
}
/** @}*/
/** @}*/
#endif // ARM_TRC_CMP_CFG_ETMV4_H_INCLUDED
/* End of File trc_cmp_cfg_etmv4.h */

View File

@ -0,0 +1,31 @@
/*
* \file trc_dcd_mngr_etmv4i.h
* \brief Reference CoreSight Trace Decoder :
*
* \copyright Copyright (c) 2016, ARM Limited. All Rights Reserved.
*/
#ifndef ARM_TRC_DCD_MNGR_ETMV4I_H_INCLUDED
#define ARM_TRC_DCD_MNGR_ETMV4I_H_INCLUDED
#include "common/ocsd_dcd_mngr.h"
#include "trc_pkt_decode_etmv4i.h"
#include "trc_pkt_proc_etmv4.h"
#include "trc_cmp_cfg_etmv4.h"
#include "trc_pkt_types_etmv4.h"
class DecoderMngrEtmV4I : public DecodeMngrFullDcd< EtmV4ITrcPacket,
ocsd_etmv4_i_pkt_type,
EtmV4Config,
ocsd_etmv4_cfg,
TrcPktProcEtmV4I,
TrcPktDecodeEtmV4I>
{
public:
DecoderMngrEtmV4I(const std::string &name) : DecodeMngrFullDcd(name,OCSD_PROTOCOL_ETMV4I) {};
virtual ~DecoderMngrEtmV4I() {};
};
#endif // ARM_TRC_DCD_MNGR_ETMV4I_H_INCLUDED
/* End of File trc_dcd_mngr_etmv4i.h */

View File

@ -0,0 +1,338 @@
/*
* \file trc_etmv4_stack_elem.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_ETMV4_STACK_ELEM_H_INCLUDED
#define ARM_TRC_ETMV4_STACK_ELEM_H_INCLUDED
#include "opencsd/etmv4/trc_pkt_types_etmv4.h"
#include <deque>
#include <vector>
/* ETMv4 I trace stack elements
Speculation requires that we stack certain elements till they are committed or
cancelled. (P0 elements + other associated parts.)
*/
typedef enum _p0_elem_t
{
P0_UNKNOWN,
P0_ATOM,
P0_ADDR,
P0_CTXT,
P0_TRC_ON,
P0_EXCEP,
P0_EXCEP_RET,
P0_EVENT,
P0_TS,
P0_CC,
P0_TS_CC,
P0_OVERFLOW
} p0_elem_t;
/************************************************************/
/***Trace stack element base class -
record originating packet type and index in buffer*/
class TrcStackElem {
public:
TrcStackElem(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
virtual ~TrcStackElem() {};
const p0_elem_t getP0Type() const { return m_P0_type; };
const ocsd_etmv4_i_pkt_type getRootPkt() const { return m_root_pkt; };
const ocsd_trc_index_t getRootIndex() const { return m_root_idx; };
const bool isP0() const { return m_is_P0; };
private:
ocsd_etmv4_i_pkt_type m_root_pkt;
ocsd_trc_index_t m_root_idx;
p0_elem_t m_P0_type;
protected:
bool m_is_P0; // true if genuine P0 - commit / cancellable, false otherwise
};
inline TrcStackElem::TrcStackElem(p0_elem_t p0_type, const bool isP0, ocsd_etmv4_i_pkt_type root_pkt, ocsd_trc_index_t root_index) :
m_root_pkt(root_pkt),
m_root_idx(root_index),
m_P0_type(p0_type),
m_is_P0(isP0)
{
}
/************************************************************/
/** Address element */
class TrcStackElemAddr : public TrcStackElem
{
protected:
TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
virtual ~TrcStackElemAddr() {};
friend class EtmV4P0Stack;
public:
void setAddr(const etmv4_addr_val_t &addr_val) { m_addr_val = addr_val; };
const etmv4_addr_val_t &getAddr() const { return m_addr_val; };
private:
etmv4_addr_val_t m_addr_val;
};
inline TrcStackElemAddr::TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
TrcStackElem(P0_ADDR, false, root_pkt,root_index)
{
m_addr_val.val = 0;
m_addr_val.isa = 0;
}
/************************************************************/
/** Context element */
class TrcStackElemCtxt : public TrcStackElem
{
protected:
TrcStackElemCtxt(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
virtual ~TrcStackElemCtxt() {};
friend class EtmV4P0Stack;
public:
void setContext(const etmv4_context_t &ctxt) { m_context = ctxt; };
const etmv4_context_t &getContext() const { return m_context; };
private:
etmv4_context_t m_context;
};
inline TrcStackElemCtxt::TrcStackElemCtxt(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
TrcStackElem(P0_CTXT, false, root_pkt,root_index)
{
}
/************************************************************/
/** Exception element */
class TrcStackElemExcept : public TrcStackElem
{
protected:
TrcStackElemExcept(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
virtual ~TrcStackElemExcept() {};
friend class EtmV4P0Stack;
public:
void setPrevSame(bool bSame) { m_prev_addr_same = bSame; };
const bool getPrevSame() const { return m_prev_addr_same; };
void setExcepNum(const uint16_t num) { m_excep_num = num; };
const uint16_t getExcepNum() const { return m_excep_num; };
private:
bool m_prev_addr_same;
uint16_t m_excep_num;
};
inline TrcStackElemExcept::TrcStackElemExcept(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
TrcStackElem(P0_EXCEP, true, root_pkt,root_index),
m_prev_addr_same(false)
{
}
/************************************************************/
/** Atom element */
class TrcStackElemAtom : public TrcStackElem
{
protected:
TrcStackElemAtom(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
virtual ~TrcStackElemAtom() {};
friend class EtmV4P0Stack;
public:
void setAtom(const ocsd_pkt_atom &atom) { m_atom = atom; };
const ocsd_atm_val commitOldest();
int cancelNewest(const int nCancel);
const bool isEmpty() const { return (m_atom.num == 0); };
private:
ocsd_pkt_atom m_atom;
};
inline TrcStackElemAtom::TrcStackElemAtom(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
TrcStackElem(P0_ATOM, true, root_pkt,root_index)
{
m_atom.num = 0;
}
// commit oldest - get value and remove it from pattern
inline const ocsd_atm_val TrcStackElemAtom::commitOldest()
{
ocsd_atm_val val = (m_atom.En_bits & 0x1) ? ATOM_E : ATOM_N;
m_atom.num--;
m_atom.En_bits >>= 1;
return val;
}
// cancel newest - just reduce the atom count.
inline int TrcStackElemAtom::cancelNewest(const int nCancel)
{
int nRemove = (nCancel <= m_atom.num) ? nCancel : m_atom.num;
m_atom.num -= nRemove;
return nRemove;
}
/************************************************************/
/** Generic param element */
class TrcStackElemParam : public TrcStackElem
{
protected:
TrcStackElemParam(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
virtual ~TrcStackElemParam() {};
friend class EtmV4P0Stack;
public:
void setParam(const uint32_t param, const int nParamNum) { m_param[(nParamNum & 0x3)] = param; };
const uint32_t &getParam(const int nParamNum) const { return m_param[(nParamNum & 0x3)]; };
private:
uint32_t m_param[4];
};
inline TrcStackElemParam::TrcStackElemParam(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
TrcStackElem(p0_type, isP0, root_pkt,root_index)
{
}
/************************************************************/
/* P0 element stack that allows push of elements, and deletion of elements when done.
*/
class EtmV4P0Stack
{
public:
EtmV4P0Stack() {};
~EtmV4P0Stack();
void push_front(TrcStackElem *pElem);
void pop_back();
TrcStackElem *back();
size_t size();
void delete_all();
void delete_back();
void delete_popped();
// creation functions - create and push if successful.
TrcStackElemParam *createParamElem(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const std::vector<uint32_t> &params);
TrcStackElemParam *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);
TrcStackElemAtom *createAtomElem (const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const ocsd_pkt_atom &atom);
TrcStackElemExcept *createExceptElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const bool bSame, const uint16_t excepNum);
TrcStackElemCtxt *createContextElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_context_t &context);
TrcStackElemAddr *createAddrElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_addr_val_t &addr_val);
private:
std::deque<TrcStackElem *> m_P0_stack; //!< P0 decode element stack
std::vector<TrcStackElem *> m_popped_elem; //!< save list of popped but not deleted elements.
};
inline EtmV4P0Stack::~EtmV4P0Stack()
{
delete_all();
delete_popped();
}
// put an element on the front of the stack
inline void EtmV4P0Stack::push_front(TrcStackElem *pElem)
{
m_P0_stack.push_front(pElem);
}
// pop last element pointer off the stack and stash it for later deletion
inline void EtmV4P0Stack::pop_back()
{
m_popped_elem.push_back(m_P0_stack.back());
m_P0_stack.pop_back();
}
// pop last element pointer off the stack and delete immediately
inline void EtmV4P0Stack::delete_back()
{
if (m_P0_stack.size() > 0)
{
TrcStackElem* pElem = m_P0_stack.back();
delete pElem;
m_P0_stack.pop_back();
}
}
// get a pointer to the last element on the stack
inline TrcStackElem *EtmV4P0Stack::back()
{
return m_P0_stack.back();
}
// remove and delete all the elements left on the stack
inline void EtmV4P0Stack::delete_all()
{
while (m_P0_stack.size() > 0)
delete_back();
m_P0_stack.clear();
}
// delete list of popped elements.
inline void EtmV4P0Stack::delete_popped()
{
while (m_popped_elem.size() > 0)
{
delete m_popped_elem.back();
m_popped_elem.pop_back();
}
m_popped_elem.clear();
}
// get current number of elements on the stack
inline size_t EtmV4P0Stack::size()
{
return m_P0_stack.size();
}
#endif // ARM_TRC_ETMV4_STACK_ELEM_H_INCLUDED
/* End of File trc_etmv4_stack_elem.h */

View File

@ -0,0 +1,183 @@
/*
* \file trc_pkt_decode_etmv4i.h
* \brief OpenCSD : ETMv4 instruction decoder
*
* \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_DECODE_ETMV4I_H_INCLUDED
#define ARM_TRC_PKT_DECODE_ETMV4I_H_INCLUDED
#include "common/trc_pkt_decode_base.h"
#include "opencsd/etmv4/trc_pkt_elem_etmv4i.h"
#include "opencsd/etmv4/trc_cmp_cfg_etmv4.h"
#include "common/trc_gen_elem.h"
#include "common/trc_ret_stack.h"
#include "opencsd/etmv4/trc_etmv4_stack_elem.h"
class TrcStackElem;
class TrcStackElemParam;
class TrcStackElemCtxt;
class TrcPktDecodeEtmV4I : public TrcPktDecodeBase<EtmV4ITrcPacket, EtmV4Config>
{
public:
TrcPktDecodeEtmV4I();
TrcPktDecodeEtmV4I(int instIDNum);
virtual ~TrcPktDecodeEtmV4I();
protected:
/* implementation packet decoding interface */
virtual ocsd_datapath_resp_t processPacket();
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 uint8_t getCoreSightTraceID() { return m_CSID; };
/* local decode methods */
void initDecoder(); // initial state on creation (zeros all config)
void resetDecoder(); // reset state to start of decode. (moves state, retains config)
ocsd_datapath_resp_t decodePacket(bool &Complete); // return true to indicate decode complete - can change FSM to commit state - return is false.
ocsd_datapath_resp_t commitElements(bool &Complete); // commit elements - may get wait response, or flag completion.
ocsd_datapath_resp_t flushEOT();
void doTraceInfoPacket();
void updateContext(TrcStackElemCtxt *pCtxtElem);
// process atom will output instruction trace, or no memory access trace elements.
ocsd_datapath_resp_t processAtom(const ocsd_atm_val, bool &bCont);
// process an exception element - output instruction trace + exception generic type.
ocsd_datapath_resp_t processException();
// process a bad packet
ocsd_datapath_resp_t handleBadPacket(const char *reason);
ocsd_datapath_resp_t outputCC(TrcStackElemParam *pParamElem);
ocsd_datapath_resp_t outputTS(TrcStackElemParam *pParamElem, bool withCC);
ocsd_datapath_resp_t outputEvent(TrcStackElemParam *pParamElem);
private:
void SetInstrInfoInAddrISA(const ocsd_vaddr_t addr_val, const uint8_t isa);
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.
ocsd_datapath_resp_t returnStackPop(); // pop return stack and update instruction address.
//** intra packet state (see ETMv4 spec 6.2.1);
// timestamping
uint64_t m_timestamp; // last broadcast global Timestamp.
// state and context
uint32_t m_context_id; // most recent context ID
uint32_t m_vmid_id; // most recent VMID
bool m_is_secure; // true if Secure
bool m_is_64bit; // true if 64 bit
// cycle counts
int m_cc_threshold;
// speculative trace (unsupported at present in the decoder).
int m_curr_spec_depth;
int m_max_spec_depth;
// data trace associative elements (unsupported at present in the decoder).
int m_p0_key;
int m_p0_key_max;
// conditional non-branch trace - when data trace active (unsupported at present in the decoder)
int m_cond_c_key;
int m_cond_r_key;
int m_cond_key_max_incr;
uint8_t m_CSID; //!< Coresight trace ID for this decoder.
bool m_IASize64; //!< True if 64 bit instruction addresses supported.
//** Other processor state;
// trace decode FSM
typedef enum {
NO_SYNC, //!< pre start trace - init state or after reset or overflow, loss of sync.
WAIT_SYNC, //!< waiting for sync packet.
WAIT_TINFO, //!< waiting for trace info packet.
DECODE_PKTS, //!< processing packets - creating decode elements on stack
COMMIT_ELEM, //!< commit elements for execution - create generic trace elements and pass on.
} processor_state_t;
processor_state_t m_curr_state;
//** P0 element stack
EtmV4P0Stack m_P0_stack; //!< P0 decode element stack
int m_P0_commit; //!< number of elements to commit
// packet decode state
bool m_need_ctxt; //!< need context to continue
bool m_need_addr; //!< need an address to continue
bool m_except_pending_addr; //!< next address packet is part of exception.
// exception packet processing state (may need excep elem only, range+excep, range+
typedef enum {
EXCEP_POP, // start of processing read exception packets off the stack and analyze
EXCEP_RANGE, // output a range element
EXCEP_NACC, // output a nacc element
EXCEP_EXCEP, // output an ecxeption element.
} excep_proc_state_t;
excep_proc_state_t m_excep_proc; //!< state of exception processing
etmv4_addr_val_t m_excep_addr; //!< excepiton return address.
ocsd_trc_index_t m_excep_index; //!< trace index for exception element
ocsd_instr_info m_instr_info; //!< instruction info for code follower - in address is the next to be decoded.
bool m_mem_nacc_pending; //!< need to output a memory access failure packet
ocsd_vaddr_t m_nacc_addr; //!< record unaccessible address
ocsd_pe_context m_pe_context; //!< current context information
etmv4_trace_info_t m_trace_info; //!< trace info for this trace run.
bool m_prev_overflow;
bool m_flush_EOT; //!< true if doing an end of trace flush - cleans up lingering events / TS / CC
TrcAddrReturnStack m_return_stack;
//** output element
OcsdTraceElement m_output_elem;
};
#endif // ARM_TRC_PKT_DECODE_ETMV4I_H_INCLUDED
/* End of File trc_pkt_decode_etmv4i.h */

View File

@ -0,0 +1,73 @@
/*
* \file trc_pkt_elem_etmv4d.h
* \brief OpenCSD :
*
* \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ARM_TRC_PKT_ELEM_ETMV4D_H_INCLUDED
#define ARM_TRC_PKT_ELEM_ETMV4D_H_INCLUDED
#include "trc_pkt_types_etmv4.h"
#include "common/trc_printable_elem.h"
#include "common/trc_pkt_elem_base.h"
/** @addtogroup trc_pkts
@{*/
/*!
* @class EtmV4DTrcPacket
* @brief ETMv4 Data Trace Protocol Packet .
*
* This class represents a single ETMv4 instruction trace packet, along with intra packet state.
*
*/
class EtmV4DTrcPacket : public TrcPacketBase, public ocsd_etmv4_d_pkt, trcPrintableElem
{
public:
EtmV4DTrcPacket();
~EtmV4DTrcPacket();
// update interface - set packet values
// packet status interface - get packet info.
// printing
virtual void toString(std::string &str) const;
virtual void toStringFmt(const uint32_t fmtFlags, std::string &str) const;
};
/** @}*/
#endif // ARM_TRC_PKT_ELEM_ETMV4D_H_INCLUDED
/* End of File trc_pkt_elem_etmv4d.h */

View File

@ -0,0 +1,520 @@
/*
* \file trc_pkt_elem_etmv4i.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_ETMV4I_H_INCLUDED
#define ARM_TRC_PKT_ELEM_ETMV4I_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 Etmv4PktAddrStack
* @brief ETMv4 Address packet values stack
* @ingroup trc_pkts
*
* This class represents a stack of recent broadcast address values -
* used to fulfil the ExactMatch address type where no address is output.
*
*/
class Etmv4PktAddrStack
{
public:
Etmv4PktAddrStack()
{
for (int i = 0; i < 3; i++)
{
m_v_addr[i].pkt_bits = 0;
m_v_addr[i].size = VA_64BIT;
m_v_addr[i].val = 0;
m_v_addr[i].valid_bits = 0;
m_v_addr_ISA[i] = 0;
}
}
~Etmv4PktAddrStack() {};
void push(const ocsd_pkt_vaddr vaddr, const uint8_t isa)
{
m_v_addr[2] = m_v_addr[1];
m_v_addr[1] = m_v_addr[0];
m_v_addr[0] = vaddr;
m_v_addr_ISA[2] = m_v_addr_ISA[1];
m_v_addr_ISA[1] = m_v_addr_ISA[0];
m_v_addr_ISA[0] = isa;
}
void get_idx(const uint8_t idx, ocsd_pkt_vaddr &vaddr, uint8_t &isa)
{
if (idx < 3)
{
vaddr = m_v_addr[idx];
isa = m_v_addr_ISA[idx];
}
}
private:
ocsd_pkt_vaddr m_v_addr[3]; //!< most recently broadcast address packet
uint8_t m_v_addr_ISA[3];
};
/*!
* @class EtmV4ITrcPacket
* @brief ETMv4 Instuction Trace Protocol Packet.
* @ingroup trc_pkts
*
* This class represents a single ETMv4 data trace packet, along with intra packet state.
*
*/
class EtmV4ITrcPacket : public TrcPacketBase, public ocsd_etmv4_i_pkt, public trcPrintableElem
{
public:
EtmV4ITrcPacket();
~EtmV4ITrcPacket();
EtmV4ITrcPacket &operator =(const ocsd_etmv4_i_pkt* p_pkt);
virtual const void *c_pkt() const { return (const ocsd_etmv4_i_pkt *)this; };
// update interface - set packet values
void initStartState(); //!< Set to initial state - no intra packet state valid. Use on start of trace / discontinuities.
void initNextPacket(); //!< clear any single packet only flags / state.
void setType(const ocsd_etmv4_i_pkt_type pkt_type) { type = pkt_type; };
void updateErrType(const ocsd_etmv4_i_pkt_type err_pkt_type);
void clearTraceInfo(); //!< clear all the trace info data prior to setting for new trace info packet.
void setTraceInfo(const uint32_t infoVal);
void setTraceInfoKey(const uint32_t keyVal);
void setTraceInfoSpec(const uint32_t specVal);
void setTraceInfoCyct(const uint32_t cyctVal);
void setTS(const uint64_t value, const uint8_t bits);
void setCycleCount(const uint32_t value);
void setCommitElements(const uint32_t commit_elem);
void setCancelElements(const uint32_t cancel_elem);
void setAtomPacket(const ocsd_pkt_atm_type type, const uint32_t En_bits, const uint8_t num);
void setCondIF1(uint32_t const cond_key);
void setCondIF2(uint8_t const c_elem_idx);
void setCondIF3(uint8_t const num_c_elem, const bool finalElem);
void setCondRF1(const uint32_t key[2], const uint8_t res[2], const uint8_t CI[2], const bool set2Keys);
void setCondRF2(const uint8_t key_incr, const uint8_t token);
void setCondRF3(const uint16_t tokens);
void setCondRF4(const uint8_t token);
void setContextInfo(const bool update, const uint8_t EL = 0, const uint8_t NS = 0, const uint8_t SF = 0);
void setContextVMID(const uint32_t VMID);
void setContextCID(const uint32_t CID);
void setExceptionInfo(const uint16_t excep_type, const uint8_t addr_interp, const uint8_t m_fault_pending, const uint8_t m_type);
void set64BitAddress(const uint64_t addr, const uint8_t IS);
void set32BitAddress(const uint32_t addr, const uint8_t IS);
void updateShortAddress(const uint32_t addr, const uint8_t IS, const uint8_t update_bits);
void setAddressExactMatch(const uint8_t idx);
void setDataSyncMarker(const uint8_t dsm_val);
void setEvent(const uint8_t event_val);
void setQType(const bool has_count, const uint32_t count, const bool has_addr, const bool addr_match, const uint8_t type);
// packet status interface - get packet info.
const ocsd_etmv4_i_pkt_type getType() const { return type; };
const ocsd_etmv4_i_pkt_type getErrType() const { return err_type; };
//! return true if this packet has set the commit packet count.
const bool hasCommitElementsCount() const
{
return pkt_valid.bits.commit_elem_valid ? true : false;
};
// trace info
const etmv4_trace_info_t &getTraceInfo() const { return trace_info; };
const uint32_t getCCThreshold() const;
const uint32_t getP0Key() const;
const uint32_t getCurrSpecDepth() const;
// atom
const ocsd_pkt_atom &getAtom() const { return atom; };
// context
const etmv4_context_t &getContext() const { return context; };
// address
const uint8_t &getAddrMatch() const { return addr_exact_match_idx; };
const ocsd_vaddr_t &getAddrVal() const { return v_addr.val; };
const uint8_t &getAddrIS() const { return v_addr_ISA; };
const bool getAddr64Bit() const { return v_addr.size == VA_64BIT; };
// ts
const uint64_t getTS() const { return pkt_valid.bits.ts_valid ? ts.timestamp : 0; };
// cc
const uint32_t getCC() const { return pkt_valid.bits.cc_valid ? cycle_count : 0; };
// packet type
const bool isBadPacket() const;
// printing
virtual void toString(std::string &str) const;
virtual void toStringFmt(const uint32_t fmtFlags, std::string &str) const;
private:
const char *packetTypeName(const ocsd_etmv4_i_pkt_type type, const char **pDesc) const;
void contextStr(std::string &ctxtStr) const;
void atomSeq(std::string &valStr) const;
void addrMatchIdx(std::string &valStr) const;
void exceptionInfo(std::string &valStr) const;
void push_vaddr();
void pop_vaddr_idx(const uint8_t idx);
Etmv4PktAddrStack m_addr_stack;
};
inline void EtmV4ITrcPacket::updateErrType(const ocsd_etmv4_i_pkt_type err_pkt_type)
{
// set primary type to incoming error type, set packet err type to previous primary type.
err_type = type;
type = err_pkt_type;
}
inline void EtmV4ITrcPacket::clearTraceInfo()
{
pkt_valid.bits.ts_valid = 0;
pkt_valid.bits.trace_info_valid = 0;
pkt_valid.bits.p0_key_valid = 0;
pkt_valid.bits.spec_depth_valid = 0;
pkt_valid.bits.cc_thresh_valid = 0;
pkt_valid.bits.ts_valid = 0; // mark TS as invalid - must be re-updated after trace info.
}
inline void EtmV4ITrcPacket::setTraceInfo(const uint32_t infoVal)
{
trace_info.val = infoVal;
pkt_valid.bits.trace_info_valid = 1;
}
inline void EtmV4ITrcPacket::setTraceInfoKey(const uint32_t keyVal)
{
p0_key = keyVal;
pkt_valid.bits.p0_key_valid = 1;
}
inline void EtmV4ITrcPacket::setTraceInfoSpec(const uint32_t specVal)
{
curr_spec_depth = specVal;
pkt_valid.bits.spec_depth_valid = 1;
}
inline void EtmV4ITrcPacket::setTraceInfoCyct(const uint32_t cyctVal)
{
cc_threshold = cyctVal;
pkt_valid.bits.cc_thresh_valid = 1;
}
inline void EtmV4ITrcPacket::setTS(const uint64_t value, const uint8_t bits)
{
uint64_t mask = (uint64_t)-1LL;
if(bits < 64) mask = (1ULL << bits) - 1;
ts.timestamp = (ts.timestamp & ~mask) | (value & mask);
ts.bits_changed = bits;
pkt_valid.bits.ts_valid = 1;
}
inline void EtmV4ITrcPacket::setCycleCount(const uint32_t value)
{
pkt_valid.bits.cc_valid = 1;
cycle_count = value;
}
inline void EtmV4ITrcPacket::setCommitElements(const uint32_t commit_elem)
{
pkt_valid.bits.commit_elem_valid = 1;
commit_elements = commit_elem;
}
inline const uint32_t EtmV4ITrcPacket::getCCThreshold() const
{
if(pkt_valid.bits.cc_thresh_valid)
return cc_threshold;
return 0;
}
inline const uint32_t EtmV4ITrcPacket::getP0Key() const
{
if(pkt_valid.bits.p0_key_valid)
return p0_key;
return 0;
}
inline const uint32_t EtmV4ITrcPacket::getCurrSpecDepth() const
{
if(pkt_valid.bits.spec_depth_valid)
return curr_spec_depth;
return 0;
}
inline void EtmV4ITrcPacket::setCancelElements(const uint32_t cancel_elem)
{
cancel_elements = cancel_elem;
}
inline void EtmV4ITrcPacket::setAtomPacket(const ocsd_pkt_atm_type type, const uint32_t En_bits, const uint8_t num)
{
if(type == ATOM_REPEAT)
{
uint32_t bit_patt = En_bits & 0x1;
if(bit_patt)
{
// none zero - all 1s
bit_patt = (bit_patt << num) - 1;
}
atom.En_bits = bit_patt;
}
else
atom.En_bits = En_bits;
atom.num = num;
}
inline void EtmV4ITrcPacket::setCondIF1(const uint32_t cond_key)
{
cond_instr.cond_key_set = 1;
cond_instr.f3_final_elem = 0;
cond_instr.f2_cond_incr = 0;
cond_instr.num_c_elem = 1;
cond_instr.cond_c_key = cond_key;
}
inline void EtmV4ITrcPacket::setCondIF2(const uint8_t c_elem_idx)
{
cond_instr.cond_key_set = 0;
cond_instr.f3_final_elem = 0;
switch(c_elem_idx & 0x3)
{
case 0:
cond_instr.f2_cond_incr = 1;
cond_instr.num_c_elem = 1;
break;
case 1:
cond_instr.f2_cond_incr = 0;
cond_instr.num_c_elem = 1;
break;
case 2:
cond_instr.f2_cond_incr = 1;
cond_instr.num_c_elem = 2;
break;
}
}
inline void EtmV4ITrcPacket::setCondIF3(const uint8_t num_c_elem, const bool finalElem)
{
cond_instr.cond_key_set = 0;
cond_instr.f3_final_elem = finalElem ? 1: 0;
cond_instr.f2_cond_incr = 0;
cond_instr.num_c_elem = num_c_elem;
}
inline void EtmV4ITrcPacket::setCondRF1(const uint32_t key[2], const uint8_t res[2], const uint8_t CI[2],const bool set2Keys)
{
cond_result.key_res_0_set = 1;
cond_result.cond_r_key_0 = key[0];
cond_result.res_0 = res[0];
cond_result.ci_0 = CI[0];
if(set2Keys)
{
cond_result.key_res_1_set = 1;
cond_result.cond_r_key_1 = key[1];
cond_result.res_1 = res[1];
cond_result.ci_1 = CI[1];
}
}
inline void EtmV4ITrcPacket::setCondRF2(const uint8_t key_incr, const uint8_t token)
{
cond_result.key_res_0_set = 0;
cond_result.key_res_1_set = 0;
cond_result.f2_key_incr = key_incr;
cond_result.f2f4_token = token;
}
inline void EtmV4ITrcPacket::setCondRF3(const uint16_t tokens)
{
cond_result.key_res_0_set = 0;
cond_result.key_res_1_set = 0;
cond_result.f3_tokens = tokens;
}
inline void EtmV4ITrcPacket::setCondRF4(const uint8_t token)
{
cond_result.key_res_0_set = 0;
cond_result.key_res_1_set = 0;
cond_result.f2f4_token = token;
}
inline void EtmV4ITrcPacket::setContextInfo(const bool update, const uint8_t EL, const uint8_t NS, const uint8_t SF)
{
pkt_valid.bits.context_valid = 1;
if(update)
{
context.updated = 1;
context.EL = EL;
context.NS = NS;
context.SF = SF;
}
}
inline void EtmV4ITrcPacket::setContextVMID(const uint32_t VMID)
{
pkt_valid.bits.context_valid = 1;
context.updated = 1;
context.VMID = VMID;
context.updated_v = 1;
}
inline void EtmV4ITrcPacket::setContextCID(const uint32_t CID)
{
pkt_valid.bits.context_valid = 1;
context.updated = 1;
context.ctxtID = CID;
context.updated_c = 1;
}
inline void EtmV4ITrcPacket::setExceptionInfo(const uint16_t excep_type, const uint8_t addr_interp, const uint8_t m_fault_pending, const uint8_t m_type)
{
exception_info.exceptionType = excep_type;
exception_info.addr_interp = addr_interp;
exception_info.m_fault_pending = m_fault_pending;
exception_info.m_type = m_type;
}
inline void EtmV4ITrcPacket::set64BitAddress(const uint64_t addr, const uint8_t IS)
{
v_addr.pkt_bits = 64;
v_addr.valid_bits = 64;
v_addr.size = VA_64BIT;
v_addr.val = addr;
v_addr_ISA = IS;
push_vaddr();
}
inline void EtmV4ITrcPacket::set32BitAddress(const uint32_t addr, const uint8_t IS)
{
uint64_t mask = OCSD_BIT_MASK(32);
v_addr.pkt_bits = 32;
if (pkt_valid.bits.context_valid && context.SF)
v_addr.size = VA_64BIT;
else
{
v_addr.val &= 0xFFFFFFFF; // ensure vaddr is only 32 bits if not 64 bit
v_addr.size = VA_32BIT;
}
if (v_addr.valid_bits < 32) // may be 64 bit address so only set 32 if less
v_addr.valid_bits = 32;
v_addr.val = (v_addr.val & ~mask) | (addr & mask);
v_addr_ISA = IS;
push_vaddr();
}
inline void EtmV4ITrcPacket::updateShortAddress(const uint32_t addr, const uint8_t IS, const uint8_t update_bits)
{
ocsd_vaddr_t update_mask = OCSD_BIT_MASK(update_bits);
v_addr.pkt_bits = update_bits;
if(v_addr.valid_bits < update_bits)
v_addr.valid_bits = update_bits;
v_addr.val = (v_addr.val & ~update_mask) | (addr & update_mask);
v_addr_ISA = IS;
push_vaddr();
}
inline void EtmV4ITrcPacket::setAddressExactMatch(const uint8_t idx)
{
addr_exact_match_idx = idx;
pop_vaddr_idx(idx);
push_vaddr();
}
inline void EtmV4ITrcPacket::setDataSyncMarker(const uint8_t dsm_value)
{
dsm_val = dsm_value;
}
inline void EtmV4ITrcPacket::setEvent(const uint8_t event_value)
{
event_val = event_value;
}
inline void EtmV4ITrcPacket::setQType(const bool has_count, const uint32_t count, const bool has_addr, const bool addr_match, const uint8_t type)
{
Q_pkt.q_count = count;
Q_pkt.q_type = type;
Q_pkt.count_present = has_count ? 1 : 0;
Q_pkt.addr_present = has_addr ? 1: 0;
Q_pkt.addr_match = addr_match ? 1 :0;
}
inline const bool EtmV4ITrcPacket::isBadPacket() const
{
return (type >= ETM4_PKT_I_BAD_SEQUENCE);
}
inline void EtmV4ITrcPacket::push_vaddr()
{
m_addr_stack.push(v_addr, v_addr_ISA);
}
inline void EtmV4ITrcPacket::pop_vaddr_idx(const uint8_t idx)
{
m_addr_stack.get_idx(idx, v_addr, v_addr_ISA);
}
/** @}*/
#endif // ARM_TRC_PKT_ELEM_ETMV4I_H_INCLUDED
/* End of File trc_pkt_elem_etmv4i.h */

View File

@ -0,0 +1,104 @@
/*
* \file trc_pkt_proc_etmv4.h
* \brief OpenCSD : ETMv4 packet processor interface classes.
*
* \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_ETMV4_H_INCLUDED
#define ARM_TRC_PKT_PROC_ETMV4_H_INCLUDED
#include "trc_pkt_types_etmv4.h"
#include "common/trc_pkt_proc_base.h"
class EtmV4IPktProcImpl; /**< ETMv4 I channel packet processor */
class EtmV4DPktProcImpl; /**< ETMv4 D channel packet processor */
class EtmV4ITrcPacket;
class EtmV4DTrcPacket;
class EtmV4Config;
/** @addtogroup ocsd_pkt_proc
@{*/
class TrcPktProcEtmV4I : public TrcPktProcBase< EtmV4ITrcPacket, ocsd_etmv4_i_pkt_type, EtmV4Config>
{
public:
TrcPktProcEtmV4I();
TrcPktProcEtmV4I(int instIDNum);
virtual ~TrcPktProcEtmV4I();
protected:
/* implementation packet processing interface */
virtual ocsd_datapath_resp_t processData( const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed);
virtual ocsd_datapath_resp_t onEOT();
virtual ocsd_datapath_resp_t onReset();
virtual ocsd_datapath_resp_t onFlush();
virtual ocsd_err_t onProtocolConfig();
virtual const bool isBadPacket() const;
friend class EtmV4IPktProcImpl;
EtmV4IPktProcImpl *m_pProcessor;
};
class TrcPktProcEtmV4D : public TrcPktProcBase< EtmV4DTrcPacket, ocsd_etmv4_d_pkt_type, EtmV4Config>
{
public:
TrcPktProcEtmV4D();
TrcPktProcEtmV4D(int instIDNum);
virtual ~TrcPktProcEtmV4D();
protected:
/* implementation packet processing interface */
virtual ocsd_datapath_resp_t processData( const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed);
virtual ocsd_datapath_resp_t onEOT();
virtual ocsd_datapath_resp_t onReset();
virtual ocsd_datapath_resp_t onFlush();
virtual ocsd_err_t onProtocolConfig();
virtual const bool isBadPacket() const;
friend class EtmV4DPktProcImpl;
EtmV4DPktProcImpl *m_pProcessor;
};
/** @}*/
#endif // ARM_TRC_PKT_PROC_ETMV4_H_INCLUDED
/* End of File trc_pkt_proc_etmv4.h */

View File

@ -0,0 +1,350 @@
/*
* \file trc_pkt_types_etmv4.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_TYPES_ETMV4_H_INCLUDED
#define ARM_TRC_PKT_TYPES_ETMV4_H_INCLUDED
#include "opencsd/trc_pkt_types.h"
/** @addtogroup trc_pkts
@{*/
/** @name ETMv4 Packet Types
@{*/
/** I stream packets. */
typedef enum _ocsd_etmv4_i_pkt_type
{
/* state of decode markers */
ETM4_PKT_I_NOTSYNC = 0x200, /*!< no sync found yet. */
ETM4_PKT_I_INCOMPLETE_EOT, /*!< flushing incomplete/empty packet at end of trace.*/
ETM4_PKT_I_NO_ERR_TYPE, /*!< error type not set for packet. */
/* markers for unknown/bad packets */
ETM4_PKT_I_BAD_SEQUENCE = 0x300, /*!< invalid sequence for packet type. */
ETM4_PKT_I_BAD_TRACEMODE, /*!< invalid packet type for this trace mode. */
ETM4_PKT_I_RESERVED, /*!< packet type reserved. */
/* I stream packet types. */
/* extension header. */
ETM4_PKT_I_EXTENSION = 0x00, /*!< b00000000 */
/* address amd context */
ETM4_PKT_I_ADDR_CTXT_L_32IS0 = 0x82, /*!< b10000010 */
ETM4_PKT_I_ADDR_CTXT_L_32IS1, /*!< b10000011 */
/* unused encoding b10000100 */
ETM4_PKT_I_ADDR_CTXT_L_64IS0 = 0x85, /*!< b10000101 */
ETM4_PKT_I_ADDR_CTXT_L_64IS1, /*!< b10000110 */
/* unused encoding b10000111 */
ETM4_PKT_I_CTXT = 0x80, /*!< b1000000x */
ETM4_PKT_I_ADDR_MATCH = 0x90, /*!< b10010000 to b10010010 */
ETM4_PKT_I_ADDR_L_32IS0 = 0x9A, /*!< b10011010 */
ETM4_PKT_I_ADDR_L_32IS1, /*!< b10011011 */
/* unused encoding b10011100 */
ETM4_PKT_I_ADDR_L_64IS0 = 0x9D, /*!< b10011101 */
ETM4_PKT_I_ADDR_L_64IS1, /*!< b10011110 */
/* unused encoding b10011111 */
ETM4_PKT_I_ADDR_S_IS0 = 0x95, /*!< b10010101 */
ETM4_PKT_I_ADDR_S_IS1, /*!< b10010110 */
/* unused encoding b10010111
unused encoding b10011000
unused encoding b10011001 */
/* Q packets */
ETM4_PKT_I_Q = 0xA0, /*!< b1010xxxx */
/* Atom packets */
ETM4_PKT_I_ATOM_F1 = 0xF6, /*!< b1111011x */
ETM4_PKT_I_ATOM_F2 = 0xD8, /*!< b110110xx */
ETM4_PKT_I_ATOM_F3 = 0xF8, //!< b11111xxx
ETM4_PKT_I_ATOM_F4 = 0xDC, //!< b110111xx
ETM4_PKT_I_ATOM_F5 = 0xD5, //!< b11010101 - b11010111, b11110101
ETM4_PKT_I_ATOM_F6 = 0xC0, //!< b11000000 - b11010100, b11100000 - b11110100
/* conditional instruction tracing */
ETM4_PKT_I_COND_FLUSH = 0x43, //!< b01000011
ETM4_PKT_I_COND_I_F1 = 0x6C, //!< b01101100
ETM4_PKT_I_COND_I_F2 = 0x40, //!< b01000000 - b01000010
ETM4_PKT_I_COND_I_F3 = 0x6D, //!< b01101101
ETM4_PKT_I_COND_RES_F1 = 0x68, //!< b0110111x, b011010xx
ETM4_PKT_I_COND_RES_F2 = 0x48, //!< b0100100x, b01001010, b0100110x, b01001110
ETM4_PKT_I_COND_RES_F3 = 0x50, //!< b0101xxxx
ETM4_PKT_I_COND_RES_F4 = 0x44, //!< b0100010x, b01000110
/* cycle count packets */
ETM4_PKT_I_CCNT_F1 = 0x0E, //!< b0000111x
ETM4_PKT_I_CCNT_F2 = 0x0C, //!< b0000110x
ETM4_PKT_I_CCNT_F3 = 0x10, //!< b0001xxxx
// data synchronisation markers
ETM4_PKT_I_NUM_DS_MKR = 0x20, //!< b00100xxx
ETM4_PKT_I_UNNUM_DS_MKR = 0x28, //!< b00101000 - b00101100
// event trace
ETM4_PKT_I_EVENT = 0x70, //!< b0111xxxx
// Exceptions
ETM4_PKT_I_EXCEPT = 0x06, //!< b00000110
ETM4_PKT_I_EXCEPT_RTN = 0x07, //!< b00000111
// timestamp
ETM4_PKT_I_TIMESTAMP = 0x02, //!< b0000001x
// speculation
ETM4_PKT_I_CANCEL_F1 = 0x2E, //!< b0010111x
ETM4_PKT_I_CANCEL_F2 = 0x34, //!< b001101xx
ETM4_PKT_I_CANCEL_F3 = 0x38, //!< b00111xxx
ETM4_PKT_I_COMMIT = 0x2D, //!< b00101101
ETM4_PKT_I_MISPREDICT = 0x30, //!< b001100xx
// Sync
ETM4_PKT_I_TRACE_INFO = 0x01, //!< b00000001
ETM4_PKT_I_TRACE_ON = 0x04, //!< b00000100
// extension packets - follow 0x00 header
ETM4_PKT_I_ASYNC = 0x100, //!< b00000000
ETM4_PKT_I_DISCARD = 0x103, //!< b00000011
ETM4_PKT_I_OVERFLOW = 0x105 //!< b00000101
} ocsd_etmv4_i_pkt_type;
typedef union _etmv4_trace_info_t {
uint32_t val; //!< trace info full value.
struct {
uint32_t cc_enabled:1; //!< 1 if cycle count enabled
uint32_t cond_enabled:3; //!< conditional trace enabeld type
uint32_t p0_load:1; //!< 1 if tracing with P0 load elements (for data trace)
uint32_t p0_store:1; //1< 1 if tracing with P0 store elements (for data trace)
} bits; //!< bitfields for trace info value.
} etmv4_trace_info_t;
typedef struct _etmv4_context_t {
struct {
uint32_t EL:2; //!< exception level.
uint32_t SF:1; //!< sixty four bit
uint32_t NS:1; //!< none secure
uint32_t updated:1; //!< updated this context packet (otherwise same as last time)
uint32_t updated_c:1; //!< updated CtxtID
uint32_t updated_v:1; //!< updated VMID
};
uint32_t ctxtID; //!< Current ctxtID
uint32_t VMID; //!< current VMID
} etmv4_context_t;
/** a broadcast address value. */
typedef struct _etmv4_addr_val_t {
ocsd_vaddr_t val; //!< Address value.
uint8_t isa; //!< instruction set.
} etmv4_addr_val_t;
typedef struct _ocsd_etmv4_i_pkt
{
ocsd_etmv4_i_pkt_type type; /**< Trace packet type derived from header byte */
//** intra-packet data - valid across packets.
ocsd_pkt_vaddr v_addr; //!< most recently broadcast address packet
uint8_t v_addr_ISA; //!< ISA for the address packet. (0 = IS0 / 1 = IS1)
etmv4_context_t context; //!< current context for PE
struct {
uint64_t timestamp; //!< current timestamp value
uint8_t bits_changed; //!< bits updated in this timestamp packet.
} ts;
uint32_t cc_threshold; //!< cycle count threshold - from trace info.
// single packet data - only valid for specific packet types on packet instance.
ocsd_pkt_atom atom; //!< atom elements - number of atoms indicates validity of packet
uint32_t cycle_count; //!< cycle count
uint32_t curr_spec_depth; //!< current speculation depth
uint32_t p0_key; //!< current P0 key value for data packet synchronisation
uint32_t commit_elements; //<! commit elements indicated by this packet - valid dependent on the packet type.
uint32_t cancel_elements; //<! cancel elements indicated by this packet - valid dependent on the packet type.
etmv4_trace_info_t trace_info; //!< trace info structure - programmed configuration of trace capture.
struct {
uint32_t exceptionType:10; //!< exception number
uint32_t addr_interp:2; //!< address value interpretation
uint32_t m_fault_pending:1; //!< M class fault pending.
uint32_t m_type:1; //!< 1 if M class exception.
} exception_info;
uint8_t addr_exact_match_idx; //!< address match index in this packet.
uint8_t dsm_val; //!< Data Sync Marker number, or unnumbered atom count - packet type determines.
uint8_t event_val; //!< Event value on event packet.
struct {
uint32_t cond_c_key;
uint8_t num_c_elem;
struct {
uint32_t cond_key_set:1;
uint32_t f3_final_elem:1;
uint32_t f2_cond_incr:1;
};
} cond_instr;
struct {
uint32_t cond_r_key_0;
uint32_t cond_r_key_1;
struct {
uint32_t res_0:4;
uint32_t res_1:4;
uint32_t ci_0:1;
uint32_t ci_1:1;
uint32_t key_res_0_set:1;
uint32_t key_res_1_set:1;
uint32_t f2_key_incr:2;
uint32_t f2f4_token:2;
uint32_t f3_tokens:12;
};
} cond_result;
struct {
uint32_t q_count;
struct {
uint32_t addr_present:1;
uint32_t addr_match:1;
uint32_t count_present:1;
uint32_t q_type:4;
};
} Q_pkt;
//! valid bits for packet elements (addresses have their own valid bits).
union {
uint32_t val;
struct {
uint32_t context_valid:1;
uint32_t ts_valid:1;
uint32_t spec_depth_valid:1;
uint32_t p0_key_valid:1;
uint32_t cond_c_key_valid:1;
uint32_t cond_r_key_valid:1;
uint32_t trace_info_valid:1;
uint32_t cc_thresh_valid:1;
uint32_t cc_valid:1;
uint32_t commit_elem_valid:1;
} bits;
} pkt_valid;
// original header type when packet type changed to error on decode error.
ocsd_etmv4_i_pkt_type err_type;
} ocsd_etmv4_i_pkt;
// D stream packets
typedef enum _ocsd_etmv4_d_pkt_type
{
// markers for unknown/bad packets
ETM4_PKT_D_NOTSYNC = 0x200, //!< no sync found yet
ETM4_PKT_D_BAD_SEQUENCE, //!< invalid sequence for packet type
ETM4_PKT_D_BAD_TRACEMODE, //!< invalid packet type for this trace mode.
ETM4_PKT_D_RESERVED, //!< packet type reserved.
ETM4_PKT_D_INCOMPLETE_EOT, //!< flushing incomplete packet at end of trace.
ETM4_PKT_D_NO_HEADER, //!< waiting for a header byte
ETM4_PKT_D_NO_ERR_TYPE, //!< error packet has no header based type. Use with unknown/res packet types.
// data sync markers
ETM4_PKT_DNUM_DS_MKR = 0x111, // ext packet, b0001xxx1
// extension header
ETM4_PKT_D_EXTENSION = 0x00, //!< b00000000
ETM4_PKT_DUNNUM_DS_MKR = 0x01, //!< b00000001
// event trace
ETM4_PKT_DEVENT = 0x04, //!< b00000100
// timestamp
ETM4_PKT_DTIMESTAMP = 0x02, //!< b00000010
// P1 Data address
ETM4_PKT_DADDR_P1_F1 = 0x70, //!< b0111xxxx
ETM4_PKT_DADDR_P1_F2 = 0x80, //!< b10xxxxxx
ETM4_PKT_DADDR_P1_F3 = 0x14, //!< b000101xx
ETM4_PKT_DADDR_P1_F4 = 0x60, //!< b0110xxxx
ETM4_PKT_DADDR_P1_F5 = 0xF8, //!< b11111xxx
ETM4_PKT_DADDR_P1_F6 = 0xF6, //!< b1111011x
ETM4_PKT_DADDR_P1_F7 = 0xF5, //!< b11110101
// P2 Data value
ETM4_PKT_DVAL_P2_F1 = 0x20, //!< b0010xxxx
ETM4_PKT_DVAL_P2_F2 = 0x30, //!< b00110xxx
ETM4_PKT_DVAL_P2_F3 = 0x40, //!< b010xxxxx
ETM4_PKT_DVAL_P2_F4 = 0x10, //!< b000100xx
ETM4_PKT_DVAL_P2_F5 = 0x18, //!< b00011xxx
ETM4_PKT_DVAL_P2_F6 = 0x38, //!< b00111xxx
// suppression
ETM4_PKT_DSUPPRESSION = 0x03, //!< b00000011
// synchronisation- extension packets - follow 0x00 header
ETM4_PKT_DTRACE_INFO = 0x101, //!< b00000001
// extension packets - follow 0x00 header
ETM4_PKT_D_ASYNC = 0x100, //!< b00000000
ETM4_PKT_D_DISCARD = 0x103, //!< b00000011
ETM4_PKT_D_OVERFLOW = 0x105 //!< b00000101
} ocsd_etmv4_d_pkt_type;
typedef struct _ocsd_etmv4_d_pkt
{
ocsd_etmv4_d_pkt_type type;
ocsd_pkt_vaddr d_addr;
uint64_t pkt_val; /**< Packet value -> data value, timestamp value, event value */
ocsd_etmv4_d_pkt_type err_type;
} ocsd_etmv4_d_pkt;
typedef struct _ocsd_etmv4_cfg
{
uint32_t reg_idr0; /**< ID0 register */
uint32_t reg_idr1; /**< ID1 register */
uint32_t reg_idr2; /**< ID2 register */
uint32_t reg_idr8;
uint32_t reg_idr9;
uint32_t reg_idr10;
uint32_t reg_idr11;
uint32_t reg_idr12;
uint32_t reg_idr13;
uint32_t reg_configr; /**< Config Register */
uint32_t reg_traceidr; /**< Trace Stream ID register */
ocsd_arch_version_t arch_ver; /**< Architecture version */
ocsd_core_profile_t core_prof; /**< Core Profile */
} ocsd_etmv4_cfg;
/** @}*/
/** @}*/
#endif // ARM_TRC_PKT_TYPES_ETMV4_H_INCLUDED
/* End of File trc_pkt_types_etmv4.h */

View File

@ -0,0 +1,592 @@
/*!
* \file opencsd/ocsd_if_types.h
* \brief OpenCSD : Standard Types used in the library interfaces.
*
* \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_OCSD_IF_TYPES_H_INCLUDED
#define ARM_OCSD_IF_TYPES_H_INCLUDED
#include <stdint.h>
#include <stddef.h>
#if defined(_MSC_VER) && (_MSC_VER < 1900)
/** VS2010 does not support inttypes - remove when VS2010 support is dropped */
#define __PRI64_PREFIX "ll"
#define PRIX64 __PRI64_PREFIX "X"
#define PRIu64 __PRI64_PREFIX "u"
#define PRIu32 "u"
#else
#include <inttypes.h>
#endif
/** @defgroup ocsd_interfaces OpenCSD Library : Interfaces
@brief Set of types, structures and virtual interface classes making up the primary API
Set of component interfaces that connect various source reader and decode components into a
decode tree to allow trace decode for the trace data being output by the source reader.
@{*/
/** @name Trace Indexing and Channel IDs
@{*/
#ifdef ENABLE_LARGE_TRACE_SOURCES
typedef uint64_t ocsd_trc_index_t; /**< Trace source index type - 64 bit size */
#define OCSD_TRC_IDX_STR PRIu64
#else
typedef uint32_t ocsd_trc_index_t; /**< Trace source index type - 32 bit size */
#define OCSD_TRC_IDX_STR PRIu32
#endif
/** Invalid trace index value */
#define OCSD_BAD_TRC_INDEX ((ocsd_trc_index_t)-1)
/** Invalid trace source ID value */
#define OCSD_BAD_CS_SRC_ID ((uint8_t)-1)
/** macro returing true if trace source ID is in valid range (0x0 < ID < 0x70) */
#define OCSD_IS_VALID_CS_SRC_ID(id) ((id > 0) && (id < 0x70))
/** macro returing true if trace source ID is in reserved range (ID == 0x0 || 0x70 <= ID <= 0x7F) */
#define OCSD_IS_RESERVED_CS_SRC_ID(id) ((id == 0) || ((id >= 0x70) && (id <= 0x7F))
/** @}*/
/** @name General Library Return and Error Codes
@{*/
/** Library Error return type */
typedef enum _ocsd_err_t {
/* general return errors */
OCSD_OK = 0, /**< No Error. */
OCSD_ERR_FAIL, /**< General systemic failure. */
OCSD_ERR_MEM, /**< Internal memory allocation error. */
OCSD_ERR_NOT_INIT, /**< Component not initialised or initialisation failure. */
OCSD_ERR_INVALID_ID, /**< Invalid CoreSight Trace Source ID. */
OCSD_ERR_BAD_HANDLE, /**< Invalid handle passed to component. */
OCSD_ERR_INVALID_PARAM_VAL, /**< Invalid value parameter passed to component. */
OCSD_ERR_INVALID_PARAM_TYPE, /**< Type mismatch on abstract interface */
OCSD_ERR_FILE_ERROR, /**< File access error */
OCSD_ERR_NO_PROTOCOL, /**< Trace protocol unsupported */
/* attachment point errors */
OCSD_ERR_ATTACH_TOO_MANY, /**< Cannot attach - attach device limit reached. */
OCSD_ERR_ATTACH_INVALID_PARAM, /**< Cannot attach - invalid parameter. */
OCSD_ERR_ATTACH_COMP_NOT_FOUND,/**< Cannot detach - component not found. */
/* source reader errors */
OCSD_ERR_RDR_FILE_NOT_FOUND, /**< source reader - file not found. */
OCSD_ERR_RDR_INVALID_INIT, /**< source reader - invalid initialisation parameter. */
OCSD_ERR_RDR_NO_DECODER, /**< source reader - not trace decoder set. */
/* data path errors */
OCSD_ERR_DATA_DECODE_FATAL, /**< A decoder in the data path has returned a fatal error. */
/* frame deformatter errors */
OCSD_ERR_DFMTR_NOTCONTTRACE, /**< Trace input to deformatter none-continuous */
/* packet processor errors - protocol issues etc */
OCSD_ERR_BAD_PACKET_SEQ, /**< Bad packet sequence */
OCSD_ERR_INVALID_PCKT_HDR, /**< Invalid packet header */
OCSD_ERR_PKT_INTERP_FAIL, /**< Interpreter failed - cannot recover - bad data or sequence */
/* packet decoder errors */
OCSD_ERR_UNSUPPORTED_ISA, /**< ISA not supported in decoder. */
OCSD_ERR_HW_CFG_UNSUPP, /**< Programmed trace configuration not supported by decoder.*/
OCSD_ERR_UNSUPP_DECODE_PKT, /**< Packet not supported in decoder */
OCSD_ERR_BAD_DECODE_PKT, /**< reserved or unknown packet in decoder. */
OCSD_ERR_COMMIT_PKT_OVERRUN, /**< overrun in commit packet stack - tried to commit more than available */
OCSD_ERR_MEM_NACC, /**< unable to access required memory address */
OCSD_ERR_RET_STACK_OVERFLOW, /**< internal return stack overflow checks failed - popped more than we pushed. */
/* decode tree errors */
OCSD_ERR_DCDT_NO_FORMATTER, /**< No formatter in use - operation not valid. */
/* target memory access errors */
OCSD_ERR_MEM_ACC_OVERLAP, /**< Attempted to set an overlapping range in memory access map */
OCSD_ERR_MEM_ACC_FILE_NOT_FOUND, /**< Memory access file could not be opened */
OCSD_ERR_MEM_ACC_FILE_DIFF_RANGE, /**< Attempt to re-use the same memory access file for a different address range */
OCSD_ERR_MEM_ACC_RANGE_INVALID, /**< Address range in accessor set to invalid values */
/* test errors - errors generated only by the test code, not the library */
OCSD_ERR_TEST_SNAPSHOT_PARSE, /**< test snapshot file parse error */
OCSD_ERR_TEST_SNAPSHOT_PARSE_INFO, /**< test snapshot file parse information */
OCSD_ERR_TEST_SNAPSHOT_READ, /**< test snapshot reader error */
OCSD_ERR_TEST_SS_TO_DECODER, /**< test snapshot to decode tree conversion error */
/* decoder registration */
OCSD_ERR_DCDREG_NAME_REPEAT, /**< attempted to register a decoder with the same name as another one */
OCSD_ERR_DCDREG_NAME_UNKNOWN, /**< attempted to find a decoder with a name that is not known in the library */
OCSD_ERR_DCDREG_TYPE_UNKNOWN, /**< attempted to find a decoder with a type that is not known in the library */
OCSD_ERR_DCDREG_TOOMANY, /**< attempted to register too many custom decoders */
/* decoder config */
OCSD_ERR_DCD_INTERFACE_UNUSED, /**< Attempt to connect or use and inteface not supported by this decoder. */
/* end marker*/
OCSD_ERR_LAST
} ocsd_err_t;
/* component handle types */
typedef unsigned int ocsd_hndl_rdr_t; /**< reader control handle */
typedef unsigned int ocsd_hndl_err_log_t; /**< error logger connection handle */
/* common invalid handle type */
#define OCSD_INVALID_HANDLE (unsigned int)-1 /**< Global invalid handle value */
/*! Error Severity Type
*
* Used to indicate the severity of an error, and also as the
* error log verbosity level in the error logger.
*
* The logger will ignore errors with a severity value higher than the
* current verbosity level.
*
* The value OCSD_ERR_SEV_NONE can only be used as a verbosity level to switch off logging,
* not as a severity value on an error. The other values can be used as both error severity and
* logger verbosity values.
*/
typedef enum _ocsd_err_severity_t {
OCSD_ERR_SEV_NONE, /**< No error logging. */
OCSD_ERR_SEV_ERROR, /**< Most severe error - perhaps fatal. */
OCSD_ERR_SEV_WARN, /**< Warning level. Inconsistent or incorrect data seen but can carry on decode processing */
OCSD_ERR_SEV_INFO, /**< Information only message. Use for debugging code or suspect input data. */
} ocsd_err_severity_t;
/** @}*/
/** @name Trace Datapath
@{*/
/** Trace Datapath operations.
*/
typedef enum _ocsd_datapath_op_t {
OCSD_OP_DATA = 0, /**< Standard index + data packet */
OCSD_OP_EOT, /**< End of available trace data. No data packet. */
OCSD_OP_FLUSH, /**< Flush existing data where possible, retain decode state. No data packet. */
OCSD_OP_RESET, /**< Reset decode state - drop any existing partial data. No data packet. */
} ocsd_datapath_op_t;
/**
* Trace Datapath responses
*/
typedef enum _ocsd_datapath_resp_t {
OCSD_RESP_CONT, /**< Continue processing */
OCSD_RESP_WARN_CONT, /**< Continue processing : a component logged a warning. */
OCSD_RESP_ERR_CONT, /**< Continue processing : a component logged an error.*/
OCSD_RESP_WAIT, /**< Pause processing */
OCSD_RESP_WARN_WAIT, /**< Pause processing : a component logged a warning. */
OCSD_RESP_ERR_WAIT, /**< Pause processing : a component logged an error. */
OCSD_RESP_FATAL_NOT_INIT, /**< Processing Fatal Error : component unintialised. */
OCSD_RESP_FATAL_INVALID_OP, /**< Processing Fatal Error : invalid data path operation. */
OCSD_RESP_FATAL_INVALID_PARAM, /**< Processing Fatal Error : invalid parameter in datapath call. */
OCSD_RESP_FATAL_INVALID_DATA, /**< Processing Fatal Error : invalid trace data */
OCSD_RESP_FATAL_SYS_ERR, /**< Processing Fatal Error : internal system error. */
} ocsd_datapath_resp_t;
/*! Macro returning true if datapath response value is FATAL. */
#define OCSD_DATA_RESP_IS_FATAL(x) (x >= OCSD_RESP_FATAL_NOT_INIT)
/*! Macro returning true if datapath response value indicates WARNING logged. */
#define OCSD_DATA_RESP_IS_WARN(x) ((x == OCSD_RESP_WARN_CONT) || (x == OCSD_RESP_WARN_WAIT))
/*! Macro returning true if datapath response value indicates ERROR logged. */
#define OCSD_DATA_RESP_IS_ERR(x) ((x == OCSD_RESP_ERR_CONT) || (x == OCSD_RESP_ERR_WAIT))
/*! Macro returning true if datapath response value indicates WARNING or ERROR logged. */
#define OCSD_DATA_RESP_IS_WARN_OR_ERR(x) (OCSD_DATA_RESP_IS_ERR(x) || OCSD_DATA_RESP_IS_WARN(x))
/*! Macro returning true if datapath response value is CONT. */
#define OCSD_DATA_RESP_IS_CONT(x) (x < OCSD_RESP_WAIT)
/*! Macro returning true if datapath response value is WAIT. */
#define OCSD_DATA_RESP_IS_WAIT(x) ((x >= OCSD_RESP_WAIT) && (x < OCSD_RESP_FATAL_NOT_INIT))
/** @}*/
/** @name Trace Decode component types
@{*/
/** Raw frame element data types
Data blocks types output from ITrcRawFrameIn.
*/
typedef enum _rcdtl_rawframe_elem_t {
OCSD_FRM_NONE, /**< None data operation on data path. (EOT etc.) */
OCSD_FRM_PACKED, /**< Raw packed frame data */
OCSD_FRM_HSYNC, /**< HSYNC data */
OCSD_FRM_FSYNC, /**< Frame Sync Data */
OCSD_FRM_ID_DATA, /**< unpacked data for ID */
} ocsd_rawframe_elem_t;
/** Indicates if the trace source will be frame formatted or a single protocol source.
Used in decode tree creation and configuration code.
*/
typedef enum _ocsd_dcd_tree_src_t {
OCSD_TRC_SRC_FRAME_FORMATTED, /**< input source is frame formatted. */
OCSD_TRC_SRC_SINGLE, /**< input source is from a single protocol generator. */
} ocsd_dcd_tree_src_t;
#define OCSD_DFRMTR_HAS_FSYNCS 0x01 /**< Deformatter Config : formatted data has fsyncs - input data 4 byte aligned */
#define OCSD_DFRMTR_HAS_HSYNCS 0x02 /**< Deformatter Config : formatted data has hsyncs - input data 2 byte aligned */
#define OCSD_DFRMTR_FRAME_MEM_ALIGN 0x04 /**< Deformatter Config : formatted frames are memory aligned, no syncs. Input data 16 byte frame aligned. */
#define OCSD_DFRMTR_PACKED_RAW_OUT 0x08 /**< Deformatter Config : output raw packed frame data if raw monitor attached. */
#define OCSD_DFRMTR_UNPACKED_RAW_OUT 0x10 /**< Deformatter Config : output raw unpacked frame data if raw monitor attached. */
#define OCSD_DFRMTR_RESET_ON_4X_FSYNC 0x20 /**< Deformatter Config : reset downstream decoders if frame aligned 4x consecutive fsyncs spotted. (perf workaround) */
#define OCSD_DFRMTR_VALID_MASK 0x3F /**< Deformatter Config : valid mask for deformatter configuration */
#define OCSD_DFRMTR_FRAME_SIZE 0x10 /**< CoreSight frame formatter frame size constant in bytes. */
/** @}*/
/** @name Trace Decode Component Name Prefixes
*
* Set of standard prefixes to be used for component names
@{*/
/** Component name prefix for trace source reader components */
#define OCSD_CMPNAME_PREFIX_SOURCE_READER "SRDR"
/** Component name prefix for trace frame deformatter component */
#define OCSD_CMPNAME_PREFIX_FRAMEDEFORMATTER "DFMT"
/** Component name prefix for trace packet processor. */
#define OCSD_CMPNAME_PREFIX_PKTPROC "PKTP"
/** Component name prefix for trace packet decoder. */
#define OCSD_CMPNAME_PREFIX_PKTDEC "PDEC"
/** @}*/
/** @name Trace Decode Arch and Profile
@{*/
/** Core Architecture Version */
typedef enum _ocsd_arch_version {
ARCH_UNKNOWN, /**< unknown architecture */
ARCH_V7, /**< V7 architecture */
ARCH_V8, /**< V8 architecture */
ARCH_CUSTOM, /**< None ARM, custom architecture */
} ocsd_arch_version_t;
/** Core Profile */
typedef enum _ocsd_core_profile {
profile_Unknown, /**< Unknown profile */
profile_CortexM, /**< Cortex-M profile */
profile_CortexR, /**< Cortex-R profile */
profile_CortexA, /**< Cortex-A profile */
profile_Custom, /**< None ARM, custom arch profile */
} ocsd_core_profile_t;
/** Combined architecture and profile descriptor for a core */
typedef struct _ocsd_arch_profile_t {
ocsd_arch_version_t arch; /**< core architecture */
ocsd_core_profile_t profile; /**< core profile */
} ocsd_arch_profile_t;
/* may want to use a 32 bit v-addr when running on 32 bit only ARM platforms. */
#ifdef USE_32BIT_V_ADDR
typedef uint32_t ocsd_vaddr_t; /**< 32 bit virtual addressing in library - use if compiling on 32 bit platforms */
#define OCSD_MAX_VA_BITSIZE 32 /**< 32 bit Virtual address bitsize macro */
#define OCSD_VA_MASK ~0UL /**< 32 bit Virtual address bitsize mask */
#else
typedef uint64_t ocsd_vaddr_t; /**< 64 bit virtual addressing in library */
#define OCSD_MAX_VA_BITSIZE 64 /**< 64 bit Virtual address bitsize macro */
#define OCSD_VA_MASK ~0ULL /**< 64 bit Virtual address bitsize mask */
#endif
/** A bit mask for the first 'bits' consecutive bits of an address */
#define OCSD_BIT_MASK(bits) (bits == OCSD_MAX_VA_BITSIZE) ? OCSD_VA_MASK : ((ocsd_vaddr_t)1 << bits) - 1
/** @}*/
/** @name Instruction Decode Information
@{*/
/** Instruction Set Architecture type
*
*/
typedef enum _ocsd_isa
{
ocsd_isa_arm, /**< V7 ARM 32, V8 AArch32 */
ocsd_isa_thumb2, /**< Thumb2 -> 16/32 bit instructions */
ocsd_isa_aarch64, /**< V8 AArch64 */
ocsd_isa_tee, /**< Thumb EE - unsupported */
ocsd_isa_jazelle, /**< Jazelle - unsupported in trace */
ocsd_isa_custom, /**< Instruction set - custom arch decoder */
ocsd_isa_unknown /**< ISA not yet known */
} ocsd_isa;
/** Security level type
*/
typedef enum _ocsd_sec_level
{
ocsd_sec_secure, /**< Core is in secure state */
ocsd_sec_nonsecure /**< Core is in non-secure state */
} ocsd_sec_level ;
/** Exception level type
*/
typedef enum _ocsd_ex_level
{
ocsd_EL_unknown = -1, /**< EL unknown / unsupported in trace */
ocsd_EL0 = 0, /**< EL0 */
ocsd_EL1, /**< EL1 */
ocsd_EL2, /**< EL2 */
ocsd_EL3, /**< EL3 */
} ocsd_ex_level;
/** instruction types - significant for waypoint calculaitons */
typedef enum _ocsd_instr_type {
OCSD_INSTR_OTHER, /**< Other instruction - not significant for waypoints. */
OCSD_INSTR_BR, /**< Immediate Branch instruction */
OCSD_INSTR_BR_INDIRECT, /**< Indirect Branch instruction */
OCSD_INSTR_ISB, /**< Barrier : ISB instruction */
OCSD_INSTR_DSB_DMB /**< Barrier : DSB or DMB instruction */
} ocsd_instr_type;
/** instruction sub types - addiitonal information passed to the output packets
for trace analysis tools.
*/
typedef enum _ocsd_instr_subtype {
OCSD_S_INSTR_NONE, /**< no subtype set */
OCSD_S_INSTR_BR_LINK, /**< branch with link */
OCSD_S_INSTR_V8_RET, /**< v8 ret instruction - subtype of BR_INDIRECT */
OCSD_S_INSTR_V8_ERET, /**< v8 eret instruction - subtype of BR_INDIRECT */
} ocsd_instr_subtype;
/** Instruction decode request structure.
*
* Used in IInstrDecode interface.
*
* Caller fills in the input: information, callee then fills in the decoder: information.
*/
typedef struct _ocsd_instr_info {
/* input information */
ocsd_arch_profile_t pe_type; /**< input: Core Arch and profile */
ocsd_isa isa; /**< Input: Current ISA. */
ocsd_vaddr_t instr_addr; /**< Input: Instruction address. */
uint32_t opcode; /**< Input: Opcode at address. 16 bit opcodes will use MS 16bits of parameter. */
uint8_t dsb_dmb_waypoints; /**< Input: DMB and DSB are waypoints */
/* instruction decode info */
ocsd_instr_type type; /**< Decoder: Current instruction type. */
ocsd_vaddr_t branch_addr; /**< Decoder: Calculated address of branch instrcution (direct branches only) */
ocsd_isa next_isa; /**< Decoder: ISA for next intruction. */
uint8_t instr_size; /**< Decoder : size of the decoded instruction */
uint8_t is_conditional; /**< Decoder : set to 1 if this instruction is conditional */
uint8_t is_link; /**< Decoder : is a branch with link instruction */
uint8_t thumb_it_conditions; /**< Decoder : return number of following instructions set with conditions by this Thumb IT instruction */
ocsd_instr_subtype sub_type; /**< Decoder : current instruction sub-type if known */
} ocsd_instr_info;
/** Core(PE) context structure
records current security state, exception level, VMID and ContextID for core.
*/
typedef struct _ocsd_pe_context {
ocsd_sec_level security_level; /**< security state */
ocsd_ex_level exception_level; /**< exception level */
uint32_t context_id; /**< context ID */
uint32_t vmid; /**< VMID */
struct {
uint32_t bits64:1; /**< 1 if 64 bit operation */
uint32_t ctxt_id_valid:1; /**< 1 if context ID value valid */
uint32_t vmid_valid:1; /**< 1 if VMID value is valid */
uint32_t el_valid:1; /**< 1 if EL value is valid (ETMv4 traces EL, other protocols do not) */
};
} ocsd_pe_context;
/** @}*/
/** @name Opcode Memory Access
Types used when accessing memory storage for traced opcodes..
@{*/
/** memory space bitfield enum for available security states and exception levels used
when accessing memory. */
typedef enum _ocsd_mem_space_acc_t {
OCSD_MEM_SPACE_EL1S = 0x1, /**< S EL1/0 */
OCSD_MEM_SPACE_EL1N = 0x2, /**< NS EL1/0 */
OCSD_MEM_SPACE_EL2 = 0x4, /**< NS EL2 */
OCSD_MEM_SPACE_EL3 = 0x8, /**< S EL3 */
OCSD_MEM_SPACE_S = 0x9, /**< Any S */
OCSD_MEM_SPACE_N = 0x6, /**< Any NS */
OCSD_MEM_SPACE_ANY = 0xF, /**< Any sec level / EL - live system use current EL + sec state */
} ocsd_mem_space_acc_t;
/**
* Callback function definition for callback function memory accessor type.
*
* When using callback memory accessor, the decoder will call this function to obtain the
* memory at the address for the current opcodes. The memory space will represent the current
* exception level and security context of the traced code.
*
* Return the number of bytes read, which can be less than the amount requested if this would take the
* access address outside the range of addresses defined when this callback was registered with the decoder.
*
* Return 0 bytes if start address out of covered range, or memory space is not one of those defined as supported
* when the callback was registered.
*
* @param p_context : opaque context pointer set by callback client.
* @param address : start address of memory to be accessed
* @param mem_space : memory space of accessed memory (current EL & security state)
* @param reqBytes : number of bytes required
* @param *byteBuffer : buffer for data.
*
* @return uint32_t : Number of bytes actually read, or 0 for access error.
*/
typedef uint32_t (* Fn_MemAcc_CB)(const void *p_context, const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint32_t reqBytes, uint8_t *byteBuffer);
/** memory region type for adding multi-region binary files to memory access interface */
typedef struct _ocsd_file_mem_region {
size_t file_offset; /**< Offset from start of file for memory region */
ocsd_vaddr_t start_address; /**< Start address of memory region */
size_t region_size; /**< size in bytes of memory region */
} ocsd_file_mem_region_t;
/** @}*/
/** @name Packet Processor Operation Control Flags
common operational flags - bottom 16 bits,
component specific - top 16 bits.
@{*/
#define OCSD_OPFLG_PKTPROC_NOFWD_BAD_PKTS 0x00000001 /**< don't forward bad packets up data path */
#define OCSD_OPFLG_PKTPROC_NOMON_BAD_PKTS 0x00000002 /**< don't forward bad packets to monitor interface */
#define OCSD_OPFLG_PKTPROC_ERR_BAD_PKTS 0x00000004 /**< throw error for bad packets - halt decoding. */
#define OCSD_OPFLG_PKTPROC_UNSYNC_ON_BAD_PKTS 0x00000008 /**< switch to unsynced state on bad packets - wait for next sync point */
/** mask to combine all common packet processor operational control flags */
#define OCSD_OPFLG_PKTPROC_COMMON (OCSD_OPFLG_PKTPROC_NOFWD_BAD_PKTS | \
OCSD_OPFLG_PKTPROC_NOMON_BAD_PKTS | \
OCSD_OPFLG_PKTPROC_ERR_BAD_PKTS | \
OCSD_OPFLG_PKTPROC_UNSYNC_ON_BAD_PKTS )
/** @}*/
/** @name Packet Decoder Operation Control Flags
common operational flags - bottom 16 bits,
component specific - top 16 bits.
@{*/
#define OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS 0x00000001 /**< throw error on bad packets input (default is to unsync and wait) */
/** mask to combine all common packet processor operational control flags */
#define OCSD_OPFLG_PKTDEC_COMMON (OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS)
/** @}*/
/** @name Decoder creation information
Flags to use when creating decoders by name
Builtin decoder names.
Protocol type enum.
@{*/
#define OCSD_CREATE_FLG_PACKET_PROC 0x01 /**< Create packet processor only. */
#define OCSD_CREATE_FLG_FULL_DECODER 0x02 /**< Create packet processor + decoder pair */
#define OCSD_CREATE_FLG_INST_ID 0x04 /**< Use instance ID in decoder instance name */
#define OCSD_BUILTIN_DCD_STM "STM" /**< STM decoder */
#define OCSD_BUILTIN_DCD_ETMV3 "ETMV3" /**< ETMv3 decoder */
#define OCSD_BUILTIN_DCD_ETMV4I "ETMV4I" /**< ETMv4 instruction decoder */
#define OCSD_BUILTIN_DCD_ETMV4D "ETMV4D" /**< ETMv4 data decoder */
#define OCSD_BUILTIN_DCD_PTM "PTM" /**< PTM decoder */
/*! Trace Protocol Builtin Types + extern
*/
typedef enum _ocsd_trace_protocol_t {
OCSD_PROTOCOL_UNKNOWN = 0, /**< Protocol unknown */
/* Built in library decoders */
OCSD_PROTOCOL_ETMV3, /**< ETMV3 instruction and data trace protocol decoder. */
OCSD_PROTOCOL_ETMV4I, /**< ETMV4 instruction trace protocol decoder. */
OCSD_PROTOCOL_ETMV4D, /**< ETMV4 data trace protocol decoder. */
OCSD_PROTOCOL_PTM, /**< PTM program flow instruction trace protocol decoder. */
OCSD_PROTOCOL_STM, /**< STM system trace protocol decoder. */
/* others to be added here */
OCSD_PROTOCOL_BUILTIN_END, /**< Invalid protocol - built-in protocol types end marker */
/* Custom / external decoders */
OCSD_PROTOCOL_CUSTOM_0 = 100, /**< Values from this onwards are assigned to external registered decoders */
OCSD_PROTOCOL_CUSTOM_1,
OCSD_PROTOCOL_CUSTOM_2,
OCSD_PROTOCOL_CUSTOM_3,
OCSD_PROTOCOL_CUSTOM_4,
OCSD_PROTOCOL_CUSTOM_5,
OCSD_PROTOCOL_CUSTOM_6,
OCSD_PROTOCOL_CUSTOM_7,
OCSD_PROTOCOL_CUSTOM_8,
OCSD_PROTOCOL_CUSTOM_9,
OCSD_PROTOCOL_END /**< Invalid protocol - protocol types end marker */
} ocsd_trace_protocol_t;
/** Test if protocol type is a library built-in decoder */
#define OCSD_PROTOCOL_IS_BUILTIN(P) ((P > OCSD_PROTOCOL_UNKNOWN) && (P < OCSD_PROTOCOL_BUILTIN_END))
/** Test if protocol type is a custom external registered decoder */
#define OCSD_PROTOCOL_IS_CUSTOM(P) ((P >= OCSD_PROTOCOL_CUSTOM_0) && (P < OCSD_PROTOCOL_END ))
/** @}*/
/** @name Software Trace Packets Info
Contains the information for the generic software trace output packet.
Software trace packet master and channel data.
Payload info:
size - packet payload size in bits;
marker - if this packet has a marker/flag
timestamp - if this packet has a timestamp associated
number of packets - packet processor can optionally correlate identically
sized packets on the same master / channel to be output as a single generic packet
Payload output as separate LE buffer, of sufficient bytes to hold all the packets.
@{*/
typedef struct _ocsd_swt_info {
uint16_t swt_master_id;
uint16_t swt_channel_id;
union {
struct {
uint32_t swt_payload_pkt_bitsize:8; /**< [bits 0:7 ] Packet size in bits of the payload packets */
uint32_t swt_payload_num_packets:8; /**< [bits 8:15 ] number of consecutive packets of this type in the payload data */
uint32_t swt_marker_packet:1; /**< [bit 16 ] packet is marker / flag packet */
uint32_t swt_has_timestamp:1; /**< [bit 17 ] packet has timestamp. */
uint32_t swt_marker_first:1; /**< [bit 18 ] for multiple packet payloads, this indicates if any marker is on first or last packet */
uint32_t swt_master_err:1; /**< [bit 19 ] current master has error - payload is error code */
uint32_t swt_global_err:1; /**< [bit 20 ] global error - payload is error code - master and channel ID not valid */
uint32_t swt_trigger_event:1; /**< [bit 21 ] trigger event packet - payload is event number */
uint32_t swt_frequency:1; /**< [bit 22 ] frequency packet - payload is frequency */
uint32_t swt_id_valid:1; /**< [bit 23 ] master & channel ID has been set by input stream */
};
uint32_t swt_flag_bits;
};
} ocsd_swt_info_t;
/** mask for the swt_id_valid flag - need to retain between packets */
#define SWT_ID_VALID_MASK (0x1 << 23)
/** @}*/
/** @}*/
#endif // ARM_OCSD_IF_TYPES_H_INCLUDED
/* End of File opencsd/ocsd_if_types.h */

View File

@ -0,0 +1,46 @@
/*
* \file ptm_decoder.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_PTM_DECODER_H_INCLUDED
#define ARM_PTM_DECODER_H_INCLUDED
#include "trc_cmp_cfg_ptm.h"
#include "trc_pkt_elem_ptm.h"
#include "trc_pkt_proc_ptm.h"
#include "trc_pkt_types_ptm.h"
#include "trc_pkt_decode_ptm.h"
#endif // ARM_PTM_DECODER_H_INCLUDED
/* End of File ptm_decoder.h */

View File

@ -0,0 +1,210 @@
/*
* \file trc_cmp_cfg_ptm.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_CMP_CFG_PTM_H_INCLUDED
#define ARM_TRC_CMP_CFG_PTM_H_INCLUDED
#include "trc_pkt_types_ptm.h"
#include "common/trc_cs_config.h"
/** @defgroup ocsd_protocol_cfg OpenCSD Library : Trace Source Protocol Configuration.
@brief Classes describing the trace capture time configuration of the trace source hardware.
Protocol configuration represents the trace capture time settings for the CoreSight hardware
component generating the trace. The packet processors and packet decoders require this configuration
information to correctly interpret packets and decode trace.
@{*/
/** @name PTM configuration
@{*/
/*!
* @class PtmConfig
* @brief Interpreter class for PTM Hardware configuration.
*
* Provides quick value interpretation methods for the PTM config register values.
* Primarily inlined for efficient code.
*/
class PtmConfig : public CSConfig // public ocsd_ptm_cfg
{
public:
PtmConfig(); /**< Default constructor */
PtmConfig(const ocsd_ptm_cfg *cfg_regs);
~PtmConfig() {}; /**< Default destructor */
/* register bit constants. */
static const uint32_t CTRL_BRANCH_BCAST = (0x1 << 8);
static const uint32_t CTRL_CYCLEACC = (0x1 << 12);
static const uint32_t CTRL_TS_ENA = (0x1 << 28);
static const uint32_t CTRL_RETSTACK_ENA = (0x1 << 29);
static const uint32_t CTRL_VMID_ENA = (0x1 << 30);
static const uint32_t CCER_TS_IMPL = (0x1 << 22);
static const uint32_t CCER_RESTACK_IMPL = (0x1 << 23);
static const uint32_t CCER_DMSB_WPT = (0x1 << 24);
static const uint32_t CCER_TS_DMSB = (0x1 << 25);
static const uint32_t CCER_VIRTEXT = (0x1 << 26);
static const uint32_t CCER_TS_ENC_NAT = (0x1 << 28);
static const uint32_t CCER_TS_64BIT = (0x1 << 29);
// operations to convert to and from C-API structure
//! copy assignment operator for base structure into class.
PtmConfig & operator=(const ocsd_ptm_cfg *p_cfg);
//! cast operator returning struct const reference
operator const ocsd_ptm_cfg &() const { return m_cfg; };
//! cast operator returning struct const pointer
operator const ocsd_ptm_cfg *() const { return &m_cfg; };
// access functions
const bool enaBranchBCast() const; //!< Branch broadcast enabled.
const bool enaCycleAcc() const; //!< cycle accurate tracing enabled.
const bool enaRetStack() const; //!< return stack enabled.
const bool hasRetStack() const; //!< return stack implemented.
const int MinorRev() const; //!< return X revision in 1.X
const bool hasTS() const; //!< Timestamps implemented in trace.
const bool enaTS() const; //!< Timestamp trace is enabled.
const bool TSPkt64() const; //!< timestamp packet is 64 bits in size.
const bool TSBinEnc() const; //!< Timestamp encoded as natural binary number.
const int CtxtIDBytes() const; //!< number of context ID bytes traced 1,2,4;
const bool hasVirtExt() const; //!< processor has virtualisation extensions.
const bool enaVMID() const; //!< VMID tracing enabled.
const bool dmsbGenTS() const; //!< TS generated for DMB and DSB
const bool dmsbWayPt() const; //!< DMB and DSB are waypoint instructions.
virtual const uint8_t getTraceID() const; //!< CoreSight Trace ID for this device.
const ocsd_core_profile_t &coreProfile() const { return m_cfg.core_prof; };
const ocsd_arch_version_t &archVersion() const { return m_cfg.arch_ver; };
private:
ocsd_ptm_cfg m_cfg;
};
/* inlines */
inline PtmConfig & PtmConfig::operator=(const ocsd_ptm_cfg *p_cfg)
{
// object of base class ocsd_ptm_cfg
m_cfg = *p_cfg;
return *this;
}
inline const bool PtmConfig::enaBranchBCast() const
{
return (bool)((m_cfg.reg_ctrl & CTRL_BRANCH_BCAST) != 0);
}
inline const bool PtmConfig::enaCycleAcc() const
{
return (bool)((m_cfg.reg_ctrl & CTRL_CYCLEACC) != 0);
}
inline const bool PtmConfig::enaRetStack() const
{
return (bool)((m_cfg.reg_ctrl & CTRL_RETSTACK_ENA) != 0);
}
inline const bool PtmConfig::hasRetStack() const
{
return (bool)((m_cfg.reg_ccer & CCER_RESTACK_IMPL) != 0);
}
inline const int PtmConfig::MinorRev() const
{
return ((int)m_cfg.reg_idr & 0xF0) >> 4;
}
inline const bool PtmConfig::hasTS() const
{
return (bool)((m_cfg.reg_ccer & CCER_TS_IMPL) != 0);
}
inline const bool PtmConfig::enaTS() const
{
return (bool)((m_cfg.reg_ctrl & CTRL_TS_ENA) != 0);
}
inline const bool PtmConfig::TSPkt64() const
{
if(MinorRev() == 0) return false;
return (bool)((m_cfg.reg_ccer & CCER_TS_64BIT) != 0);
}
inline const bool PtmConfig::TSBinEnc() const
{
if(MinorRev() == 0) return false;
return (bool)((m_cfg.reg_ccer & CCER_TS_ENC_NAT) != 0);
}
inline const bool PtmConfig::hasVirtExt() const
{
return (bool)((m_cfg.reg_ccer & CCER_VIRTEXT) != 0);
}
inline const bool PtmConfig::enaVMID() const
{
return (bool)((m_cfg.reg_ctrl & CTRL_VMID_ENA) != 0);
}
inline const bool PtmConfig::dmsbGenTS() const
{
return (bool)((m_cfg.reg_ccer & CCER_TS_DMSB) != 0);
}
inline const bool PtmConfig::dmsbWayPt() const
{
return (bool)((m_cfg.reg_ccer & CCER_DMSB_WPT) != 0);
}
inline const uint8_t PtmConfig::getTraceID() const
{
return (uint8_t)(m_cfg.reg_trc_id & 0x7F);
}
/** @}*/
/** @}*/
#endif // ARM_TRC_CMP_CFG_PTM_H_INCLUDED
/* End of File trc_cmp_cfg_ptm.h */

View File

@ -0,0 +1,57 @@
/*
* \file trc_dcd_mngr_ptm.h
* \brief OpenCSD : PTM decoder manager / handler specialisation
*
* \copyright Copyright (c) 2016, 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_DCD_MNGR_PTM_H_INCLUDED
#define ARM_TRC_DCD_MNGR_PTM_H_INCLUDED
#include "common/ocsd_dcd_mngr.h"
#include "trc_pkt_decode_ptm.h"
#include "trc_pkt_proc_ptm.h"
#include "trc_cmp_cfg_ptm.h"
#include "trc_pkt_types_ptm.h"
class DecoderMngrPtm : public DecodeMngrFullDcd< PtmTrcPacket,
ocsd_ptm_pkt_type,
PtmConfig,
ocsd_ptm_cfg,
TrcPktProcPtm,
TrcPktDecodePtm>
{
public:
DecoderMngrPtm(const std::string &name) : DecodeMngrFullDcd(name,OCSD_PROTOCOL_PTM) {};
virtual ~DecoderMngrPtm() {};
};
#endif // ARM_TRC_DCD_MNGR_PTM_H_INCLUDED
/* End of File trc_dcd_mngr_ptm.h */

View File

@ -0,0 +1,197 @@
/*
* \file trc_pkt_decode_ptm.h
* \brief OpenCSD : PTM packet decoder.
*
* \copyright Copyright (c) 2016, 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_DECODE_PTM_H_INCLUDED
#define ARM_TRC_PKT_DECODE_PTM_H_INCLUDED
#include "common/trc_pkt_decode_base.h"
#include "opencsd/ptm/trc_pkt_elem_ptm.h"
#include "opencsd/ptm/trc_cmp_cfg_ptm.h"
#include "common/trc_gen_elem.h"
#include "common/trc_ret_stack.h"
/**************** Atom handling class **************************************/
class PtmAtoms
{
public:
PtmAtoms() {};
~PtmAtoms() {};
//! initialise the atom and index values
void initAtomPkt(const ocsd_pkt_atom &atom, const ocsd_trc_index_t &root_index);
const ocsd_atm_val getCurrAtomVal() const;
const int numAtoms() const; //!< number of atoms
const ocsd_trc_index_t pktIndex() const; //!< originating packet index
void clearAtom(); //!< clear the current atom, set the next.
void clearAll(); //!< clear all
private:
ocsd_pkt_atom m_atom;
ocsd_trc_index_t m_root_index; //!< root index for the atom packet
};
inline void PtmAtoms::initAtomPkt(const ocsd_pkt_atom &atom, const ocsd_trc_index_t &root_index)
{
m_atom = atom;
m_root_index = root_index;
}
inline const ocsd_atm_val PtmAtoms::getCurrAtomVal() const
{
return (m_atom.En_bits & 0x1) ? ATOM_E : ATOM_N;
}
inline const int PtmAtoms::numAtoms() const
{
return m_atom.num;
}
inline const ocsd_trc_index_t PtmAtoms::pktIndex() const
{
return m_root_index;
}
inline void PtmAtoms::clearAtom()
{
if(m_atom.num)
{
m_atom.num--;
m_atom.En_bits >>=1;
}
}
inline void PtmAtoms::clearAll()
{
m_atom.num = 0;
}
/********** Main decode class ****************************************************/
class TrcPktDecodePtm : public TrcPktDecodeBase<PtmTrcPacket, PtmConfig>
{
public:
TrcPktDecodePtm();
TrcPktDecodePtm(int instIDNum);
virtual ~TrcPktDecodePtm();
protected:
/* implementation packet decoding interface */
virtual ocsd_datapath_resp_t processPacket();
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 uint8_t getCoreSightTraceID() { return m_CSID; };
/* local decode methods */
private:
/** operation for the trace instruction follower */
typedef enum {
TRACE_WAYPOINT, //!< standard operation - trace to waypoint - default op
TRACE_TO_ADDR_EXCL, //!< trace to supplied address - address is 1st instuction not executed.
TRACE_TO_ADDR_INCL //!< trace to supplied address - address is last instruction executed.
} waypoint_trace_t;
void initDecoder();
void resetDecoder();
ocsd_datapath_resp_t decodePacket();
ocsd_datapath_resp_t contProcess();
ocsd_datapath_resp_t processIsync();
ocsd_datapath_resp_t processBranch();
ocsd_datapath_resp_t processWPUpdate();
ocsd_datapath_resp_t processAtom();
ocsd_err_t traceInstrToWP(bool &bWPFound, const waypoint_trace_t traceWPOp = TRACE_WAYPOINT, const ocsd_vaddr_t nextAddrMatch = 0); //!< follow instructions from the current address to a WP. true if good, false if memory cannot be accessed.
ocsd_datapath_resp_t processAtomRange(const ocsd_atm_val A, const char *pkt_msg, const waypoint_trace_t traceWPOp = TRACE_WAYPOINT, const ocsd_vaddr_t nextAddrMatch = 0);
void checkPendingNacc(ocsd_datapath_resp_t &resp);
uint8_t m_CSID; //!< Coresight trace ID for this decoder.
//** Other processor state;
// trace decode FSM
typedef enum {
NO_SYNC, //!< pre start trace - init state or after reset or overflow, loss of sync.
WAIT_SYNC, //!< waiting for sync packet.
WAIT_ISYNC, //!< waiting for isync packet after 1st ASYNC.
DECODE_PKTS, //!< processing input packet
CONT_ISYNC, //!< continue processing isync packet after WAIT.
CONT_ATOM, //!< continue processing atom packet after WAIT.
CONT_WPUP, //!< continue processing WP update packet after WAIT.
CONT_BRANCH, //!< continue processing Branch packet after WAIT.
} processor_state_t;
processor_state_t m_curr_state;
const bool processStateIsCont() const;
// PE decode state - address and isa
//! Structure to contain the PE addr and ISA state.
typedef struct _ptm_pe_addr_state {
ocsd_isa isa; //!< current isa.
ocsd_vaddr_t instr_addr; //!< current address.
bool valid; //!< address valid - false if we need an address to continue decode.
} ptm_pe_addr_state;
ptm_pe_addr_state m_curr_pe_state; //!< current instruction state for PTM decode.
ocsd_pe_context m_pe_context; //!< current context information
// packet decode state
bool m_need_isync; //!< need context to continue
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; //!< address of memory access failure
bool m_i_sync_pe_ctxt; //!< isync has pe context.
PtmAtoms m_atoms; //!< atoms to process in an atom packet
TrcAddrReturnStack m_return_stack; //!< trace return stack.
//** output element
OcsdTraceElement m_output_elem;
};
inline const bool TrcPktDecodePtm::processStateIsCont() const
{
return (bool)(m_curr_state >= CONT_ISYNC);
}
#endif // ARM_TRC_PKT_DECODE_PTM_H_INCLUDED
/* End of File trc_pkt_decode_ptm.h */

View File

@ -0,0 +1,221 @@
/*
* \file trc_pkt_elem_ptm.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_PTM_H_INCLUDED
#define ARM_TRC_PKT_ELEM_PTM_H_INCLUDED
#include "trc_pkt_types_ptm.h"
#include "common/trc_printable_elem.h"
#include "common/trc_pkt_elem_base.h"
/** @addtogroup trc_pkts
@{*/
class PtmTrcPacket : public TrcPacketBase, public ocsd_ptm_pkt, trcPrintableElem
{
public:
PtmTrcPacket();
~PtmTrcPacket();
PtmTrcPacket &operator =(const ocsd_ptm_pkt* p_pkt);
virtual const void *c_pkt() const { return (const ocsd_ptm_pkt *)this; };
// update interface - set packet values
void Clear(); //!< clear update data in packet ready for new one.
void ResetState(); //!< reset intra packet state data - on full decoder reset.
void SetType(const ocsd_ptm_pkt_type p_type);
void SetErrType(const ocsd_ptm_pkt_type e_type);
void SetException( const ocsd_armv7_exception type,
const uint16_t number);
void SetISyncReason(const ocsd_iSync_reason reason);
void SetCycleCount(const uint32_t cycleCount);
void SetAtomFromPHdr(const uint8_t pHdr);
void SetCycleAccAtomFromPHdr(const uint8_t pHdr);
void UpdateAddress(const ocsd_vaddr_t partAddrVal, const int updateBits);
void UpdateNS(const int NS);
void UpdateAltISA(const int AltISA);
void UpdateHyp(const int Hyp);
void UpdateISA(const ocsd_isa isa);
void UpdateContextID(const uint32_t contextID);
void UpdateVMID(const uint8_t VMID);
void UpdateTimestamp(const uint64_t tsVal, const uint8_t updateBits);
// packet status interface
// get packet info.
const bool isBadPacket() const;
const ocsd_ptm_pkt_type getType() const;
// isa
const ocsd_isa getISA() const;
const bool ISAChanged() const { return (bool)(curr_isa != prev_isa); };
const uint8_t getAltISA() const { return context.curr_alt_isa; };
const uint8_t getNS() const { return context.curr_NS; };
const uint8_t getHyp() const { return context.curr_Hyp; };
// address
const ocsd_vaddr_t getAddrVal() const { return addr.val; };
// pe context information
const bool CtxtIDUpdated() const { return (bool)(context.updated_c == 1); };
const bool VMIDUpdated() const { return (bool)(context.updated_v == 1); };
const uint32_t getCtxtID() const { return context.ctxtID; };
const uint8_t getVMID() const { return context.VMID; };
const bool PEContextUpdated() const { return context.updated; };
// atom info
const ocsd_pkt_atom &getAtom() const { return atom; };
// branch address info
const bool isBranchExcepPacket() const { return (exception.bits.present == 1); };
const ocsd_armv7_exception excepType() const { return exception.type; };
const uint16_t excepNum() const { return exception.number; };
// isync
const ocsd_iSync_reason iSyncReason() const { return i_sync_reason; };
// cycle count
const bool hasCC() const { return (cc_valid == 1); };
const uint32_t getCCVal() const { return cycle_count; };
// printing
virtual void toString(std::string &str) const;
virtual void toStringFmt(const uint32_t fmtFlags, std::string &str) const;
private:
void packetTypeName(const ocsd_ptm_pkt_type pkt_type, std::string &name, std::string &desc) const;
void getAtomStr(std::string &valStr) const;
void getBranchAddressStr(std::string &valStr) const;
void getExcepStr(std::string &excepStr) const;
void getISAStr(std::string &isaStr) const;
void getCycleCountStr(std::string &subStr) const;
void getISyncStr(std::string &valStr) const;
void getTSStr(std::string &valStr) const;
};
//*** update interface - set packet values
inline void PtmTrcPacket::SetType(const ocsd_ptm_pkt_type p_type)
{
type = p_type;
}
inline void PtmTrcPacket::SetErrType(const ocsd_ptm_pkt_type e_type)
{
err_type = type;
type = e_type;
}
inline void PtmTrcPacket::UpdateNS(const int NS)
{
context.curr_NS = NS;
context.updated = 1;
};
inline void PtmTrcPacket::UpdateAltISA(const int AltISA)
{
context.curr_alt_isa = AltISA;
context.updated = 1;
}
inline void PtmTrcPacket::UpdateHyp(const int Hyp)
{
context.curr_Hyp = Hyp;
context.updated = 1;
}
inline void PtmTrcPacket::UpdateISA(const ocsd_isa isa)
{
prev_isa = curr_isa;
curr_isa = isa;
}
inline void PtmTrcPacket::UpdateContextID(const uint32_t contextID)
{
context.ctxtID = contextID;
context.updated_c = 1;
}
inline void PtmTrcPacket::UpdateVMID(const uint8_t VMID)
{
context.VMID = VMID;
context.updated_v = 1;
}
inline void PtmTrcPacket::SetException( const ocsd_armv7_exception type, const uint16_t number)
{
exception.bits.present = 1;
exception.number = number;
exception.type = type;
}
inline void PtmTrcPacket::SetISyncReason(const ocsd_iSync_reason reason)
{
i_sync_reason = reason;
}
inline void PtmTrcPacket::SetCycleCount(const uint32_t cycleCount)
{
cycle_count = cycleCount;
cc_valid = 1;
}
//*** packet status interface - get packet info.
inline const bool PtmTrcPacket::isBadPacket() const
{
return (bool)(type >= PTM_PKT_BAD_SEQUENCE);
}
inline const ocsd_ptm_pkt_type PtmTrcPacket::getType() const
{
return type;
}
inline const ocsd_isa PtmTrcPacket::getISA() const
{
return curr_isa;
}
/** @}*/
#endif // ARM_TRC_PKT_ELEM_PTM_H_INCLUDED
/* End of File trc_pkt_elem_ptm.h */

View File

@ -0,0 +1,215 @@
/*
* \file trc_pkt_proc_ptm.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_PTM_H_INCLUDED
#define ARM_TRC_PKT_PROC_PTM_H_INCLUDED
#include "trc_pkt_types_ptm.h"
#include "common/trc_pkt_proc_base.h"
#include "trc_pkt_elem_ptm.h"
#include "trc_cmp_cfg_ptm.h"
class PtmTrcPacket;
class PtmConfig;
/** @addtogroup ocsd_pkt_proc
@{*/
class TrcPktProcPtm : public TrcPktProcBase< PtmTrcPacket, ocsd_ptm_pkt_type, PtmConfig>
{
public:
TrcPktProcPtm();
TrcPktProcPtm(int instIDNum);
virtual ~TrcPktProcPtm();
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;
void InitPacketState(); // clear current packet state.
void InitProcessorState(); // clear all previous process state
ocsd_datapath_resp_t outputPacket();
typedef enum _process_state {
WAIT_SYNC,
PROC_HDR,
PROC_DATA,
SEND_PKT,
} process_state;
process_state m_process_state; // process algorithm state.
std::vector<uint8_t> m_currPacketData; // raw data
uint32_t m_currPktIdx; // index into packet when expanding
PtmTrcPacket m_curr_packet; // expanded packet
ocsd_trc_index_t m_curr_pkt_index; // trace index at start of packet.
const bool readByte(uint8_t &currByte);
const bool readByte(); // just read into buffer, don't need the value
void unReadByte(); // remove last byte from the buffer.
uint8_t m_chanIDCopy;
// current data block being processed.
const uint8_t *m_pDataIn;
uint32_t m_dataInLen;
uint32_t m_dataInProcessed;
ocsd_trc_index_t m_block_idx; // index start for current block
// processor synchronisation
const bool isSync() const;
ocsd_datapath_resp_t waitASync(); //!< look for first synchronisation point in the packet stream
bool m_waitASyncSOPkt;
bool m_bAsyncRawOp;
bool m_bOPNotSyncPkt; //!< true if output not sync packet when waiting for ASYNC
// ** packet processing functions.
void pktASync();
void pktISync();
void pktTrigger();
void pktWPointUpdate();
void pktIgnore();
void pktCtxtID();
void pktVMID();
void pktAtom();
void pktTimeStamp();
void pktExceptionRet();
void pktBranchAddr();
void pktReserved();
// async finder
typedef enum _async_result {
ASYNC, //!< pattern confirmed async 0x00 x 5, 0x80
NOT_ASYNC, //!< pattern confirmed not async
ASYNC_EXTRA_0, //!< pattern confirmed 0x00 x N + ASYNC
THROW_0, //!< long pattern of 0x00 - throw some away.
ASYNC_INCOMPLETE, //!< not enough input data.
} async_result_t;
async_result_t findAsync();
int m_async_0; // number of current consecutive async 0s
bool m_part_async;
// number of extra 0s before we throw 0 on async detect.
#define ASYNC_PAD_0_LIMIT 11
// number of 0s minimum to form an async
#define ASYNC_REQ_0 5
// extraction sub-routines
void extractCtxtID(int idx, uint32_t &ctxtID);
void extractCycleCount(int idx, uint32_t &cycleCount);
int extractTS(uint64_t &tsVal, uint8_t &tsUpdateBits);
uint32_t extractAddress(const int offset,uint8_t &total_bits);
// number of bytes required for a complete packet - used in some multi byte packets
int m_numPktBytesReq;
// packet processing state
bool m_needCycleCount;
bool m_gotCycleCount;
int m_gotCCBytes; // number of CC bytes read so far
int m_numCtxtIDBytes;
int m_gotCtxtIDBytes;
bool m_gotTSBytes; //!< got all TS bytes
int m_tsByteMax; //!< max size for TS portion of TS packet.
// branch address state
bool m_gotAddrBytes; //!< got all Addr bytes in branch packet
int m_numAddrBytes; //!< number of address bytes
bool m_gotExcepBytes; //!< got all needed exception bytes
int m_numExcepBytes; //!< got 1st exception byte
ocsd_isa m_addrPktIsa; //!< ISA of the branch address packet
int m_excepAltISA; //!< Alt ISA bit iff exception bytes
// bad packets
void throwMalformedPacketErr(const char *pszErrMsg);
void throwPacketHeaderErr(const char *pszErrMsg);
// packet processing function table
typedef void (TrcPktProcPtm::*PPKTFN)(void);
PPKTFN m_pIPktFn;
struct _pkt_i_table_t {
ocsd_ptm_pkt_type pkt_type;
PPKTFN pptkFn;
} m_i_table[256];
void BuildIPacketTable();
};
inline const bool TrcPktProcPtm::isSync() const
{
return (bool)(m_curr_packet.getType() == PTM_PKT_NOTSYNC);
}
inline void TrcPktProcPtm::throwMalformedPacketErr(const char *pszErrMsg)
{
m_curr_packet.SetErrType(PTM_PKT_BAD_SEQUENCE);
throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_BAD_PACKET_SEQ,m_curr_pkt_index,m_chanIDCopy,pszErrMsg);
}
inline void TrcPktProcPtm::throwPacketHeaderErr(const char *pszErrMsg)
{
throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PCKT_HDR,m_curr_pkt_index,m_chanIDCopy,pszErrMsg);
}
inline const bool TrcPktProcPtm::readByte()
{
uint8_t currByte;
return readByte(currByte);
}
/** @}*/
#endif // ARM_TRC_PKT_PROC_PTM_H_INCLUDED
/* End of File trc_pkt_proc_ptm.h */

View File

@ -0,0 +1,137 @@
/*
* \file trc_pkt_ptm_types.h
* \brief OpenCSD : PTM specific types
*
* \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_PTM_TYPES_H_INCLUDED
#define ARM_TRC_PKT_PTM_TYPES_H_INCLUDED
#include "opencsd/trc_pkt_types.h"
/** @addtogroup trc_pkts
@{*/
/** @name PTM Packet Types
@{*/
typedef enum _ocsd_ptm_pkt_type
{
// markers for unknown packets
PTM_PKT_NOTSYNC, //!< no sync found yet
PTM_PKT_INCOMPLETE_EOT, //!< flushing incomplete packet at end of trace.
PTM_PKT_NOERROR, //!< no error base type packet.
// markers for valid packets
PTM_PKT_BRANCH_ADDRESS, //!< Branch address with optional exception.
PTM_PKT_A_SYNC, //!< Alignment Synchronisation.
PTM_PKT_I_SYNC, //!< Instruction sync with address.
PTM_PKT_TRIGGER, //!< trigger packet
PTM_PKT_WPOINT_UPDATE, //!< Waypoint update.
PTM_PKT_IGNORE, //!< ignore packet.
PTM_PKT_CONTEXT_ID, //!< context id packet.
PTM_PKT_VMID, //!< VMID packet
PTM_PKT_ATOM, //!< atom waypoint packet.
PTM_PKT_TIMESTAMP, //!< timestamp packet.
PTM_PKT_EXCEPTION_RET, //!< exception return.
PTM_PKT_BRANCH_OR_BYPASS_EOT, // interpreter FSM 'state' : unsure if branch 0 packet or bypass flush end of trace
PTM_PKT_TPIU_PAD_EOB, // pad end of a buffer - no valid trace at this point
// markers for bad packets
PTM_PKT_BAD_SEQUENCE, //!< invalid sequence for packet type
PTM_PKT_RESERVED, //!< Reserved packet encoding
} ocsd_ptm_pkt_type;
typedef struct _ptm_context_t {
struct {
uint32_t curr_alt_isa:1; /**< current Alt ISA flag for Tee / T32 (used if not in present packet) */
uint32_t curr_NS:1; /**< current NS flag (used if not in present packet) */
uint32_t curr_Hyp:1; /**< current Hyp flag (used if not in present packet) */
uint32_t updated:1; /**< context updated */
uint32_t updated_c:1; /**< updated CtxtID */
uint32_t updated_v:1; /**< updated VMID */
};
uint32_t ctxtID; /**< Context ID */
uint8_t VMID; /**< VMID */
} ptm_context_t;
typedef struct _ocsd_ptm_excep {
ocsd_armv7_exception type; /**< exception type. */
uint16_t number; /**< exception as number */
struct {
uint32_t present:1; /**< exception present in packet */
} bits;
} ocsd_ptm_excep;
typedef struct _ocsd_ptm_pkt
{
ocsd_ptm_pkt_type type; /**< Primary packet type. */
ocsd_isa curr_isa; /**< current ISA. */
ocsd_isa prev_isa; /**< previous ISA */
ocsd_pkt_vaddr addr; /**< current address. */
ptm_context_t context; /**< current context. */
ocsd_pkt_atom atom;
ocsd_iSync_reason i_sync_reason; /**< reason for ISync Packet. */
uint32_t cycle_count; /**< cycle count value associated with this packet. */
uint8_t cc_valid; /**< cycle count value valid. */
uint64_t timestamp; /**< timestamp value. */
uint8_t ts_update_bits; /**< bits of ts updated this packet. (if TS packet) */
ocsd_ptm_excep exception; /**< exception information in packet */
ocsd_ptm_pkt_type err_type; /**< Basic packet type if primary type indicates error or incomplete. */
} ocsd_ptm_pkt;
typedef struct _ocsd_ptm_cfg
{
uint32_t reg_idr; /**< PTM ID register */
uint32_t reg_ctrl; /**< Control Register */
uint32_t reg_ccer; /**< Condition code extension register */
uint32_t reg_trc_id; /**< CoreSight Trace ID register */
ocsd_arch_version_t arch_ver; /**< Architecture version */
ocsd_core_profile_t core_prof; /**< Core Profile */
} ocsd_ptm_cfg;
/** @}*/
/** @}*/
#endif // ARM_TRC_PKT_PTM_TYPES_H_INCLUDED
/* End of File trc_pkt_ptm_types.h */

View File

@ -0,0 +1,45 @@
/*
* \file stm_decoder.h
* \brief OpenCSD : STM decoder
*
* \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_STM_DECODER_H_INCLUDED
#define ARM_STM_DECODER_H_INCLUDED
#include "trc_pkt_types_stm.h"
#include "trc_pkt_elem_stm.h"
#include "trc_pkt_proc_stm.h"
#endif // ARM_STM_DECODER_H_INCLUDED
/* End of File stm_decoder.h */

View File

@ -0,0 +1,161 @@
/*
* \file trc_cmp_cfg_stm.h
* \brief OpenCSD : STM compnent configuration.
*
* \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_CMP_CFG_STM_H_INCLUDED
#define ARM_TRC_CMP_CFG_STM_H_INCLUDED
#include "trc_pkt_types_stm.h"
#include "common/trc_cs_config.h"
/** @addtogroup ocsd_protocol_cfg
@{*/
/** @name STM configuration
@{*/
/*!
* @class STMConfig
* @brief STM hardware configuration data.
*
* Represents the programmed and hardware configured state of an STM device.
* Creates default values for most RO register values to effect a default STM
* with values of 256 masters, 65536 channels, HW event trace not present / disabled.
*
* If this default is sufficient a single call to setTraceID() will be all that is
* required to decode the STM protocol.
*
* Can also be initialised with a fully populated ocsd_stm_cfg structure.
*/
class STMConfig : public CSConfig // public ocsd_stm_cfg
{
public:
STMConfig(); //!< Constructor - creates a default configuration
STMConfig(const ocsd_stm_cfg *cfg_regs);
~STMConfig() {};
// operations to convert to and from C-API structure
STMConfig & operator=(const ocsd_stm_cfg *p_cfg); //!< set from full configuration structure.
//! cast operator returning struct const reference
operator const ocsd_stm_cfg &() const { return m_cfg; };
//! cast operator returning struct const pointer
operator const ocsd_stm_cfg *() const { return &m_cfg; };
// access functions
void setTraceID(const uint8_t traceID); //!< Set the CoreSight trace ID.
void setHWTraceFeat(const hw_event_feat_t hw_feat); //!< set usage of STM HW event trace.
virtual const uint8_t getTraceID() const; //!< Get the CoreSight trace ID.
const uint8_t getMaxMasterIdx() const; //!< Get the maximum master index
const uint16_t getMaxChannelIdx() const; //!< Get the maximum channel index.
const uint16_t getHWTraceMasterIdx() const; //!< Get the master used for HW event trace.
bool getHWTraceEn() const; //!< return true if HW trace is present and enabled.
private:
bool m_bHWTraceEn;
ocsd_stm_cfg m_cfg;
};
inline STMConfig::STMConfig()
{
m_cfg.reg_tcsr = 0;
m_cfg.reg_devid = 0xFF; // default to 256 masters.
m_cfg.reg_feat3r = 0x10000; // default to 65536 channels.
m_cfg.reg_feat1r = 0x0;
m_cfg.reg_hwev_mast = 0; // default hwtrace master = 0;
m_cfg.hw_event = HwEvent_Unknown_Disabled; // default to not present / disabled.
m_bHWTraceEn = false;
}
inline STMConfig::STMConfig(const ocsd_stm_cfg *cfg_regs)
{
m_cfg = *cfg_regs;
setHWTraceFeat(m_cfg.hw_event);
}
inline STMConfig & STMConfig::operator=(const ocsd_stm_cfg *p_cfg)
{
m_cfg = *p_cfg;
setHWTraceFeat(p_cfg->hw_event);
return *this;
}
inline void STMConfig::setTraceID(const uint8_t traceID)
{
uint32_t IDmask = 0x007F0000;
m_cfg.reg_tcsr &= ~IDmask;
m_cfg.reg_tcsr |= (((uint32_t)traceID) << 16) & IDmask;
}
inline void STMConfig::setHWTraceFeat(const hw_event_feat_t hw_feat)
{
m_cfg.hw_event = hw_feat;
m_bHWTraceEn = (m_cfg.hw_event == HwEvent_Enabled);
if(m_cfg.hw_event == HwEvent_UseRegisters)
m_bHWTraceEn = (((m_cfg.reg_feat1r & 0xC0000) == 0x80000) && ((m_cfg.reg_tcsr & 0x8) == 0x8));
}
inline const uint8_t STMConfig::getTraceID() const
{
return (uint8_t)((m_cfg.reg_tcsr >> 16) & 0x7F);
}
inline const uint8_t STMConfig::getMaxMasterIdx() const
{
return (uint8_t)(m_cfg.reg_devid & 0xFF);
}
inline const uint16_t STMConfig::getMaxChannelIdx() const
{
return (uint16_t)(m_cfg.reg_feat3r - 1);
}
inline const uint16_t STMConfig::getHWTraceMasterIdx() const
{
return (uint16_t)(m_cfg.reg_hwev_mast & 0xFFFF);
}
inline bool STMConfig::getHWTraceEn() const
{
return m_bHWTraceEn;
}
/** @}*/
/** @}*/
#endif // ARM_TRC_CMP_CFG_STM_H_INCLUDED
/* End of File trc_cmp_cfg_stm.h */

View File

@ -0,0 +1,57 @@
/*
* \file trc_dcd_mngr_stm.h
* \brief OpenCSD : STM decoder manager / handler specialisation
*
* \copyright Copyright (c) 2016, 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_DCD_MNGR_STM_H_INCLUDED
#define ARM_TRC_DCD_MNGR_STM_H_INCLUDED
#include "common/ocsd_dcd_mngr.h"
#include "trc_pkt_decode_stm.h"
#include "trc_pkt_proc_stm.h"
#include "trc_cmp_cfg_stm.h"
#include "trc_pkt_types_stm.h"
class DecoderMngrStm : public DecodeMngrFullDcd< StmTrcPacket,
ocsd_stm_pkt_type,
STMConfig,
ocsd_stm_cfg,
TrcPktProcStm,
TrcPktDecodeStm>
{
public:
DecoderMngrStm(const std::string &name) : DecodeMngrFullDcd(name,OCSD_PROTOCOL_STM) {};
virtual ~DecoderMngrStm() {};
};
#endif // ARM_TRC_DCD_MNGR_STM_H_INCLUDED
/* End of File trc_dcd_mngr_stm.h */

View File

@ -0,0 +1,103 @@
/*
* \file trc_pkt_decode_stm.h
* \brief OpenCSD : STM packet decoder
*
* Convert the incoming indidvidual STM packets to
*
* \copyright Copyright (c) 2016, 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_DECODE_STM_H_INCLUDED
#define ARM_TRC_PKT_DECODE_STM_H_INCLUDED
#include "common/trc_pkt_decode_base.h"
#include "opencsd/stm/trc_pkt_elem_stm.h"
#include "opencsd/stm/trc_cmp_cfg_stm.h"
#include "common/trc_gen_elem.h"
class TrcPktDecodeStm : public TrcPktDecodeBase<StmTrcPacket, STMConfig>
{
public:
TrcPktDecodeStm();
TrcPktDecodeStm(int instIDNum);
virtual ~TrcPktDecodeStm();
protected:
/* implementation packet decoding interface */
virtual ocsd_datapath_resp_t processPacket();
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 uint8_t getCoreSightTraceID() { return m_CSID; };
/* local decode methods */
private:
void initDecoder();
void resetDecoder();
void initPayloadBuffer();
bool isInit() { return (bool)((m_config != 0) && (m_payload_buffer != 0)); };
ocsd_datapath_resp_t decodePacket(bool &bPktDone); //!< decode the current incoming packet
void clearSWTPerPcktInfo();
void updatePayload(bool &bSendPacket);
typedef enum {
NO_SYNC, //!< pre start trace - init state or after reset or overflow, loss of sync.
WAIT_SYNC, //!< waiting for sync packet.
DECODE_PKTS //!< processing input packet.
} processor_state_t;
processor_state_t m_curr_state;
ocsd_swt_info_t m_swt_packet_info;
uint8_t *m_payload_buffer; //!< payload buffer - allocated for one or multiple packets according to config
int m_payload_size; //!< payload buffer total size in bytes.
int m_payload_used; //!< payload buffer used in bytes - current payload size.
bool m_payload_odd_nibble; //!< last used byte in payload contains a single 4 bit packet.
int m_num_pkt_correlation; //!< number of identical payload packets to buffer up before output. - fixed at 1 till later update
uint8_t m_CSID; //!< Coresight trace ID for this decoder.
bool m_decode_pass1; //!< flag to indicate 1st pass of packet decode.
//** output element
OcsdTraceElement m_output_elem; //!< output packet
};
#endif // ARM_TRC_PKT_DECODE_STM_H_INCLUDED
/* End of File trc_pkt_decode_stm.h */

View File

@ -0,0 +1,238 @@
/*!
* \file trc_pkt_elem_stm.h
* \brief OpenCSD : STM packet class.
*
* \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_STM_H_INCLUDED
#define ARM_TRC_PKT_ELEM_STM_H_INCLUDED
#include "trc_pkt_types_stm.h"
#include "common/trc_printable_elem.h"
#include "common/trc_pkt_elem_base.h"
/*!
* @class StmTrcPacket
* @brief STM trace packet with packet printing functionality
*
* This class allows for the update and access of the current STM trace
* packet, implementing the STM protocol rules as appropriate. Maintains
* the intra packet state as well as updates on a per packet basis.
*
* Based on data structure ocsd_stm_pkt.
*
*/
class StmTrcPacket : public TrcPacketBase, public ocsd_stm_pkt, public trcPrintableElem
{
public:
StmTrcPacket();
~StmTrcPacket() {};
StmTrcPacket &operator =(const ocsd_stm_pkt *p_pkt);
virtual const void *c_pkt() const { return (const ocsd_stm_pkt *)this; };
void initStartState(); //!< Initialise packet state at start of decoder.
void initNextPacket(); //!< Initialise state for next packet.
void setPacketType(const ocsd_stm_pkt_type type, const bool bMarker);
void updateErrType(const ocsd_stm_pkt_type err_type);
void setMaster(const uint8_t master);
void setChannel(const uint16_t channel, const bool b8Bit);
void setTS(const uint64_t ts_val, const uint8_t updatedBits);
void onVersionPkt(const ocsd_stm_ts_type type);
void setD4Payload(const uint8_t value);
void setD8Payload(const uint8_t value);
void setD16Payload(const uint16_t value);
void setD32Payload(const uint32_t value);
void setD64Payload(const uint64_t value);
const bool isMarkerPkt() const;
const bool isTSPkt() const;
const ocsd_stm_pkt_type getPktType() const;
const ocsd_stm_pkt_type getPktErrType() const;
const uint8_t getMaster() const;
const uint16_t getChannel() const;
const ocsd_stm_ts_type getTSType() const;
const uint64_t getTSVal() const;
const uint8_t getD4Val() const;
const uint8_t getD8Val() const;
const uint16_t getD16Val() const;
const uint32_t getD32Val() const;
const uint64_t getD64Val() const;
const bool isBadPacket() const;
// printing
virtual void toString(std::string &str) const;
virtual void toStringFmt(const uint32_t fmtFlags, std::string &str) const;
private:
void pktTypeName(const ocsd_stm_pkt_type pkt_type, std::string &name, std::string &desc) const;
};
inline void StmTrcPacket::setPacketType(const ocsd_stm_pkt_type type, const bool bMarker)
{
this->type = type;
if(bMarker)
pkt_has_marker = 1;
}
inline void StmTrcPacket::updateErrType(const ocsd_stm_pkt_type err_type)
{
this->err_type = this->type; // original type is the err type;
this->type = err_type; // mark main type as an error.
}
inline void StmTrcPacket::setMaster(const uint8_t master)
{
this->master = master;
channel = 0; // M8 forces current channel to 0.
}
inline void StmTrcPacket::setChannel(const uint16_t channel, const bool b8Bit)
{
if(b8Bit)
this->channel = (this->channel & 0xFF00) | (channel & 0xFF);
else
this->channel = channel;
}
inline void StmTrcPacket::onVersionPkt(const ocsd_stm_ts_type type)
{
this->ts_type = type;
master = 0;
channel = 0;
}
inline void StmTrcPacket::setD4Payload(const uint8_t value)
{
payload.D8 = value & 0xF;
}
inline void StmTrcPacket::setD8Payload(const uint8_t value)
{
payload.D8 = value;
}
inline void StmTrcPacket::setD16Payload(const uint16_t value)
{
payload.D16 = value;
}
inline void StmTrcPacket::setD32Payload(const uint32_t value)
{
payload.D32 = value;
}
inline void StmTrcPacket::setD64Payload(const uint64_t value)
{
payload.D64 = value;
}
inline const bool StmTrcPacket::isMarkerPkt() const
{
return (pkt_has_marker != 0);
}
inline const bool StmTrcPacket::isTSPkt() const
{
return (pkt_has_ts != 0);
}
inline const ocsd_stm_pkt_type StmTrcPacket::getPktType() const
{
return type;
}
inline const ocsd_stm_pkt_type StmTrcPacket::getPktErrType() const
{
return err_type;
}
inline const uint8_t StmTrcPacket::getMaster() const
{
return master;
}
inline const uint16_t StmTrcPacket::getChannel() const
{
return channel;
}
inline const ocsd_stm_ts_type StmTrcPacket::getTSType() const
{
return ts_type;
}
inline const uint64_t StmTrcPacket::getTSVal() const
{
return timestamp;
}
inline const uint8_t StmTrcPacket::getD4Val() const
{
return payload.D8;
}
inline const uint8_t StmTrcPacket::getD8Val() const
{
return payload.D8;
}
inline const uint16_t StmTrcPacket::getD16Val() const
{
return payload.D16;
}
inline const uint32_t StmTrcPacket::getD32Val() const
{
return payload.D32;
}
inline const uint64_t StmTrcPacket::getD64Val() const
{
return payload.D64;
}
inline const bool StmTrcPacket::isBadPacket() const
{
return (bool)(type >= STM_PKT_BAD_SEQUENCE);
}
#endif // ARM_TRC_PKT_ELEM_STM_H_INCLUDED
/* End of File trc_pkt_elem_stm.h */

View File

@ -0,0 +1,289 @@
/*
* \file trc_pkt_proc_stm.h
* \brief OpenCSD : STM packet processing
*
* \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_STM_H_INCLUDED
#define ARM_TRC_PKT_PROC_STM_H_INCLUDED
#include <vector>
#include "trc_pkt_types_stm.h"
#include "common/trc_pkt_proc_base.h"
#include "trc_pkt_elem_stm.h"
#include "trc_cmp_cfg_stm.h"
/** @addtogroup ocsd_pkt_proc
@{*/
class TrcPktProcStm : public TrcPktProcBase<StmTrcPacket, ocsd_stm_pkt_type, STMConfig>
{
public:
TrcPktProcStm();
TrcPktProcStm(int instIDNum);
virtual ~TrcPktProcStm();
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;
typedef enum _process_state {
WAIT_SYNC,
PROC_HDR,
PROC_DATA,
SEND_PKT
} process_state;
process_state m_proc_state;
private:
void initObj();
void initProcessorState();
void initNextPacket();
void waitForSync(const ocsd_trc_index_t blk_st_index);
ocsd_datapath_resp_t outputPacket(); //!< send packet on output
void sendPacket(); //!< mark packet for send.
void setProcUnsynced(); //!< set processor state to unsynced
void throwBadSequenceError(const char *pszMessage = "");
void throwReservedHdrError(const char *pszMessage = "");
// packet processing routines
// 1 nibble opcodes
void stmPktReserved();
void stmPktNull();
void stmPktM8();
void stmPktMERR();
void stmPktC8();
void stmPktD4();
void stmPktD8();
void stmPktD16();
void stmPktD32();
void stmPktD64();
void stmPktD4MTS();
void stmPktD8MTS();
void stmPktD16MTS();
void stmPktD32MTS();
void stmPktD64MTS();
void stmPktFlagTS();
void stmPktFExt();
// 2 nibble opcodes 0xFn
void stmPktReservedFn();
void stmPktF0Ext();
void stmPktGERR();
void stmPktC16();
void stmPktD4TS();
void stmPktD8TS();
void stmPktD16TS();
void stmPktD32TS();
void stmPktD64TS();
void stmPktD4M();
void stmPktD8M();
void stmPktD16M();
void stmPktD32M();
void stmPktD64M();
void stmPktFlag();
void stmPktASync();
// 3 nibble opcodes 0xF0n
void stmPktReservedF0n();
void stmPktVersion();
void stmPktNullTS();
void stmPktTrigger();
void stmPktTriggerTS();
void stmPktFreq();
void stmExtractTS(); // extract a TS in packets that require it.
void stmExtractVal8(uint8_t nibbles_to_val);
void stmExtractVal16(uint8_t nibbles_to_val);
void stmExtractVal32(uint8_t nibbles_to_val);
void stmExtractVal64(uint8_t nibbles_to_val);
uint64_t bin_to_gray(uint64_t bin_value);
uint64_t gray_to_bin(uint64_t gray_value);
void pktNeedsTS(); // init the TS extraction routines
// data processing op function tables
void buildOpTables();
typedef void (TrcPktProcStm::*PPKTFN)(void);
PPKTFN m_pCurrPktFn; // current active processing function.
PPKTFN m_1N_ops[0x10];
PPKTFN m_2N_ops[0x10];
PPKTFN m_3N_ops[0x10];
// read a nibble from the input data - may read a byte and set spare or return spare.
// handles setting up packet data block and end of input
bool readNibble();
const bool dataToProcess() const; //!< true if data to process, or packet to send
void savePacketByte(const uint8_t val); //!< save data to packet buffer if we need it for monitor.
// packet data
StmTrcPacket m_curr_packet; //!< current packet.
bool m_bNeedsTS; //!< packet requires a TS
bool m_bIsMarker;
bool m_bStreamSync; //!< packet stream is synced
// input data handling
uint8_t m_num_nibbles; //!< number of nibbles in the current packet
uint8_t m_nibble; //!< current nibble being processed.
uint8_t m_nibble_2nd; //!< 2nd unused nibble from a processed byte.
bool m_nibble_2nd_valid; //!< 2nd nibble is valid;
uint8_t m_num_data_nibbles; //!< number of nibbles needed to acheive payload.
const uint8_t *m_p_data_in; //!< pointer to input data.
uint32_t m_data_in_size; //!< amount of data in.
uint32_t m_data_in_used; //!< amount of data processed.
ocsd_trc_index_t m_packet_index; //!< byte index for start of current packet
std::vector<uint8_t> m_packet_data; //!< current packet data (bytes) - only saved if needed to output to monitor.
bool m_bWaitSyncSaveSuppressed; //!< don't save byte at a time when waitsync
// payload data
uint8_t m_val8; //!< 8 bit payload.
uint16_t m_val16; //!< 16 bit payload
uint32_t m_val32; //!< 32 bit payload
uint64_t m_val64; //!< 64 bit payload
// timestamp handling
uint8_t m_req_ts_nibbles;
uint8_t m_curr_ts_nibbles;
uint64_t m_ts_update_value;
bool m_ts_req_set;
// sync handling - need to spot sync mid other packet in case of wrap / discontinuity
uint8_t m_num_F_nibbles; //!< count consecutive F nibbles.
bool m_sync_start; //!< possible start of sync
bool m_is_sync; //!< true if found sync at current nibble
ocsd_trc_index_t m_sync_index; //!< index of start of possible sync packet
void checkSyncNibble(); //!< check current nibble as part of sync.
void clearSyncCount(); //!< valid packet, so clear sync counters (i.e. a trailing ffff is not part of sync).
class monAttachNotify : public IComponentAttachNotifier
{
public:
monAttachNotify() { m_bInUse = false; };
virtual ~monAttachNotify() {};
virtual void attachNotify(const int num_attached) { m_bInUse = (num_attached > 0); };
const bool usingMonitor() const { return m_bInUse; };
private:
bool m_bInUse;
} mon_in_use;
};
inline const bool TrcPktProcStm::dataToProcess() const
{
// data to process if
// 1) not processed all the input bytes
// 2) there is still a nibble available from the last byte.
// 3) bytes processed, but there is a full packet to send
return (m_data_in_used < m_data_in_size) || m_nibble_2nd_valid || (m_proc_state == SEND_PKT);
}
inline void TrcPktProcStm::checkSyncNibble()
{
if(m_nibble != 0xF)
{
if(!m_sync_start)
return;
if((m_nibble == 0) && (m_num_F_nibbles >= 21))
{
m_is_sync = true; //this nibble marks a sync sequence - keep the F nibble count
}
else
{
clearSyncCount(); // clear all sync counters
}
return;
}
m_num_F_nibbles++;
if(!m_sync_start)
{
m_sync_start = true;
m_sync_index = m_packet_index + ((m_num_nibbles - 1) / 2);
}
}
inline void TrcPktProcStm::clearSyncCount()
{
m_num_F_nibbles = 0;
m_sync_start = false;
m_is_sync = false;
}
inline void TrcPktProcStm::sendPacket()
{
m_proc_state = SEND_PKT;
}
inline void TrcPktProcStm::setProcUnsynced()
{
m_proc_state = WAIT_SYNC;
m_bStreamSync = false;
}
inline void TrcPktProcStm::savePacketByte(const uint8_t val)
{
// save packet data if using monitor and synchronised.
if(mon_in_use.usingMonitor() && !m_bWaitSyncSaveSuppressed)
m_packet_data.push_back(val);
}
/** @}*/
#endif // ARM_TRC_PKT_PROC_STM_H_INCLUDED
/* End of File trc_pkt_proc_stm.h */

View File

@ -0,0 +1,158 @@
/*
* \file trc_pkt_types_stm.h
* \brief OpenCSD : STM decoder
*
* \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_TYPES_STM_H_INCLUDED
#define ARM_TRC_PKT_TYPES_STM_H_INCLUDED
#include "opencsd/trc_pkt_types.h"
/** @addtogroup trc_pkts
@{*/
/** @name STM Packet Types
@{*/
/** STM protocol packet types.
Contains both protocol packet types and markers for unsynced processor
state and bad packet sequences.
*/
typedef enum _ocsd_stm_pkt_type
{
/* markers for unknown packets / state*/
STM_PKT_NOTSYNC, /**< Not synchronised */
STM_PKT_INCOMPLETE_EOT, /**< Incomplete packet flushed at end of trace. */
STM_PKT_NO_ERR_TYPE, /**< No error in error packet marker. */
/* markers for valid packets*/
STM_PKT_ASYNC, /**< Alignment synchronisation packet */
STM_PKT_VERSION, /**< Version packet */
STM_PKT_FREQ, /**< Frequency packet */
STM_PKT_NULL, /**< Null packet */
STM_PKT_TRIG, /**< Trigger event packet. */
STM_PKT_GERR, /**< Global error packet - protocol error but unknown which master had error */
STM_PKT_MERR, /**< Master error packet - current master detected an error (e.g. dropped trace) */
STM_PKT_M8, /**< Set current master */
STM_PKT_C8, /**< Set lower 8 bits of current channel */
STM_PKT_C16, /**< Set current channel */
STM_PKT_FLAG, /**< Flag packet */
STM_PKT_D4, /**< 4 bit data payload packet */
STM_PKT_D8, /**< 8 bit data payload packet */
STM_PKT_D16, /**< 16 bit data payload packet */
STM_PKT_D32, /**< 32 bit data payload packet */
STM_PKT_D64, /**< 64 bit data payload packet */
/* packet errors.*/
STM_PKT_BAD_SEQUENCE, /**< Incorrect protocol sequence */
STM_PKT_RESERVED, /**< Reserved packet header / not supported by CS-STM */
} ocsd_stm_pkt_type;
/** STM timestamp encoding type.
Extracted from STM version packet.
CS-STM supports Natural binary and grey encodings.
*/
typedef enum _ocsd_stm_ts_type
{
STM_TS_UNKNOWN, /**< TS encoding unknown at present. */
STM_TS_NATBINARY, /**< TS encoding natural binary */
STM_TS_GREY /**< TS encoding grey coded. */
} ocsd_stm_ts_type;
/** STM trace packet
Structure containing the packet data for a single STM packet, plus
data persisting between packets (master, channel, last timestamp).
*/
typedef struct _ocsd_stm_pkt
{
ocsd_stm_pkt_type type; /**< STM packet type */
uint8_t master; /**< current master */
uint16_t channel; /**< current channel */
uint64_t timestamp; /**< latest timestamp value -> as binary - packet processor does grey decoding */
uint8_t pkt_ts_bits; /**< timestamp bits updated this packet */
uint8_t pkt_has_ts; /**< current packet has associated timestamp (ts bits can be 0 if same value as last time) */
ocsd_stm_ts_type ts_type; /**< timestamp encoding type */
uint8_t pkt_has_marker; /**< flag to indicate current packet has marker */
union {
uint8_t D8; /**< payload for D8 or D4 data packet, or parameter value for other packets with 8 bit value [VERSION, TRIG, xERR] */
uint16_t D16; /**< payload for D16 data packet, or reserved opcode in bad packet header (1-3 nibbles) */
uint32_t D32; /**< payload for D32 data packet, or parameter value for other packets with 32 bit value [FREQ] */
uint64_t D64; /**< payload for D64 data packet */
} payload;
ocsd_stm_pkt_type err_type; /**< Initial type of packet if type indicates bad sequence. */
} ocsd_stm_pkt;
/** HW Event trace feature
Defines if the STM supports or has enabled the HW event trace feature.
This may not always be able to be determined by the registers, or the feature
values can override if HW event trace is to be ignored.
*/
typedef enum _hw_event_feat {
HwEvent_Unknown_Disabled, /*!< status of HW event features not known - assume not present or disabled */
HwEvent_Enabled, /*!< HW event present and enabled - ignore Feat regs, assume hwev_mast value valid */
HwEvent_UseRegisters /*!< Feature Register values and enable bits used to determine HW event trace status */
} hw_event_feat_t;
/** STM hardware configuration.
Contains hardware register values at time of trace capture and HW event feature
field to enable and control decode of STM trace stream.
*/
typedef struct _ocsd_stm_cfg
{
uint32_t reg_tcsr; /**< Contains CoreSight trace ID, HWTEN */
uint32_t reg_feat3r; /**< defines number of masters */
uint32_t reg_devid; /**< defines number of channels per master */
uint32_t reg_feat1r; /**< defines HW trace features */
uint32_t reg_hwev_mast; /**< master ID for HW event trace */
hw_event_feat_t hw_event; /**< status of HW event trace */
} ocsd_stm_cfg;
/** @}*/
/** @}*/
#endif // ARM_TRC_PKT_TYPES_STM_H_INCLUDED
/* End of File trc_pkt_types_stm.h */

View File

@ -0,0 +1,126 @@
/*!
* \file opencsd/trc_gen_elem_types.h
* \brief OpenCSD : Decoder Output Generic Element types.
*
* \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_GEN_ELEM_TYPES_H_INCLUDED
#define ARM_TRC_GEN_ELEM_TYPES_H_INCLUDED
/** @defgroup gen_trc_elem OpenCSD Library : Generic Trace Elements
* @brief Generic trace elements output by the PE trace decode and SW stim decode stages.
*
*
@{*/
#include "opencsd/ocsd_if_types.h"
/** Enum for generic element types */
typedef enum _ocsd_gen_trc_elem_t
{
OCSD_GEN_TRC_ELEM_UNKNOWN = 0, /*!< Unknown trace element - default value or indicate error in stream to client */
OCSD_GEN_TRC_ELEM_NO_SYNC, /*!< Waiting for sync - either at start of decode, or after overflow / bad packet */
OCSD_GEN_TRC_ELEM_TRACE_ON, /*!< Start of trace - beginning of elements or restart after discontinuity (overflow, trace filtering). */
OCSD_GEN_TRC_ELEM_EO_TRACE, /*!< end of the available trace in the buffer. */
OCSD_GEN_TRC_ELEM_PE_CONTEXT, /*!< PE status update / change (arch, ctxtid, vmid etc). */
OCSD_GEN_TRC_ELEM_INSTR_RANGE, /*!< traced N consecutive instructions from addr (no intervening events or data elements), may have data assoc key */
OCSD_GEN_TRC_ELEM_ADDR_NACC, /*!< tracing in inaccessible memory area */
OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN, /*!< address currently unknown - need address packet update */
OCSD_GEN_TRC_ELEM_EXCEPTION, /*!< exception - start address may be exception target, end address may be preferred ret addr. */
OCSD_GEN_TRC_ELEM_EXCEPTION_RET, /*!< expection return */
OCSD_GEN_TRC_ELEM_TIMESTAMP, /*!< Timestamp - preceding elements happeded before this time. */
OCSD_GEN_TRC_ELEM_CYCLE_COUNT, /*!< Cycle count - cycles since last cycle count value - associated with a preceding instruction range. */
OCSD_GEN_TRC_ELEM_EVENT, /*!< Event - trigger, (TBC - perhaps have a set of event types - cut down additional processing?) */
OCSD_GEN_TRC_ELEM_SWTRACE, /*!< Software trace packet - may contain data payload. */
OCSD_GEN_TRC_ELEM_CUSTOM, /*!< Fully custom packet type - used by none-ARM architecture decoders */
} ocsd_gen_trc_elem_t;
typedef enum _trace_on_reason_t {
TRACE_ON_NORMAL = 0, /**< Trace on at start of trace or filtering discontinuity */
TRACE_ON_OVERFLOW, /**< Trace on due to prior trace overflow discontinuity */
TRACE_ON_EX_DEBUG, /**< Trace restarted due to debug exit */
} trace_on_reason_t;
typedef struct _trace_event_t {
uint16_t ev_type; /**< event type - unknown (0) trigger (1), numbered event (2)*/
uint16_t ev_number; /**< event number if numbered event type */
} trace_event_t;
typedef struct _ocsd_generic_trace_elem {
ocsd_gen_trc_elem_t elem_type; /**< Element type - remaining data interpreted according to this value */
ocsd_isa isa; /**< instruction set for executed instructions */
ocsd_vaddr_t st_addr; /**< start address for instruction execution range / inaccessible code address / data address */
ocsd_vaddr_t en_addr; /**< end address (exclusive) for instruction execution range. */
ocsd_pe_context context; /**< PE Context */
uint64_t timestamp; /**< timestamp value for TS element type */
uint32_t cycle_count; /**< cycle count for explicit cycle count element, or count for element with associated cycle count */
ocsd_instr_type last_i_type; /**< Last instruction type if instruction execution range */
ocsd_instr_subtype last_i_subtype; /**< sub type for last instruction in range */
//! per element flags
union {
struct {
uint32_t last_instr_exec:1; /**< 1 if last instruction in range was executed; */
uint32_t has_cc:1; /**< 1 if this packet has a valid cycle count included (e.g. cycle count included as part of instruction range packet, always 1 for pure cycle count packet.*/
uint32_t cpu_freq_change:1; /**< 1 if this packet indicates a change in CPU frequency */
uint32_t excep_ret_addr:1; /**< 1 if en_addr is the preferred exception return address on exception packet type */
uint32_t excep_data_marker:1; /**< 1 if the exception entry packet is a data push marker only, with no address information (used typically in v7M trace for marking data pushed onto stack) */
uint32_t extended_data:1; /**< 1 if the packet extended data pointer is valid. Allows packet extensions for custom decoders, or additional data payloads for data trace. */
uint32_t has_ts:1; /**< 1 if the packet has an associated timestamp - e.g. SW/STM trace TS+Payload as a single packet */
};
uint32_t flag_bits;
};
//! packet specific payloads
union {
uint32_t exception_number; /**< exception number for exception type packets */
trace_event_t trace_event; /**< Trace event - trigger etc */
trace_on_reason_t trace_on_reason; /**< reason for the trace on packet */
ocsd_swt_info_t sw_trace_info; /**< software trace packet info */
};
const void *ptr_extended_data; /**< pointer to extended data buffer (data trace, sw trace payload) / custom structure */
} ocsd_generic_trace_elem;
typedef enum _event_t {
EVENT_UNKNOWN = 0,
EVENT_TRIGGER,
EVENT_NUMBERED
} event_t;
/** @}*/
#endif // ARM_TRC_GEN_ELEM_TYPES_H_INCLUDED
/* End of File opencsd/trc_gen_elem_types.h */

View File

@ -0,0 +1,137 @@
/*!
* \file opencsd/trc_pkt_types.h
* \brief OpenCSD: Common "C" types for trace packets.
*
* \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_TYPES_H_INCLUDED
#define ARM_TRC_PKT_TYPES_H_INCLUDED
#include <stdint.h>
#include "opencsd/ocsd_if_types.h"
/** @defgroup trc_pkts OpenCSD Library : Trace Packet Types
@brief Types used in trace packet description structures.
@{*/
/** @name Common Packet Types
@{*/
typedef enum _ocsd_pkt_va_size
{
VA_32BIT,
VA_64BIT
} ocsd_pkt_va_size;
typedef struct _ocsd_pkt_vaddr
{
ocsd_pkt_va_size size; /**< Virtual address size. */
ocsd_vaddr_t val; /**< Current value */
uint8_t pkt_bits; /**< Bits updated this packet */
uint8_t valid_bits; /**< Currently valid bits */
} ocsd_pkt_vaddr;
typedef struct _ocsd_pkt_byte_sz_val
{
uint32_t val;
uint8_t size_bytes;
uint8_t valid_bytes;
} ocsd_pkt_byte_sz_val;
typedef enum _ocsd_pkt_atm_type
{
ATOM_PATTERN, /**< set atom packet using pattern supplied */
ATOM_REPEAT /**< set atom packet using repeat value (convert to pattern) */
} ocsd_pkt_atm_type;
typedef enum _ocsd_atm_val {
ATOM_N,
ATOM_E
} ocsd_atm_val;
typedef struct _ocsd_pkt_atom
{
/** pattern across num bits.
Bit sequence:- ls bit = oldest atom (1st instruction executed), ms bit = newest (last instruction executed),
Bit values :- 1'b1 = E atom, 1'b0 = N atom.
*/
uint32_t En_bits;
uint8_t num; /**< number of atoms represented */
} ocsd_pkt_atom;
/** Isync Reason - common to PTM and ETMv3 **/
typedef enum _ocsd_iSync_reason {
iSync_Periodic = 0,
iSync_TraceEnable,
iSync_TraceRestartAfterOverflow,
iSync_DebugExit
} ocsd_iSync_reason;
typedef enum _ocsd_armv7_exception {
Excp_Reserved,
Excp_NoException,
Excp_Reset,
Excp_IRQ,
Excp_FIQ,
Excp_AsyncDAbort,
Excp_DebugHalt,
Excp_Jazelle,
Excp_SVC,
Excp_SMC,
Excp_Hyp,
Excp_Undef,
Excp_PrefAbort,
Excp_Generic,
Excp_SyncDataAbort,
Excp_CMUsageFault,
Excp_CMNMI,
Excp_CMDebugMonitor,
Excp_CMMemManage,
Excp_CMPendSV,
Excp_CMSysTick,
Excp_CMBusFault,
Excp_CMHardFault,
Excp_CMIRQn,
Excp_ThumbEECheckFail,
} ocsd_armv7_exception;
/** @}*/
/** @}*/
#endif // ARM_TRC_PKT_TYPES_H_INCLUDED
/* End of File opencsd/trc_pkt_types.h */

View File

@ -0,0 +1,95 @@
/*
* \file gen_elem_printer.h
* \brief OpenCSD : Generic element printer class.
*
* \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_GEN_ELEM_PRINTER_H_INCLUDED
#define ARM_GEN_ELEM_PRINTER_H_INCLUDED
#include "opencsd.h"
class TrcGenericElementPrinter : public ItemPrinter, public ITrcGenElemIn
{
public:
TrcGenericElementPrinter();
virtual ~TrcGenericElementPrinter() {};
virtual ocsd_datapath_resp_t TraceElemIn(const ocsd_trc_index_t index_sop,
const uint8_t trc_chan_id,
const OcsdTraceElement &elem);
// funtionality to test wait / flush mechanism
void ackWait() { m_needWaitAck = false; };
const bool needAckWait() const { return m_needWaitAck; };
protected:
bool m_needWaitAck;
};
inline TrcGenericElementPrinter::TrcGenericElementPrinter() :
m_needWaitAck(false)
{
}
inline ocsd_datapath_resp_t TrcGenericElementPrinter::TraceElemIn(const ocsd_trc_index_t index_sop,
const uint8_t trc_chan_id,
const OcsdTraceElement &elem)
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
std::string elemStr;
std::ostringstream oss;
oss << "Idx:" << index_sop << "; ID:"<< std::hex << (uint32_t)trc_chan_id << "; ";
elem.toString(elemStr);
oss << elemStr << std::endl;
itemPrintLine(oss.str());
// funtionality to test wait / flush mechanism
if(m_needWaitAck)
{
oss.str("");
oss << "WARNING: Generic Element Printer; New element without previous _WAIT acknowledged\n";
itemPrintLine(oss.str());
m_needWaitAck = false;
}
if(getTestWaits())
{
resp = OCSD_RESP_WAIT; // return _WAIT for the 1st N packets.
decTestWaits();
m_needWaitAck = true;
}
return resp;
}
#endif // ARM_GEN_ELEM_PRINTER_H_INCLUDED
/* End of File gen_elem_printer.h */

View File

@ -0,0 +1,94 @@
/*
* \file item_printer.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_ITEM_PRINTER_H_INCLUDED
#define ARM_ITEM_PRINTER_H_INCLUDED
#include "opencsd.h"
#include <string>
class ItemPrinter
{
public:
ItemPrinter();
virtual ~ItemPrinter();
void setMessageLogger(ocsdMsgLogger *pMsgLogger) { m_pMsgLogger = pMsgLogger; };
void itemPrintLine(const std::string &msg);
// return wait for the first N packets - test the wait mechanism.
void setTestWaits(const int num_waits);
const int getTestWaits() const;
void decTestWaits();
protected:
ocsdMsgLogger *m_pMsgLogger;
int m_test_waits;
};
inline ItemPrinter::ItemPrinter() :
m_pMsgLogger(0),
m_test_waits(0)
{
}
inline ItemPrinter::~ItemPrinter()
{
m_pMsgLogger = 0;
}
inline void ItemPrinter::itemPrintLine(const std::string &msg)
{
if(m_pMsgLogger)
m_pMsgLogger->LogMsg(msg);
}
inline void ItemPrinter::setTestWaits(const int num_waits)
{
m_test_waits = num_waits;
}
inline const int ItemPrinter::getTestWaits() const
{
return m_test_waits;
}
inline void ItemPrinter::decTestWaits()
{
m_test_waits--;
}
#endif // ARM_ITEM_PRINTER_H_INCLUDED
/* End of File item_printer.h */

View File

@ -0,0 +1,189 @@
/*
* \file pkt_printer_t.h
* \brief OpenCSD : Test packet printer.
*
* \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_PKT_PRINTER_T_H_INCLUDED
#define ARM_PKT_PRINTER_T_H_INCLUDED
#include "opencsd.h"
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>
template<class P>
class PacketPrinter : public IPktDataIn<P>, public IPktRawDataMon<P>, public ItemPrinter
{
public:
PacketPrinter(const uint8_t trcID);
PacketPrinter(const uint8_t trcID, ocsdMsgLogger *pMsgLogger);
virtual ~PacketPrinter();
virtual ocsd_datapath_resp_t PacketDataIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const P *p_packet_in);
virtual void RawPacketDataMon( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const P *pkt,
const uint32_t size,
const uint8_t *p_data);
private:
void printIdx_ID(const ocsd_trc_index_t index_sop);
uint8_t m_trcID;
bool m_bRawPrint;
std::ostringstream m_oss;
ocsd_datapath_resp_t m_last_resp;
};
template<class P> PacketPrinter<P>::PacketPrinter(uint8_t trcID) :
m_trcID(trcID),
m_bRawPrint(false),
m_last_resp(OCSD_RESP_CONT)
{
}
template<class P> PacketPrinter<P>::PacketPrinter(const uint8_t trcID, ocsdMsgLogger *pMsgLogger) :
m_trcID(trcID),
m_bRawPrint(false),
m_last_resp(OCSD_RESP_CONT)
{
setMessageLogger(pMsgLogger);
}
template<class P> PacketPrinter<P>::~PacketPrinter()
{
}
template<class P> ocsd_datapath_resp_t PacketPrinter<P>::PacketDataIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const P *p_packet_in)
{
std::string pktstr;
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
// wait / flush test verification
if(!m_bRawPrint && (m_last_resp == OCSD_RESP_WAIT))
{
// expect a flush or a complete reset after a wait.
if((op != OCSD_OP_FLUSH) || (op != OCSD_OP_RESET))
{
m_oss <<"ID:"<< std::hex << (uint32_t)m_trcID << "\tERROR: FLUSH operation expected after wait on trace decode path\n";
itemPrintLine(m_oss.str());
m_oss.str("");
return OCSD_RESP_FATAL_INVALID_OP;
}
}
switch(op)
{
case OCSD_OP_DATA:
p_packet_in->toString(pktstr);
if(!m_bRawPrint)
printIdx_ID(index_sop);
m_oss << ";\t" << pktstr << std::endl;
// test the wait/flush response mechnism
if(getTestWaits() && !m_bRawPrint)
{
decTestWaits();
resp = OCSD_RESP_WAIT;
}
break;
case OCSD_OP_EOT:
m_oss <<"ID:"<< std::hex << (uint32_t)m_trcID << "\tEND OF TRACE DATA\n";
break;
case OCSD_OP_FLUSH:
m_oss <<"ID:"<< std::hex << (uint32_t)m_trcID << "\tFLUSH operation on trace decode path\n";
break;
case OCSD_OP_RESET:
m_oss <<"ID:"<< std::hex << (uint32_t)m_trcID << "\tRESET operation on trace decode path\n";
break;
}
m_last_resp = resp;
itemPrintLine(m_oss.str());
m_oss.str("");
return resp;
}
template<class P> void PacketPrinter<P>::RawPacketDataMon( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const P *pkt,
const uint32_t size,
const uint8_t *p_data)
{
switch(op)
{
case OCSD_OP_DATA:
printIdx_ID(index_sop);
m_oss << "; [";
if((size > 0) && (p_data != 0))
{
uint32_t data = 0;
for(uint32_t i = 0; i < size; i++)
{
data = (uint32_t)(p_data[i] & 0xFF);
m_oss << "0x" << std::hex << std::setw(2) << std::setfill('0') << data << " ";
}
}
m_oss << "]";
m_bRawPrint = true;
PacketDataIn(op,index_sop,pkt);
m_bRawPrint = false;
break;
default:
PacketDataIn(op,index_sop,pkt);
break;
}
}
template<class P> void PacketPrinter<P>::printIdx_ID(const ocsd_trc_index_t index_sop)
{
m_oss << "Idx:" << std::dec << index_sop << "; ID:"<< std::hex << (uint32_t)m_trcID;
}
#endif // ARM_PKT_PRINTER_T_H_INCLUDED
/* End of File pkt_printer_t.h */

View File

@ -0,0 +1,69 @@
/*
* \file raw_frame_printer.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_RAW_FRAME_PRINTER_H_INCLUDED
#define ARM_RAW_FRAME_PRINTER_H_INCLUDED
#include "opencsd.h"
#include <string>
#include <sstream>
class RawFramePrinter : public ITrcRawFrameIn, public ItemPrinter
{
public:
RawFramePrinter() {};
RawFramePrinter(ocsdMsgLogger *pMsgLogger);
virtual ~RawFramePrinter() {};
virtual ocsd_err_t TraceRawFrameIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index,
const ocsd_rawframe_elem_t frame_element,
const int dataBlockSize,
const uint8_t *pDataBlock,
const uint8_t traceID);
private:
void createDataString(const int dataSize, const uint8_t *pData, int bytesPerLine, std::string &dataStr);
};
inline RawFramePrinter::RawFramePrinter(ocsdMsgLogger *pMsgLogger)
{
setMessageLogger(pMsgLogger);
}
#endif // ARM_RAW_FRAME_PRINTER_H_INCLUDED
/* End of File raw_frame_printer.h */

View File

@ -0,0 +1,43 @@
/*
* \file trc_pkt_printers.h
* \brief OpenCSD : Known protocol packet printers.
*
* \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_PRINTERS_H_INCLUDED
#define ARM_TRC_PKT_PRINTERS_H_INCLUDED
#include "pkt_printers/item_printer.h"
#include "pkt_printers/pkt_printer_t.h"
#include "pkt_printers/gen_elem_printer.h"
#include "pkt_printers/raw_frame_printer.h"
#endif // ARM_TRC_PKT_PRINTERS_H_INCLUDED

View File

@ -0,0 +1,60 @@
/*
* \file trc_print_fact.h
* \brief OpenCSD : Factory for protocol packet printers.
*
* \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_PRINT_FACT_H_INCLUDED
#define ARM_TRC_PRINT_FACT_H_INCLUDED
#include "opencsd.h"
class PktPrinterFact
{
public:
static ItemPrinter *createProtocolPrinter(std::vector<ItemPrinter *> &printer_list, ocsd_trace_protocol_t protocol, uint8_t elemID, ocsdMsgLogger *pMsgLogger = 0);
static RawFramePrinter *createRawFramePrinter(std::vector<ItemPrinter *> &printer_list, ocsdMsgLogger *pMsgLogger = 0);
static TrcGenericElementPrinter *createGenElemPrinter(std::vector<ItemPrinter *> &printer_list, ocsdMsgLogger *pMsgLogger = 0);
static void destroyPrinter(std::vector<ItemPrinter *> &printer_list, ItemPrinter *pPrinter);
static void destroyAllPrinters(std::vector<ItemPrinter *> &printer_list);
static const int numPrinters(std::vector<ItemPrinter *> &printer_list);
private:
static void SavePrinter(std::vector<ItemPrinter *> &printer_list, ItemPrinter *pPrinter, ocsdMsgLogger *pMsgLogger);
PktPrinterFact() {};
~PktPrinterFact() {};
};
#endif // ARM_TRC_PRINT_FACT_H_INCLUDED
/* end of file trc_print_fact.h */

View File

@ -0,0 +1,572 @@
/*
* \file ocsd_c_api.cpp
* \brief OpenCSD : "C" API libary implementation.
*
* \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstring>
/* pull in the C++ decode library */
#include "opencsd.h"
/* C-API and wrapper objects */
#include "opencsd/c_api/opencsd_c_api.h"
#include "ocsd_c_api_obj.h"
/** MSVC2010 unwanted export workaround */
#ifdef WIN32
#if (_MSC_VER == 1600)
#include <new>
namespace std { const nothrow_t nothrow = nothrow_t(); }
#endif
#endif
/*******************************************************************************/
/* C API internal helper function declarations */
/*******************************************************************************/
static ocsd_err_t ocsd_create_pkt_sink_cb(ocsd_trace_protocol_t protocol, FnDefPktDataIn pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj );
static ocsd_err_t ocsd_create_pkt_mon_cb(ocsd_trace_protocol_t protocol, FnDefPktDataMon pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj );
static ocsd_err_t ocsd_check_and_add_mem_acc_mapper(const dcd_tree_handle_t handle, DecodeTree **ppDT);
/*******************************************************************************/
/* C library data - additional data on top of the C++ library objects */
/*******************************************************************************/
/* keep a list of interface objects for a decode tree for later disposal */
typedef struct _lib_dt_data_list {
std::vector<ITrcTypedBase *> cb_objs;
DefLogStrCBObj s_def_log_str_cb;
} lib_dt_data_list;
/* map lists to handles */
static std::map<dcd_tree_handle_t, lib_dt_data_list *> s_data_map;
/*******************************************************************************/
/* C API functions */
/*******************************************************************************/
/** Get Library version. Return a 32 bit version in form MMMMnnpp - MMMM = major verison, nn = minor version, pp = patch version */
OCSD_C_API uint32_t ocsd_get_version(void)
{
return ocsdVersion::vers_num();
}
/** Get library version string */
OCSD_C_API const char * ocsd_get_version_str(void)
{
return ocsdVersion::vers_str();
}
/*** Decode tree creation etc. */
OCSD_C_API dcd_tree_handle_t ocsd_create_dcd_tree(const ocsd_dcd_tree_src_t src_type, const uint32_t deformatterCfgFlags)
{
dcd_tree_handle_t handle = C_API_INVALID_TREE_HANDLE;
handle = (dcd_tree_handle_t)DecodeTree::CreateDecodeTree(src_type,deformatterCfgFlags);
if(handle != C_API_INVALID_TREE_HANDLE)
{
lib_dt_data_list *pList = new (std::nothrow) lib_dt_data_list;
if(pList != 0)
{
s_data_map.insert(std::pair<dcd_tree_handle_t, lib_dt_data_list *>(handle,pList));
}
else
{
ocsd_destroy_dcd_tree(handle);
handle = C_API_INVALID_TREE_HANDLE;
}
}
return handle;
}
OCSD_C_API void ocsd_destroy_dcd_tree(const dcd_tree_handle_t handle)
{
if(handle != C_API_INVALID_TREE_HANDLE)
{
GenTraceElemCBObj * pIf = (GenTraceElemCBObj *)(((DecodeTree *)handle)->getGenTraceElemOutI());
if(pIf != 0)
delete pIf;
/* need to clear any associated callback data. */
std::map<dcd_tree_handle_t, lib_dt_data_list *>::iterator it;
it = s_data_map.find(handle);
if(it != s_data_map.end())
{
std::vector<ITrcTypedBase *>::iterator itcb;
itcb = it->second->cb_objs.begin();
while(itcb != it->second->cb_objs.end())
{
delete *itcb;
itcb++;
}
it->second->cb_objs.clear();
delete it->second;
s_data_map.erase(it);
}
DecodeTree::DestroyDecodeTree((DecodeTree *)handle);
}
}
/*** Decode tree process data */
OCSD_C_API ocsd_datapath_resp_t ocsd_dt_process_data(const dcd_tree_handle_t handle,
const ocsd_datapath_op_t op,
const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed)
{
ocsd_datapath_resp_t resp = OCSD_RESP_FATAL_NOT_INIT;
if(handle != C_API_INVALID_TREE_HANDLE)
resp = ((DecodeTree *)handle)->TraceDataIn(op,index,dataBlockSize,pDataBlock,numBytesProcessed);
return resp;
}
/*** Decode tree - decoder management */
OCSD_C_API ocsd_err_t ocsd_dt_create_decoder(const dcd_tree_handle_t handle,
const char *decoder_name,
const int create_flags,
const void *decoder_cfg,
unsigned char *pCSID
)
{
ocsd_err_t err = OCSD_OK;
DecodeTree *dt = (DecodeTree *)handle;
std::string dName = decoder_name;
IDecoderMngr *pDcdMngr;
err = OcsdLibDcdRegister::getDecoderRegister()->getDecoderMngrByName(dName,&pDcdMngr);
if(err != OCSD_OK)
return err;
CSConfig *pConfig = 0;
err = pDcdMngr->createConfigFromDataStruct(&pConfig,decoder_cfg);
if(err != OCSD_OK)
return err;
err = dt->createDecoder(dName,create_flags,pConfig);
if(err == OCSD_OK)
*pCSID = pConfig->getTraceID();
delete pConfig;
return err;
}
OCSD_C_API ocsd_err_t ocsd_dt_remove_decoder( const dcd_tree_handle_t handle,
const unsigned char CSID)
{
return ((DecodeTree *)handle)->removeDecoder(CSID);
}
OCSD_C_API ocsd_err_t ocsd_dt_attach_packet_callback( const dcd_tree_handle_t handle,
const unsigned char CSID,
const ocsd_c_api_cb_types callback_type,
void *p_fn_callback_data,
const void *p_context)
{
ocsd_err_t err = OCSD_OK;
DecodeTree *pDT = static_cast<DecodeTree *>(handle);
DecodeTreeElement *pElem = pDT->getDecoderElement(CSID);
if(pElem == 0)
return OCSD_ERR_INVALID_ID; // cannot find entry for that CSID
ITrcTypedBase *pDataInSink = 0; // pointer to a sink callback object
switch(callback_type)
{
case OCSD_C_API_CB_PKT_SINK:
err = ocsd_create_pkt_sink_cb(pElem->getProtocol(),(FnDefPktDataIn)p_fn_callback_data,p_context,&pDataInSink);
if(err == OCSD_OK)
err = pElem->getDecoderMngr()->attachPktSink(pElem->getDecoderHandle(), pDataInSink);
break;
case OCSD_C_API_CB_PKT_MON:
err = ocsd_create_pkt_mon_cb(pElem->getProtocol(),(FnDefPktDataMon)p_fn_callback_data,p_context,&pDataInSink);
if (err == OCSD_OK)
err = pElem->getDecoderMngr()->attachPktMonitor(pElem->getDecoderHandle(), pDataInSink);
break;
default:
err = OCSD_ERR_INVALID_PARAM_VAL;
}
if(err == OCSD_OK)
{
if (err == OCSD_OK)
{
// save object pointer for destruction later.
std::map<dcd_tree_handle_t, lib_dt_data_list *>::iterator it;
it = s_data_map.find(handle);
if (it != s_data_map.end())
it->second->cb_objs.push_back(pDataInSink);
}
else
delete pDataInSink;
}
return err;
}
/*** Decode tree set element output */
OCSD_C_API ocsd_err_t ocsd_dt_set_gen_elem_outfn(const dcd_tree_handle_t handle, FnTraceElemIn pFn, const void *p_context)
{
GenTraceElemCBObj * pCBObj = new (std::nothrow)GenTraceElemCBObj(pFn, p_context);
if(pCBObj)
{
((DecodeTree *)handle)->setGenTraceElemOutI(pCBObj);
return OCSD_OK;
}
return OCSD_ERR_MEM;
}
/*** Default error logging */
OCSD_C_API ocsd_err_t ocsd_def_errlog_init(const ocsd_err_severity_t verbosity, const int create_output_logger)
{
if(DecodeTree::getDefaultErrorLogger()->initErrorLogger(verbosity,(bool)(create_output_logger != 0)))
return OCSD_OK;
return OCSD_ERR_NOT_INIT;
}
OCSD_C_API ocsd_err_t ocsd_def_errlog_config_output(const int output_flags, const char *log_file_name)
{
ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger();
if(pLogger)
{
pLogger->setLogOpts(output_flags & C_API_MSGLOGOUT_MASK);
if(log_file_name != NULL)
{
pLogger->setLogFileName(log_file_name);
}
return OCSD_OK;
}
return OCSD_ERR_NOT_INIT;
}
OCSD_C_API ocsd_err_t ocsd_def_errlog_set_strprint_cb(const dcd_tree_handle_t handle, void *p_context, FnDefLoggerPrintStrCB p_str_print_cb)
{
ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger();
if (pLogger)
{
std::map<dcd_tree_handle_t, lib_dt_data_list *>::iterator it;
it = s_data_map.find(handle);
if (it != s_data_map.end())
{
DefLogStrCBObj *pCBObj = &(it->second->s_def_log_str_cb);
pCBObj->setCBFn(p_context, p_str_print_cb);
pLogger->setStrOutFn(pCBObj);
int logOpts = pLogger->getLogOpts();
logOpts |= (int)(ocsdMsgLogger::OUT_STR_CB);
pLogger->setLogOpts(logOpts);
return OCSD_OK;
}
}
return OCSD_ERR_NOT_INIT;
}
OCSD_C_API void ocsd_def_errlog_msgout(const char *msg)
{
ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger();
if(pLogger)
pLogger->LogMsg(msg);
}
/*** Convert packet to string */
OCSD_C_API ocsd_err_t ocsd_pkt_str(const ocsd_trace_protocol_t pkt_protocol, const void *p_pkt, char *buffer, const int buffer_size)
{
ocsd_err_t err = OCSD_OK;
if((buffer == NULL) || (buffer_size < 2))
return OCSD_ERR_INVALID_PARAM_VAL;
std::string pktStr = "";
buffer[0] = 0;
switch(pkt_protocol)
{
case OCSD_PROTOCOL_ETMV4I:
trcPrintElemToString<EtmV4ITrcPacket,ocsd_etmv4_i_pkt>(p_pkt, pktStr);
break;
case OCSD_PROTOCOL_ETMV3:
trcPrintElemToString<EtmV3TrcPacket,ocsd_etmv3_pkt>(p_pkt, pktStr);
break;
case OCSD_PROTOCOL_STM:
trcPrintElemToString<StmTrcPacket,ocsd_stm_pkt>(p_pkt, pktStr);
break;
case OCSD_PROTOCOL_PTM:
trcPrintElemToString<PtmTrcPacket,ocsd_ptm_pkt>(p_pkt, pktStr);
break;
default:
if (OCSD_PROTOCOL_IS_CUSTOM(pkt_protocol))
err = ocsd_cust_protocol_to_str(pkt_protocol, p_pkt, buffer, buffer_size);
else
err = OCSD_ERR_NO_PROTOCOL;
break;
}
if(pktStr.size() > 0)
{
strncpy(buffer,pktStr.c_str(),buffer_size-1);
buffer[buffer_size-1] = 0;
}
return err;
}
OCSD_C_API ocsd_err_t ocsd_gen_elem_str(const ocsd_generic_trace_elem *p_pkt, char *buffer, const int buffer_size)
{
ocsd_err_t err = OCSD_OK;
if((buffer == NULL) || (buffer_size < 2))
return OCSD_ERR_INVALID_PARAM_VAL;
std::string str;
trcPrintElemToString<OcsdTraceElement,ocsd_generic_trace_elem>(p_pkt,str);
if(str.size() > 0)
{
strncpy(buffer,str.c_str(),buffer_size -1);
buffer[buffer_size-1] = 0;
}
return err;
}
/*** Decode tree -- memory accessor control */
OCSD_C_API ocsd_err_t ocsd_dt_add_binfile_mem_acc(const dcd_tree_handle_t handle, const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const char *filepath)
{
ocsd_err_t err = OCSD_OK;
DecodeTree *pDT;
err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT);
if(err == OCSD_OK)
err = pDT->addBinFileMemAcc(address,mem_space,filepath);
return err;
}
OCSD_C_API ocsd_err_t ocsd_dt_add_binfile_region_mem_acc(const dcd_tree_handle_t handle, const ocsd_file_mem_region_t *region_array, const int num_regions, const ocsd_mem_space_acc_t mem_space, const char *filepath)
{
ocsd_err_t err = OCSD_OK;
DecodeTree *pDT;
err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT);
if(err == OCSD_OK)
err = pDT->addBinFileRegionMemAcc(region_array,num_regions,mem_space,filepath);
return err;
}
OCSD_C_API ocsd_err_t ocsd_dt_add_buffer_mem_acc(const dcd_tree_handle_t handle, const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t *p_mem_buffer, const uint32_t mem_length)
{
ocsd_err_t err = OCSD_OK;
DecodeTree *pDT;
err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT);
if(err == OCSD_OK)
err = pDT->addBufferMemAcc(address,mem_space,p_mem_buffer,mem_length);
return err;
}
OCSD_C_API ocsd_err_t ocsd_dt_add_callback_mem_acc(const dcd_tree_handle_t handle, const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, const ocsd_mem_space_acc_t mem_space, Fn_MemAcc_CB p_cb_func, const void *p_context)
{
ocsd_err_t err = OCSD_OK;
DecodeTree *pDT;
err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT);
if(err == OCSD_OK)
err = pDT->addCallbackMemAcc(st_address,en_address,mem_space,p_cb_func,p_context);
return err;
}
OCSD_C_API ocsd_err_t ocsd_dt_remove_mem_acc(const dcd_tree_handle_t handle, const ocsd_vaddr_t st_address, const ocsd_mem_space_acc_t mem_space)
{
ocsd_err_t err = OCSD_OK;
if(handle != C_API_INVALID_TREE_HANDLE)
{
DecodeTree *pDT = static_cast<DecodeTree *>(handle);
err = pDT->removeMemAccByAddress(st_address,mem_space);
}
else
err = OCSD_ERR_INVALID_PARAM_VAL;
return err;
}
OCSD_C_API void ocsd_tl_log_mapped_mem_ranges(const dcd_tree_handle_t handle)
{
if(handle != C_API_INVALID_TREE_HANDLE)
{
DecodeTree *pDT = static_cast<DecodeTree *>(handle);
pDT->logMappedRanges();
}
}
OCSD_C_API void ocsd_gen_elem_init(ocsd_generic_trace_elem *p_pkt, const ocsd_gen_trc_elem_t elem_type)
{
p_pkt->elem_type = elem_type;
p_pkt->flag_bits = 0;
p_pkt->ptr_extended_data = 0;
}
OCSD_C_API ocsd_err_t ocsd_dt_set_raw_frame_printer(const dcd_tree_handle_t handle, int flags)
{
if (handle != C_API_INVALID_TREE_HANDLE)
return ((DecodeTree *)handle)->addRawFramePrinter(0, (uint32_t)flags);
return OCSD_ERR_NOT_INIT;
}
OCSD_C_API ocsd_err_t ocsd_dt_set_gen_elem_printer(const dcd_tree_handle_t handle)
{
if (handle != C_API_INVALID_TREE_HANDLE)
return ((DecodeTree *)handle)->addGenElemPrinter(0);
return OCSD_ERR_NOT_INIT;
}
OCSD_C_API ocsd_err_t ocsd_dt_set_pkt_protocol_printer(const dcd_tree_handle_t handle, uint8_t cs_id, int monitor)
{
ocsd_err_t err = OCSD_ERR_NOT_INIT;
if (handle != C_API_INVALID_TREE_HANDLE)
{
DecodeTree *p_tree = (DecodeTree *)handle;
err = p_tree->addPacketPrinter(cs_id, (bool)(monitor != 0), 0);
}
return err;
}
/*******************************************************************************/
/* C API local fns */
/*******************************************************************************/
static ocsd_err_t ocsd_create_pkt_sink_cb(ocsd_trace_protocol_t protocol, FnDefPktDataIn pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj )
{
ocsd_err_t err = OCSD_OK;
*ppCBObj = 0;
switch(protocol)
{
case OCSD_PROTOCOL_ETMV4I:
*ppCBObj = new (std::nothrow) PktCBObj<EtmV4ITrcPacket>(pPktInFn,p_context);
break;
case OCSD_PROTOCOL_ETMV3:
*ppCBObj = new (std::nothrow) PktCBObj<EtmV3TrcPacket>(pPktInFn,p_context);
break;
case OCSD_PROTOCOL_PTM:
*ppCBObj = new (std::nothrow) PktCBObj<PtmTrcPacket>(pPktInFn,p_context);
break;
case OCSD_PROTOCOL_STM:
*ppCBObj = new (std::nothrow) PktCBObj<StmTrcPacket>(pPktInFn,p_context);
break;
default:
if ((protocol >= OCSD_PROTOCOL_CUSTOM_0) && (protocol < OCSD_PROTOCOL_END))
{
*ppCBObj = new (std::nothrow) PktCBObj<void>(pPktInFn, p_context);
}
else
err = OCSD_ERR_NO_PROTOCOL;
break;
}
if((*ppCBObj == 0) && (err == OCSD_OK))
err = OCSD_ERR_MEM;
return err;
}
static ocsd_err_t ocsd_create_pkt_mon_cb(ocsd_trace_protocol_t protocol, FnDefPktDataMon pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj )
{
ocsd_err_t err = OCSD_OK;
*ppCBObj = 0;
switch(protocol)
{
case OCSD_PROTOCOL_ETMV4I:
*ppCBObj = new (std::nothrow) PktMonCBObj<EtmV4ITrcPacket>(pPktInFn,p_context);
break;
case OCSD_PROTOCOL_ETMV3:
*ppCBObj = new (std::nothrow) PktMonCBObj<EtmV3TrcPacket>(pPktInFn,p_context);
break;
case OCSD_PROTOCOL_PTM:
*ppCBObj = new (std::nothrow) PktMonCBObj<PtmTrcPacket>(pPktInFn,p_context);
break;
case OCSD_PROTOCOL_STM:
*ppCBObj = new (std::nothrow) PktMonCBObj<StmTrcPacket>(pPktInFn,p_context);
break;
default:
if ((protocol >= OCSD_PROTOCOL_CUSTOM_0) && (protocol < OCSD_PROTOCOL_END))
{
*ppCBObj = new (std::nothrow) PktMonCBObj<void>(pPktInFn, p_context);
}
else
err = OCSD_ERR_NO_PROTOCOL;
break;
}
if((*ppCBObj == 0) && (err == OCSD_OK))
err = OCSD_ERR_MEM;
return err;
}
static ocsd_err_t ocsd_check_and_add_mem_acc_mapper(const dcd_tree_handle_t handle, DecodeTree **ppDT)
{
*ppDT = 0;
if(handle == C_API_INVALID_TREE_HANDLE)
return OCSD_ERR_INVALID_PARAM_VAL;
*ppDT = static_cast<DecodeTree *>(handle);
if(!(*ppDT)->hasMemAccMapper())
return (*ppDT)->createMemAccMapper();
return OCSD_OK;
}
/*******************************************************************************/
/* C API Helper objects */
/*******************************************************************************/
/****************** Generic trace element output callback function ************/
GenTraceElemCBObj::GenTraceElemCBObj(FnTraceElemIn pCBFn, const void *p_context) :
m_c_api_cb_fn(pCBFn),
m_p_cb_context(p_context)
{
}
ocsd_datapath_resp_t GenTraceElemCBObj::TraceElemIn(const ocsd_trc_index_t index_sop,
const uint8_t trc_chan_id,
const OcsdTraceElement &elem)
{
return m_c_api_cb_fn(m_p_cb_context, index_sop, trc_chan_id, &elem);
}
/* End of File ocsd_c_api.cpp */

View File

@ -0,0 +1,431 @@
/*
* \file ocsd_c_api_custom_obj.cpp
* \brief OpenCSD :
*
* \copyright Copyright (c) 2016, 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.
*/
/* pull in the C++ decode library */
#include "opencsd.h"
#include "opencsd/c_api/opencsd_c_api.h"
#include "ocsd_c_api_custom_obj.h"
#include "common/ocsd_lib_dcd_register.h"
/***************** C-API functions ********************************/
/** register a custom decoder with the library */
OCSD_C_API ocsd_err_t ocsd_register_custom_decoder(const char *name, ocsd_extern_dcd_fact_t *p_dcd_fact)
{
ocsd_err_t err = OCSD_OK;
OcsdLibDcdRegister *pRegister = OcsdLibDcdRegister::getDecoderRegister();
// check not already registered
if(pRegister->isRegisteredDecoder(name))
return OCSD_ERR_DCDREG_NAME_REPEAT;
// validate the factory interface structure
if((p_dcd_fact->createDecoder == 0) ||
(p_dcd_fact->destroyDecoder == 0) ||
(p_dcd_fact->csidFromConfig == 0)
)
return OCSD_ERR_INVALID_PARAM_VAL;
// create a wrapper.
CustomDcdMngrWrapper *pWrapper = new (std::nothrow) CustomDcdMngrWrapper();
if(pRegister == 0)
return OCSD_ERR_MEM;
p_dcd_fact->protocol_id = OcsdLibDcdRegister::getNextCustomProtocolID();
if(p_dcd_fact->protocol_id < OCSD_PROTOCOL_END)
{
// fill out the wrapper and register it
pWrapper->setAPIDcdFact(p_dcd_fact);
err = pRegister->registerDecoderTypeByName(name,pWrapper);
if(err != OCSD_OK)
OcsdLibDcdRegister::releaseLastCustomProtocolID();
}
else
err = OCSD_ERR_DCDREG_TOOMANY; // too many decoders
if(err != OCSD_OK)
delete pWrapper;
return err;
}
OCSD_C_API ocsd_err_t ocsd_deregister_decoders()
{
// destroys all builtin and custom decoders & library registration object.
OcsdLibDcdRegister::deregisterAllDecoders();
return OCSD_OK;
}
OCSD_C_API ocsd_err_t ocsd_cust_protocol_to_str(const ocsd_trace_protocol_t pkt_protocol, const void *trc_pkt, char *buffer, const int buflen)
{
OcsdLibDcdRegister *pRegister = OcsdLibDcdRegister::getDecoderRegister();
IDecoderMngr *p_mngr = 0;
if (OCSD_PROTOCOL_IS_CUSTOM(pkt_protocol) && (pRegister->getDecoderMngrByType(pkt_protocol, &p_mngr) == OCSD_OK))
{
CustomDcdMngrWrapper *pWrapper = static_cast<CustomDcdMngrWrapper *>(p_mngr);
pWrapper->pktToString(trc_pkt, buffer, buflen);
return OCSD_OK;
}
return OCSD_ERR_NO_PROTOCOL;
}
/***************** Decode Manager Wrapper *****************************/
CustomDcdMngrWrapper::CustomDcdMngrWrapper()
{
m_dcd_fact.protocol_id = OCSD_PROTOCOL_END;
}
// set the C-API decoder factory interface
void CustomDcdMngrWrapper::setAPIDcdFact(ocsd_extern_dcd_fact_t *p_dcd_fact)
{
m_dcd_fact = *p_dcd_fact;
}
// create and destroy decoders
ocsd_err_t CustomDcdMngrWrapper::createDecoder(const int create_flags, const int instID, const CSConfig *p_config, TraceComponent **ppComponent)
{
ocsd_err_t err = OCSD_OK;
if(m_dcd_fact.protocol_id == OCSD_PROTOCOL_END)
return OCSD_ERR_NOT_INIT;
CustomDecoderWrapper *pComp = new (std::nothrow) CustomDecoderWrapper();
*ppComponent = pComp;
if (pComp == 0)
return OCSD_ERR_MEM;
ocsd_extern_dcd_cb_fns lib_callbacks;
CustomDecoderWrapper::SetCallbacks(lib_callbacks);
lib_callbacks.lib_context = pComp;
lib_callbacks.packetCBFlags = 0;
ocsd_extern_dcd_inst_t *pDecodeInst = pComp->getDecoderInstInfo();
err = m_dcd_fact.createDecoder( create_flags,
((CustomConfigWrapper *)p_config)->getConfig(),
&lib_callbacks,
pDecodeInst);
if (err == OCSD_OK)
{
// validate the decoder
if ((pDecodeInst->fn_data_in == 0) ||
(pDecodeInst->fn_update_pkt_mon == 0) ||
(pDecodeInst->cs_id == 0) ||
(pDecodeInst->decoder_handle == 0) ||
(pDecodeInst->p_decoder_name == 0)
)
{
err = OCSD_ERR_INVALID_PARAM_VAL;
}
}
if (err != OCSD_OK)
delete pComp;
else
pComp->updateNameFromDcdInst();
return err;
}
ocsd_err_t CustomDcdMngrWrapper::destroyDecoder(TraceComponent *pComponent)
{
CustomDecoderWrapper *pCustWrap = dynamic_cast<CustomDecoderWrapper *>(pComponent);
if(m_dcd_fact.protocol_id != OCSD_PROTOCOL_END)
m_dcd_fact.destroyDecoder(pCustWrap->getDecoderInstInfo()->decoder_handle);
delete pCustWrap;
return OCSD_OK;
}
const ocsd_trace_protocol_t CustomDcdMngrWrapper::getProtocolType() const
{
return m_dcd_fact.protocol_id;
}
ocsd_err_t CustomDcdMngrWrapper::createConfigFromDataStruct(CSConfig **pConfigBase, const void *pDataStruct)
{
ocsd_err_t err = OCSD_OK;
CustomConfigWrapper *pConfig = new (std::nothrow) CustomConfigWrapper(pDataStruct);
if(!pConfig)
return OCSD_ERR_MEM;
if(m_dcd_fact.csidFromConfig == 0)
return OCSD_ERR_NOT_INIT;
unsigned char csid;
err = m_dcd_fact.csidFromConfig(pDataStruct,&csid);
if(err == OCSD_OK)
{
pConfig->setCSID(csid);
*pConfigBase = pConfig;
}
return err;
}
ocsd_err_t CustomDcdMngrWrapper::getDataInputI(TraceComponent *pComponent, ITrcDataIn **ppDataIn)
{
CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent);
if(pDecoder == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
*ppDataIn = pDecoder;
return OCSD_OK;
}
// component connections
// all
ocsd_err_t CustomDcdMngrWrapper::attachErrorLogger(TraceComponent *pComponent, ITraceErrorLog *pIErrorLog)
{
CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent);
if (pDecoder == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
pDecoder->getErrorLogAttachPt()->replace_first(pIErrorLog);
return OCSD_OK;
}
// full decoder
ocsd_err_t CustomDcdMngrWrapper::attachInstrDecoder(TraceComponent *pComponent, IInstrDecode *pIInstrDec)
{
CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent);
if(pDecoder == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
pDecoder->attachInstrDecI(pIInstrDec);
return OCSD_OK;
}
ocsd_err_t CustomDcdMngrWrapper::attachMemAccessor(TraceComponent *pComponent, ITargetMemAccess *pMemAccessor)
{
CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent);
if(pDecoder == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
pDecoder->attachMemAccI(pMemAccessor);
return OCSD_OK;
}
ocsd_err_t CustomDcdMngrWrapper::attachOutputSink(TraceComponent *pComponent, ITrcGenElemIn *pOutSink)
{
CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent);
if(pDecoder == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
pDecoder->attachGenElemI(pOutSink);
return OCSD_OK;
}
// pkt processor only
ocsd_err_t CustomDcdMngrWrapper::attachPktMonitor(TraceComponent *pComponent, ITrcTypedBase *pPktRawDataMon)
{
CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent);
if(pDecoder == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
IPktRawDataMon<void> *pIF = 0;
if (pPktRawDataMon)
{
pIF = dynamic_cast<IPktRawDataMon<void> *>(pPktRawDataMon);
if (!pIF)
return OCSD_ERR_INVALID_PARAM_TYPE;
}
pDecoder->attachPtkMonI(pIF);
return OCSD_OK;
}
ocsd_err_t CustomDcdMngrWrapper::attachPktIndexer(TraceComponent *pComponent, ITrcTypedBase *pPktIndexer)
{
// indexers for external custom will also be external and custom.
return OCSD_ERR_DCD_INTERFACE_UNUSED;
}
ocsd_err_t CustomDcdMngrWrapper::attachPktSink(TraceComponent *pComponent, ITrcTypedBase *pPktDataInSink)
{
CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent);
if(pDecoder == 0)
return OCSD_ERR_INVALID_PARAM_TYPE;
IPktDataIn<void> *pIF = 0;
if (pPktDataInSink)
{
pIF = dynamic_cast<IPktDataIn<void> *>(pPktDataInSink);
if(!pIF)
return OCSD_ERR_INVALID_PARAM_TYPE;
}
pDecoder->attachPtkSinkI(pIF);
return OCSD_OK;
}
void CustomDcdMngrWrapper::pktToString(const void *pkt, char *pStrBuffer, int bufSize)
{
if (m_dcd_fact.pktToString)
m_dcd_fact.pktToString(pkt, pStrBuffer, bufSize);
else
snprintf(pStrBuffer, bufSize, "CUSTOM_PKT[]: print unsupported; protocol(%d).",m_dcd_fact.protocol_id);
}
/************************** Decoder instance wrapper **************************************/
/* callback functions */
ocsd_datapath_resp_t GenElemOpCB( const void *lib_context,
const ocsd_trc_index_t index_sop,
const uint8_t trc_chan_id,
const ocsd_generic_trace_elem *elem)
{
if (lib_context && ((CustomDecoderWrapper *)lib_context)->m_pGenElemIn)
return ((CustomDecoderWrapper *)lib_context)->m_pGenElemIn->TraceElemIn(index_sop,trc_chan_id,*(OcsdTraceElement *)elem);
return OCSD_RESP_FATAL_NOT_INIT;
}
void LogErrorCB(const void *lib_context, const ocsd_err_severity_t filter_level, const ocsd_err_t code, const ocsd_trc_index_t idx, const uint8_t chan_id, const char *pMsg)
{
if (lib_context)
{
if(pMsg)
((CustomDecoderWrapper *)lib_context)->LogError(ocsdError(filter_level, code, idx, chan_id, std::string(pMsg)));
else
((CustomDecoderWrapper *)lib_context)->LogError(ocsdError(filter_level, code, idx, chan_id));
}
}
void LogMsgCB(const void *lib_context, const ocsd_err_severity_t filter_level, const char *msg)
{
if (lib_context && msg)
((CustomDecoderWrapper *)lib_context)->LogMessage(filter_level, std::string(msg));
}
ocsd_err_t DecodeArmInstCB(const void *lib_context, ocsd_instr_info *instr_info)
{
if (lib_context && ((CustomDecoderWrapper *)lib_context)->m_pIInstrDec)
return ((CustomDecoderWrapper *)lib_context)->m_pIInstrDec->DecodeInstruction(instr_info);
return OCSD_ERR_ATTACH_INVALID_PARAM;
}
ocsd_err_t MemAccessCB(const void *lib_context,
const ocsd_vaddr_t address,
const uint8_t cs_trace_id,
const ocsd_mem_space_acc_t mem_space,
uint32_t *num_bytes,
uint8_t *p_buffer)
{
if (lib_context && ((CustomDecoderWrapper *)lib_context)->m_pMemAccessor)
return ((CustomDecoderWrapper *)lib_context)->m_pMemAccessor->ReadTargetMemory(address, cs_trace_id, mem_space, num_bytes, p_buffer);
return OCSD_ERR_INVALID_PARAM_VAL;
}
void PktMonCB(const void *lib_context,
const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const void *pkt,
const uint32_t size,
const uint8_t *p_data)
{
if (lib_context && ((CustomDecoderWrapper *)lib_context)->m_pPktMon)
((CustomDecoderWrapper *)lib_context)->m_pPktMon->RawPacketDataMon(op, index_sop, pkt, size, p_data);
}
ocsd_datapath_resp_t PktDataSinkCB(const void *lib_context,
const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const void *pkt)
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
if (lib_context && ((CustomDecoderWrapper *)lib_context)->m_pPktIn)
resp = ((CustomDecoderWrapper *)lib_context)->m_pPktIn->PacketDataIn(op, index_sop, pkt);
return resp;
}
/** decoder instance object */
CustomDecoderWrapper::CustomDecoderWrapper() : TraceComponent("extern_wrapper"),
m_pGenElemIn(0),
m_pIInstrDec(0),
m_pMemAccessor(0),
m_pPktMon(0),
m_pPktIn(0)
{
}
CustomDecoderWrapper::~CustomDecoderWrapper()
{
}
ocsd_datapath_resp_t CustomDecoderWrapper::TraceDataIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed)
{
if(m_decoder_inst.fn_data_in)
return m_decoder_inst.fn_data_in( m_decoder_inst.decoder_handle,
op,
index,
dataBlockSize,
pDataBlock,
numBytesProcessed);
return OCSD_RESP_FATAL_NOT_INIT;
}
void CustomDecoderWrapper::attachPtkMonI(IPktRawDataMon<void>* pIF)
{
m_pPktMon = pIF;
int flags = (m_pPktMon ? OCSD_CUST_DCD_PKT_CB_USE_MON : 0) | (m_pPktIn ? OCSD_CUST_DCD_PKT_CB_USE_SINK : 0);
m_decoder_inst.fn_update_pkt_mon(m_decoder_inst.decoder_handle, flags);
}
void CustomDecoderWrapper::attachPtkSinkI(IPktDataIn<void>* pIF)
{
m_pPktIn = pIF;
int flags = (m_pPktMon ? OCSD_CUST_DCD_PKT_CB_USE_MON : 0) | (m_pPktIn ? OCSD_CUST_DCD_PKT_CB_USE_SINK : 0);
m_decoder_inst.fn_update_pkt_mon(m_decoder_inst.decoder_handle, flags);
}
void CustomDecoderWrapper::updateNameFromDcdInst()
{
// create a unique component name from the decoder name + cs-id.
std::string name_combined = m_decoder_inst.p_decoder_name;
char num_buffer[32];
sprintf(num_buffer, "_%04d", m_decoder_inst.cs_id);
name_combined += (std::string)num_buffer;
setComponentName(name_combined);
}
void CustomDecoderWrapper::SetCallbacks(ocsd_extern_dcd_cb_fns & callbacks)
{
callbacks.fn_arm_instruction_decode = DecodeArmInstCB;
callbacks.fn_gen_elem_out = GenElemOpCB;
callbacks.fn_log_error = LogErrorCB;
callbacks.fn_log_msg = LogMsgCB;
callbacks.fn_memory_access = MemAccessCB;
callbacks.fn_packet_data_sink = PktDataSinkCB;
callbacks.fn_packet_mon = PktMonCB;
}
/* End of File ocsd_c_api_custom_obj.cpp */

View File

@ -0,0 +1,189 @@
/*
* \file ocsd_c_api_custom_obj.h
* \brief OpenCSD :
*
* \copyright Copyright (c) 2016, 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_OCSD_C_API_CUSTOM_OBJ_H_INCLUDED
#define ARM_OCSD_C_API_CUSTOM_OBJ_H_INCLUDED
#include "opencsd/c_api/ocsd_c_api_custom.h"
#include "common/ocsd_dcd_mngr_i.h"
/***** Decoder manager interface ******************************/
class CustomDcdMngrWrapper : public IDecoderMngr
{
public:
CustomDcdMngrWrapper();
virtual ~CustomDcdMngrWrapper() {};
// set the C-API decoder factory interface.
void setAPIDcdFact(ocsd_extern_dcd_fact_t *p_dcd_fact);
// create and destroy decoders
virtual ocsd_err_t createDecoder(const int create_flags, const int instID, const CSConfig *p_config, TraceComponent **ppComponent);
virtual ocsd_err_t destroyDecoder(TraceComponent *pComponent);
//! Get the built in protocol type ID managed by this instance - extern for custom decoders
virtual const ocsd_trace_protocol_t getProtocolType() const;
// connect decoders to other components - (replace current / 0 pointer value to detach );
// compatible with all decoders
//!attach error logger to ptk-processor, or both of pkt processor and pkt decoder pair
virtual ocsd_err_t attachErrorLogger(TraceComponent *pComponent, ITraceErrorLog *pIErrorLog);
// pkt decoder only
//! attach instruction decoder to pkt decoder
virtual ocsd_err_t attachInstrDecoder(TraceComponent *pComponent, IInstrDecode *pIInstrDec);
//! attach memory accessor to pkt decoder
virtual ocsd_err_t attachMemAccessor(TraceComponent *pComponent, ITargetMemAccess *pMemAccessor);
//! attach generic output interface to pkt decoder
virtual ocsd_err_t attachOutputSink(TraceComponent *pComponent, ITrcGenElemIn *pOutSink);
// pkt processor only
//! attach a raw packet monitor to pkt processor (solo pkt processor, or pkt processor part of pair)
virtual ocsd_err_t attachPktMonitor(TraceComponent *pComponent, ITrcTypedBase *pPktRawDataMon);
//! attach a packet indexer to pkt processor (solo pkt processor, or pkt processor part of pair)
virtual ocsd_err_t attachPktIndexer(TraceComponent *pComponent, ITrcTypedBase *pPktIndexer);
//! attach a packet data sink to pkt processor output (solo pkt processor only - instead of decoder when pkt processor only created.)
virtual ocsd_err_t attachPktSink(TraceComponent *pComponent, ITrcTypedBase *pPktDataInSink);
// data input connection interface
//! get raw data input interface from packet processor
virtual ocsd_err_t getDataInputI(TraceComponent *pComponent, ITrcDataIn **ppDataIn);
// create configuration from data structure
virtual ocsd_err_t createConfigFromDataStruct(CSConfig **pConfigBase, const void *pDataStruct);
// custom packet to string interface.
void pktToString(const void *pkt, char *pStrBuffer, int bufSize);
private:
ocsd_extern_dcd_fact_t m_dcd_fact;
};
/**** Decoder instance wrapper */
class CustomDecoderWrapper : public TraceComponent, public ITrcDataIn
{
public:
CustomDecoderWrapper();
virtual ~CustomDecoderWrapper();
ocsd_extern_dcd_inst_t *getDecoderInstInfo() { return &m_decoder_inst; }
virtual ocsd_datapath_resp_t TraceDataIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed);
void attachGenElemI(ITrcGenElemIn *pIF) { m_pGenElemIn = pIF; };
void attachInstrDecI(IInstrDecode *pIF) { m_pIInstrDec = pIF; };
void attachMemAccI(ITargetMemAccess *pIF) { m_pMemAccessor = pIF; };
void attachPtkMonI(IPktRawDataMon<void> *pIF);
void attachPtkSinkI(IPktDataIn<void> *pIF);
void updateNameFromDcdInst();
static void SetCallbacks(ocsd_extern_dcd_cb_fns &callbacks);
private:
// declare the callback functions as friend functions.
friend ocsd_datapath_resp_t GenElemOpCB( const void *lib_context,
const ocsd_trc_index_t index_sop,
const uint8_t trc_chan_id,
const ocsd_generic_trace_elem *elem);
friend void LogErrorCB( const void *lib_context,
const ocsd_err_severity_t filter_level,
const ocsd_err_t code,
const ocsd_trc_index_t idx,
const uint8_t chan_id,
const char *pMsg);
friend void LogMsgCB(const void *lib_context,
const ocsd_err_severity_t filter_level,
const char *msg);
friend ocsd_err_t DecodeArmInstCB(const void *lib_context, ocsd_instr_info *instr_info);
friend ocsd_err_t MemAccessCB(const void *lib_context,
const ocsd_vaddr_t address,
const uint8_t cs_trace_id,
const ocsd_mem_space_acc_t mem_space,
uint32_t *num_bytes,
uint8_t *p_buffer);
friend void PktMonCB(const void *lib_context,
const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const void *pkt,
const uint32_t size,
const uint8_t *p_data);
friend ocsd_datapath_resp_t PktDataSinkCB(const void *lib_context,
const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const void *pkt);
private:
ITrcGenElemIn *m_pGenElemIn; //!< generic element sink interface - output from decoder fed to common sink.
IInstrDecode *m_pIInstrDec; //!< arm instruction decode interface - decoder may want to use this.
ITargetMemAccess *m_pMemAccessor; //!< system memory accessor insterface - decoder may want to use this.
IPktRawDataMon<void> *m_pPktMon; //!< interface to packet monitor (full or packet only decode).
IPktDataIn<void> *m_pPktIn; //!< interface to packet sink (decode packets only).
ocsd_extern_dcd_inst_t m_decoder_inst;
};
/**** Decoder configuration wrapper - implements CSConfig base class interface ***/
class CustomConfigWrapper : public CSConfig
{
public:
CustomConfigWrapper(const void *p_config) : m_p_config(p_config), m_CSID(0) {};
virtual ~CustomConfigWrapper() {};
virtual const uint8_t getTraceID() const { return m_CSID; };
void setCSID(const uint8_t CSID) { m_CSID = CSID; };
const void *getConfig() { return m_p_config; };
private:
const void *m_p_config;
uint8_t m_CSID;
};
#endif // ARM_OCSD_C_API_CUSTOM_OBJ_H_INCLUDED
/* End of File ocsd_c_api_custom_obj.h */

View File

@ -0,0 +1,182 @@
/*
* \file ocsd_c_api_obj.h
* \brief OpenCSD : C API callback objects.
*
* \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
*/
#ifndef ARM_OCSD_C_API_OBJ_H_INCLUDED
#define ARM_OCSD_C_API_OBJ_H_INCLUDED
#include "opencsd/c_api/ocsd_c_api_types.h"
#include "interfaces/trc_gen_elem_in_i.h"
#include "common/ocsd_msg_logger.h"
class TraceElemCBBase
{
public:
TraceElemCBBase() {};
virtual ~TraceElemCBBase() {};
};
class GenTraceElemCBObj : public ITrcGenElemIn, public TraceElemCBBase
{
public:
GenTraceElemCBObj(FnTraceElemIn pCBFn, const void *p_context);
virtual ~GenTraceElemCBObj() {};
virtual ocsd_datapath_resp_t TraceElemIn(const ocsd_trc_index_t index_sop,
const uint8_t trc_chan_id,
const OcsdTraceElement &elem);
private:
FnTraceElemIn m_c_api_cb_fn;
const void *m_p_cb_context;
};
template<class TrcPkt>
class PktCBObj : public IPktDataIn<TrcPkt>
{
public:
PktCBObj( FnDefPktDataIn pCBFunc, const void *p_context)
{
m_c_api_cb_fn = pCBFunc;
m_p_context = p_context;
};
virtual ~PktCBObj() {};
virtual ocsd_datapath_resp_t PacketDataIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const TrcPkt *p_packet_in)
{
const void *c_pkt_struct = 0;
if(op == OCSD_OP_DATA)
c_pkt_struct = p_packet_in->c_pkt(); // always output the c struct packet
return m_c_api_cb_fn(m_p_context,op,index_sop,c_pkt_struct);
};
private:
FnDefPktDataIn m_c_api_cb_fn;
const void *m_p_context;
};
// void specialisation for custom decoders that pass packets as const void * pointers
template<>
class PktCBObj<void> : public IPktDataIn<void>
{
public:
PktCBObj(FnDefPktDataIn pCBFunc, const void *p_context)
{
m_c_api_cb_fn = pCBFunc;
m_p_context = p_context;
};
virtual ~PktCBObj() {};
virtual ocsd_datapath_resp_t PacketDataIn(const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const void *p_packet_in)
{
return m_c_api_cb_fn(m_p_context, op, index_sop, p_packet_in);
};
private:
FnDefPktDataIn m_c_api_cb_fn;
const void *m_p_context;
};
template<class TrcPkt>
class PktMonCBObj : public IPktRawDataMon<TrcPkt>
{
public:
PktMonCBObj( FnDefPktDataMon pCBFunc, const void *p_context)
{
m_c_api_cb_fn = pCBFunc;
m_p_context = p_context;
};
virtual ~PktMonCBObj() {};
virtual void RawPacketDataMon( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const TrcPkt *p_packet_in,
const uint32_t size,
const uint8_t *p_data)
{
const void *c_pkt_struct = 0;
if(op == OCSD_OP_DATA)
c_pkt_struct = p_packet_in->c_pkt(); // always output the c struct packet
m_c_api_cb_fn(m_p_context,op,index_sop,c_pkt_struct,size,p_data);
};
private:
FnDefPktDataMon m_c_api_cb_fn;
const void *m_p_context;
};
// void specialisation for custom decoders that pass packets as const void * pointers
template<>
class PktMonCBObj<void> : public IPktRawDataMon<void>
{
public:
PktMonCBObj(FnDefPktDataMon pCBFunc, const void *p_context)
{
m_c_api_cb_fn = pCBFunc;
m_p_context = p_context;
};
virtual ~PktMonCBObj() {};
virtual void RawPacketDataMon(const ocsd_datapath_op_t op,
const ocsd_trc_index_t index_sop,
const void *p_packet_in,
const uint32_t size,
const uint8_t *p_data)
{
m_c_api_cb_fn(m_p_context, op, index_sop, p_packet_in, size, p_data);
};
private:
FnDefPktDataMon m_c_api_cb_fn;
const void *m_p_context;
};
/* handler for default string print CB object */
class DefLogStrCBObj : public ocsdMsgLogStrOutI
{
public:
DefLogStrCBObj()
{
m_c_api_cb_fn = 0;
m_p_context = 0;
};
virtual ~DefLogStrCBObj()
{
m_c_api_cb_fn = 0;
m_p_context = 0;
};
void setCBFn(const void *p_context, FnDefLoggerPrintStrCB pCBFn)
{
m_c_api_cb_fn = pCBFn;
m_p_context = p_context;
};
virtual void printOutStr(const std::string &outStr)
{
if(m_c_api_cb_fn)
m_c_api_cb_fn(m_p_context, outStr.c_str(), outStr.length());
}
private:
FnDefLoggerPrintStrCB m_c_api_cb_fn;
const void *m_p_context;
};
#endif // ARM_OCSD_C_API_OBJ_H_INCLUDED
/* End of File ocsd_c_api_obj.h */

View File

@ -0,0 +1,65 @@
/*
* \file trc_cmp_cfg_etmv3.cpp
* \brief OpenCSD :
*
* \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "opencsd/etmv3/trc_cmp_cfg_etmv3.h"
EtmV3Config::EtmV3Config()
{
// defaults set ETMv3.4, V7A, instruction only.
m_cfg.arch_ver = ARCH_V7;
m_cfg.core_prof = profile_CortexA;
m_cfg.reg_ccer = 0;
m_cfg.reg_idr = 0x4100F240; // default trace IDR value
m_cfg.reg_ctrl = 0;
}
EtmV3Config::EtmV3Config(const ocsd_etmv3_cfg *cfg_regs)
{
m_cfg = *cfg_regs;
}
EtmV3Config::EtmTraceMode const EtmV3Config::GetTraceMode() const
{
int mode = 0 + ( isDataValTrace() ? 1 : 0 ) + (isDataAddrTrace() ? 2 : 0) + (isInstrTrace() ? 0 : 3);
return (EtmTraceMode)mode;
}
const int EtmV3Config::CtxtIDBytes() const
{
int ctxtIdsizes[] = { 0, 1, 2, 4 };
return ctxtIdsizes[(m_cfg.reg_ctrl >> 14) & 0x3];
}
/* End of File trc_cmp_cfg_etmv3.cpp */

View File

@ -0,0 +1,670 @@
/*!
* \file trc_pkt_decode_etmv3.cpp
* \brief OpenCSD : ETMv3 trace packet decode.
*
* \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/etmv3/trc_pkt_decode_etmv3.h"
#define DCD_NAME "DCD_ETMV3"
TrcPktDecodeEtmV3::TrcPktDecodeEtmV3() :
TrcPktDecodeBase(DCD_NAME)
{
initDecoder();
}
TrcPktDecodeEtmV3::TrcPktDecodeEtmV3(int instIDNum) :
TrcPktDecodeBase(DCD_NAME, instIDNum)
{
initDecoder();
}
TrcPktDecodeEtmV3::~TrcPktDecodeEtmV3()
{
}
/* implementation packet decoding interface */
ocsd_datapath_resp_t TrcPktDecodeEtmV3::processPacket()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
bool bPktDone = false;
if(!m_config)
return OCSD_RESP_FATAL_NOT_INIT;
// iterate round the state machine, waiting for sync, then decoding packets.
while(!bPktDone)
{
switch(m_curr_state)
{
case NO_SYNC:
// output the initial not synced packet to the sink
resp = sendUnsyncPacket();
m_curr_state = WAIT_ASYNC; // immediate wait for ASync and actually check out the packet
break;
case WAIT_ASYNC:
// if async, wait for ISync, but this packet done.
if(m_curr_packet_in->getType() == ETM3_PKT_A_SYNC)
m_curr_state = WAIT_ISYNC;
bPktDone = true;
break;
case WAIT_ISYNC:
m_bWaitISync = true; // we are waiting for ISync
if((m_curr_packet_in->getType() == ETM3_PKT_I_SYNC) ||
(m_curr_packet_in->getType() == ETM3_PKT_I_SYNC_CYCLE))
{
// process the ISync immediately as the first ISync seen.
resp = processISync((m_curr_packet_in->getType() == ETM3_PKT_I_SYNC_CYCLE),true);
m_curr_state = SEND_PKTS;
m_bWaitISync = false;
}
// something like TS, CC, PHDR+CC, which after ASYNC may be valid prior to ISync
else if(preISyncValid(m_curr_packet_in->getType()))
{
// decode anything that might be valid - send will be set automatically
resp = decodePacket(bPktDone);
}
else
bPktDone = true;
break;
case DECODE_PKTS:
resp = decodePacket(bPktDone);
break;
case SEND_PKTS:
resp = m_outputElemList.sendElements();
if(OCSD_DATA_RESP_IS_CONT(resp))
m_curr_state = m_bWaitISync ? WAIT_ISYNC : DECODE_PKTS;
bPktDone = true;
break;
default:
bPktDone = true;
LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_FAIL,m_index_curr_pkt,"Unknown Decoder State"));
resetDecoder(); // mark decoder as unsynced - dump any current state.
resp = OCSD_RESP_FATAL_SYS_ERR;
break;
}
}
return resp;
}
ocsd_datapath_resp_t TrcPktDecodeEtmV3::onEOT()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
OcsdTraceElement *pElem = 0;
try {
pElem = GetNextOpElem(resp);
pElem->setType(OCSD_GEN_TRC_ELEM_EO_TRACE);
m_outputElemList.commitAllPendElem();
m_curr_state = SEND_PKTS;
resp = m_outputElemList.sendElements();
if(OCSD_DATA_RESP_IS_CONT(resp))
m_curr_state = DECODE_PKTS;
}
catch(ocsdError &err)
{
LogError(err);
resetDecoder(); // mark decoder as unsynced - dump any current state.
}
return resp;
}
ocsd_datapath_resp_t TrcPktDecodeEtmV3::onReset()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
resetDecoder();
return resp;
}
ocsd_datapath_resp_t TrcPktDecodeEtmV3::onFlush()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
if(m_curr_state == SEND_PKTS)
{
resp = m_outputElemList.sendElements();
if(OCSD_DATA_RESP_IS_CONT(resp))
m_curr_state = m_bWaitISync ? WAIT_ISYNC : DECODE_PKTS;
}
return resp;
}
ocsd_err_t TrcPktDecodeEtmV3::onProtocolConfig()
{
ocsd_err_t err = OCSD_OK;
if(m_config)
{
// set some static config elements
m_CSID = m_config->getTraceID();
// check config compatible with current decoder support level.
// at present no data trace;
if(m_config->GetTraceMode() != EtmV3Config::TM_INSTR_ONLY)
{
err = OCSD_ERR_HW_CFG_UNSUPP;
LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_HW_CFG_UNSUPP,"ETMv3 trace decoder : data trace decode not yet supported"));
}
// need to set up core profile info in follower
ocsd_arch_profile_t arch_profile;
arch_profile.arch = m_config->getArchVersion();
arch_profile.profile = m_config->getCoreProfile();
m_code_follower.setArchProfile(arch_profile);
m_code_follower.setMemSpaceCSID(m_CSID);
m_outputElemList.initCSID(m_CSID);
}
else
err = OCSD_ERR_NOT_INIT;
return err;
}
/* local decode methods */
// initialise on creation
void TrcPktDecodeEtmV3::initDecoder()
{
m_CSID = 0;
resetDecoder();
m_code_follower.initInterfaces(getMemoryAccessAttachPt(),getInstrDecodeAttachPt());
m_outputElemList.initSendIf(getTraceElemOutAttachPt());
}
// reset for first use / re-use.
void TrcPktDecodeEtmV3::resetDecoder()
{
m_curr_state = NO_SYNC; // mark as not synced
m_bNeedAddr = true;
m_bSentUnknown = false;
m_bWaitISync = false;
m_outputElemList.reset();
}
OcsdTraceElement *TrcPktDecodeEtmV3::GetNextOpElem(ocsd_datapath_resp_t &resp)
{
OcsdTraceElement *pElem = m_outputElemList.getNextElem(m_index_curr_pkt);
if(pElem == 0)
{
resp = OCSD_RESP_FATAL_NOT_INIT;
throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_MEM,m_index_curr_pkt,m_CSID,"Memory Allocation Error - fatal");
}
return pElem;
}
bool TrcPktDecodeEtmV3::preISyncValid(ocsd_etmv3_pkt_type pkt_type)
{
bool bValid = false;
// its a timestamp
if((pkt_type == ETM3_PKT_TIMESTAMP) ||
// or we are cycleacc and its a packet that can have CC in it
(m_config->isCycleAcc() && ((pkt_type == ETM3_PKT_CYCLE_COUNT) || (pkt_type == ETM3_PKT_P_HDR)))
)
bValid = true;
return bValid;
}
// simple packet transforms handled here, more complex processing passed on to specific routines.
ocsd_datapath_resp_t TrcPktDecodeEtmV3::decodePacket(bool &pktDone)
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
bool bISyncHasCC = false;
OcsdTraceElement *pElem = 0;
pktDone = false;
// there may be pended packets that can now be committed.
// only the branch address with exception and cancel element can cancel
// if not one of those, commit immediately, otherwise defer to branch address handler.
if(m_curr_packet_in->getType() != ETM3_PKT_BRANCH_ADDRESS)
m_outputElemList.commitAllPendElem();
try {
switch(m_curr_packet_in->getType())
{
case ETM3_PKT_NOTSYNC:
// mark as not synced - must have lost sync in the packet processor somehow
throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_BAD_PACKET_SEQ,m_index_curr_pkt,m_CSID,"Trace Packet Synchronisation Lost");
break;
// no action for these packets - ignore and continue
case ETM3_PKT_INCOMPLETE_EOT:
case ETM3_PKT_A_SYNC:
case ETM3_PKT_IGNORE:
break;
// markers for valid packets
case ETM3_PKT_CYCLE_COUNT:
pElem = GetNextOpElem(resp);
pElem->setType(OCSD_GEN_TRC_ELEM_CYCLE_COUNT);
pElem->setCycleCount(m_curr_packet_in->getCycleCount());
break;
case ETM3_PKT_TRIGGER:
pElem = GetNextOpElem(resp);
pElem->setType(OCSD_GEN_TRC_ELEM_EVENT);
pElem->setEvent(EVENT_TRIGGER,0);
break;
case ETM3_PKT_BRANCH_ADDRESS:
resp = processBranchAddr();
break;
case ETM3_PKT_I_SYNC_CYCLE:
bISyncHasCC = true;
case ETM3_PKT_I_SYNC:
resp = processISync(bISyncHasCC);
break;
case ETM3_PKT_P_HDR:
resp = processPHdr();
break;
case ETM3_PKT_CONTEXT_ID:
pElem = GetNextOpElem(resp);
pElem->setType(OCSD_GEN_TRC_ELEM_PE_CONTEXT);
m_PeContext.setCtxtID(m_curr_packet_in->getCtxtID());
pElem->setContext(m_PeContext);
break;
case ETM3_PKT_VMID:
pElem = GetNextOpElem(resp);
pElem->setType(OCSD_GEN_TRC_ELEM_PE_CONTEXT);
m_PeContext.setVMID(m_curr_packet_in->getVMID());
pElem->setContext(m_PeContext);
break;
case ETM3_PKT_EXCEPTION_ENTRY:
pElem = GetNextOpElem(resp);
pElem->setType(OCSD_GEN_TRC_ELEM_EXCEPTION);
pElem->setExcepMarker(); // exception entries are always v7M data markers in ETMv3 trace.
break;
case ETM3_PKT_EXCEPTION_EXIT:
pElem = GetNextOpElem(resp);
pElem->setType(OCSD_GEN_TRC_ELEM_EXCEPTION_RET);
pendExceptionReturn();
break;
case ETM3_PKT_TIMESTAMP:
pElem = GetNextOpElem(resp);
pElem->setType(OCSD_GEN_TRC_ELEM_TIMESTAMP);
pElem->setTS(m_curr_packet_in->getTS());
break;
// data packets - data trace not supported at present
case ETM3_PKT_STORE_FAIL:
case ETM3_PKT_OOO_DATA:
case ETM3_PKT_OOO_ADDR_PLC:
case ETM3_PKT_NORM_DATA:
case ETM3_PKT_DATA_SUPPRESSED:
case ETM3_PKT_VAL_NOT_TRACED:
case ETM3_PKT_BAD_TRACEMODE:
resp = OCSD_RESP_FATAL_INVALID_DATA;
throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_HW_CFG_UNSUPP,m_index_curr_pkt,m_CSID,"Invalid packet type : Data Tracing decode not supported.");
break;
// packet errors
case ETM3_PKT_BAD_SEQUENCE:
resp = OCSD_RESP_FATAL_INVALID_DATA;
throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_BAD_PACKET_SEQ,m_index_curr_pkt,m_CSID,"Bad Packet sequence.");
break;
default:
case ETM3_PKT_RESERVED:
resp = OCSD_RESP_FATAL_INVALID_DATA;
throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_BAD_PACKET_SEQ,m_index_curr_pkt,m_CSID,"Reserved or unknown packet ID.");
break;
}
m_curr_state = m_outputElemList.elemToSend() ? SEND_PKTS : DECODE_PKTS;
pktDone = !m_outputElemList.elemToSend();
}
catch(ocsdError &err)
{
LogError(err);
resetDecoder(); // mark decoder as unsynced - dump any current state.
pktDone = true;
}
catch(...)
{
LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_FAIL,m_index_curr_pkt,m_CSID,"Bad Packet sequence."));
resp = OCSD_RESP_FATAL_SYS_ERR;
resetDecoder(); // mark decoder as unsynced - dump any current state.
pktDone = true;
}
return resp;
}
ocsd_datapath_resp_t TrcPktDecodeEtmV3::sendUnsyncPacket()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
OcsdTraceElement *pElem = 0;
try {
pElem = GetNextOpElem(resp);
pElem->setType(OCSD_GEN_TRC_ELEM_NO_SYNC);
resp = m_outputElemList.sendElements();
}
catch(ocsdError &err)
{
LogError(err);
resetDecoder(); // mark decoder as unsynced - dump any current state.
}
return resp;
}
void TrcPktDecodeEtmV3::setNeedAddr(bool bNeedAddr)
{
m_bNeedAddr = bNeedAddr;
m_bSentUnknown = false;
}
ocsd_datapath_resp_t TrcPktDecodeEtmV3::processISync(const bool withCC, const bool firstSync /* = false */)
{
// map ISync reason to generic reason codes.
static trace_on_reason_t on_map[] = { TRACE_ON_NORMAL, TRACE_ON_NORMAL,
TRACE_ON_OVERFLOW, TRACE_ON_EX_DEBUG };
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
bool ctxtUpdate = m_curr_packet_in->isCtxtUpdated();
OcsdTraceElement *pElem = 0;
try {
pElem = GetNextOpElem(resp);
if(firstSync || (m_curr_packet_in->getISyncReason() != iSync_Periodic))
{
pElem->setType(OCSD_GEN_TRC_ELEM_TRACE_ON);
pElem->setTraceOnReason(on_map[(int)m_curr_packet_in->getISyncReason()]);
pElem = GetNextOpElem(resp);
}
// look for context changes....
if(ctxtUpdate || firstSync)
{
// if not first time out, read existing context in output element,
// otherwise we are setting it new.
if(firstSync)
m_PeContext.resetCtxt();
if(m_curr_packet_in->isCtxtIDUpdated())
m_PeContext.setCtxtID(m_curr_packet_in->getCtxtID());
if(m_curr_packet_in->isVMIDUpdated())
m_PeContext.setVMID(m_curr_packet_in->getVMID());
if(m_curr_packet_in->isCtxtFlagsUpdated())
{
m_PeContext.setEL(m_curr_packet_in->isHyp() ? ocsd_EL2 : ocsd_EL_unknown);
m_PeContext.setSecLevel(m_curr_packet_in->isNS() ? ocsd_sec_nonsecure : ocsd_sec_secure);
}
// prepare the context packet
pElem->setType(OCSD_GEN_TRC_ELEM_PE_CONTEXT);
pElem->setContext(m_PeContext);
pElem->setISA(m_curr_packet_in->ISA());
// with cycle count...
if(m_curr_packet_in->getISyncHasCC())
pElem->setCycleCount(m_curr_packet_in->getCycleCount());
}
// set ISync address - if it is a valid I address
if(!m_curr_packet_in->getISyncNoAddr())
{
if(m_curr_packet_in->getISyncIsLSiPAddr())
{
// TBD: handle extra data processing instruction for data trace
// need to output E atom relating to the data instruction
// rare - on start-up case.
// main instruction address saved in data address for this packet type.
m_IAddr = m_curr_packet_in->getDataAddr();
}
else
{
m_IAddr = m_curr_packet_in->getAddr();
}
setNeedAddr(false); // ready to process atoms.
}
m_curr_state = m_outputElemList.elemToSend() ? SEND_PKTS : DECODE_PKTS;
}
catch(ocsdError &err)
{
LogError(err);
resetDecoder(); // mark decoder as unsynced - dump any current state.
}
return resp;
}
ocsd_datapath_resp_t TrcPktDecodeEtmV3::processBranchAddr()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
OcsdTraceElement *pElem = 0;
bool bUpdatePEContext = false;
// might need to cancel something ... if the last output was an instruction range or excep return
if(m_curr_packet_in->isExcepCancel())
m_outputElemList.cancelPendElem();
else
m_outputElemList.commitAllPendElem(); // otherwise commit any pending elements.
// record the address
m_IAddr = m_curr_packet_in->getAddr();
setNeedAddr(false); // no longer need an address.
// exception packet - may need additional output
if(m_curr_packet_in->isExcepPkt())
{
// exeception packet may have exception, context change, or both.
// check for context change
if(m_curr_packet_in->isCtxtUpdated())
{
ocsd_sec_level sec = m_curr_packet_in->isNS() ? ocsd_sec_nonsecure : ocsd_sec_secure;
if(sec != m_PeContext.getSecLevel())
{
m_PeContext.setSecLevel(sec);
bUpdatePEContext = true;
}
ocsd_ex_level pkt_el = m_curr_packet_in->isHyp() ? ocsd_EL2 : ocsd_EL_unknown;
if(pkt_el != m_PeContext.getEL())
{
m_PeContext.setEL(pkt_el);
bUpdatePEContext = true;
}
}
// now decide if we need to send any packets out.
try {
if(bUpdatePEContext)
{
pElem = GetNextOpElem(resp);
pElem->setType(OCSD_GEN_TRC_ELEM_PE_CONTEXT);
pElem->setContext(m_PeContext);
}
// check for exception
if(m_curr_packet_in->excepNum() != 0)
{
pElem = GetNextOpElem(resp);
pElem->setType(OCSD_GEN_TRC_ELEM_EXCEPTION);
pElem->setExceptionNum(m_curr_packet_in->excepNum());
}
// finally - do we have anything to send yet?
m_curr_state = m_outputElemList.elemToSend() ? SEND_PKTS : DECODE_PKTS;
}
catch(ocsdError &err)
{
LogError(err);
resetDecoder(); // mark decoder as unsynced - dump any current state.
}
}
return resp;
}
ocsd_datapath_resp_t TrcPktDecodeEtmV3::processPHdr()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
OcsdTraceElement *pElem = 0;
ocsd_isa isa;
Etmv3Atoms atoms(m_config->isCycleAcc());
atoms.initAtomPkt(m_curr_packet_in,m_index_curr_pkt);
isa = m_curr_packet_in->ISA();
m_code_follower.setMemSpaceAccess((m_PeContext.getSecLevel() == ocsd_sec_secure) ? OCSD_MEM_SPACE_S : OCSD_MEM_SPACE_N);
try
{
do
{
// if we do not have a valid address then send any cycle count elements
// and stop processing
if(m_bNeedAddr)
{
// output unknown address packet or a cycle count packet
if(!m_bSentUnknown || m_config->isCycleAcc())
{
pElem = GetNextOpElem(resp);
if(m_bSentUnknown || !atoms.numAtoms())
pElem->setType(OCSD_GEN_TRC_ELEM_CYCLE_COUNT);
else
pElem->setType(OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN);
if(m_config->isCycleAcc())
pElem->setCycleCount(atoms.getRemainCC());
m_bSentUnknown = true;
}
atoms.clearAll(); // skip remaining atoms
}
else // have an address, can process atoms
{
pElem = GetNextOpElem(resp);
pElem->setType(OCSD_GEN_TRC_ELEM_INSTR_RANGE);
// cycle accurate may have a cycle count to use
if(m_config->isCycleAcc())
{
// note: it is possible to have a CC only atom packet.
if(!atoms.numAtoms()) // override type if CC only
pElem->setType(OCSD_GEN_TRC_ELEM_CYCLE_COUNT);
// set cycle count
pElem->setCycleCount(atoms.getAtomCC());
}
// now process the atom
if(atoms.numAtoms())
{
m_code_follower.setISA(isa);
m_code_follower.followSingleAtom(m_IAddr,atoms.getCurrAtomVal());
// valid code range
if(m_code_follower.hasRange())
{
pElem->setAddrRange(m_IAddr,m_code_follower.getRangeEn());
pElem->setLastInstrInfo(atoms.getCurrAtomVal() == ATOM_E,
m_code_follower.getInstrType(),
m_code_follower.getInstrSubType());
pElem->setISA(isa);
if(m_code_follower.hasNextAddr())
m_IAddr = m_code_follower.getNextAddr();
else
setNeedAddr(true);
}
// next address has new ISA?
if(m_code_follower.ISAChanged())
isa = m_code_follower.nextISA();
// there is a nacc
if(m_code_follower.isNacc())
{
if(m_code_follower.hasRange())
{
pElem = GetNextOpElem(resp);
pElem->setType(OCSD_GEN_TRC_ELEM_ADDR_NACC);
}
else
pElem->updateType(OCSD_GEN_TRC_ELEM_ADDR_NACC);
pElem->setAddrStart(m_code_follower.getNaccAddr());
setNeedAddr(true);
m_code_follower.clearNacc(); // we have generated some code for the nacc.
}
}
atoms.clearAtom(); // next atom
}
}
while(atoms.numAtoms());
// is tha last element an atom?
int numElem = m_outputElemList.getNumElem();
if(numElem >= 1)
{
// if the last thing is an instruction range, pend it - could be cancelled later.
if(m_outputElemList.getElemType(numElem-1) == OCSD_GEN_TRC_ELEM_INSTR_RANGE)
m_outputElemList.pendLastNElem(1);
}
// finally - do we have anything to send yet?
m_curr_state = m_outputElemList.elemToSend() ? SEND_PKTS : DECODE_PKTS;
}
catch(ocsdError &err)
{
LogError(err);
resetDecoder(); // mark decoder as unsynced - dump any current state.
}
return resp;
}
// if v7M -> pend only ERET, if V7A/R pend ERET and prev instr.
void TrcPktDecodeEtmV3::pendExceptionReturn()
{
int pendElem = 1;
if(m_config->getCoreProfile() != profile_CortexM)
{
int nElem = m_outputElemList.getNumElem();
if(nElem > 1)
{
if(m_outputElemList.getElemType(nElem - 2) == OCSD_GEN_TRC_ELEM_INSTR_RANGE)
pendElem = 2; // need to pend instr+eret for A/R
}
}
m_outputElemList.pendLastNElem(pendElem);
}
/* End of File trc_pkt_decode_etmv3.cpp */

View File

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

View File

@ -0,0 +1,122 @@
/*
* \file trc_pkt_proc_etmv3.cpp
* \brief OpenCSD :
*
* \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "opencsd/etmv3/trc_pkt_proc_etmv3.h"
#include "trc_pkt_proc_etmv3_impl.h"
#include "common/ocsd_error.h"
#ifdef __GNUC__
// G++ doesn't like the ## pasting
#define ETMV3_PKTS_NAME "PKTP_ETMV3"
#else
#define ETMV3_PKTS_NAME OCSD_CMPNAME_PREFIX_PKTPROC##"_"##OCSD_BUILTIN_DCD_ETMV3
#endif
static const uint32_t ETMV3_SUPPORTED_OP_FLAGS = OCSD_OPFLG_PKTPROC_COMMON |
ETMV3_OPFLG_UNFORMATTED_SOURCE;
TrcPktProcEtmV3::TrcPktProcEtmV3() : TrcPktProcBase(ETMV3_PKTS_NAME),
m_pProcessor(0)
{
m_supported_op_flags = ETMV3_SUPPORTED_OP_FLAGS;
}
TrcPktProcEtmV3::TrcPktProcEtmV3(int instIDNum) : TrcPktProcBase(ETMV3_PKTS_NAME, instIDNum),
m_pProcessor(0)
{
m_supported_op_flags = ETMV3_SUPPORTED_OP_FLAGS;
}
TrcPktProcEtmV3::~TrcPktProcEtmV3()
{
if(m_pProcessor)
delete m_pProcessor;
m_pProcessor = 0;
}
ocsd_err_t TrcPktProcEtmV3::onProtocolConfig()
{
if(m_pProcessor == 0)
{
m_pProcessor = new (std::nothrow) EtmV3PktProcImpl();
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 TrcPktProcEtmV3::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 TrcPktProcEtmV3::onEOT()
{
if(m_pProcessor)
return m_pProcessor->onEOT();
return OCSD_RESP_FATAL_NOT_INIT;
}
ocsd_datapath_resp_t TrcPktProcEtmV3::onReset()
{
if(m_pProcessor)
return m_pProcessor->onReset();
return OCSD_RESP_FATAL_NOT_INIT;
}
ocsd_datapath_resp_t TrcPktProcEtmV3::onFlush()
{
if(m_pProcessor)
return m_pProcessor->onFlush();
return OCSD_RESP_FATAL_NOT_INIT;
}
const bool TrcPktProcEtmV3::isBadPacket() const
{
if(m_pProcessor)
return m_pProcessor->isBadPacket();
return false;
}
/* End of File trc_pkt_proc_etmv3.cpp */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,175 @@
/*
* \file trc_pkt_proc_etmv3_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_ETMV3_IMPL_H_INCLUDED
#define ARM_TRC_PKT_PROC_ETMV3_IMPL_H_INCLUDED
#include "opencsd/etmv3/trc_pkt_proc_etmv3.h"
#include "opencsd/etmv3/trc_cmp_cfg_etmv3.h"
#include "opencsd/etmv3/trc_pkt_elem_etmv3.h"
#define MAX_PACKET_SIZE 32
#define ASYNC_SIZE 6
class EtmV3PktProcImpl
{
public:
EtmV3PktProcImpl();
~EtmV3PktProcImpl();
void Initialise(TrcPktProcEtmV3 *p_interface);
ocsd_err_t Configure(const EtmV3Config *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();
const bool isBadPacket() const;
protected:
typedef enum _process_state {
WAIT_SYNC,
PROC_HDR,
PROC_DATA,
SEND_PKT,
PROC_ERR,
} process_state;
process_state m_process_state;
void InitPacketState(); // clear current packet state.
void InitProcessorState(); // clear all previous process state
// byte processing
uint32_t waitForSync(const uint32_t dataBlockSize, const uint8_t *pDataBlock); //!< look for sync, return none-sync bytes processed.
ocsd_err_t processHeaderByte(uint8_t by);
ocsd_err_t processPayloadByte(uint8_t by);
// packet handling - main routines
void OnBranchAddress();
void OnISyncPacket();
uint32_t extractCtxtID();
uint64_t extractTimestamp(uint8_t &tsBits);
uint32_t extractDataAddress(uint8_t &bits, bool &updateBE, uint8_t &beVal);
uint32_t extractDataValue(const int dataByteSize);
uint32_t extractCycleCount();
// packet handling - helper routines
uint32_t extractBrAddrPkt(int &nBitsOut);
void extractExceptionData();
void checkPktLimits();
void setBytesPartPkt(const int numBytes, const process_state nextState, const ocsd_etmv3_pkt_type nextType); // set first n bytes from current packet to be sent via alt packet.
// packet output
void SendPacket(); // mark state for packet output
ocsd_datapath_resp_t outputPacket(); // output a packet
// bad packets
void throwMalformedPacketErr(const char *pszErrMsg);
void throwPacketHeaderErr(const char *pszErrMsg);
void throwUnsupportedErr(const char *pszErrMsg);
uint32_t m_bytesProcessed; // bytes processed by the process data routine (index into input buffer)
std::vector<uint8_t> m_currPacketData; // raw data
uint32_t m_currPktIdx; // index into packet when expanding
EtmV3TrcPacket m_curr_packet; // expanded packet
std::vector<uint8_t> m_partPktData; // raw data when we need to split a packet.
bool m_bSendPartPkt; // mark the part packet as the one we send.
process_state m_post_part_pkt_state; // state to set after part packet set
ocsd_etmv3_pkt_type m_post_part_pkt_type; // reset the packet type.
// process state
bool m_bStreamSync; //!< true if we have synced this stream
bool m_bStartOfSync; //!< true if we have a start of sync.
// packet state
uint32_t m_bytesExpectedThisPkt; // used by some of the variable packet length types.
bool m_BranchPktNeedsException;
bool m_bIsync_got_cycle_cnt;
bool m_bIsync_get_LSiP_addr;
int m_IsyncInfoIdx;
bool m_bExpectingDataAddress;
bool m_bFoundDataAddress;
ocsd_trc_index_t m_packet_index; // index of the start of the current packet
ocsd_trc_index_t m_packet_curr_byte_index; // index of the current byte.
bool m_isInit;
TrcPktProcEtmV3 *m_interface; /**< The interface to the other decode components */
EtmV3Config m_config;
uint8_t m_chanIDCopy;
};
inline void EtmV3PktProcImpl::SendPacket()
{
m_process_state = SEND_PKT;
}
inline void EtmV3PktProcImpl::throwMalformedPacketErr(const char *pszErrMsg)
{
throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_BAD_PACKET_SEQ,m_packet_index,m_chanIDCopy,pszErrMsg);
}
inline void EtmV3PktProcImpl::throwPacketHeaderErr(const char *pszErrMsg)
{
throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PCKT_HDR,m_packet_index,m_chanIDCopy,pszErrMsg);
}
inline void EtmV3PktProcImpl::throwUnsupportedErr(const char *pszErrMsg)
{
throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_HW_CFG_UNSUPP,m_packet_index,m_chanIDCopy,pszErrMsg);
}
inline const bool EtmV3PktProcImpl::isBadPacket() const
{
return m_curr_packet.isBadPacket();
}
#endif // ARM_TRC_PKT_PROC_ETMV3_IMPL_H_INCLUDED
/* End of File trc_pkt_proc_etmv3_impl.h */

Some files were not shown because too many files have changed in this diff Show More