diff options
Diffstat (limited to 'decoder/include')
29 files changed, 761 insertions, 66 deletions
diff --git a/decoder/include/common/ocsd_dcd_mngr.h b/decoder/include/common/ocsd_dcd_mngr.h index 3342eacb24ca..34c4ef1dc1c4 100644 --- a/decoder/include/common/ocsd_dcd_mngr.h +++ b/decoder/include/common/ocsd_dcd_mngr.h @@ -80,16 +80,16 @@ public: private: - ocsd_trace_protocol_t m_builtInProtocol; //!< Protocol ID if built in type. + const 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) + DecoderMngrBase<P,Pt,Pc>::DecoderMngrBase(const std::string &decoderTypeName, ocsd_trace_protocol_t builtInProtocol) : + m_builtInProtocol(builtInProtocol) { OcsdLibDcdRegister *pDcdReg = OcsdLibDcdRegister::getDecoderRegister(); if(pDcdReg) pDcdReg->registerDecoderTypeByName(decoderTypeName,this); - m_builtInProtocol = builtInProtocol; } template <class P, class Pt, class Pc> @@ -362,6 +362,49 @@ public: } }; +/* full decode - extended config object - base + derived. */ +template< class P, // Packet class. + class Pt, // Packet enum type ID. + class Pc, // Processor config base class. + class PcEx, // Processor config derived class + class PcSt, // Processor config struct type + class PktProc, // Packet processor class. + class PktDcd> // Packet decoder class. + class DecodeMngrFullDcdExCfg : public DecoderMngrBase<P, Pt, Pc> +{ +public: + DecodeMngrFullDcdExCfg(const std::string &name, ocsd_trace_protocol_t builtInProtocol) + : DecoderMngrBase<P, Pt, Pc>(name, builtInProtocol) {}; + + virtual ~DecodeMngrFullDcdExCfg() {}; + + 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) PcEx((PcSt *)pDataStruct); + } +}; + + /****************************************************************************************************/ /* Packet processor only, templated base for creating decoder objects */ /****************************************************************************************************/ diff --git a/decoder/include/common/ocsd_dcd_tree.h b/decoder/include/common/ocsd_dcd_tree.h index e4e74f2bc659..b1c3dc601cab 100644 --- a/decoder/include/common/ocsd_dcd_tree.h +++ b/decoder/include/common/ocsd_dcd_tree.h @@ -168,6 +168,30 @@ public: */ ocsd_err_t removeDecoder(const uint8_t CSID); + /*! + * Get the stats block for the channel indicated. + * Caller must check p_stats_block->version to esure that the block + * is filled in a compatible manner. + * + * @param CSID : Configured CoreSight trace ID for the decoder. + * @param p_stats_block: block pointer to set to reference the stats block. + * + * @return ocsd_err_t : Library error code - OCSD_OK if valid block pointer returned, + * OCSD_ERR_NOTINIT if decoder does not support stats counting. + */ + ocsd_err_t getDecoderStats(const uint8_t CSID, ocsd_decode_stats_t **p_stats_block); + + /*! + * Reset the stats block for the chosens decode channel. + * stats block is reset independently of the decoder reset to allow counts across + * multiple decode runs. + * + * @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_err_t resetDecoderStats(const uint8_t CSID); /* get decoder elements currently in use */ @@ -387,7 +411,7 @@ private: void destroyMemAccMapper(); ocsd_err_t initCallbackMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, const ocsd_mem_space_acc_t mem_space, void *p_cb_func, bool IDfn, const void *p_context); - + TrcPktProcI *getPktProcI(const uint8_t CSID); ocsd_dcd_tree_src_t m_dcd_tree_type; @@ -417,6 +441,9 @@ private: /**! default instruction decoder */ static TrcIDecode s_instruction_decoder; + + /**! demux stats block */ + ocsd_demux_stats_t m_demux_stats; }; /** @}*/ diff --git a/decoder/include/common/ocsd_error.h b/decoder/include/common/ocsd_error.h index e547f4878033..7c6ed3af141f 100644 --- a/decoder/include/common/ocsd_error.h +++ b/decoder/include/common/ocsd_error.h @@ -108,6 +108,17 @@ inline ocsdError& ocsdError::operator=(const ocsdError &err) return (*this = &err); } +/* class to get data path response values as strings */ +class ocsdDataRespStr +{ +public: + ocsdDataRespStr(ocsd_datapath_resp_t type) { m_type = type; } + ~ocsdDataRespStr() {}; + + const char* getStr(); +private: + ocsd_datapath_resp_t m_type; +}; /** @}*/ diff --git a/decoder/include/common/trc_core_arch_map.h b/decoder/include/common/trc_core_arch_map.h index b72b4b411fa4..aa976c39f908 100644 --- a/decoder/include/common/trc_core_arch_map.h +++ b/decoder/include/common/trc_core_arch_map.h @@ -53,7 +53,8 @@ * * Valid architecture profile names are:- * - ARMv7-A, ARMv7-R, ARMv7-M; - * - ARMv8-A, ARMv8.3A, ARMv8-R, ARMv8-M; + * - ARMv8-A, ARMv8.x-A, ARMv8-R, ARMv8-M; + * - ARM-AA64, ARM-aa64 * */ class CoreArchProfileMap @@ -65,36 +66,12 @@ public: ocsd_arch_profile_t getArchProfile(const std::string &coreName); private: + ocsd_arch_profile_t getPatternMatchCoreName(const std::string &coreName); std::map<std::string, ocsd_arch_profile_t> core_profiles; std::map<std::string, ocsd_arch_profile_t> arch_profiles; }; -inline ocsd_arch_profile_t CoreArchProfileMap::getArchProfile(const std::string &coreName) -{ - ocsd_arch_profile_t ap = { ARCH_UNKNOWN, profile_Unknown }; - bool bFound = false; - - std::map<std::string, ocsd_arch_profile_t>::const_iterator it; - - /* match against the core name map. */ - it = core_profiles.find(coreName); - if (it != core_profiles.end()) - { - ap = it->second; - bFound = true; - } - - /* scan architecture profiles on no core name match */ - if (!bFound) - { - it = arch_profiles.find(coreName); - if (it != arch_profiles.end()) - ap = it->second; - } - return ap; -} - #endif // ARM_TRC_CORE_ARCH_MAP_H_INCLUDED /* End of File trc_core_arch_map.h */ diff --git a/decoder/include/common/trc_frame_deformatter.h b/decoder/include/common/trc_frame_deformatter.h index e4297a41e8fd..cb2960fcdd07 100644 --- a/decoder/include/common/trc_frame_deformatter.h +++ b/decoder/include/common/trc_frame_deformatter.h @@ -73,6 +73,9 @@ public: componentAttachPt<ITraceErrorLog> *getErrLogAttachPt(); + /* init decoder implementation object */ + ocsd_err_t Init(); + /* configuration - set operational mode for incoming stream (has FSYNCS etc) */ ocsd_err_t Configure(uint32_t cfg_flags); const uint32_t getConfigFlags() const; @@ -85,9 +88,13 @@ public: 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 */ + /* demux stats */ + void SetDemuxStatsBlock(ocsd_demux_stats_t *pStatsBlock); + private: TraceFmtDcdImpl *m_pDecoder; int m_instNum; + }; /** @}*/ diff --git a/decoder/include/common/trc_gen_elem.h b/decoder/include/common/trc_gen_elem.h index 5d8983a8c274..405abfef8341 100644 --- a/decoder/include/common/trc_gen_elem.h +++ b/decoder/include/common/trc_gen_elem.h @@ -69,19 +69,22 @@ public: void setExcepMarker() { excep_data_marker = 1; }; void setExceptionNum(uint32_t excepNum) { exception_number = excepNum; }; - - void setTraceOnReason(const trace_on_reason_t reason); void setUnSyncEOTReason(const unsync_info_t reason); + void setTransactionType(const trace_memtrans_t trans) { mem_trans = trans; }; void setAddrRange(const ocsd_vaddr_t st_addr, const ocsd_vaddr_t en_addr, const int num_instr = 1); void setLastInstrInfo(const bool exec, const ocsd_instr_type last_i_type, const ocsd_instr_subtype last_i_subtype, const uint8_t size); - void setAddrStart(const ocsd_vaddr_t st_addr) { this->st_addr = st_addr; }; + void setAddrStart(const ocsd_vaddr_t st_addr) { this->st_addr = st_addr; }; void setLastInstrCond(const int is_cond) { this->last_instr_cond = is_cond; }; void setSWTInfo(const ocsd_swt_info_t swt_info) { sw_trace_info = swt_info; }; void setExtendedDataPtr(const void *data_ptr); + void setITEInfo(const trace_sw_ite_t sw_instrumentation) { sw_ite = sw_instrumentation; }; + + void setSyncMarker(const trace_marker_payload_t &marker); + // stringize the element virtual void toString(std::string &str) const; @@ -208,6 +211,11 @@ inline void OcsdTraceElement::setExtendedDataPtr(const void *data_ptr) ptr_extended_data = data_ptr; } +inline void OcsdTraceElement::setSyncMarker(const trace_marker_payload_t &marker) +{ + sync_marker = marker; +} + // set persistent data between output packets. inline void OcsdTraceElement::copyPersistentData(const OcsdTraceElement &src) { diff --git a/decoder/include/common/trc_pkt_decode_base.h b/decoder/include/common/trc_pkt_decode_base.h index da702068f372..24ea2b05a6f9 100644 --- a/decoder/include/common/trc_pkt_decode_base.h +++ b/decoder/include/common/trc_pkt_decode_base.h @@ -96,6 +96,7 @@ protected: /* 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); + ocsd_err_t invalidateMemAccCache(); /* instruction decode */ ocsd_err_t instrDecode(ocsd_instr_info *instr_info); @@ -180,6 +181,14 @@ inline ocsd_err_t TrcPktDecodeI::accessMemory(const ocsd_vaddr_t address, const return OCSD_ERR_DCD_INTERFACE_UNUSED; } +inline ocsd_err_t TrcPktDecodeI::invalidateMemAccCache() +{ + if (!m_uses_memaccess) + return OCSD_ERR_DCD_INTERFACE_UNUSED; + m_mem_access.first()->InvalidateMemAccCache(getCoreSightTraceID()); + return OCSD_OK; +} + /**********************************************************************/ template <class P, class Pc> class TrcPktDecodeBase : public TrcPktDecodeI, public IPktDataIn<P> diff --git a/decoder/include/common/trc_pkt_proc_base.h b/decoder/include/common/trc_pkt_proc_base.h index 3098a3d0c0ea..8ed7d83b2d5a 100644 --- a/decoder/include/common/trc_pkt_proc_base.h +++ b/decoder/include/common/trc_pkt_proc_base.h @@ -43,6 +43,7 @@ #include "trc_component.h" #include "comp_attach_pt_t.h" +#include "opencsd/ocsd_if_version.h" /** @defgroup ocsd_pkt_proc OpenCSD Library : Packet Processors. @brief Classes providing Protocol Packet Processing capability. @@ -76,6 +77,8 @@ public: const uint8_t *pDataBlock, uint32_t *numBytesProcessed) = 0; + virtual ocsd_err_t getStatsBlock(ocsd_decode_stats_t **pp_stats) = 0; + virtual void resetStats() = 0; protected: /* implementation packet processing interface */ @@ -155,6 +158,10 @@ public: //!< Get the configuration for the decoder. virtual const Pc *getProtocolConfig() const { return m_config; }; +/* stats block access - derived class must init stats for the block to be returned. */ + virtual ocsd_err_t getStatsBlock(ocsd_decode_stats_t **pp_stats); + virtual void resetStats(); /* reset the counts - operates separately from decoder reset. */ + protected: /* data output functions */ @@ -183,6 +190,14 @@ protected: const bool checkInit(); // return true if init (configured and at least one output sink attached), false otherwise. + /* stats block updates - called by derived protocol specific decoder */ + void statsAddTotalCount(const uint64_t count) { m_stats.channel_total += count; }; + void statsAddUnsyncCount(const uint64_t count) { m_stats.channel_unsynced += count; }; + void statsAddBadSeqCount(const uint32_t count) { m_stats.bad_sequence_errs += count; }; + void statsAddBadHdrCount(const uint32_t count) { m_stats.bad_header_errs += count; }; + void statsInit() { m_stats_init = true; }; /* mark stats as in use */ + + private: /* decode control */ ocsd_datapath_resp_t Reset(const ocsd_trc_index_t index); @@ -195,20 +210,29 @@ private: componentAttachPt<ITrcPktIndexer<Pt>> m_pkt_indexer_i; bool m_b_is_init; + + /* decode statistics block */ + ocsd_decode_stats_t m_stats; + bool m_stats_init; /*< true if the specific decoder is using the stats */ + }; 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) + m_b_is_init(false), + m_stats_init(false) { + resetStats(); } 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) + m_b_is_init(false), + m_stats_init(false) { + resetStats(); } template<class P,class Pt, class Pc> TrcPktProcBase<P, Pt, Pc>::~TrcPktProcBase() @@ -405,6 +429,26 @@ template<class P,class Pt, class Pc> const bool TrcPktProcBase<P, Pt, Pc>::check return m_b_is_init; } +template<class P,class Pt, class Pc> ocsd_err_t TrcPktProcBase<P, Pt, Pc>::getStatsBlock(ocsd_decode_stats_t **pp_stats) +{ + + *pp_stats = &m_stats; + return m_stats_init ? OCSD_OK : OCSD_ERR_NOT_INIT; +} + +template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::resetStats() +{ + m_stats.version = OCSD_VER_NUM; + m_stats.revision = OCSD_STATS_REVISION; + m_stats.channel_total = 0; + m_stats.channel_unsynced = 0; + m_stats.bad_header_errs = 0; + m_stats.bad_sequence_errs = 0; + m_stats.demux.frame_bytes = 0; + m_stats.demux.no_id_bytes = 0; + m_stats.demux.valid_id_bytes = 0; +} + /** @}*/ #endif // ARM_TRC_PKT_PROC_BASE_H_INCLUDED diff --git a/decoder/include/i_dec/trc_idec_arminst.h b/decoder/include/i_dec/trc_idec_arminst.h index 911b0cf7db95..e90ec04ae84d 100644 --- a/decoder/include/i_dec/trc_idec_arminst.h +++ b/decoder/include/i_dec/trc_idec_arminst.h @@ -44,7 +44,7 @@ /* supplementary decode information */ struct decode_info { - uint16_t arch_version; + ocsd_arch_version_t arch_version; ocsd_instr_subtype instr_sub_type; }; @@ -121,7 +121,8 @@ arm_barrier_t inst_A64_barrier(uint32_t inst); int inst_ARM_wfiwfe(uint32_t inst); int inst_Thumb_wfiwfe(uint32_t inst); -int inst_A64_wfiwfe(uint32_t inst); +int inst_A64_wfiwfe(uint32_t inst, struct decode_info *info); +int inst_A64_Tstart(uint32_t inst); /* Test whether an instruction is definitely undefined, e.g. because diff --git a/decoder/include/interfaces/trc_pkt_raw_in_i.h b/decoder/include/interfaces/trc_pkt_raw_in_i.h index 6f7b21383024..dfa7e057ca67 100644 --- a/decoder/include/interfaces/trc_pkt_raw_in_i.h +++ b/decoder/include/interfaces/trc_pkt_raw_in_i.h @@ -47,7 +47,7 @@ * * 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 + * type, plus the raw packet bytes. Use for tools which need to display complete * packets or require additional processing on raw packet data. * * This interface is not part of the data decode path and cannot provide feedback. diff --git a/decoder/include/interfaces/trc_tgt_mem_access_i.h b/decoder/include/interfaces/trc_tgt_mem_access_i.h index effc9b5e161e..68a4e10055d4 100644 --- a/decoder/include/interfaces/trc_tgt_mem_access_i.h +++ b/decoder/include/interfaces/trc_tgt_mem_access_i.h @@ -83,6 +83,14 @@ public: const ocsd_mem_space_acc_t mem_space, uint32_t *num_bytes, uint8_t *p_buffer) = 0; + + /*! + * Invalidate any caching that the memory accessor functions are using. + * Generally called when a memory context changes in the trace. + * + * @param cs_trace_id : protocol source trace ID. + */ + virtual void InvalidateMemAccCache(const uint8_t cs_trace_id) = 0; }; diff --git a/decoder/include/mem_acc/trc_mem_acc_mapper.h b/decoder/include/mem_acc/trc_mem_acc_mapper.h index a700e9dbd07e..4a08498df14e 100644 --- a/decoder/include/mem_acc/trc_mem_acc_mapper.h +++ b/decoder/include/mem_acc/trc_mem_acc_mapper.h @@ -61,6 +61,8 @@ public: uint32_t *num_bytes, uint8_t *p_buffer); + virtual void InvalidateMemAccCache(const uint8_t cs_trace_id); + // mapper memory area configuration interface // add an accessor to this map diff --git a/decoder/include/opencsd.h b/decoder/include/opencsd.h index 615bbcafa2d9..8af4fd0df5ef 100644 --- a/decoder/include/opencsd.h +++ b/decoder/include/opencsd.h @@ -63,6 +63,7 @@ #include "opencsd/etmv4/etmv4_decoder.h" #include "opencsd/ptm/ptm_decoder.h" #include "opencsd/stm/stm_decoder.h" +#include "opencsd/ete/ete_decoder.h" /** C++ library object types */ #include "common/ocsd_error_logger.h" diff --git a/decoder/include/opencsd/c_api/ocsd_c_api_types.h b/decoder/include/opencsd/c_api/ocsd_c_api_types.h index cde351fc525f..7f9b4bab9494 100644 --- a/decoder/include/opencsd/c_api/ocsd_c_api_types.h +++ b/decoder/include/opencsd/c_api/ocsd_c_api_types.h @@ -46,6 +46,7 @@ #include "opencsd/etmv4/trc_pkt_types_etmv4.h" #include "opencsd/ptm/trc_pkt_types_ptm.h" #include "opencsd/stm/trc_pkt_types_stm.h" +#include "opencsd/ete/trc_pkt_types_ete.h" /** @ingroup lib_c_api @{*/ diff --git a/decoder/include/opencsd/c_api/opencsd_c_api.h b/decoder/include/opencsd/c_api/opencsd_c_api.h index 90201d436e08..ebbba87d952e 100644 --- a/decoder/include/opencsd/c_api/opencsd_c_api.h +++ b/decoder/include/opencsd/c_api/opencsd_c_api.h @@ -210,10 +210,36 @@ OCSD_C_API ocsd_err_t ocsd_dt_attach_packet_callback( const dcd_tree_handle_t h const void *p_context); +/*! + * Get the stats block for the channel indicated. + * Caller must check p_stats_block->version to esure that the block + * is filled in a compatible manner. + * + * @param handle : Handle to decode tree. + * @param CSID : Configured CoreSight trace ID for the decoder. + * @param p_stats_block: block pointer to set to reference the stats block. + * + * @return ocsd_err_t : Library error code - OCSD_OK if valid block pointer returned, + * OCSD_ERR_NOTINIT if decoder does not support stats counting. + */ +OCSD_C_API ocsd_err_t ocsd_dt_get_decode_stats( const dcd_tree_handle_t handle, + const unsigned char CSID, + ocsd_decode_stats_t **p_stats_block); + +/*! + * Reset the stats block for the chosens decode channel. + * stats block is reset independently of the decoder reset to allow counts across + * multiple decode runs. + * + * @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_reset_decode_stats( const dcd_tree_handle_t handle, + const unsigned char CSID); - - /** @}*/ /*---------------------- Memory Access for traced opcodes ----------------------------------------------------------------------------------*/ /** @name Library Memory Accessor configuration on decode tree. @@ -373,6 +399,28 @@ OCSD_C_API ocsd_err_t ocsd_def_errlog_set_strprint_cb(const dcd_tree_handle_t ha */ OCSD_C_API void ocsd_def_errlog_msgout(const char *msg); +/*! + * Convert an error code into a string. + * + * @param err : error code. + * @param buffer : buffer for return string + * @param buffer_size : length of buffer. + */ +OCSD_C_API void ocsd_err_str(const ocsd_err_t err, char *buffer, const int buffer_size); + +/*! + * returns the last error logged by the system, with the related trace byte index, trace channel id, + * and any error message related string. + * If index or channel ID are not valid these will return OCSD_BAD_TRC_INDEX and OCSD_BAD_CS_SRC_ID. + * + * return value is the error code of the last logged error, OCSD_OK for no error available. + * + * @param index : returns trace byte index relating to error, or OCSD_BAD_TRC_INDEX + * @param chan_id : returns trace channel ID relating to error, or OCSD_BAD_CS_SRC_ID + * @param message : buffer to copy the last error message. + * @param message_len: length of message buffer. + */ +OCSD_C_API ocsd_err_t ocsd_get_last_err(ocsd_trc_index_t *index, uint8_t *chan_id, char *message, const int message_len); /** @}*/ diff --git a/decoder/include/opencsd/ete/ete_decoder.h b/decoder/include/opencsd/ete/ete_decoder.h new file mode 100644 index 000000000000..ba0d718bfff1 --- /dev/null +++ b/decoder/include/opencsd/ete/ete_decoder.h @@ -0,0 +1,47 @@ +/* +* \file ete_decoder.h +* \brief OpenCSD : Top level header file for ETE decoder. +* +* \copyright Copyright (c) 2019, ARM Limited. All Rights Reserved. +*/ + +/* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* +* 3. Neither the name of the copyright holder nor the names of its contributors +* may be used to endorse or promote products derived from this software without +* specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef ARM_ETE_DECODER_H_INCLUDED +#define ARM_ETE_DECODER_H_INCLUDED + +// ETE actually uses extended ETMv4 packet processor and decode +// ETE specifics limited to configuration +// +#include "trc_cmp_cfg_ete.h" +#include "trc_pkt_types_ete.h" + +#endif // ARM_ETE_DECODER_H_INCLUDED + +/* End of File ete_decoder.h */ + diff --git a/decoder/include/opencsd/ete/trc_cmp_cfg_ete.h b/decoder/include/opencsd/ete/trc_cmp_cfg_ete.h new file mode 100644 index 000000000000..8365ffa88460 --- /dev/null +++ b/decoder/include/opencsd/ete/trc_cmp_cfg_ete.h @@ -0,0 +1,81 @@ +/* +* \file trc_cmp_cfg_ete.h +* \brief OpenCSD : ETE configuration +* +* \copyright Copyright (c) 2019, ARM Limited. All Rights Reserved. +*/ + +/* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* +* 3. Neither the name of the copyright holder nor the names of its contributors +* may be used to endorse or promote products derived from this software without +* specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef ARM_TRC_CMP_CFG_ETE_H_INCLUDED +#define ARM_TRC_CMP_CFG_ETE_H_INCLUDED + +#include "trc_pkt_types_ete.h" +#include "opencsd/etmv4/trc_cmp_cfg_etmv4.h" + +/** @addtogroup ocsd_protocol_cfg +@{*/ + +/** @name ETE configuration +@{*/ + +/*! + * @class ETEConfig + * @brief Interpreter class for ETE config structure + * + * ETE trace and config are a superset of ETMv4 trace and config - hence + * use the EtmV4Config class as a base. + */ +class ETEConfig : public EtmV4Config +{ +public: + ETEConfig(); + ETEConfig(const ocsd_ete_cfg *cfg_regs); + ~ETEConfig(); + + //! copy assignment operator for base structure into class. + ETEConfig & operator=(const ocsd_ete_cfg *p_cfg); + + //! cast operator returning struct const reference + operator const ocsd_ete_cfg &() const { return m_ete_cfg; }; + //! cast operator returning struct const pointer + operator const ocsd_ete_cfg *() const { return &m_ete_cfg; }; + +private: + void copyV4(); // copy relevent config to underlying structure. + + ocsd_ete_cfg m_ete_cfg; +}; + + +/** @}*/ +/** @}*/ + +#endif // ARM_TRC_CMP_CFG_ETE_H_INCLUDED + +/* End of File trc_cmp_cfg_ete.h */ diff --git a/decoder/include/opencsd/ete/trc_dcd_mngr_ete.h b/decoder/include/opencsd/ete/trc_dcd_mngr_ete.h new file mode 100644 index 000000000000..7b0c134b20c5 --- /dev/null +++ b/decoder/include/opencsd/ete/trc_dcd_mngr_ete.h @@ -0,0 +1,58 @@ +/* +* \file trc_dcd_mngr_ete.h +* \brief OpenCSD : ETE decoder creation. +* +* \copyright Copyright (c) 2019, ARM Limited. All Rights Reserved. +*/ + +/* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* +* 3. Neither the name of the copyright holder nor the names of its contributors +* may be used to endorse or promote products derived from this software without +* specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef ARM_TRC_DCD_MNGR_ETE_H_INCLUDED +#define ARM_TRC_DCD_MNGR_ETE_H_INCLUDED + +#include "common/ocsd_dcd_mngr.h" +#include "trc_cmp_cfg_ete.h" +#include "opencsd/etmv4/trc_pkt_decode_etmv4i.h" +#include "opencsd/etmv4/trc_pkt_proc_etmv4.h" + +class DecoderMngrETE : public DecodeMngrFullDcdExCfg< EtmV4ITrcPacket, + ocsd_etmv4_i_pkt_type, + EtmV4Config, + ETEConfig, + ocsd_ete_cfg, + TrcPktProcEtmV4I, + TrcPktDecodeEtmV4I> +{ +public: + DecoderMngrETE(const std::string &name) : DecodeMngrFullDcdExCfg(name, OCSD_PROTOCOL_ETE) {}; + virtual ~DecoderMngrETE() {}; +}; + +#endif // ARM_TRC_DCD_MNGR_ETE_H_INCLUDED + +/* End of File trc_dcd_mngr_ete.h */ diff --git a/decoder/include/opencsd/ete/trc_pkt_types_ete.h b/decoder/include/opencsd/ete/trc_pkt_types_ete.h new file mode 100644 index 000000000000..f87d454605fd --- /dev/null +++ b/decoder/include/opencsd/ete/trc_pkt_types_ete.h @@ -0,0 +1,66 @@ +/* + * \file trc_pkt_types_ete.h + * \brief OpenCSD : ETE types + * + * \copyright Copyright (c) 2019, ARM Limited. All Rights Reserved. + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ARM_TRC_PKT_TYPES_ETE_H_INCLUDED +#define ARM_TRC_PKT_TYPES_ETE_H_INCLUDED + +#include "opencsd/trc_pkt_types.h" +#include "opencsd/etmv4/trc_pkt_types_etmv4.h" + /** @addtogroup trc_pkts + @{*/ + + /** @name ETE config Types + @{*/ + + +typedef struct _ocsd_ete_cfg +{ + uint32_t reg_idr0; /**< ID0 register */ + uint32_t reg_idr1; /**< ID1 register */ + uint32_t reg_idr2; /**< ID2 register */ + uint32_t reg_idr8; /**< ID8 - maxspec */ + uint32_t reg_devarch; /**< DevArch register */ + 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_ete_cfg; + + +/** @}*/ +/** @}*/ + +#endif // ARM_TRC_PKT_TYPES_ETE_H_INCLUDED + +/* End of File trc_pkt_types_ete.h */ diff --git a/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h b/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h index 1d72d97afe59..223dbda44510 100644 --- a/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h +++ b/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h @@ -81,6 +81,7 @@ public: const bool hasCycleCountI() const; const bool hasRetStack() const; const uint8_t numEvents() const; + const bool eteHasTSMarker() const; typedef enum _condType { COND_PASS_FAIL, @@ -104,6 +105,7 @@ public: const uint32_t TimeStampSize() const; const bool commitOpt1() const; + const bool commTransP0() const; /* idr 1 */ const uint8_t MajVersion() const; @@ -151,6 +153,7 @@ public: const bool enabledCCI() const; const bool enabledCID() const; const bool enabledVMID() const; + const bool enabledVMIDOpt() const; typedef enum { COND_TR_DIS, @@ -253,6 +256,11 @@ inline const bool EtmV4Config::hasTrcExcpData() const return (bool)((m_cfg.reg_idr0 & 0x20000) == 0x20000); } +inline const bool EtmV4Config::eteHasTSMarker() const +{ + return (FullVersion() >= 0x51) && ((m_cfg.reg_idr0 & 0x800000) == 0x800000); +} + inline const uint32_t EtmV4Config::TimeStampSize() const { uint32_t tsSizeF = (m_cfg.reg_idr0 >> 24) & 0x1F; @@ -268,6 +276,11 @@ inline const bool EtmV4Config::commitOpt1() const return (bool)((m_cfg.reg_idr0 & 0x20000000) == 0x20000000) && hasCycleCountI(); } +inline const bool EtmV4Config::commTransP0() const +{ + return (bool)((m_cfg.reg_idr0 & 0x40000000) == 0x0); +} + /* idr 1 */ inline const uint8_t EtmV4Config::MajVersion() const { @@ -424,6 +437,20 @@ inline const bool EtmV4Config::enabledVMID() const return ((m_cfg.reg_configr & (0x1 << 7)) != 0); } +inline const bool EtmV4Config::enabledVMIDOpt() const +{ + bool vmidOptVal = ((m_cfg.reg_configr & (0x1 << 15)) != 0); + /* TRIDR2.VMIDOPT[30:29] determine value used */ + if (!vmidOpt()) { /* [29] = 1'b0 */ + vmidOptVal = false; /* res0 */ + if (FullVersion() >= 0x45) { + /* umless version > 4.5 in which case [30] determines res val */ + vmidOptVal = ((m_cfg.reg_idr2 & (0x1 << 30)) != 0); + } + } + return vmidOptVal; +} + inline const EtmV4Config::CondITrace_t EtmV4Config::enabledCondITrace() { if(!m_condTraceCalc) diff --git a/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h b/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h index 5a283c541f3e..21bd7af434de 100644 --- a/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h +++ b/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h @@ -34,6 +34,7 @@ #define ARM_TRC_ETMV4_STACK_ELEM_H_INCLUDED #include "opencsd/etmv4/trc_pkt_types_etmv4.h" +#include "opencsd/trc_gen_elem_types.h" #include <deque> #include <vector> @@ -56,9 +57,16 @@ typedef enum _p0_elem_t P0_TS, P0_CC, P0_TS_CC, + P0_MARKER, P0_Q, P0_OVERFLOW, P0_FUNC_RET, + P0_SRC_ADDR, + P0_TRANS_TRACE_INIT, + P0_TRANS_START, + P0_TRANS_COMMIT, + P0_TRANS_FAIL, + P0_ITE, } p0_elem_t; @@ -101,6 +109,7 @@ class TrcStackElemAddr : public TrcStackElem { protected: TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); + TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const bool src_addr); virtual ~TrcStackElemAddr() {}; friend class EtmV4P0Stack; @@ -120,6 +129,14 @@ inline TrcStackElemAddr::TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, m_addr_val.isa = 0; } +inline TrcStackElemAddr::TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const bool src_addr) : + TrcStackElem(src_addr ? P0_SRC_ADDR : P0_ADDR, false, root_pkt, root_index) +{ + m_addr_val.val = 0; + m_addr_val.isa = 0; +} + + /************************************************************/ /** Q element */ class TrcStackQElem : public TrcStackElem @@ -295,6 +312,55 @@ inline TrcStackElemParam::TrcStackElemParam(const p0_elem_t p0_type, const bool } /************************************************************/ +/** Marker element */ + +class TrcStackElemMarker : public TrcStackElem +{ +protected: + TrcStackElemMarker(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); + virtual ~TrcStackElemMarker() {}; + + friend class EtmV4P0Stack; + +public: + void setMarker(const trace_marker_payload_t &marker) { m_marker = marker; }; + const trace_marker_payload_t &getMarker() const { return m_marker; }; + +private: + trace_marker_payload_t m_marker; +}; + +inline TrcStackElemMarker::TrcStackElemMarker(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : + TrcStackElem(P0_MARKER, false, root_pkt, root_index) +{ +} + +/************************************************************/ +/* Instrumentation element + */ + +class TrcStackElemITE : public TrcStackElem +{ +protected: + TrcStackElemITE(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); + virtual ~TrcStackElemITE() {}; + + friend class EtmV4P0Stack; + +public: + void setITE(const trace_sw_ite_t &ite) { m_ite = ite; }; + const trace_sw_ite_t &getITE() { return m_ite; }; + +private: + trace_sw_ite_t m_ite; +}; + +inline TrcStackElemITE::TrcStackElemITE(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : + TrcStackElem(P0_ITE, false, root_pkt, root_index) +{ +} + +/************************************************************/ /* P0 element stack that allows push of elements, and deletion of elements when done. */ class EtmV4P0Stack @@ -329,6 +395,10 @@ public: TrcStackElemCtxt *createContextElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_context_t &context, const uint8_t IS, const bool back = false); TrcStackElemAddr *createAddrElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_addr_val_t &addr_val); TrcStackQElem *createQElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const int count); + TrcStackElemMarker *createMarkerElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const trace_marker_payload_t &marker); + TrcStackElemAddr *createSrcAddrElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_addr_val_t &addr_val); + TrcStackElemITE *createITEElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const trace_sw_ite_t &ite); + 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. diff --git a/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h index 419cd828928c..7838ece04e57 100644 --- a/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h +++ b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h @@ -88,11 +88,29 @@ protected: // process Q element ocsd_err_t processQElement(); + // process a source address element + ocsd_err_t processSourceAddress(); + // process an element that cannot be cancelled / discarded ocsd_err_t processTS_CC_EventElem(TrcStackElem *pElem); + // process marker elements + ocsd_err_t processMarkerElem(TrcStackElem *pElem); + + // process a transaction element + ocsd_err_t processTransElem(TrcStackElem *pElem); + + // process an Instrumentation element + ocsd_err_t processITEElem(TrcStackElem *pElem); + // process a bad packet - ocsd_err_t handleBadPacket(const char *reason); + ocsd_err_t handleBadPacket(const char *reason, ocsd_trc_index_t index = OCSD_BAD_TRC_INDEX); + + // sequencing error on packet processing - optionally continue + ocsd_err_t handlePacketSeqErr(ocsd_err_t err, ocsd_trc_index_t index, const char *reason); + + // common packet error routine + ocsd_err_t handlePacketErr(ocsd_err_t err, ocsd_err_severity_t sev, ocsd_trc_index_t index, const char *reason); ocsd_err_t addElemCC(TrcStackElemParam *pParamElem); ocsd_err_t addElemTS(TrcStackElemParam *pParamElem, bool withCC); @@ -127,6 +145,13 @@ private: ocsd_err_t returnStackPop(); // pop return stack and update instruction address. void setElemTraceRange(OcsdTraceElement &elemIn, const instr_range_t &addr_range, const bool executed, ocsd_trc_index_t index); + void setElemTraceRangeInstr(OcsdTraceElement &elemIn, const instr_range_t &addr_range, + const bool executed, ocsd_trc_index_t index, ocsd_instr_info &instr); + + // true if we are ETE configured. + inline bool isETEConfig() { + return (m_config->MajVersion() >= ETE_ARCH_VERSION); + } ocsd_mem_space_acc_t getCurrMemSpace(); @@ -134,6 +159,7 @@ private: // timestamping uint64_t m_timestamp; // last broadcast global Timestamp. + bool m_ete_first_ts_marker; // state and context uint32_t m_context_id; // most recent context ID diff --git a/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h index 8ccf36b373db..02404749718d 100644 --- a/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h +++ b/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h @@ -145,7 +145,7 @@ public: 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 setContextInfo(const bool update, const uint8_t EL = 0, const uint8_t NS = 0, const uint8_t SF = 0, const uint8_t NSE = 0); void setContextVMID(const uint32_t VMID); void setContextCID(const uint32_t CID); @@ -160,6 +160,7 @@ public: 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); + void setITE(const uint8_t el, const uint64_t value); // packet status interface - get packet info. const ocsd_etmv4_i_pkt_type getType() const { return type; }; @@ -200,6 +201,10 @@ public: const int getCommitElem() const { return commit_elements; }; const int getCancelElem() const { return cancel_elements; }; + // ITE + const uint8_t getITE_EL() const { return ite_pkt.el; }; + const uint64_t getITE_value() const { return ite_pkt.value; }; + // packet type const bool isBadPacket() const; @@ -207,6 +212,8 @@ public: virtual void toString(std::string &str) const; virtual void toStringFmt(const uint32_t fmtFlags, std::string &str) const; + void setProtocolVersion(const uint8_t version) { protocol_version = version; }; + private: const char *packetTypeName(const ocsd_etmv4_i_pkt_type type, const char **pDesc) const; void contextStr(std::string &ctxtStr) const; @@ -217,6 +224,8 @@ private: void push_vaddr(); void pop_vaddr_idx(const uint8_t idx); + const bool isETE() const { return (protocol_version & 0xF0) == 0x50; }; + Etmv4PktAddrStack m_addr_stack; }; @@ -412,7 +421,7 @@ inline void EtmV4ITrcPacket::setCondRF4(const uint8_t token) cond_result.f2f4_token = token; } -inline void EtmV4ITrcPacket::setContextInfo(const bool update, const uint8_t EL, const uint8_t NS, const uint8_t SF) +inline void EtmV4ITrcPacket::setContextInfo(const bool update, const uint8_t EL, const uint8_t NS, const uint8_t SF, const uint8_t NSE) { pkt_valid.bits.context_valid = 1; if(update) @@ -421,6 +430,7 @@ inline void EtmV4ITrcPacket::setContextInfo(const bool update, const uint8_t EL, context.EL = EL; context.NS = NS; context.SF = SF; + context.NSE = NSE; } } @@ -534,6 +544,12 @@ inline void EtmV4ITrcPacket::pop_vaddr_idx(const uint8_t idx) m_addr_stack.get_idx(idx, v_addr, v_addr_ISA); } +inline void EtmV4ITrcPacket::setITE(const uint8_t el, const uint64_t value) +{ + ite_pkt.el = el; + ite_pkt.value = value; +} + /** @}*/ #endif // ARM_TRC_PKT_ELEM_ETMV4I_H_INCLUDED diff --git a/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4i.h index abc322654b8d..58c0d78806c3 100644 --- a/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4i.h +++ b/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4i.h @@ -117,6 +117,7 @@ private: #define TINFO_KEY_SECT 0x02 #define TINFO_SPEC_SECT 0x04 #define TINFO_CYCT_SECT 0x08 + #define TINFO_WNDW_SECT 0x10 #define TINFO_CTRL 0x20 #define TINFO_ALL_SECT 0x1F #define TINFO_ALL 0x3F @@ -178,9 +179,10 @@ private: void iPktQ(const uint8_t lastByte); void iAtom(const uint8_t lastByte); void iPktInvalidCfg(const uint8_t lastByte); // packet invalid in current config. + void iPktITE(const uint8_t lastByte); unsigned extractContField(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint32_t &value, const unsigned byte_limit = 5); - unsigned extractContField64(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint64_t &value, const unsigned byte_limit = 9); + unsigned extractTSField64(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint64_t &value); unsigned extractCondResult(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint32_t& key, uint8_t &result); void extractAndSetContextInfo(const std::vector<uint8_t> &buffer, const int st_idx); int extract64BitLongAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint64_t &value); diff --git a/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h b/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h index 7e98050c77c4..2a03b088c043 100644 --- a/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h +++ b/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h @@ -1,8 +1,8 @@ /* * \file trc_pkt_types_etmv4.h - * \brief OpenCSD : ETMv4 packet info + * \brief OpenCSD : ETMv4 / ETE packet info * - * \copyright Copyright (c) 2015,2019 ARM Limited. All Rights Reserved. + * \copyright Copyright (c) 2015,2019,2022 ARM Limited. All Rights Reserved. */ @@ -41,7 +41,7 @@ /** @addtogroup trc_pkts @{*/ -/** @name ETMv4 Packet Types +/** @name ETMv4 Packet Types, ETE packet Types @{*/ /** I stream packets. */ @@ -70,9 +70,12 @@ typedef enum _ocsd_etmv4_i_pkt_type ETM4_PKT_I_FUNC_RET = 0x05, /*!< b00000101 (V8M only) */ // Exceptions ETM4_PKT_I_EXCEPT = 0x06, /*!< b00000110 */ - ETM4_PKT_I_EXCEPT_RTN = 0x07, /*!< b00000111 */ + ETM4_PKT_I_EXCEPT_RTN = 0x07, /*!< b00000111 (ETE invalid) */ - /* unused encodings 0x08-0xB b00001000 to b00001011 */ + /* unused encoding 0x08 b00001000 */ + ETE_PKT_I_ITE = 0x09, /*! b00001001 (ETE only) */ + ETE_PKT_I_TRANS_ST = 0x0A, /*! b00001010 (ETE only) */ + ETE_PKT_I_TRANS_COMMIT = 0x0B, /*! b00001011 (ETE only) */ /* cycle count packets */ ETM4_PKT_I_CCNT_F2 = 0x0C, /*!< b0000110x */ @@ -91,7 +94,7 @@ typedef enum _ocsd_etmv4_i_pkt_type ETM4_PKT_I_CANCEL_F2 = 0x34, /*!< b001101xx */ ETM4_PKT_I_CANCEL_F3 = 0x38, /*!< b00111xxx */ - /* conditional instruction tracing */ + /* conditional instruction tracing - (reserved encodings ETE) */ ETM4_PKT_I_COND_I_F2 = 0x40, /*!< b01000000 - b01000010 */ ETM4_PKT_I_COND_FLUSH = 0x43, /*!< b01000011 */ ETM4_PKT_I_COND_RES_F4 = 0x44, /*!< b0100010x, b01000110 */ @@ -116,7 +119,8 @@ typedef enum _ocsd_etmv4_i_pkt_type ETM4_PKT_I_ADDR_CTXT_L_64IS0 = 0x85, /*!< b10000101 */ ETM4_PKT_I_ADDR_CTXT_L_64IS1, /*!< b10000110 */ /* unused encoding 0x87 b10000111 */ - /* unused encodings 0x88-0x8F b10001xxx */ + ETE_PKT_I_TS_MARKER = 0x88, /*!< b10001000 */ + /* unused encodings 0x89-0x8F b10001001 to b10001111 */ ETM4_PKT_I_ADDR_MATCH = 0x90, /*!< b10010000 to b10010010 0x92 */ /* unused encodings 0x93-0x94 b10010011 to b10010010 */ ETM4_PKT_I_ADDR_S_IS0 = 0x95, /*!< b10010101 */ @@ -132,7 +136,15 @@ typedef enum _ocsd_etmv4_i_pkt_type /* Q packets */ ETM4_PKT_I_Q = 0xA0, /*!< b1010xxxx */ - /* unused encodings 0xB0-0xBF b1011xxxx */ + /* ETE source address packets, unused ETMv4 */ + ETE_PKT_I_SRC_ADDR_MATCH = 0xB0, /*!< b101100xx */ + ETE_PKT_I_SRC_ADDR_S_IS0 = 0xB4, /*!< b10110100 */ + ETE_PKT_I_SRC_ADDR_S_IS1 = 0xB5, /*!< b10110101 */ + ETE_PKT_I_SRC_ADDR_L_32IS0 = 0xB6, /*!< b10110110 */ + ETE_PKT_I_SRC_ADDR_L_32IS1 = 0xB7, /*!< b10110111 */ + ETE_PKT_I_SRC_ADDR_L_64IS0 = 0xB8, /*!< b10111000 */ + ETE_PKT_I_SRC_ADDR_L_64IS1 = 0xB9, /*!< b10111001 */ + /* unused encodings 0xBA-0xBF b10111010 - b10111111 */ /* Atom packets */ ETM4_PKT_I_ATOM_F6 = 0xC0, /*!< b11000000 - b11010100 0xC0 - 0xD4, b11100000 - b11110100 0xE0 - 0xF4 */ @@ -147,15 +159,20 @@ typedef enum _ocsd_etmv4_i_pkt_type ETM4_PKT_I_DISCARD = 0x103, //!< b00000011 ETM4_PKT_I_OVERFLOW = 0x105, //!< b00000101 + // ETE extended types + ETE_PKT_I_PE_RESET = 0x400, // base type is exception packet. + ETE_PKT_I_TRANS_FAIL = 0x401, // base type is exception packet. + } 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 cond_enabled:3; //!< conditional trace enabled type. uint32_t p0_load:1; //!< 1 if tracing with P0 load elements (for data trace) uint32_t p0_store:1; //!< 1 if tracing with P0 store elements (for data trace) + uint32_t in_trans_state:1; //!< 1 if starting trace when in a transactional state (ETE trace). } bits; //!< bitfields for trace info value. } etmv4_trace_info_t; @@ -167,6 +184,7 @@ typedef struct _etmv4_context_t { 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 NSE:1; //!< PE FEAT_RME: root / realm indicator }; uint32_t ctxtID; //!< Current ctxtID uint32_t VMID; //!< current VMID @@ -256,6 +274,11 @@ typedef struct _ocsd_etmv4_i_pkt }; } Q_pkt; + struct { + uint8_t el; + uint64_t value; + } ite_pkt; + //! valid bits for packet elements (addresses have their own valid bits). union { uint32_t val; @@ -277,6 +300,9 @@ typedef struct _ocsd_etmv4_i_pkt ocsd_etmv4_i_pkt_type err_type; uint8_t err_hdr_val; + // protocol version - validity of ETE specific fields 0xMm == v Major.minor + uint8_t protocol_version; + } ocsd_etmv4_i_pkt; @@ -359,6 +385,9 @@ typedef struct _ocsd_etmv4_cfg ocsd_core_profile_t core_prof; /**< Core Profile */ } ocsd_etmv4_cfg; +#define ETE_ARCH_VERSION 0x5 + +#define ETE_OPFLG_PKTDEC_SRCADDR_N_ATOMS 0x00010000 /**< Split source address output ranges for N-atoms */ /** @}*/ /** @}*/ diff --git a/decoder/include/opencsd/ocsd_if_types.h b/decoder/include/opencsd/ocsd_if_types.h index 23087ee694b1..f5ff6ac6c530 100644 --- a/decoder/include/opencsd/ocsd_if_types.h +++ b/decoder/include/opencsd/ocsd_if_types.h @@ -278,11 +278,13 @@ typedef enum _ocsd_arch_version { ARCH_V7 = 0x0700, /**< V7 architecture */ ARCH_V8 = 0x0800, /**< V8 architecture */ ARCH_V8r3 = 0x0803, /**< V8.3 architecture */ + ARCH_AA64 = 0x0864, /**< Min v8r3 plus additional AA64 PE features */ + ARCH_V8_max = ARCH_AA64, } ocsd_arch_version_t; // macros for arch version comparisons. -#define OCSD_IS_V8_ARCH(arch) ((arch >= ARCH_V8) && (arch <= ARCH_V8r3)) -#define OCSD_MIN_V8_ARCH(arch) (arch >= ARCH_V8) +#define OCSD_IS_V8_ARCH(arch) ((arch >= ARCH_V8) && (arch <= ARCH_V8_max)) +#define OCSD_IS_ARCH_MINVER(arch, min_arch) (arch >= min_arch) /** Core Profile */ typedef enum _ocsd_core_profile { @@ -336,8 +338,10 @@ typedef enum _ocsd_isa */ typedef enum _ocsd_sec_level { - ocsd_sec_secure, /**< Core is in secure state */ - ocsd_sec_nonsecure /**< Core is in non-secure state */ + ocsd_sec_secure, /**< Core is in secure state */ + ocsd_sec_nonsecure, /**< Core is in non-secure state */ + ocsd_sec_root, /**< PE FEAT_RME: Core is in root state. */ + ocsd_sec_realm, /**< PE FEAT_RME: Core is in realm state. */ } ocsd_sec_level ; /** Exception level type @@ -352,7 +356,7 @@ typedef enum _ocsd_ex_level } ocsd_ex_level; -/** instruction types - significant for waypoint calculaitons */ +/** instruction types - significant for waypoint calculations */ typedef enum _ocsd_instr_type { OCSD_INSTR_OTHER, /**< Other instruction - not significant for waypoints. */ OCSD_INSTR_BR, /**< Immediate Branch instruction */ @@ -360,6 +364,7 @@ typedef enum _ocsd_instr_type { OCSD_INSTR_ISB, /**< Barrier : ISB instruction */ OCSD_INSTR_DSB_DMB, /**< Barrier : DSB or DMB instruction */ OCSD_INSTR_WFI_WFE, /**< WFI or WFE traced as direct branch */ + OCSD_INSTR_TSTART, /**< PE Arch feature FEAT_TME - TSTART instruction */ } ocsd_instr_type; /** instruction sub types - addiitonal information passed to the output packets @@ -521,10 +526,11 @@ typedef struct _ocsd_file_mem_region { (common flags share bitfield with pkt processor common flags and create flags) @{*/ -#define OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS 0x00000100 /**< throw error on bad packets input (default is to unsync and wait) */ +#define OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS 0x00000100 /**< throw error on bad packets input (default is to warn) */ +#define OCSD_OPFLG_PKTDEC_HALT_BAD_PKTS 0x00000200 /**< halt decoder on bad packets (default is to log error and continue by resetting decoder and wait for sync */ /** mask to combine all common packet processor operational control flags */ -#define OCSD_OPFLG_PKTDEC_COMMON (OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS) +#define OCSD_OPFLG_PKTDEC_COMMON (OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS | OCSD_OPFLG_PKTDEC_HALT_BAD_PKTS) /** @}*/ @@ -547,6 +553,7 @@ typedef struct _ocsd_file_mem_region { #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 */ +#define OCSD_BUILTIN_DCD_ETE "ETE" /**< ETE decoder */ /*! Trace Protocol Builtin Types + extern */ @@ -559,6 +566,7 @@ typedef enum _ocsd_trace_protocol_t { 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. */ + OCSD_PROTOCOL_ETE, /**< ETE trace protocol decoder */ /* others to be added here */ OCSD_PROTOCOL_BUILTIN_END, /**< Invalid protocol - built-in protocol types end marker */ @@ -627,6 +635,56 @@ typedef struct _ocsd_swt_info { /** @}*/ +/** @name Demux Statistics + + Contains statistics for the CoreSight frame demultiplexor. + + Counts total bytes sent to decoders registered against a trace ID, bytes in the input stream that are + associated with a trace ID that has no registered decoder, and frame bytes that are not trace data, but + are used to decode the frames - ID bytes, sync bytes etc. +@{*/ + +typedef struct _ocsd_demux_stats { + uint64_t valid_id_bytes; /**< number of bytes associated with an ID that has a registered decoder */ + uint64_t no_id_bytes; /**< number of bytes associated with an ID that has no decoder */ + uint64_t reserved_id_bytes; /**< number of bytes associated with reserved IDs */ + uint64_t unknown_id_bytes; /**< bytes processed before ID seen in input frames */ + uint64_t frame_bytes; /**< number of non-data bytes used for frame de-mux - ID bytes, sync etc */ +} ocsd_demux_stats_t; + +/** @}*/ + +/** @name Decode statistics + + Contains statistics for bytes decoded by the packet decoder, if statistics are supported. + + Stats block instantiated in the base class - derived protocol specific decoder must initialise and + use as required. + + The single channel block contains the stats for the requested channel via the API call. + + The global demux block contains the totals for all channels and non-data bytes used in CoreSight + frame demux. This block will show identical data for every requested channel via the API. + +@{*/ + +typedef struct _ocsd_decode_stats { + uint32_t version; /**< library version number */ + uint16_t revision; /**< revision number - defines the structure version for the stats. */ + /* single channel block */ + uint64_t channel_total; /**< total bytes processed for this channel */ + uint64_t channel_unsynced; /**< number of unsynced bytes processed on this channel */ + uint32_t bad_header_errs; /**< number of bad packet header errors */ + uint32_t bad_sequence_errs; /**< number of bad packet sequence errors */ + + ocsd_demux_stats_t demux; /**< global demux stats block */ +} ocsd_decode_stats_t; + +#define OCSD_STATS_REVISION 0x1 + +/** @}*/ + + /** @}*/ #endif // ARM_OCSD_IF_TYPES_H_INCLUDED diff --git a/decoder/include/opencsd/ocsd_if_version.h b/decoder/include/opencsd/ocsd_if_version.h index 38baa02e8b48..41033f0675ed 100644 --- a/decoder/include/opencsd/ocsd_if_version.h +++ b/decoder/include/opencsd/ocsd_if_version.h @@ -42,9 +42,9 @@ /** @name Library Versioning @{*/ -#define OCSD_VER_MAJOR 0x0 /**< Library Major Version */ -#define OCSD_VER_MINOR 0xE /**< Library Minor Version */ -#define OCSD_VER_PATCH 0x2 /**< Library Patch Version */ +#define OCSD_VER_MAJOR 0x1 /**< Library Major Version */ +#define OCSD_VER_MINOR 0x4 /**< Library Minor Version */ +#define OCSD_VER_PATCH 0x0 /**< Library Patch Version */ /** Library version number - MMMMnnpp format. MMMM = major version, @@ -53,7 +53,7 @@ */ #define OCSD_VER_NUM ((OCSD_VER_MAJOR << 16) | (OCSD_VER_MINOR << 8) | OCSD_VER_PATCH) -#define OCSD_VER_STRING "0.14.2" /**< Library Version string */ +#define OCSD_VER_STRING "1.4.0" /**< Library Version string */ #define OCSD_LIB_NAME "OpenCSD Library" /**< Library name string */ #define OCSD_LIB_SHORT_NAME "OCSD" /**< Library Short name string */ /** @}*/ diff --git a/decoder/include/opencsd/stm/trc_pkt_proc_stm.h b/decoder/include/opencsd/stm/trc_pkt_proc_stm.h index 909ac0cb0566..bc4391bfebfb 100644 --- a/decoder/include/opencsd/stm/trc_pkt_proc_stm.h +++ b/decoder/include/opencsd/stm/trc_pkt_proc_stm.h @@ -239,7 +239,8 @@ inline void TrcPktProcStm::checkSyncNibble() if((m_nibble == 0) && (m_num_F_nibbles >= 21)) { - m_is_sync = true; //this nibble marks a sync sequence - keep the F nibble count + m_is_sync = true; //this nibble marks a sync sequence + m_num_F_nibbles = 21; // set the F nibble count - lose any extra as unsynced data. } else { diff --git a/decoder/include/opencsd/trc_gen_elem_types.h b/decoder/include/opencsd/trc_gen_elem_types.h index 1a285a064b63..99194d118438 100644 --- a/decoder/include/opencsd/trc_gen_elem_types.h +++ b/decoder/include/opencsd/trc_gen_elem_types.h @@ -60,7 +60,10 @@ typedef enum _ocsd_gen_trc_elem_t 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 or numbered event */ - OCSD_GEN_TRC_ELEM_SWTRACE, /*!< Software trace packet - may contain data payload. */ + OCSD_GEN_TRC_ELEM_SWTRACE, /*!< Software trace packet - may contain data payload. STM / ITM hardware trace with channel protocol */ + OCSD_GEN_TRC_ELEM_SYNC_MARKER, /*!< Synchronisation marker - marks position in stream of an element that is output later. */ + OCSD_GEN_TRC_ELEM_MEMTRANS, /*!< Trace indication of transactional memory operations. */ + OCSD_GEN_TRC_ELEM_INSTRUMENTATION, /*!< PE instrumentation trace - PE generated SW trace, application dependent protocol. */ OCSD_GEN_TRC_ELEM_CUSTOM, /*!< Fully custom packet type - used by none-ARM architecture decoders */ } ocsd_gen_trc_elem_t; @@ -86,6 +89,27 @@ typedef enum _unsync_info_t { UNSYNC_EOT, /**< end of trace - no additional info */ } unsync_info_t; +typedef enum _trace_sync_marker_t { + ELEM_MARKER_TS, /**< Marker for timestamp element */ +} trace_sync_marker_t; + +typedef struct _trace_marker_payload_t { + trace_sync_marker_t type; /**< type of sync marker */ + uint32_t value; /**< sync marker value - usage depends on type */ +} trace_marker_payload_t; + +typedef enum _memtrans_t { + OCSD_MEM_TRANS_TRACE_INIT,/**< Trace started while PE in transactional state */ + OCSD_MEM_TRANS_START, /**< Trace after this packet is part of a transactional memory sequence */ + OCSD_MEM_TRANS_COMMIT, /**< Transactional memory sequence valid. */ + OCSD_MEM_TRANS_FAIL, /**< Transactional memory sequence failed - operations since start of transaction have been unwound. */ +} trace_memtrans_t; + +typedef struct _sw_ite_t { + uint8_t el; /**< exception level for PE sw instrumentation instruction */ + uint64_t value; /**< payload for PE sw instrumentation instruction */ +} trace_sw_ite_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 */ @@ -122,6 +146,9 @@ typedef struct _ocsd_generic_trace_elem { ocsd_swt_info_t sw_trace_info; /**< software trace packet info */ uint32_t num_instr_range; /**< number of instructions covered by range packet (for T32 this cannot be calculated from en-st/i_size) */ unsync_info_t unsync_eot_info; /**< additional information for unsync / end-of-trace packets. */ + trace_marker_payload_t sync_marker; /**< marker element - sync later element to position in stream */ + trace_memtrans_t mem_trans; /**< memory transaction packet - transaction event */ + trace_sw_ite_t sw_ite; /**< PE sw instrumentation using FEAT_ITE */ }; const void *ptr_extended_data; /**< pointer to extended data buffer (data trace, sw trace payload) / custom structure */ |