diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 07:24:57 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 07:24:57 +0000 |
commit | 070852d8604cece0c31f28ff3eb8d21d9ba415fb (patch) | |
tree | 9097175a6a5b8b7e37af9a96269ac0b61a0189cd /decoder/include/opencsd | |
parent | Initial commit. (diff) | |
download | libopencsd-070852d8604cece0c31f28ff3eb8d21d9ba415fb.tar.xz libopencsd-070852d8604cece0c31f28ff3eb8d21d9ba415fb.zip |
Adding upstream version 1.3.3.upstream/1.3.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'decoder/include/opencsd')
43 files changed, 8197 insertions, 0 deletions
diff --git a/decoder/include/opencsd/c_api/ocsd_c_api_cust_fact.h b/decoder/include/opencsd/c_api/ocsd_c_api_cust_fact.h new file mode 100644 index 0000000..f9e6a95 --- /dev/null +++ b/decoder/include/opencsd/c_api/ocsd_c_api_cust_fact.h @@ -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 */ diff --git a/decoder/include/opencsd/c_api/ocsd_c_api_cust_impl.h b/decoder/include/opencsd/c_api/ocsd_c_api_cust_impl.h new file mode 100644 index 0000000..245ce16 --- /dev/null +++ b/decoder/include/opencsd/c_api/ocsd_c_api_cust_impl.h @@ -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 */ diff --git a/decoder/include/opencsd/c_api/ocsd_c_api_custom.h b/decoder/include/opencsd/c_api/ocsd_c_api_custom.h new file mode 100644 index 0000000..ada0a68 --- /dev/null +++ b/decoder/include/opencsd/c_api/ocsd_c_api_custom.h @@ -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 */ diff --git a/decoder/include/opencsd/c_api/ocsd_c_api_types.h b/decoder/include/opencsd/c_api/ocsd_c_api_types.h new file mode 100644 index 0000000..7f9b4ba --- /dev/null +++ b/decoder/include/opencsd/c_api/ocsd_c_api_types.h @@ -0,0 +1,107 @@ +/*! + * \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/ocsd_if_version.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" +#include "opencsd/ete/trc_pkt_types_ete.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 */ diff --git a/decoder/include/opencsd/c_api/opencsd_c_api.h b/decoder/include/opencsd/c_api/opencsd_c_api.h new file mode 100644 index 0000000..ebbba87 --- /dev/null +++ b/decoder/include/opencsd/c_api/opencsd_c_api.h @@ -0,0 +1,550 @@ +/*! + * \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 version, 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); + + +/*! + * 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. + @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); + + +/*! + * 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 - Signature for CB with Trace ID passed to client. + * @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_trcid_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_MemAccID_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); + +/*! + * 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); + +/** @}*/ + +/** @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 */ diff --git a/decoder/include/opencsd/ete/ete_decoder.h b/decoder/include/opencsd/ete/ete_decoder.h new file mode 100644 index 0000000..ba0d718 --- /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 0000000..8365ffa --- /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 0000000..7b0c134 --- /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 0000000..f87d454 --- /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/etmv3/etmv3_decoder.h b/decoder/include/opencsd/etmv3/etmv3_decoder.h new file mode 100644 index 0000000..2d5b728 --- /dev/null +++ b/decoder/include/opencsd/etmv3/etmv3_decoder.h @@ -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 */ diff --git a/decoder/include/opencsd/etmv3/trc_cmp_cfg_etmv3.h b/decoder/include/opencsd/etmv3/trc_cmp_cfg_etmv3.h new file mode 100644 index 0000000..509de20 --- /dev/null +++ b/decoder/include/opencsd/etmv3/trc_cmp_cfg_etmv3.h @@ -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 */ diff --git a/decoder/include/opencsd/etmv3/trc_dcd_mngr_etmv3.h b/decoder/include/opencsd/etmv3/trc_dcd_mngr_etmv3.h new file mode 100644 index 0000000..c3a96ff --- /dev/null +++ b/decoder/include/opencsd/etmv3/trc_dcd_mngr_etmv3.h @@ -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 */ diff --git a/decoder/include/opencsd/etmv3/trc_pkt_decode_etmv3.h b/decoder/include/opencsd/etmv3/trc_pkt_decode_etmv3.h new file mode 100644 index 0000000..9027706 --- /dev/null +++ b/decoder/include/opencsd/etmv3/trc_pkt_decode_etmv3.h @@ -0,0 +1,275 @@ +/*! + * \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; + unsync_info_t m_unsync_info; //!< additional state for unsync + + 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 */ diff --git a/decoder/include/opencsd/etmv3/trc_pkt_elem_etmv3.h b/decoder/include/opencsd/etmv3/trc_pkt_elem_etmv3.h new file mode 100644 index 0000000..a874ea3 --- /dev/null +++ b/decoder/include/opencsd/etmv3/trc_pkt_elem_etmv3.h @@ -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 */ diff --git a/decoder/include/opencsd/etmv3/trc_pkt_proc_etmv3.h b/decoder/include/opencsd/etmv3/trc_pkt_proc_etmv3.h new file mode 100644 index 0000000..5a7f959 --- /dev/null +++ b/decoder/include/opencsd/etmv3/trc_pkt_proc_etmv3.h @@ -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 */ diff --git a/decoder/include/opencsd/etmv3/trc_pkt_types_etmv3.h b/decoder/include/opencsd/etmv3/trc_pkt_types_etmv3.h new file mode 100644 index 0000000..c2e0114 --- /dev/null +++ b/decoder/include/opencsd/etmv3/trc_pkt_types_etmv3.h @@ -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 */ diff --git a/decoder/include/opencsd/etmv4/etmv4_decoder.h b/decoder/include/opencsd/etmv4/etmv4_decoder.h new file mode 100644 index 0000000..5d18363 --- /dev/null +++ b/decoder/include/opencsd/etmv4/etmv4_decoder.h @@ -0,0 +1,47 @@ +/* + * \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_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 */ diff --git a/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h b/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h new file mode 100644 index 0000000..223dbda --- /dev/null +++ b/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h @@ -0,0 +1,492 @@ +/* + * \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; + const bool eteHasTSMarker() 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; + const bool commTransP0() const; + + /* idr 1 */ + const uint8_t MajVersion() const; + const uint8_t MinVersion() const; + const uint8_t FullVersion() 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; + const bool wfiwfeBranch() 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; + const bool enabledVMIDOpt() 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; + +protected: + ocsd_etmv4_cfg m_cfg; + uint8_t m_MajVer; + uint8_t m_MinVer; + +}; + +/* 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 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; + 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(); +} + +inline const bool EtmV4Config::commTransP0() const +{ + return (bool)((m_cfg.reg_idr0 & 0x40000000) == 0x0); +} + + /* idr 1 */ +inline const uint8_t EtmV4Config::MajVersion() const +{ + return m_MajVer; +} + +inline const uint8_t EtmV4Config::MinVersion() const +{ + return m_MinVer; +} + +inline const uint8_t EtmV4Config::FullVersion() const +{ + return (m_MajVer << 4) | m_MinVer; +} + +/* 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); +} + +inline const bool EtmV4Config::wfiwfeBranch() const +{ + return (bool)((m_cfg.reg_idr2 & 0x80000000) && (FullVersion() >= 0x43)); +} + + +/* 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 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) + { + 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 */ diff --git a/decoder/include/opencsd/etmv4/trc_dcd_mngr_etmv4i.h b/decoder/include/opencsd/etmv4/trc_dcd_mngr_etmv4i.h new file mode 100644 index 0000000..a5b2540 --- /dev/null +++ b/decoder/include/opencsd/etmv4/trc_dcd_mngr_etmv4i.h @@ -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 */ diff --git a/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h b/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h new file mode 100644 index 0000000..c5c609c --- /dev/null +++ b/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h @@ -0,0 +1,477 @@ +/* + * \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 "opencsd/trc_gen_elem_types.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_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_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); + 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; + +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; +} + +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 +{ +protected: + TrcStackQElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); + virtual ~TrcStackQElem() {}; + + friend class EtmV4P0Stack; + +public: + void setInstrCount(const int instr_count) { m_instr_count = instr_count; }; + const int getInstrCount() const { return m_instr_count; } + + void setAddr(const etmv4_addr_val_t &addr_val) + { + m_addr_val = addr_val; + m_has_addr = true; + }; + const etmv4_addr_val_t &getAddr() const { return m_addr_val; }; + const bool hasAddr() const { return m_has_addr; }; + +private: + bool m_has_addr; + etmv4_addr_val_t m_addr_val; + int m_instr_count; + +}; + +inline TrcStackQElem::TrcStackQElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : + TrcStackElem(P0_Q , true, root_pkt, root_index) +{ + m_addr_val.val = 0; + m_addr_val.isa = 0; + m_has_addr = false; + m_instr_count = 0; +} + +/************************************************************/ +/** Context element */ + +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; }; + void setIS(const uint8_t IS) { m_IS = IS; }; + const uint8_t getIS() const { return m_IS; }; + +private: + etmv4_context_t m_context; + uint8_t m_IS; //!< IS value at time of generation of packet. +}; + +inline TrcStackElemCtxt::TrcStackElemCtxt(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : + 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); + void mispredictNewest(); + 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; +} + +// mispredict newest - flip the bit of the newest atom +inline void TrcStackElemAtom::mispredictNewest() +{ + uint32_t mask = 0x1 << (m_atom.num - 1); + if (m_atom.En_bits & mask) + m_atom.En_bits &= ~mask; + else + m_atom.En_bits |= mask; +} + +/************************************************************/ +/** Generic param element */ + +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) +{ +} + +/************************************************************/ +/** 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) +{ +} + + +/************************************************************/ +/* 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 push_back(TrcStackElem *pElem); // insert element when processing + void pop_back(bool pend_delete = true); + void pop_front(bool pend_delete = true); + TrcStackElem *back(); + TrcStackElem *front(); + size_t size(); + + // iterate through stack from front + void from_front_init(); + TrcStackElem *from_front_next(); + void erase_curr_from_front(); // erase the element last returned + + void delete_all(); + void delete_back(); + void delete_front(); + void delete_popped(); + + // creation functions - create and push if successful. + 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> ¶ms); + TrcStackElem *createParamElemNoParam(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, bool back = false); + TrcStackElemAtom *createAtomElem (const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const ocsd_pkt_atom &atom); + TrcStackElemExcept *createExceptElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const bool bSame, const uint16_t excepNum); + TrcStackElemCtxt *createContextElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_context_t &context, 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); + +private: + std::deque<TrcStackElem *> m_P0_stack; //!< P0 decode element stack + std::vector<TrcStackElem *> m_popped_elem; //!< save list of popped but not deleted elements. + std::deque<TrcStackElem *>::iterator m_iter; //!< iterate across the list w/o removing stuff +}; + +inline EtmV4P0Stack::~EtmV4P0Stack() +{ + 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); +} + +// put an element on the back of the stack +inline void EtmV4P0Stack::push_back(TrcStackElem *pElem) +{ + m_P0_stack.push_back(pElem); +} + +// pop last element pointer off the stack and stash it for later deletion +inline void EtmV4P0Stack::pop_back(bool pend_delete /* = true */) +{ + if (pend_delete) + m_popped_elem.push_back(m_P0_stack.back()); + m_P0_stack.pop_back(); +} + +inline void EtmV4P0Stack::pop_front(bool pend_delete /* = true */) +{ + if (pend_delete) + m_popped_elem.push_back(m_P0_stack.front()); + m_P0_stack.pop_front(); +} + +// pop last element pointer off the stack and delete immediately +inline void EtmV4P0Stack::delete_back() +{ + if (m_P0_stack.size() > 0) + { + TrcStackElem* pElem = m_P0_stack.back(); + delete pElem; + m_P0_stack.pop_back(); + } +} + +// pop first element pointer off the stack and delete immediately +inline void EtmV4P0Stack::delete_front() +{ + if (m_P0_stack.size() > 0) + { + TrcStackElem* pElem = m_P0_stack.front(); + delete pElem; + m_P0_stack.pop_front(); + } +} + + + +// get a pointer to the last element on the stack +inline TrcStackElem *EtmV4P0Stack::back() +{ + return m_P0_stack.back(); +} + +inline TrcStackElem *EtmV4P0Stack::front() +{ + return m_P0_stack.front(); +} + +// remove and delete all the elements left on the stack +inline void EtmV4P0Stack::delete_all() +{ + 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 */ diff --git a/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h new file mode 100644 index 0000000..65230ff --- /dev/null +++ b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h @@ -0,0 +1,250 @@ +/* + * \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 "common/ocsd_gen_elem_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) + virtual void onFirstInitOK(); // override to set init related info. + + ocsd_err_t decodePacket(); // decode packet into trace elements. return true to indicate decode complete - can change FSM to commit state - return is false. + ocsd_datapath_resp_t resolveElements(); // commit/cancel trace elements generated from latest / prior packets & send to output - may get wait response, or flag completion. + ocsd_err_t commitElements(); // commit elements - process element stack to generate output packets. + ocsd_err_t commitElemOnEOT(); + ocsd_err_t cancelElements(); // cancel elements. These not output + ocsd_err_t mispredictAtom(); // mispredict an atom + ocsd_err_t discardElements(); // discard elements and flush + + void doTraceInfoPacket(); + void updateContext(TrcStackElemCtxt *pCtxtElem, OcsdTraceElement &elem); + + // process atom will create instruction trace, or no memory access trace output elements. + ocsd_err_t processAtom(const ocsd_atm_val atom); + + // process an exception element - output instruction trace + exception generic type. + ocsd_err_t processException(); + + // 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 a bad packet + 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); + ocsd_err_t addElemEvent(TrcStackElemParam *pParamElem); + +private: + void SetInstrInfoInAddrISA(const ocsd_vaddr_t addr_val, const uint8_t isa); + const ocsd_isa calcISA(const bool SF, const uint8_t IS) const + { + if (SF) + return ocsd_isa_aarch64; + return (IS == 0) ? ocsd_isa_arm : ocsd_isa_thumb2; + } + typedef enum { + WP_NOT_FOUND, + WP_FOUND, + WP_NACC + } WP_res_t; + + typedef struct { + ocsd_vaddr_t st_addr; + ocsd_vaddr_t en_addr; + uint32_t num_instr; + } instr_range_t; + + //!< follow instructions from the current address to a WP. true if good, false if memory cannot be accessed. + ocsd_err_t traceInstrToWP(instr_range_t &instr_range, WP_res_t &WPRes, const bool traceToAddrNext = false, const ocsd_vaddr_t nextAddrMatch = 0); + + inline const bool WPFound(WP_res_t res) const { return (res == WP_FOUND); }; + inline const bool WPNacc(WP_res_t res) const { return (res == WP_NACC); }; + + ocsd_err_t returnStackPop(); // pop return stack and update instruction address. + + void setElemTraceRange(OcsdTraceElement &elemIn, const instr_range_t &addr_range, const bool executed, ocsd_trc_index_t index); + 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(); + +//** intra packet state (see ETMv4 spec 6.2.1); + + // 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 + uint32_t m_vmid_id; // most recent VMID + bool m_is_secure; // true if Secure + bool m_is_64bit; // true if 64 bit + uint8_t m_last_IS; // last instruction set value from address packet. + + // cycle counts + int m_cc_threshold; + + // speculative trace + int m_curr_spec_depth; + int m_max_spec_depth; // nax depth - from ID reg, beyond which auto-commit occurs + int m_unseen_spec_elem; // speculative elements at decode start + +/** Remove elements that are associated with data trace */ +#ifdef DATA_TRACE_SUPPORTED + // data trace associative elements (unsupported at present in the decoder). + int m_p0_key; + int m_p0_key_max; + + // 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; +#endif + + 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 + RESOLVE_ELEM, //!< analyze / resolve decode elements - create generic trace elements and pass on. + } processor_state_t; + + processor_state_t m_curr_state; + unsync_info_t m_unsync_eot_info; //!< addition info when / why unsync / eot + +//** P0 element stack + EtmV4P0Stack m_P0_stack; //!< P0 decode element stack + + // element resolution + struct { + int P0_commit; //!< number of elements to commit + int P0_cancel; //!< elements to cancel + bool mispredict; //!< mispredict latest atom + bool discard; //!< discard elements + } m_elem_res; + + //! true if any of the element resolution fields are non-zero + const bool isElemForRes() const { + return (m_elem_res.P0_commit || m_elem_res.P0_cancel || + m_elem_res.mispredict || m_elem_res.discard); + } + + void clearElemRes() { + m_elem_res.P0_commit = 0; + m_elem_res.P0_cancel = 0; + m_elem_res.mispredict = false; + m_elem_res.discard = false; + } + + // packet decode state + bool m_need_ctxt; //!< need context to continue + bool m_need_addr; //!< need an address to continue + bool m_elem_pending_addr; //!< next address packet is needed for prev element. + + ocsd_instr_info m_instr_info; //!< instruction info for code follower - in address is the next to be decoded. + + etmv4_trace_info_t m_trace_info; //!< trace info for this trace run. + + bool m_prev_overflow; + + TrcAddrReturnStack m_return_stack; //!< the address return stack. + +//** output element handling + OcsdGenElemStack m_out_elem; //!< output element stack. + OcsdTraceElement &outElem() { return m_out_elem.getCurrElem(); }; //!< current out element +}; + +#endif // ARM_TRC_PKT_DECODE_ETMV4I_H_INCLUDED + +/* End of File trc_pkt_decode_etmv4i.h */ diff --git a/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h new file mode 100644 index 0000000..22f39d9 --- /dev/null +++ b/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h @@ -0,0 +1,546 @@ +/* + * \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() + { + reset_stack(); + } + ~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]; + } + } + + // explicit reset for TInfo. + void reset_stack() + { + for (int i = 0; i < 3; i++) + { + m_v_addr[i].pkt_bits = 0; + m_v_addr[i].size = OCSD_MAX_VA_BITSIZE == 64 ? VA_64BIT : VA_32BIT; + m_v_addr[i].val = 0; + m_v_addr[i].valid_bits = OCSD_MAX_VA_BITSIZE; + m_v_addr_ISA[i] = 0; + } + + } + +private: + ocsd_pkt_vaddr m_v_addr[3]; //!< most recently broadcast address packet + uint8_t m_v_addr_ISA[3]; +}; + +/*! + * @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, const uint8_t val = 0); + + 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, const uint8_t NSE = 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; }; + const int getNumAtoms() const { return atom.num; }; + + // 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; }; + + // speculation + const int getCommitElem() const { return commit_elements; }; + const int getCancelElem() const { return cancel_elements; }; + + // 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; + + 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; + 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); + + const bool isETE() const { return (protocol_version & 0xF0) == 0x50; }; + + Etmv4PktAddrStack m_addr_stack; +}; + +inline void EtmV4ITrcPacket::updateErrType(const ocsd_etmv4_i_pkt_type err_pkt_type, const uint8_t err_val /* = 0 */) +{ + // set primary type to incoming error type, set packet err type to previous primary type. + err_type = type; + type = err_pkt_type; + err_hdr_val = err_val; +} + +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; + + // set these as defaults - if they don't appear in TINFO this is the state. + setTraceInfo(0); + setTraceInfoSpec(0); + + // explicitly reset the stack & zero the current address. + m_addr_stack.reset_stack(); + m_addr_stack.get_idx(0, v_addr, v_addr_ISA); +} + +inline void EtmV4ITrcPacket::setTraceInfo(const uint32_t infoVal) +{ + 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, const uint8_t NSE) +{ + pkt_valid.bits.context_valid = 1; + if(update) + { + context.updated = 1; + context.EL = EL; + context.NS = NS; + context.SF = SF; + context.NSE = NSE; + } +} + +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; + v_addr.val = (v_addr.val & ~mask) | (addr & mask); + } + else + { + v_addr.val = addr; + v_addr.size = VA_32BIT; + } + + if (v_addr.valid_bits < 32) // may be updating a 64 bit address so only set 32 if currently less. + v_addr.valid_bits = 32; + + v_addr_ISA = IS; + push_vaddr(); +} + +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 */ diff --git a/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4.h b/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4.h new file mode 100644 index 0000000..25bdf51 --- /dev/null +++ b/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4.h @@ -0,0 +1,47 @@ +/* + * \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 + +// split I & D into separate files, retain this header for backward compatibility +// for now just include the I packet processor as that is the only one implemented. + +#include "trc_pkt_types_etmv4.h" +#include "trc_pkt_proc_etmv4i.h" +#include "common/trc_pkt_proc_base.h" + +#endif // ARM_TRC_PKT_PROC_ETMV4_H_INCLUDED + +/* End of File trc_pkt_proc_etmv4.h */ diff --git a/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4i.h new file mode 100644 index 0000000..19388c3 --- /dev/null +++ b/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4i.h @@ -0,0 +1,215 @@ +/* + * \file trc_pkt_proc_etmv4i.h + * \brief OpenCSD : Implementation of ETMv4 packet processing + * + * \copyright Copyright (c) 2015, 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_PROC_ETMV4I_IMPL_H_INCLUDED +#define ARM_TRC_PKT_PROC_ETMV4I_IMPL_H_INCLUDED + +#include "trc_pkt_types_etmv4.h" +#include "opencsd/etmv4/trc_pkt_proc_etmv4.h" +#include "opencsd/etmv4/trc_cmp_cfg_etmv4.h" +#include "opencsd/etmv4/trc_pkt_elem_etmv4i.h" +#include "common/trc_raw_buffer.h" +#include "common/trc_pkt_proc_base.h" + +class EtmV4ITrcPacket; +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; + +protected: + typedef enum _process_state { + PROC_HDR, + PROC_DATA, + SEND_PKT, + SEND_UNSYNCED, + PROC_ERR, + } process_state; + + process_state m_process_state; + + void InitPacketState(); // clear current packet state. + void InitProcessorState(); // clear all previous process state + + /** packet processor configuration **/ + bool m_isInit; + + // etmv4 hardware configuration + EtmV4Config m_config; + + /** packet data **/ + TraceRawBuffer m_trcIn; // trace data in buffer + std::vector<uint8_t> m_currPacketData; // raw data packet + int m_currPktIdx; // index into raw packet when expanding + EtmV4ITrcPacket m_curr_packet; // expanded packet + ocsd_trc_index_t m_packet_index; // index of the start of the current packet + ocsd_trc_index_t m_blockIndex; // index at the start of the current data block being processed + + // searching for sync + bool m_is_sync; //!< seen first sync packet + bool m_first_trace_info; //!< seen first trace info packet after sync + bool m_sent_notsync_packet; //!< send one not sync packet if we see any unsynced data on the channel + unsigned m_dump_unsynced_bytes; //!< number of unsynced bytes to send + ocsd_trc_index_t m_update_on_unsync_packet_index; + + +private: + // current processing state data - counts and flags to determine if a packet is complete. + + // TraceInfo Packet + // flags to indicate processing progress for these sections is complete. + struct _t_info_pkt_prog { + uint8_t sectFlags; + uint8_t ctrlBytes; + } m_tinfo_sections; + + #define TINFO_INFO_SECT 0x01 + #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 + + + // address and context packets + int m_addrBytes; + uint8_t m_addrIS; + bool m_bAddr64bit; + int m_vmidBytes; // bytes still to find + int m_ctxtidBytes; // bytes still to find + bool m_bCtxtInfoDone; + bool m_addr_done; + + // timestamp + bool m_ccount_done; // done or not needed + bool m_ts_done; + int m_ts_bytes; + + // exception + int m_excep_size; + + // cycle count + bool m_has_count; + bool m_count_done; + bool m_commit_done; + + // cond result + bool m_F1P1_done; // F1 payload 1 done + bool m_F1P2_done; // F1 payload 2 done + bool m_F1has_P2; // F1 has a payload 2 + + // Q packets (use some from above too) + bool m_has_addr; + bool m_addr_short; + bool m_addr_match; + uint8_t m_Q_type; + uint8_t m_QE; + + ocsd_datapath_resp_t outputPacket(); + ocsd_datapath_resp_t outputUnsyncedRawPacket(); + + void iNotSync(const uint8_t lastByte); // not synced yet + void iPktNoPayload(const uint8_t lastByte); // process a single byte packet + void iPktReserved(const uint8_t lastByte); // deal with reserved header value + void iPktExtension(const uint8_t lastByte); + void iPktASync(const uint8_t lastByte); + void iPktTraceInfo(const uint8_t lastByte); + void iPktTimestamp(const uint8_t lastByte); + void iPktException(const uint8_t lastByte); + void iPktCycleCntF123(const uint8_t lastByte); + void iPktSpeclRes(const uint8_t lastByte); + void iPktCondInstr(const uint8_t lastByte); + void iPktCondResult(const uint8_t lastByte); + void iPktContext(const uint8_t lastByte); + void iPktAddrCtxt(const uint8_t lastByte); + void iPktShortAddr(const uint8_t lastByte); + void iPktLongAddr(const uint8_t lastByte); + void iPktQ(const uint8_t lastByte); + void iAtom(const uint8_t lastByte); + void iPktInvalidCfg(const uint8_t lastByte); // packet invalid in current config. + + unsigned extractContField(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint32_t &value, const unsigned byte_limit = 5); + 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); + int extract32BitLongAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint32_t &value); + int extractShortAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint32_t &value, int &bits); + + // packet processing is table driven. + typedef void (TrcPktProcEtmV4I::*PPKTFN)(uint8_t); + PPKTFN m_pIPktFn; + + struct _pkt_i_table_t { + ocsd_etmv4_i_pkt_type pkt_type; + PPKTFN pptkFn; + } m_i_table[256]; + + void BuildIPacketTable(); + + void throwBadSequenceError(const char *pszExtMsg); +}; + + +inline const bool TrcPktProcEtmV4I::isBadPacket() const +{ + return m_curr_packet.isBadPacket(); +} + +/** @}*/ + +#endif // ARM_TRC_PKT_PROC_ETMV4I_IMPL_H_INCLUDED + +/* End of File trc_pkt_proc_etmv4i_impl.h */ diff --git a/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h b/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h new file mode 100644 index 0000000..38963d1 --- /dev/null +++ b/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h @@ -0,0 +1,392 @@ +/* + * \file trc_pkt_types_etmv4.h + * \brief OpenCSD : ETMv4 / ETE packet info + * + * \copyright Copyright (c) 2015,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_ETMV4_H_INCLUDED +#define ARM_TRC_PKT_TYPES_ETMV4_H_INCLUDED + +#include "opencsd/trc_pkt_types.h" + +/** @addtogroup trc_pkts +@{*/ + +/** @name ETMv4 Packet Types, ETE 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. */ + ETM4_PKT_I_RESERVED_CFG, /*!< packet type reserved for current configuration */ + +/* I stream packet types. */ + /* extension header. */ + ETM4_PKT_I_EXTENSION = 0x00, /*!< b00000000 */ + + /* sync */ + ETM4_PKT_I_TRACE_INFO = 0x01, /*!< b00000001 */ + // timestamp + ETM4_PKT_I_TIMESTAMP = 0x02, /*!< b0000001x */ + ETM4_PKT_I_TRACE_ON = 0x04, /*!< b00000100 */ + ETM4_PKT_I_FUNC_RET = 0x05, /*!< b00000101 (V8M only) */ + // Exceptions + ETM4_PKT_I_EXCEPT = 0x06, /*!< b00000110 */ + ETM4_PKT_I_EXCEPT_RTN = 0x07, /*!< b00000111 (ETE invalid) */ + + /* unused encoding 0x08 b00001000 */ + ETE_PKT_I_COMMIT_WIN_MV = 0x09, /*! b00001001 (ETE only - unused in current versions) */ + 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 */ + ETM4_PKT_I_CCNT_F1 = 0x0E, /*!< b0000111x */ + 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 to b00101100 0x2C */ + + // speculation + ETM4_PKT_I_COMMIT = 0x2D, /*!< b00101101 */ + ETM4_PKT_I_CANCEL_F1 = 0x2E, /*!< b00101110 */ + ETM4_PKT_I_CANCEL_F1_MISPRED = 0x2F, /*!< b00101111 */ + ETM4_PKT_I_MISPREDICT = 0x30, /*!< b001100xx */ + ETM4_PKT_I_CANCEL_F2 = 0x34, /*!< b001101xx */ + ETM4_PKT_I_CANCEL_F3 = 0x38, /*!< b00111xxx */ + + /* 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 */ + /* unused encoding 0x47 b01000111 */ + ETM4_PKT_I_COND_RES_F2 = 0x48, /*!< b0100100x, b01001010, b0100110x, b01001110 */ + /* unused encodings 0x4B,0x4F b01001011, b01001111 */ + ETM4_PKT_I_COND_RES_F3 = 0x50, /*!< b0101xxxx */ + /* unused encodings 0x60-0x67 b01100xxx */ + ETM4_PKT_I_COND_RES_F1 = 0x68, /*!< b011010xx, b0110111x 0x68-0x6B, 0x6e-0x6F */ + ETM4_PKT_I_COND_I_F1 = 0x6C, /*!< b01101100 */ + ETM4_PKT_I_COND_I_F3 = 0x6D, /*!< b01101101 */ + + // event trace + ETM4_PKT_I_IGNORE = 0x70, /*!< b01110000 */ + ETM4_PKT_I_EVENT = 0x71, /*!< b01110001 to 0x01111111 0x7F */ + + /* address and context */ + ETM4_PKT_I_CTXT = 0x80, /*!< b1000000x */ + ETM4_PKT_I_ADDR_CTXT_L_32IS0 = 0x82, /*!< b10000010 */ + ETM4_PKT_I_ADDR_CTXT_L_32IS1, /*!< b10000011 */ + /* unused encoding 0x84 b10000100 */ + ETM4_PKT_I_ADDR_CTXT_L_64IS0 = 0x85, /*!< b10000101 */ + ETM4_PKT_I_ADDR_CTXT_L_64IS1, /*!< b10000110 */ + /* unused encoding 0x87 b10000111 */ + 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 */ + ETM4_PKT_I_ADDR_S_IS1, /*!< b10010110 */ + /* unused encodings 0x97 b10010111 to b10011001 0x99 */ + ETM4_PKT_I_ADDR_L_32IS0 = 0x9A, /*!< b10011010 */ + ETM4_PKT_I_ADDR_L_32IS1, /*!< b10011011 */ + /* unused encoding 0x9C b10011100 */ + ETM4_PKT_I_ADDR_L_64IS0 = 0x9D, /*!< b10011101 */ + ETM4_PKT_I_ADDR_L_64IS1, /*!< b10011110 */ + /* unused encoding 0x9F b10011111 */ + + /* Q packets */ + ETM4_PKT_I_Q = 0xA0, /*!< b1010xxxx */ + + /* 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 */ + ETM4_PKT_I_ATOM_F5 = 0xD5, /*!< b11010101 - b11010111 0xD5 - 0xD7, b11110101 0xF5 */ + ETM4_PKT_I_ATOM_F2 = 0xD8, /*!< b110110xx to 0xDB */ + ETM4_PKT_I_ATOM_F4 = 0xDC, /*!< b110111xx to 0xDF */ + ETM4_PKT_I_ATOM_F1 = 0xF6, /*!< b1111011x to 0xF7 */ + ETM4_PKT_I_ATOM_F3 = 0xF8, /*!< b11111xxx to 0xFF */ + + // extension packets - follow 0x00 header + ETM4_PKT_I_ASYNC = 0x100, //!< b00000000 + 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 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; + +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 NSE:1; //!< PE FEAT_RME: root / realm indicator + }; + 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; + uint8_t err_hdr_val; + + // protocol version - validity of ETE specific fields 0xMm == v Major.minor + uint8_t protocol_version; + +} 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; + +#define ETE_ARCH_VERSION 0x5 + +#define ETE_OPFLG_PKTDEC_SRCADDR_N_ATOMS 0x00010000 /**< Split source address output ranges for N-atoms */ + +/** @}*/ +/** @}*/ +#endif // ARM_TRC_PKT_TYPES_ETMV4_H_INCLUDED + +/* End of File trc_pkt_types_etmv4.h */ + diff --git a/decoder/include/opencsd/ocsd_if_types.h b/decoder/include/opencsd/ocsd_if_types.h new file mode 100644 index 0000000..f5ff6ac --- /dev/null +++ b/decoder/include/opencsd/ocsd_if_types.h @@ -0,0 +1,691 @@ +/*! + * \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 */ + OCSD_ERR_DFMTR_BAD_FHSYNC, /**< Bad frame or half frame sync in trace deformatter */ + /* 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 */ + OCSD_ERR_MEM_ACC_BAD_LEN, /**< Memory accessor returned a bad read length value (larger than requested */ + /* 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 interface 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 = 0x0000, /**< unknown architecture */ + ARCH_CUSTOM = 0x0001, /**< None ARM, custom architecture */ + ARCH_V7 = 0x0700, /**< V7 architecture */ + ARCH_V8 = 0x0800, /**< V8 architecture */ + ARCH_V8r3 = 0x0803, /**< V8.3 architecture */ + 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_V8_max)) +#define OCSD_IS_ARCH_MINVER(arch, min_arch) (arch >= min_arch) + +/** 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_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 +*/ +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 calculations */ +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_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 + 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_S_INSTR_V7_IMPLIED_RET, /**< v7 instruction which could imply return e.g. MOV PC, LR; POP { ,pc} */ +} 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 */ + uint8_t wfi_wfe_branch; /**< Input: WFI, WFE classed as direct branches */ + + /* 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_EL2S = 0x10, /**< S EL2 */ + OCSD_MEM_SPACE_S = 0x19, /**< Any S */ + OCSD_MEM_SPACE_N = 0x6, /**< Any NS */ + OCSD_MEM_SPACE_ANY = 0x1F, /**< 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); + +/** +* 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 trcID : Trace ID for source of trace - allow CB to client to associate mem req with source cpu. +* @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_MemAccID_CB)(const void *p_context, const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t trcID, 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, + protocol component specific - top 16 bits. + (common flags share bitfield with pkt decoder common flags and create flags) +@{*/ + +#define OCSD_OPFLG_PKTPROC_NOFWD_BAD_PKTS 0x00000010 /**< don't forward bad packets up data path */ +#define OCSD_OPFLG_PKTPROC_NOMON_BAD_PKTS 0x00000020 /**< don't forward bad packets to monitor interface */ +#define OCSD_OPFLG_PKTPROC_ERR_BAD_PKTS 0x00000040 /**< throw error for bad packets - halt decoding. */ +#define OCSD_OPFLG_PKTPROC_UNSYNC_ON_BAD_PKTS 0x00000080 /**< switch to unsynced state on bad packets - wait for next sync point */ + +/** mask to combine all common packet processor operational control flags */ +#define OCSD_OPFLG_PKTPROC_COMMON (OCSD_OPFLG_PKTPROC_NOFWD_BAD_PKTS | \ + OCSD_OPFLG_PKTPROC_NOMON_BAD_PKTS | \ + OCSD_OPFLG_PKTPROC_ERR_BAD_PKTS | \ + OCSD_OPFLG_PKTPROC_UNSYNC_ON_BAD_PKTS ) + +/** mask for the component spcific flags */ +#define OCSD_OPFLG_COMP_MODE_MASK 0xFFFF0000 + +/** @}*/ + +/** @name Packet Decoder Operation Control Flags + common operational flags - bottom 16 bits, + protcol component specific - top 16 bits. + (common flags share bitfield with pkt processor common flags and create flags) + @{*/ + +#define OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS 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 | OCSD_OPFLG_PKTDEC_HALT_BAD_PKTS) + +/** @}*/ + +/** @name Decoder creation information + + Flags to use when creating decoders by name. + - share bitfield with pkt processor flags and packet decoder common flags. + + 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 */ +#define OCSD_BUILTIN_DCD_ETE "ETE" /**< ETE 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. */ + OCSD_PROTOCOL_ETE, /**< ETE 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) + +/** @}*/ + +/** @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 + +/* End of File opencsd/ocsd_if_types.h */ diff --git a/decoder/include/opencsd/ocsd_if_version.h b/decoder/include/opencsd/ocsd_if_version.h new file mode 100644 index 0000000..355204c --- /dev/null +++ b/decoder/include/opencsd/ocsd_if_version.h @@ -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 0x1 /**< Library Major Version */ +#define OCSD_VER_MINOR 0x3 /**< Library Minor Version */ +#define OCSD_VER_PATCH 0x3 /**< Library Patch Version */ + +/** Library version number - MMMMnnpp format. + MMMM = major version, + nn = minor version, + pp = patch version +*/ +#define OCSD_VER_NUM ((OCSD_VER_MAJOR << 16) | (OCSD_VER_MINOR << 8) | OCSD_VER_PATCH) + +#define OCSD_VER_STRING "1.3.3" /**< 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 */ diff --git a/decoder/include/opencsd/ptm/ptm_decoder.h b/decoder/include/opencsd/ptm/ptm_decoder.h new file mode 100644 index 0000000..80086d2 --- /dev/null +++ b/decoder/include/opencsd/ptm/ptm_decoder.h @@ -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 */ diff --git a/decoder/include/opencsd/ptm/trc_cmp_cfg_ptm.h b/decoder/include/opencsd/ptm/trc_cmp_cfg_ptm.h new file mode 100644 index 0000000..e086aae --- /dev/null +++ b/decoder/include/opencsd/ptm/trc_cmp_cfg_ptm.h @@ -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 */ diff --git a/decoder/include/opencsd/ptm/trc_dcd_mngr_ptm.h b/decoder/include/opencsd/ptm/trc_dcd_mngr_ptm.h new file mode 100644 index 0000000..0defb0d --- /dev/null +++ b/decoder/include/opencsd/ptm/trc_dcd_mngr_ptm.h @@ -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 */ diff --git a/decoder/include/opencsd/ptm/trc_pkt_decode_ptm.h b/decoder/include/opencsd/ptm/trc_pkt_decode_ptm.h new file mode 100644 index 0000000..f9e1abe --- /dev/null +++ b/decoder/include/opencsd/ptm/trc_pkt_decode_ptm.h @@ -0,0 +1,198 @@ +/* + * \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; + unsync_info_t m_unsync_info; + + 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 */ diff --git a/decoder/include/opencsd/ptm/trc_pkt_elem_ptm.h b/decoder/include/opencsd/ptm/trc_pkt_elem_ptm.h new file mode 100644 index 0000000..266bd2b --- /dev/null +++ b/decoder/include/opencsd/ptm/trc_pkt_elem_ptm.h @@ -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 */ diff --git a/decoder/include/opencsd/ptm/trc_pkt_proc_ptm.h b/decoder/include/opencsd/ptm/trc_pkt_proc_ptm.h new file mode 100644 index 0000000..87e933a --- /dev/null +++ b/decoder/include/opencsd/ptm/trc_pkt_proc_ptm.h @@ -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 */ diff --git a/decoder/include/opencsd/ptm/trc_pkt_types_ptm.h b/decoder/include/opencsd/ptm/trc_pkt_types_ptm.h new file mode 100644 index 0000000..45d994d --- /dev/null +++ b/decoder/include/opencsd/ptm/trc_pkt_types_ptm.h @@ -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 */ diff --git a/decoder/include/opencsd/stm/stm_decoder.h b/decoder/include/opencsd/stm/stm_decoder.h new file mode 100644 index 0000000..1367cad --- /dev/null +++ b/decoder/include/opencsd/stm/stm_decoder.h @@ -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 */ diff --git a/decoder/include/opencsd/stm/trc_cmp_cfg_stm.h b/decoder/include/opencsd/stm/trc_cmp_cfg_stm.h new file mode 100644 index 0000000..41003ec --- /dev/null +++ b/decoder/include/opencsd/stm/trc_cmp_cfg_stm.h @@ -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 */ diff --git a/decoder/include/opencsd/stm/trc_dcd_mngr_stm.h b/decoder/include/opencsd/stm/trc_dcd_mngr_stm.h new file mode 100644 index 0000000..33632c6 --- /dev/null +++ b/decoder/include/opencsd/stm/trc_dcd_mngr_stm.h @@ -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 */ diff --git a/decoder/include/opencsd/stm/trc_pkt_decode_stm.h b/decoder/include/opencsd/stm/trc_pkt_decode_stm.h new file mode 100644 index 0000000..bd29caf --- /dev/null +++ b/decoder/include/opencsd/stm/trc_pkt_decode_stm.h @@ -0,0 +1,104 @@ +/* + * \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; + unsync_info_t m_unsync_info; + + 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 */ diff --git a/decoder/include/opencsd/stm/trc_pkt_elem_stm.h b/decoder/include/opencsd/stm/trc_pkt_elem_stm.h new file mode 100644 index 0000000..738e452 --- /dev/null +++ b/decoder/include/opencsd/stm/trc_pkt_elem_stm.h @@ -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 */ diff --git a/decoder/include/opencsd/stm/trc_pkt_proc_stm.h b/decoder/include/opencsd/stm/trc_pkt_proc_stm.h new file mode 100644 index 0000000..bc4391b --- /dev/null +++ b/decoder/include/opencsd/stm/trc_pkt_proc_stm.h @@ -0,0 +1,290 @@ +/* + * \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 + m_num_F_nibbles = 21; // set the F nibble count - lose any extra as unsynced data. + } + 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 */ diff --git a/decoder/include/opencsd/stm/trc_pkt_types_stm.h b/decoder/include/opencsd/stm/trc_pkt_types_stm.h new file mode 100644 index 0000000..fd44cea --- /dev/null +++ b/decoder/include/opencsd/stm/trc_pkt_types_stm.h @@ -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 */ diff --git a/decoder/include/opencsd/trc_gen_elem_types.h b/decoder/include/opencsd/trc_gen_elem_types.h new file mode 100644 index 0000000..6c1fd09 --- /dev/null +++ b/decoder/include/opencsd/trc_gen_elem_types.h @@ -0,0 +1,162 @@ +/*! + * \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_I_RANGE_NOPATH, /*!< traced N instructions in a range, but incomplete information as to program execution path from start to end of range */ + OCSD_GEN_TRC_ELEM_ADDR_NACC, /*!< tracing in inaccessible memory area */ + OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN, /*!< address currently unknown - need address packet update */ + OCSD_GEN_TRC_ELEM_EXCEPTION, /*!< exception - start address may be exception target, end address may be preferred ret addr. */ + 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 or numbered event */ + OCSD_GEN_TRC_ELEM_SWTRACE, /*!< Software trace packet - may contain data payload. */ + 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_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 enum _unsync_info_t { + UNSYNC_UNKNOWN, /**< unknown /undefined */ + UNSYNC_INIT_DECODER, /**< decoder intialisation - start of trace. */ + UNSYNC_RESET_DECODER, /**< decoder reset. */ + UNSYNC_OVERFLOW, /**< overflow packet - need to re-sync / end of trace after overflow. */ + UNSYNC_DISCARD, /**< specl trace discard - need to re-sync. */ + UNSYNC_BAD_PACKET, /**< bad packet at input - resync to restart. */ + UNSYNC_EOT, /**< end of trace - no additional info */ +} unsync_info_t; + +typedef 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 _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 last_instr_sz:3; /**< size of last instruction in bytes (2/4) */ + 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 last_instr_cond:1; /**< 1 if the last instruction was conditional */ + uint32_t excep_ret_addr_br_tgt:1; /**< 1 if exception return address (en_addr) is also the target of a taken branch addr from the previous range. */ + }; + 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 */ + 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 */ + }; + + 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 */ diff --git a/decoder/include/opencsd/trc_pkt_types.h b/decoder/include/opencsd/trc_pkt_types.h new file mode 100644 index 0000000..2eb353a --- /dev/null +++ b/decoder/include/opencsd/trc_pkt_types.h @@ -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 */ |