-DecoderMngrBase::DecoderMngrBase(const std::string &decoderTypeName, ocsd_trace_protocol_t builtInProtocol)
+ DecoderMngrBase
::DecoderMngrBase(const std::string &decoderTypeName, ocsd_trace_protocol_t builtInProtocol) :
+ m_builtInProtocol(builtInProtocol)
{
OcsdLibDcdRegister *pDcdReg = OcsdLibDcdRegister::getDecoderRegister();
if(pDcdReg)
pDcdReg->registerDecoderTypeByName(decoderTypeName,this);
- m_builtInProtocol = builtInProtocol;
}
template
@@ -362,6 +362,49 @@ public:
}
};
+/* full decode - extended config object - base + derived. */
+template< class P, // Packet class.
+ class Pt, // Packet enum type ID.
+ class Pc, // Processor config base class.
+ class PcEx, // Processor config derived class
+ class PcSt, // Processor config struct type
+ class PktProc, // Packet processor class.
+ class PktDcd> // Packet decoder class.
+ class DecodeMngrFullDcdExCfg : public DecoderMngrBase
+{
+public:
+ DecodeMngrFullDcdExCfg(const std::string &name, ocsd_trace_protocol_t builtInProtocol)
+ : DecoderMngrBase
(name, builtInProtocol) {};
+
+ virtual ~DecodeMngrFullDcdExCfg() {};
+
+ virtual TraceComponent *createPktProc(const bool useInstID, const int instID)
+ {
+ TraceComponent *pComp;
+ if (useInstID)
+ pComp = new (std::nothrow) PktProc(instID);
+ else
+ pComp = new (std::nothrow) PktProc();
+ return pComp;
+ }
+
+ virtual TraceComponent *createPktDecode(const bool useInstID, const int instID)
+ {
+ TraceComponent *pComp;
+ if (useInstID)
+ pComp = new (std::nothrow)PktDcd(instID);
+ else
+ pComp = new (std::nothrow)PktDcd();
+ return pComp;
+ }
+
+ virtual CSConfig *createConfig(const void *pDataStruct)
+ {
+ return new (std::nothrow) PcEx((PcSt *)pDataStruct);
+ }
+};
+
+
/****************************************************************************************************/
/* Packet processor only, templated base for creating decoder objects */
/****************************************************************************************************/
diff --git a/decoder/include/common/ocsd_dcd_tree.h b/decoder/include/common/ocsd_dcd_tree.h
index e4e74f2bc659..b1c3dc601cab 100644
--- a/decoder/include/common/ocsd_dcd_tree.h
+++ b/decoder/include/common/ocsd_dcd_tree.h
@@ -168,6 +168,30 @@ public:
*/
ocsd_err_t removeDecoder(const uint8_t CSID);
+ /*!
+ * Get the stats block for the channel indicated.
+ * Caller must check p_stats_block->version to esure that the block
+ * is filled in a compatible manner.
+ *
+ * @param CSID : Configured CoreSight trace ID for the decoder.
+ * @param p_stats_block: block pointer to set to reference the stats block.
+ *
+ * @return ocsd_err_t : Library error code - OCSD_OK if valid block pointer returned,
+ * OCSD_ERR_NOTINIT if decoder does not support stats counting.
+ */
+ ocsd_err_t getDecoderStats(const uint8_t CSID, ocsd_decode_stats_t **p_stats_block);
+
+ /*!
+ * Reset the stats block for the chosens decode channel.
+ * stats block is reset independently of the decoder reset to allow counts across
+ * multiple decode runs.
+ *
+ * @param handle : Handle to decode tree.
+ * @param CSID : Configured CoreSight trace ID for the decoder.
+ *
+ * @return ocsd_err_t : Library error code - OCSD_OK if successful.
+ */
+ ocsd_err_t resetDecoderStats(const uint8_t CSID);
/* get decoder elements currently in use */
@@ -387,7 +411,7 @@ private:
void destroyMemAccMapper();
ocsd_err_t initCallbackMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address,
const ocsd_mem_space_acc_t mem_space, void *p_cb_func, bool IDfn, const void *p_context);
-
+ TrcPktProcI *getPktProcI(const uint8_t CSID);
ocsd_dcd_tree_src_t m_dcd_tree_type;
@@ -417,6 +441,9 @@ private:
/**! default instruction decoder */
static TrcIDecode s_instruction_decoder;
+
+ /**! demux stats block */
+ ocsd_demux_stats_t m_demux_stats;
};
/** @}*/
diff --git a/decoder/include/common/ocsd_error.h b/decoder/include/common/ocsd_error.h
index e547f4878033..7c6ed3af141f 100644
--- a/decoder/include/common/ocsd_error.h
+++ b/decoder/include/common/ocsd_error.h
@@ -108,6 +108,17 @@ inline ocsdError& ocsdError::operator=(const ocsdError &err)
return (*this = &err);
}
+/* class to get data path response values as strings */
+class ocsdDataRespStr
+{
+public:
+ ocsdDataRespStr(ocsd_datapath_resp_t type) { m_type = type; }
+ ~ocsdDataRespStr() {};
+
+ const char* getStr();
+private:
+ ocsd_datapath_resp_t m_type;
+};
/** @}*/
diff --git a/decoder/include/common/trc_core_arch_map.h b/decoder/include/common/trc_core_arch_map.h
index b72b4b411fa4..aa976c39f908 100644
--- a/decoder/include/common/trc_core_arch_map.h
+++ b/decoder/include/common/trc_core_arch_map.h
@@ -53,7 +53,8 @@
*
* Valid architecture profile names are:-
* - ARMv7-A, ARMv7-R, ARMv7-M;
- * - ARMv8-A, ARMv8.3A, ARMv8-R, ARMv8-M;
+ * - ARMv8-A, ARMv8.x-A, ARMv8-R, ARMv8-M;
+ * - ARM-AA64, ARM-aa64
*
*/
class CoreArchProfileMap
@@ -65,36 +66,12 @@ public:
ocsd_arch_profile_t getArchProfile(const std::string &coreName);
private:
+ ocsd_arch_profile_t getPatternMatchCoreName(const std::string &coreName);
std::map core_profiles;
std::map arch_profiles;
};
-inline ocsd_arch_profile_t CoreArchProfileMap::getArchProfile(const std::string &coreName)
-{
- ocsd_arch_profile_t ap = { ARCH_UNKNOWN, profile_Unknown };
- bool bFound = false;
-
- std::map::const_iterator it;
-
- /* match against the core name map. */
- it = core_profiles.find(coreName);
- if (it != core_profiles.end())
- {
- ap = it->second;
- bFound = true;
- }
-
- /* scan architecture profiles on no core name match */
- if (!bFound)
- {
- it = arch_profiles.find(coreName);
- if (it != arch_profiles.end())
- ap = it->second;
- }
- return ap;
-}
-
#endif // ARM_TRC_CORE_ARCH_MAP_H_INCLUDED
/* End of File trc_core_arch_map.h */
diff --git a/decoder/include/common/trc_frame_deformatter.h b/decoder/include/common/trc_frame_deformatter.h
index e4297a41e8fd..cb2960fcdd07 100644
--- a/decoder/include/common/trc_frame_deformatter.h
+++ b/decoder/include/common/trc_frame_deformatter.h
@@ -73,6 +73,9 @@ public:
componentAttachPt *getErrLogAttachPt();
+ /* init decoder implementation object */
+ ocsd_err_t Init();
+
/* configuration - set operational mode for incoming stream (has FSYNCS etc) */
ocsd_err_t Configure(uint32_t cfg_flags);
const uint32_t getConfigFlags() const;
@@ -85,9 +88,13 @@ public:
ocsd_datapath_resp_t Reset(); /* reset the decode to the start state, drop partial data - propogate to attached components */
ocsd_datapath_resp_t Flush(); /* flush existing data if possible, retain state - propogate to attached components */
+ /* demux stats */
+ void SetDemuxStatsBlock(ocsd_demux_stats_t *pStatsBlock);
+
private:
TraceFmtDcdImpl *m_pDecoder;
int m_instNum;
+
};
/** @}*/
diff --git a/decoder/include/common/trc_gen_elem.h b/decoder/include/common/trc_gen_elem.h
index 5d8983a8c274..405abfef8341 100644
--- a/decoder/include/common/trc_gen_elem.h
+++ b/decoder/include/common/trc_gen_elem.h
@@ -69,19 +69,22 @@ public:
void setExcepMarker() { excep_data_marker = 1; };
void setExceptionNum(uint32_t excepNum) { exception_number = excepNum; };
-
-
void setTraceOnReason(const trace_on_reason_t reason);
void setUnSyncEOTReason(const unsync_info_t reason);
+ void setTransactionType(const trace_memtrans_t trans) { mem_trans = trans; };
void setAddrRange(const ocsd_vaddr_t st_addr, const ocsd_vaddr_t en_addr, const int num_instr = 1);
void setLastInstrInfo(const bool exec, const ocsd_instr_type last_i_type, const ocsd_instr_subtype last_i_subtype, const uint8_t size);
- void setAddrStart(const ocsd_vaddr_t st_addr) { this->st_addr = st_addr; };
+ void setAddrStart(const ocsd_vaddr_t st_addr) { this->st_addr = st_addr; };
void setLastInstrCond(const int is_cond) { this->last_instr_cond = is_cond; };
void setSWTInfo(const ocsd_swt_info_t swt_info) { sw_trace_info = swt_info; };
void setExtendedDataPtr(const void *data_ptr);
+ void setITEInfo(const trace_sw_ite_t sw_instrumentation) { sw_ite = sw_instrumentation; };
+
+ void setSyncMarker(const trace_marker_payload_t &marker);
+
// stringize the element
virtual void toString(std::string &str) const;
@@ -208,6 +211,11 @@ inline void OcsdTraceElement::setExtendedDataPtr(const void *data_ptr)
ptr_extended_data = data_ptr;
}
+inline void OcsdTraceElement::setSyncMarker(const trace_marker_payload_t &marker)
+{
+ sync_marker = marker;
+}
+
// set persistent data between output packets.
inline void OcsdTraceElement::copyPersistentData(const OcsdTraceElement &src)
{
diff --git a/decoder/include/common/trc_pkt_decode_base.h b/decoder/include/common/trc_pkt_decode_base.h
index da702068f372..24ea2b05a6f9 100644
--- a/decoder/include/common/trc_pkt_decode_base.h
+++ b/decoder/include/common/trc_pkt_decode_base.h
@@ -96,6 +96,7 @@ protected:
/* target access */
ocsd_err_t accessMemory(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, uint32_t *num_bytes, uint8_t *p_buffer);
+ ocsd_err_t invalidateMemAccCache();
/* instruction decode */
ocsd_err_t instrDecode(ocsd_instr_info *instr_info);
@@ -180,6 +181,14 @@ inline ocsd_err_t TrcPktDecodeI::accessMemory(const ocsd_vaddr_t address, const
return OCSD_ERR_DCD_INTERFACE_UNUSED;
}
+inline ocsd_err_t TrcPktDecodeI::invalidateMemAccCache()
+{
+ if (!m_uses_memaccess)
+ return OCSD_ERR_DCD_INTERFACE_UNUSED;
+ m_mem_access.first()->InvalidateMemAccCache(getCoreSightTraceID());
+ return OCSD_OK;
+}
+
/**********************************************************************/
template
class TrcPktDecodeBase : public TrcPktDecodeI, public IPktDataIn
diff --git a/decoder/include/common/trc_pkt_proc_base.h b/decoder/include/common/trc_pkt_proc_base.h
index 3098a3d0c0ea..8ed7d83b2d5a 100644
--- a/decoder/include/common/trc_pkt_proc_base.h
+++ b/decoder/include/common/trc_pkt_proc_base.h
@@ -43,6 +43,7 @@
#include "trc_component.h"
#include "comp_attach_pt_t.h"
+#include "opencsd/ocsd_if_version.h"
/** @defgroup ocsd_pkt_proc OpenCSD Library : Packet Processors.
@brief Classes providing Protocol Packet Processing capability.
@@ -76,6 +77,8 @@ public:
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed) = 0;
+ virtual ocsd_err_t getStatsBlock(ocsd_decode_stats_t **pp_stats) = 0;
+ virtual void resetStats() = 0;
protected:
/* implementation packet processing interface */
@@ -155,6 +158,10 @@ public:
//!< Get the configuration for the decoder.
virtual const Pc *getProtocolConfig() const { return m_config; };
+/* stats block access - derived class must init stats for the block to be returned. */
+ virtual ocsd_err_t getStatsBlock(ocsd_decode_stats_t **pp_stats);
+ virtual void resetStats(); /* reset the counts - operates separately from decoder reset. */
+
protected:
/* data output functions */
@@ -183,6 +190,14 @@ protected:
const bool checkInit(); // return true if init (configured and at least one output sink attached), false otherwise.
+ /* stats block updates - called by derived protocol specific decoder */
+ void statsAddTotalCount(const uint64_t count) { m_stats.channel_total += count; };
+ void statsAddUnsyncCount(const uint64_t count) { m_stats.channel_unsynced += count; };
+ void statsAddBadSeqCount(const uint32_t count) { m_stats.bad_sequence_errs += count; };
+ void statsAddBadHdrCount(const uint32_t count) { m_stats.bad_header_errs += count; };
+ void statsInit() { m_stats_init = true; }; /* mark stats as in use */
+
+
private:
/* decode control */
ocsd_datapath_resp_t Reset(const ocsd_trc_index_t index);
@@ -195,20 +210,29 @@ private:
componentAttachPt> m_pkt_indexer_i;
bool m_b_is_init;
+
+ /* decode statistics block */
+ ocsd_decode_stats_t m_stats;
+ bool m_stats_init; /*< true if the specific decoder is using the stats */
+
};
template TrcPktProcBase::TrcPktProcBase(const char *component_name) :
TrcPktProcI(component_name),
m_config(0),
- m_b_is_init(false)
+ m_b_is_init(false),
+ m_stats_init(false)
{
+ resetStats();
}
template TrcPktProcBase::TrcPktProcBase(const char *component_name, int instIDNum) :
TrcPktProcI(component_name, instIDNum),
m_config(0),
- m_b_is_init(false)
+ m_b_is_init(false),
+ m_stats_init(false)
{
+ resetStats();
}
template TrcPktProcBase::~TrcPktProcBase()
@@ -405,6 +429,26 @@ template const bool TrcPktProcBase::check
return m_b_is_init;
}
+template ocsd_err_t TrcPktProcBase::getStatsBlock(ocsd_decode_stats_t **pp_stats)
+{
+
+ *pp_stats = &m_stats;
+ return m_stats_init ? OCSD_OK : OCSD_ERR_NOT_INIT;
+}
+
+template void TrcPktProcBase::resetStats()
+{
+ m_stats.version = OCSD_VER_NUM;
+ m_stats.revision = OCSD_STATS_REVISION;
+ m_stats.channel_total = 0;
+ m_stats.channel_unsynced = 0;
+ m_stats.bad_header_errs = 0;
+ m_stats.bad_sequence_errs = 0;
+ m_stats.demux.frame_bytes = 0;
+ m_stats.demux.no_id_bytes = 0;
+ m_stats.demux.valid_id_bytes = 0;
+}
+
/** @}*/
#endif // ARM_TRC_PKT_PROC_BASE_H_INCLUDED
diff --git a/decoder/include/i_dec/trc_idec_arminst.h b/decoder/include/i_dec/trc_idec_arminst.h
index 911b0cf7db95..e90ec04ae84d 100644
--- a/decoder/include/i_dec/trc_idec_arminst.h
+++ b/decoder/include/i_dec/trc_idec_arminst.h
@@ -44,7 +44,7 @@
/* supplementary decode information */
struct decode_info {
- uint16_t arch_version;
+ ocsd_arch_version_t arch_version;
ocsd_instr_subtype instr_sub_type;
};
@@ -121,7 +121,8 @@ arm_barrier_t inst_A64_barrier(uint32_t inst);
int inst_ARM_wfiwfe(uint32_t inst);
int inst_Thumb_wfiwfe(uint32_t inst);
-int inst_A64_wfiwfe(uint32_t inst);
+int inst_A64_wfiwfe(uint32_t inst, struct decode_info *info);
+int inst_A64_Tstart(uint32_t inst);
/*
Test whether an instruction is definitely undefined, e.g. because
diff --git a/decoder/include/interfaces/trc_pkt_raw_in_i.h b/decoder/include/interfaces/trc_pkt_raw_in_i.h
index 6f7b21383024..dfa7e057ca67 100644
--- a/decoder/include/interfaces/trc_pkt_raw_in_i.h
+++ b/decoder/include/interfaces/trc_pkt_raw_in_i.h
@@ -47,7 +47,7 @@
*
* This interface provides a monitor point for the packet processor block.
* The templated interface is called with a complete packet of the given
- * type, plus the raw packet bytes. Use for tools which need to display compplete
+ * type, plus the raw packet bytes. Use for tools which need to display complete
* packets or require additional processing on raw packet data.
*
* This interface is not part of the data decode path and cannot provide feedback.
diff --git a/decoder/include/interfaces/trc_tgt_mem_access_i.h b/decoder/include/interfaces/trc_tgt_mem_access_i.h
index effc9b5e161e..68a4e10055d4 100644
--- a/decoder/include/interfaces/trc_tgt_mem_access_i.h
+++ b/decoder/include/interfaces/trc_tgt_mem_access_i.h
@@ -83,6 +83,14 @@ public:
const ocsd_mem_space_acc_t mem_space,
uint32_t *num_bytes,
uint8_t *p_buffer) = 0;
+
+ /*!
+ * Invalidate any caching that the memory accessor functions are using.
+ * Generally called when a memory context changes in the trace.
+ *
+ * @param cs_trace_id : protocol source trace ID.
+ */
+ virtual void InvalidateMemAccCache(const uint8_t cs_trace_id) = 0;
};
diff --git a/decoder/include/mem_acc/trc_mem_acc_mapper.h b/decoder/include/mem_acc/trc_mem_acc_mapper.h
index a700e9dbd07e..4a08498df14e 100644
--- a/decoder/include/mem_acc/trc_mem_acc_mapper.h
+++ b/decoder/include/mem_acc/trc_mem_acc_mapper.h
@@ -61,6 +61,8 @@ public:
uint32_t *num_bytes,
uint8_t *p_buffer);
+ virtual void InvalidateMemAccCache(const uint8_t cs_trace_id);
+
// mapper memory area configuration interface
// add an accessor to this map
diff --git a/decoder/include/opencsd.h b/decoder/include/opencsd.h
index 615bbcafa2d9..8af4fd0df5ef 100644
--- a/decoder/include/opencsd.h
+++ b/decoder/include/opencsd.h
@@ -63,6 +63,7 @@
#include "opencsd/etmv4/etmv4_decoder.h"
#include "opencsd/ptm/ptm_decoder.h"
#include "opencsd/stm/stm_decoder.h"
+#include "opencsd/ete/ete_decoder.h"
/** C++ library object types */
#include "common/ocsd_error_logger.h"
diff --git a/decoder/include/opencsd/c_api/ocsd_c_api_types.h b/decoder/include/opencsd/c_api/ocsd_c_api_types.h
index cde351fc525f..7f9b4bab9494 100644
--- a/decoder/include/opencsd/c_api/ocsd_c_api_types.h
+++ b/decoder/include/opencsd/c_api/ocsd_c_api_types.h
@@ -46,6 +46,7 @@
#include "opencsd/etmv4/trc_pkt_types_etmv4.h"
#include "opencsd/ptm/trc_pkt_types_ptm.h"
#include "opencsd/stm/trc_pkt_types_stm.h"
+#include "opencsd/ete/trc_pkt_types_ete.h"
/** @ingroup lib_c_api
@{*/
diff --git a/decoder/include/opencsd/c_api/opencsd_c_api.h b/decoder/include/opencsd/c_api/opencsd_c_api.h
index 90201d436e08..ebbba87d952e 100644
--- a/decoder/include/opencsd/c_api/opencsd_c_api.h
+++ b/decoder/include/opencsd/c_api/opencsd_c_api.h
@@ -210,10 +210,36 @@ OCSD_C_API ocsd_err_t ocsd_dt_attach_packet_callback( const dcd_tree_handle_t h
const void *p_context);
-
-
+/*!
+ * Get the stats block for the channel indicated.
+ * Caller must check p_stats_block->version to esure that the block
+ * is filled in a compatible manner.
+ *
+ * @param handle : Handle to decode tree.
+ * @param CSID : Configured CoreSight trace ID for the decoder.
+ * @param p_stats_block: block pointer to set to reference the stats block.
+ *
+ * @return ocsd_err_t : Library error code - OCSD_OK if valid block pointer returned,
+ * OCSD_ERR_NOTINIT if decoder does not support stats counting.
+ */
+OCSD_C_API ocsd_err_t ocsd_dt_get_decode_stats( const dcd_tree_handle_t handle,
+ const unsigned char CSID,
+ ocsd_decode_stats_t **p_stats_block);
-
+
+/*!
+ * Reset the stats block for the chosens decode channel.
+ * stats block is reset independently of the decoder reset to allow counts across
+ * multiple decode runs.
+ *
+ * @param handle : Handle to decode tree.
+ * @param CSID : Configured CoreSight trace ID for the decoder.
+ *
+ * @return ocsd_err_t : Library error code - OCSD_OK if successful.
+ */
+OCSD_C_API ocsd_err_t ocsd_dt_reset_decode_stats( const dcd_tree_handle_t handle,
+ const unsigned char CSID);
+
/** @}*/
/*---------------------- Memory Access for traced opcodes ----------------------------------------------------------------------------------*/
/** @name Library Memory Accessor configuration on decode tree.
@@ -373,6 +399,28 @@ OCSD_C_API ocsd_err_t ocsd_def_errlog_set_strprint_cb(const dcd_tree_handle_t ha
*/
OCSD_C_API void ocsd_def_errlog_msgout(const char *msg);
+/*!
+ * Convert an error code into a string.
+ *
+ * @param err : error code.
+ * @param buffer : buffer for return string
+ * @param buffer_size : length of buffer.
+ */
+OCSD_C_API void ocsd_err_str(const ocsd_err_t err, char *buffer, const int buffer_size);
+
+/*!
+ * returns the last error logged by the system, with the related trace byte index, trace channel id,
+ * and any error message related string.
+ * If index or channel ID are not valid these will return OCSD_BAD_TRC_INDEX and OCSD_BAD_CS_SRC_ID.
+ *
+ * return value is the error code of the last logged error, OCSD_OK for no error available.
+ *
+ * @param index : returns trace byte index relating to error, or OCSD_BAD_TRC_INDEX
+ * @param chan_id : returns trace channel ID relating to error, or OCSD_BAD_CS_SRC_ID
+ * @param message : buffer to copy the last error message.
+ * @param message_len: length of message buffer.
+ */
+OCSD_C_API ocsd_err_t ocsd_get_last_err(ocsd_trc_index_t *index, uint8_t *chan_id, char *message, const int message_len);
/** @}*/
diff --git a/decoder/include/opencsd/ete/ete_decoder.h b/decoder/include/opencsd/ete/ete_decoder.h
new file mode 100644
index 000000000000..ba0d718bfff1
--- /dev/null
+++ b/decoder/include/opencsd/ete/ete_decoder.h
@@ -0,0 +1,47 @@
+/*
+* \file ete_decoder.h
+* \brief OpenCSD : Top level header file for ETE decoder.
+*
+* \copyright Copyright (c) 2019, ARM Limited. All Rights Reserved.
+*/
+
+/*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
+* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef ARM_ETE_DECODER_H_INCLUDED
+#define ARM_ETE_DECODER_H_INCLUDED
+
+// ETE actually uses extended ETMv4 packet processor and decode
+// ETE specifics limited to configuration
+//
+#include "trc_cmp_cfg_ete.h"
+#include "trc_pkt_types_ete.h"
+
+#endif // ARM_ETE_DECODER_H_INCLUDED
+
+/* End of File ete_decoder.h */
+
diff --git a/decoder/include/opencsd/ete/trc_cmp_cfg_ete.h b/decoder/include/opencsd/ete/trc_cmp_cfg_ete.h
new file mode 100644
index 000000000000..8365ffa88460
--- /dev/null
+++ b/decoder/include/opencsd/ete/trc_cmp_cfg_ete.h
@@ -0,0 +1,81 @@
+/*
+* \file trc_cmp_cfg_ete.h
+* \brief OpenCSD : ETE configuration
+*
+* \copyright Copyright (c) 2019, ARM Limited. All Rights Reserved.
+*/
+
+/*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
+* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef ARM_TRC_CMP_CFG_ETE_H_INCLUDED
+#define ARM_TRC_CMP_CFG_ETE_H_INCLUDED
+
+#include "trc_pkt_types_ete.h"
+#include "opencsd/etmv4/trc_cmp_cfg_etmv4.h"
+
+/** @addtogroup ocsd_protocol_cfg
+@{*/
+
+/** @name ETE configuration
+@{*/
+
+/*!
+ * @class ETEConfig
+ * @brief Interpreter class for ETE config structure
+ *
+ * ETE trace and config are a superset of ETMv4 trace and config - hence
+ * use the EtmV4Config class as a base.
+ */
+class ETEConfig : public EtmV4Config
+{
+public:
+ ETEConfig();
+ ETEConfig(const ocsd_ete_cfg *cfg_regs);
+ ~ETEConfig();
+
+ //! copy assignment operator for base structure into class.
+ ETEConfig & operator=(const ocsd_ete_cfg *p_cfg);
+
+ //! cast operator returning struct const reference
+ operator const ocsd_ete_cfg &() const { return m_ete_cfg; };
+ //! cast operator returning struct const pointer
+ operator const ocsd_ete_cfg *() const { return &m_ete_cfg; };
+
+private:
+ void copyV4(); // copy relevent config to underlying structure.
+
+ ocsd_ete_cfg m_ete_cfg;
+};
+
+
+/** @}*/
+/** @}*/
+
+#endif // ARM_TRC_CMP_CFG_ETE_H_INCLUDED
+
+/* End of File trc_cmp_cfg_ete.h */
diff --git a/decoder/include/opencsd/ete/trc_dcd_mngr_ete.h b/decoder/include/opencsd/ete/trc_dcd_mngr_ete.h
new file mode 100644
index 000000000000..7b0c134b20c5
--- /dev/null
+++ b/decoder/include/opencsd/ete/trc_dcd_mngr_ete.h
@@ -0,0 +1,58 @@
+/*
+* \file trc_dcd_mngr_ete.h
+* \brief OpenCSD : ETE decoder creation.
+*
+* \copyright Copyright (c) 2019, ARM Limited. All Rights Reserved.
+*/
+
+/*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
+* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef ARM_TRC_DCD_MNGR_ETE_H_INCLUDED
+#define ARM_TRC_DCD_MNGR_ETE_H_INCLUDED
+
+#include "common/ocsd_dcd_mngr.h"
+#include "trc_cmp_cfg_ete.h"
+#include "opencsd/etmv4/trc_pkt_decode_etmv4i.h"
+#include "opencsd/etmv4/trc_pkt_proc_etmv4.h"
+
+class DecoderMngrETE : public DecodeMngrFullDcdExCfg< EtmV4ITrcPacket,
+ ocsd_etmv4_i_pkt_type,
+ EtmV4Config,
+ ETEConfig,
+ ocsd_ete_cfg,
+ TrcPktProcEtmV4I,
+ TrcPktDecodeEtmV4I>
+{
+public:
+ DecoderMngrETE(const std::string &name) : DecodeMngrFullDcdExCfg(name, OCSD_PROTOCOL_ETE) {};
+ virtual ~DecoderMngrETE() {};
+};
+
+#endif // ARM_TRC_DCD_MNGR_ETE_H_INCLUDED
+
+/* End of File trc_dcd_mngr_ete.h */
diff --git a/decoder/include/opencsd/ete/trc_pkt_types_ete.h b/decoder/include/opencsd/ete/trc_pkt_types_ete.h
new file mode 100644
index 000000000000..f87d454605fd
--- /dev/null
+++ b/decoder/include/opencsd/ete/trc_pkt_types_ete.h
@@ -0,0 +1,66 @@
+/*
+ * \file trc_pkt_types_ete.h
+ * \brief OpenCSD : ETE types
+ *
+ * \copyright Copyright (c) 2019, ARM Limited. All Rights Reserved.
+ */
+
+/*
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ARM_TRC_PKT_TYPES_ETE_H_INCLUDED
+#define ARM_TRC_PKT_TYPES_ETE_H_INCLUDED
+
+#include "opencsd/trc_pkt_types.h"
+#include "opencsd/etmv4/trc_pkt_types_etmv4.h"
+ /** @addtogroup trc_pkts
+ @{*/
+
+ /** @name ETE config Types
+ @{*/
+
+
+typedef struct _ocsd_ete_cfg
+{
+ uint32_t reg_idr0; /**< ID0 register */
+ uint32_t reg_idr1; /**< ID1 register */
+ uint32_t reg_idr2; /**< ID2 register */
+ uint32_t reg_idr8; /**< ID8 - maxspec */
+ uint32_t reg_devarch; /**< DevArch register */
+ uint32_t reg_configr; /**< Config Register */
+ uint32_t reg_traceidr; /**< Trace Stream ID register */
+ ocsd_arch_version_t arch_ver; /**< Architecture version */
+ ocsd_core_profile_t core_prof; /**< Core Profile */
+} ocsd_ete_cfg;
+
+
+/** @}*/
+/** @}*/
+
+#endif // ARM_TRC_PKT_TYPES_ETE_H_INCLUDED
+
+/* End of File trc_pkt_types_ete.h */
diff --git a/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h b/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h
index 1d72d97afe59..223dbda44510 100644
--- a/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h
+++ b/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h
@@ -81,6 +81,7 @@ public:
const bool hasCycleCountI() const;
const bool hasRetStack() const;
const uint8_t numEvents() const;
+ const bool eteHasTSMarker() const;
typedef enum _condType {
COND_PASS_FAIL,
@@ -104,6 +105,7 @@ public:
const uint32_t TimeStampSize() const;
const bool commitOpt1() const;
+ const bool commTransP0() const;
/* idr 1 */
const uint8_t MajVersion() const;
@@ -151,6 +153,7 @@ public:
const bool enabledCCI() const;
const bool enabledCID() const;
const bool enabledVMID() const;
+ const bool enabledVMIDOpt() const;
typedef enum {
COND_TR_DIS,
@@ -253,6 +256,11 @@ inline const bool EtmV4Config::hasTrcExcpData() const
return (bool)((m_cfg.reg_idr0 & 0x20000) == 0x20000);
}
+inline const bool EtmV4Config::eteHasTSMarker() const
+{
+ return (FullVersion() >= 0x51) && ((m_cfg.reg_idr0 & 0x800000) == 0x800000);
+}
+
inline const uint32_t EtmV4Config::TimeStampSize() const
{
uint32_t tsSizeF = (m_cfg.reg_idr0 >> 24) & 0x1F;
@@ -268,6 +276,11 @@ inline const bool EtmV4Config::commitOpt1() const
return (bool)((m_cfg.reg_idr0 & 0x20000000) == 0x20000000) && hasCycleCountI();
}
+inline const bool EtmV4Config::commTransP0() const
+{
+ return (bool)((m_cfg.reg_idr0 & 0x40000000) == 0x0);
+}
+
/* idr 1 */
inline const uint8_t EtmV4Config::MajVersion() const
{
@@ -424,6 +437,20 @@ inline const bool EtmV4Config::enabledVMID() const
return ((m_cfg.reg_configr & (0x1 << 7)) != 0);
}
+inline const bool EtmV4Config::enabledVMIDOpt() const
+{
+ bool vmidOptVal = ((m_cfg.reg_configr & (0x1 << 15)) != 0);
+ /* TRIDR2.VMIDOPT[30:29] determine value used */
+ if (!vmidOpt()) { /* [29] = 1'b0 */
+ vmidOptVal = false; /* res0 */
+ if (FullVersion() >= 0x45) {
+ /* umless version > 4.5 in which case [30] determines res val */
+ vmidOptVal = ((m_cfg.reg_idr2 & (0x1 << 30)) != 0);
+ }
+ }
+ return vmidOptVal;
+}
+
inline const EtmV4Config::CondITrace_t EtmV4Config::enabledCondITrace()
{
if(!m_condTraceCalc)
diff --git a/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h b/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h
index 5a283c541f3e..21bd7af434de 100644
--- a/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h
+++ b/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h
@@ -34,6 +34,7 @@
#define ARM_TRC_ETMV4_STACK_ELEM_H_INCLUDED
#include "opencsd/etmv4/trc_pkt_types_etmv4.h"
+#include "opencsd/trc_gen_elem_types.h"
#include
#include
@@ -56,9 +57,16 @@ typedef enum _p0_elem_t
P0_TS,
P0_CC,
P0_TS_CC,
+ P0_MARKER,
P0_Q,
P0_OVERFLOW,
P0_FUNC_RET,
+ P0_SRC_ADDR,
+ P0_TRANS_TRACE_INIT,
+ P0_TRANS_START,
+ P0_TRANS_COMMIT,
+ P0_TRANS_FAIL,
+ P0_ITE,
} p0_elem_t;
@@ -101,6 +109,7 @@ class TrcStackElemAddr : public TrcStackElem
{
protected:
TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
+ TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const bool src_addr);
virtual ~TrcStackElemAddr() {};
friend class EtmV4P0Stack;
@@ -120,6 +129,14 @@ inline TrcStackElemAddr::TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt,
m_addr_val.isa = 0;
}
+inline TrcStackElemAddr::TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const bool src_addr) :
+ TrcStackElem(src_addr ? P0_SRC_ADDR : P0_ADDR, false, root_pkt, root_index)
+{
+ m_addr_val.val = 0;
+ m_addr_val.isa = 0;
+}
+
+
/************************************************************/
/** Q element */
class TrcStackQElem : public TrcStackElem
@@ -294,6 +311,55 @@ inline TrcStackElemParam::TrcStackElemParam(const p0_elem_t p0_type, const bool
{
}
+/************************************************************/
+/** Marker element */
+
+class TrcStackElemMarker : public TrcStackElem
+{
+protected:
+ TrcStackElemMarker(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
+ virtual ~TrcStackElemMarker() {};
+
+ friend class EtmV4P0Stack;
+
+public:
+ void setMarker(const trace_marker_payload_t &marker) { m_marker = marker; };
+ const trace_marker_payload_t &getMarker() const { return m_marker; };
+
+private:
+ trace_marker_payload_t m_marker;
+};
+
+inline TrcStackElemMarker::TrcStackElemMarker(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
+ TrcStackElem(P0_MARKER, false, root_pkt, root_index)
+{
+}
+
+/************************************************************/
+/* Instrumentation element
+ */
+
+class TrcStackElemITE : public TrcStackElem
+{
+protected:
+ TrcStackElemITE(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
+ virtual ~TrcStackElemITE() {};
+
+ friend class EtmV4P0Stack;
+
+public:
+ void setITE(const trace_sw_ite_t &ite) { m_ite = ite; };
+ const trace_sw_ite_t &getITE() { return m_ite; };
+
+private:
+ trace_sw_ite_t m_ite;
+};
+
+inline TrcStackElemITE::TrcStackElemITE(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
+ TrcStackElem(P0_ITE, false, root_pkt, root_index)
+{
+}
+
/************************************************************/
/* P0 element stack that allows push of elements, and deletion of elements when done.
*/
@@ -329,6 +395,10 @@ public:
TrcStackElemCtxt *createContextElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_context_t &context, const uint8_t IS, const bool back = false);
TrcStackElemAddr *createAddrElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_addr_val_t &addr_val);
TrcStackQElem *createQElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const int count);
+ TrcStackElemMarker *createMarkerElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const trace_marker_payload_t &marker);
+ TrcStackElemAddr *createSrcAddrElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_addr_val_t &addr_val);
+ TrcStackElemITE *createITEElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const trace_sw_ite_t &ite);
+
private:
std::deque m_P0_stack; //!< P0 decode element stack
std::vector m_popped_elem; //!< save list of popped but not deleted elements.
diff --git a/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
index 419cd828928c..7838ece04e57 100644
--- a/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
+++ b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
@@ -88,11 +88,29 @@ protected:
// process Q element
ocsd_err_t processQElement();
+ // process a source address element
+ ocsd_err_t processSourceAddress();
+
// process an element that cannot be cancelled / discarded
ocsd_err_t processTS_CC_EventElem(TrcStackElem *pElem);
+ // process marker elements
+ ocsd_err_t processMarkerElem(TrcStackElem *pElem);
+
+ // process a transaction element
+ ocsd_err_t processTransElem(TrcStackElem *pElem);
+
+ // process an Instrumentation element
+ ocsd_err_t processITEElem(TrcStackElem *pElem);
+
// process a bad packet
- ocsd_err_t handleBadPacket(const char *reason);
+ ocsd_err_t handleBadPacket(const char *reason, ocsd_trc_index_t index = OCSD_BAD_TRC_INDEX);
+
+ // sequencing error on packet processing - optionally continue
+ ocsd_err_t handlePacketSeqErr(ocsd_err_t err, ocsd_trc_index_t index, const char *reason);
+
+ // common packet error routine
+ ocsd_err_t handlePacketErr(ocsd_err_t err, ocsd_err_severity_t sev, ocsd_trc_index_t index, const char *reason);
ocsd_err_t addElemCC(TrcStackElemParam *pParamElem);
ocsd_err_t addElemTS(TrcStackElemParam *pParamElem, bool withCC);
@@ -127,6 +145,13 @@ private:
ocsd_err_t returnStackPop(); // pop return stack and update instruction address.
void setElemTraceRange(OcsdTraceElement &elemIn, const instr_range_t &addr_range, const bool executed, ocsd_trc_index_t index);
+ void setElemTraceRangeInstr(OcsdTraceElement &elemIn, const instr_range_t &addr_range,
+ const bool executed, ocsd_trc_index_t index, ocsd_instr_info &instr);
+
+ // true if we are ETE configured.
+ inline bool isETEConfig() {
+ return (m_config->MajVersion() >= ETE_ARCH_VERSION);
+ }
ocsd_mem_space_acc_t getCurrMemSpace();
@@ -134,6 +159,7 @@ private:
// timestamping
uint64_t m_timestamp; // last broadcast global Timestamp.
+ bool m_ete_first_ts_marker;
// state and context
uint32_t m_context_id; // most recent context ID
diff --git a/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h
index 8ccf36b373db..02404749718d 100644
--- a/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h
+++ b/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h
@@ -145,7 +145,7 @@ public:
void setCondRF3(const uint16_t tokens);
void setCondRF4(const uint8_t token);
- void setContextInfo(const bool update, const uint8_t EL = 0, const uint8_t NS = 0, const uint8_t SF = 0);
+ void setContextInfo(const bool update, const uint8_t EL = 0, const uint8_t NS = 0, const uint8_t SF = 0, const uint8_t NSE = 0);
void setContextVMID(const uint32_t VMID);
void setContextCID(const uint32_t CID);
@@ -160,6 +160,7 @@ public:
void setEvent(const uint8_t event_val);
void setQType(const bool has_count, const uint32_t count, const bool has_addr, const bool addr_match, const uint8_t type);
+ void setITE(const uint8_t el, const uint64_t value);
// packet status interface - get packet info.
const ocsd_etmv4_i_pkt_type getType() const { return type; };
@@ -200,6 +201,10 @@ public:
const int getCommitElem() const { return commit_elements; };
const int getCancelElem() const { return cancel_elements; };
+ // ITE
+ const uint8_t getITE_EL() const { return ite_pkt.el; };
+ const uint64_t getITE_value() const { return ite_pkt.value; };
+
// packet type
const bool isBadPacket() const;
@@ -207,6 +212,8 @@ public:
virtual void toString(std::string &str) const;
virtual void toStringFmt(const uint32_t fmtFlags, std::string &str) const;
+ void setProtocolVersion(const uint8_t version) { protocol_version = version; };
+
private:
const char *packetTypeName(const ocsd_etmv4_i_pkt_type type, const char **pDesc) const;
void contextStr(std::string &ctxtStr) const;
@@ -217,6 +224,8 @@ private:
void push_vaddr();
void pop_vaddr_idx(const uint8_t idx);
+ const bool isETE() const { return (protocol_version & 0xF0) == 0x50; };
+
Etmv4PktAddrStack m_addr_stack;
};
@@ -412,7 +421,7 @@ inline void EtmV4ITrcPacket::setCondRF4(const uint8_t token)
cond_result.f2f4_token = token;
}
-inline void EtmV4ITrcPacket::setContextInfo(const bool update, const uint8_t EL, const uint8_t NS, const uint8_t SF)
+inline void EtmV4ITrcPacket::setContextInfo(const bool update, const uint8_t EL, const uint8_t NS, const uint8_t SF, const uint8_t NSE)
{
pkt_valid.bits.context_valid = 1;
if(update)
@@ -421,6 +430,7 @@ inline void EtmV4ITrcPacket::setContextInfo(const bool update, const uint8_t EL,
context.EL = EL;
context.NS = NS;
context.SF = SF;
+ context.NSE = NSE;
}
}
@@ -534,6 +544,12 @@ inline void EtmV4ITrcPacket::pop_vaddr_idx(const uint8_t idx)
m_addr_stack.get_idx(idx, v_addr, v_addr_ISA);
}
+inline void EtmV4ITrcPacket::setITE(const uint8_t el, const uint64_t value)
+{
+ ite_pkt.el = el;
+ ite_pkt.value = value;
+}
+
/** @}*/
#endif // ARM_TRC_PKT_ELEM_ETMV4I_H_INCLUDED
diff --git a/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4i.h
index abc322654b8d..58c0d78806c3 100644
--- a/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4i.h
+++ b/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4i.h
@@ -117,6 +117,7 @@ private:
#define TINFO_KEY_SECT 0x02
#define TINFO_SPEC_SECT 0x04
#define TINFO_CYCT_SECT 0x08
+ #define TINFO_WNDW_SECT 0x10
#define TINFO_CTRL 0x20
#define TINFO_ALL_SECT 0x1F
#define TINFO_ALL 0x3F
@@ -178,9 +179,10 @@ private:
void iPktQ(const uint8_t lastByte);
void iAtom(const uint8_t lastByte);
void iPktInvalidCfg(const uint8_t lastByte); // packet invalid in current config.
+ void iPktITE(const uint8_t lastByte);
unsigned extractContField(const std::vector &buffer, const unsigned st_idx, uint32_t &value, const unsigned byte_limit = 5);
- unsigned extractContField64(const std::vector &buffer, const unsigned st_idx, uint64_t &value, const unsigned byte_limit = 9);
+ unsigned extractTSField64(const std::vector &buffer, const unsigned st_idx, uint64_t &value);
unsigned extractCondResult(const std::vector &buffer, const unsigned st_idx, uint32_t& key, uint8_t &result);
void extractAndSetContextInfo(const std::vector &buffer, const int st_idx);
int extract64BitLongAddr(const std::vector &buffer, const int st_idx, const uint8_t IS, uint64_t &value);
diff --git a/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h b/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h
index 7e98050c77c4..2a03b088c043 100644
--- a/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h
+++ b/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h
@@ -1,8 +1,8 @@
/*
* \file trc_pkt_types_etmv4.h
- * \brief OpenCSD : ETMv4 packet info
+ * \brief OpenCSD : ETMv4 / ETE packet info
*
- * \copyright Copyright (c) 2015,2019 ARM Limited. All Rights Reserved.
+ * \copyright Copyright (c) 2015,2019,2022 ARM Limited. All Rights Reserved.
*/
@@ -41,7 +41,7 @@
/** @addtogroup trc_pkts
@{*/
-/** @name ETMv4 Packet Types
+/** @name ETMv4 Packet Types, ETE packet Types
@{*/
/** I stream packets. */
@@ -70,9 +70,12 @@ typedef enum _ocsd_etmv4_i_pkt_type
ETM4_PKT_I_FUNC_RET = 0x05, /*!< b00000101 (V8M only) */
// Exceptions
ETM4_PKT_I_EXCEPT = 0x06, /*!< b00000110 */
- ETM4_PKT_I_EXCEPT_RTN = 0x07, /*!< b00000111 */
+ ETM4_PKT_I_EXCEPT_RTN = 0x07, /*!< b00000111 (ETE invalid) */
- /* unused encodings 0x08-0xB b00001000 to b00001011 */
+ /* unused encoding 0x08 b00001000 */
+ ETE_PKT_I_ITE = 0x09, /*! b00001001 (ETE only) */
+ ETE_PKT_I_TRANS_ST = 0x0A, /*! b00001010 (ETE only) */
+ ETE_PKT_I_TRANS_COMMIT = 0x0B, /*! b00001011 (ETE only) */
/* cycle count packets */
ETM4_PKT_I_CCNT_F2 = 0x0C, /*!< b0000110x */
@@ -91,7 +94,7 @@ typedef enum _ocsd_etmv4_i_pkt_type
ETM4_PKT_I_CANCEL_F2 = 0x34, /*!< b001101xx */
ETM4_PKT_I_CANCEL_F3 = 0x38, /*!< b00111xxx */
- /* conditional instruction tracing */
+ /* conditional instruction tracing - (reserved encodings ETE) */
ETM4_PKT_I_COND_I_F2 = 0x40, /*!< b01000000 - b01000010 */
ETM4_PKT_I_COND_FLUSH = 0x43, /*!< b01000011 */
ETM4_PKT_I_COND_RES_F4 = 0x44, /*!< b0100010x, b01000110 */
@@ -116,7 +119,8 @@ typedef enum _ocsd_etmv4_i_pkt_type
ETM4_PKT_I_ADDR_CTXT_L_64IS0 = 0x85, /*!< b10000101 */
ETM4_PKT_I_ADDR_CTXT_L_64IS1, /*!< b10000110 */
/* unused encoding 0x87 b10000111 */
- /* unused encodings 0x88-0x8F b10001xxx */
+ ETE_PKT_I_TS_MARKER = 0x88, /*!< b10001000 */
+ /* unused encodings 0x89-0x8F b10001001 to b10001111 */
ETM4_PKT_I_ADDR_MATCH = 0x90, /*!< b10010000 to b10010010 0x92 */
/* unused encodings 0x93-0x94 b10010011 to b10010010 */
ETM4_PKT_I_ADDR_S_IS0 = 0x95, /*!< b10010101 */
@@ -132,7 +136,15 @@ typedef enum _ocsd_etmv4_i_pkt_type
/* Q packets */
ETM4_PKT_I_Q = 0xA0, /*!< b1010xxxx */
- /* unused encodings 0xB0-0xBF b1011xxxx */
+ /* ETE source address packets, unused ETMv4 */
+ ETE_PKT_I_SRC_ADDR_MATCH = 0xB0, /*!< b101100xx */
+ ETE_PKT_I_SRC_ADDR_S_IS0 = 0xB4, /*!< b10110100 */
+ ETE_PKT_I_SRC_ADDR_S_IS1 = 0xB5, /*!< b10110101 */
+ ETE_PKT_I_SRC_ADDR_L_32IS0 = 0xB6, /*!< b10110110 */
+ ETE_PKT_I_SRC_ADDR_L_32IS1 = 0xB7, /*!< b10110111 */
+ ETE_PKT_I_SRC_ADDR_L_64IS0 = 0xB8, /*!< b10111000 */
+ ETE_PKT_I_SRC_ADDR_L_64IS1 = 0xB9, /*!< b10111001 */
+ /* unused encodings 0xBA-0xBF b10111010 - b10111111 */
/* Atom packets */
ETM4_PKT_I_ATOM_F6 = 0xC0, /*!< b11000000 - b11010100 0xC0 - 0xD4, b11100000 - b11110100 0xE0 - 0xF4 */
@@ -147,15 +159,20 @@ typedef enum _ocsd_etmv4_i_pkt_type
ETM4_PKT_I_DISCARD = 0x103, //!< b00000011
ETM4_PKT_I_OVERFLOW = 0x105, //!< b00000101
+ // ETE extended types
+ ETE_PKT_I_PE_RESET = 0x400, // base type is exception packet.
+ ETE_PKT_I_TRANS_FAIL = 0x401, // base type is exception packet.
+
} ocsd_etmv4_i_pkt_type;
typedef union _etmv4_trace_info_t {
uint32_t val; //!< trace info full value.
struct {
uint32_t cc_enabled:1; //!< 1 if cycle count enabled
- uint32_t cond_enabled:3; //!< conditional trace enabeld type
+ uint32_t cond_enabled:3; //!< conditional trace enabled type.
uint32_t p0_load:1; //!< 1 if tracing with P0 load elements (for data trace)
uint32_t p0_store:1; //!< 1 if tracing with P0 store elements (for data trace)
+ uint32_t in_trans_state:1; //!< 1 if starting trace when in a transactional state (ETE trace).
} bits; //!< bitfields for trace info value.
} etmv4_trace_info_t;
@@ -167,6 +184,7 @@ typedef struct _etmv4_context_t {
uint32_t updated:1; //!< updated this context packet (otherwise same as last time)
uint32_t updated_c:1; //!< updated CtxtID
uint32_t updated_v:1; //!< updated VMID
+ uint32_t NSE:1; //!< PE FEAT_RME: root / realm indicator
};
uint32_t ctxtID; //!< Current ctxtID
uint32_t VMID; //!< current VMID
@@ -256,6 +274,11 @@ typedef struct _ocsd_etmv4_i_pkt
};
} Q_pkt;
+ struct {
+ uint8_t el;
+ uint64_t value;
+ } ite_pkt;
+
//! valid bits for packet elements (addresses have their own valid bits).
union {
uint32_t val;
@@ -277,6 +300,9 @@ typedef struct _ocsd_etmv4_i_pkt
ocsd_etmv4_i_pkt_type err_type;
uint8_t err_hdr_val;
+ // protocol version - validity of ETE specific fields 0xMm == v Major.minor
+ uint8_t protocol_version;
+
} ocsd_etmv4_i_pkt;
@@ -359,6 +385,9 @@ typedef struct _ocsd_etmv4_cfg
ocsd_core_profile_t core_prof; /**< Core Profile */
} ocsd_etmv4_cfg;
+#define ETE_ARCH_VERSION 0x5
+
+#define ETE_OPFLG_PKTDEC_SRCADDR_N_ATOMS 0x00010000 /**< Split source address output ranges for N-atoms */
/** @}*/
/** @}*/
diff --git a/decoder/include/opencsd/ocsd_if_types.h b/decoder/include/opencsd/ocsd_if_types.h
index 23087ee694b1..f5ff6ac6c530 100644
--- a/decoder/include/opencsd/ocsd_if_types.h
+++ b/decoder/include/opencsd/ocsd_if_types.h
@@ -278,11 +278,13 @@ typedef enum _ocsd_arch_version {
ARCH_V7 = 0x0700, /**< V7 architecture */
ARCH_V8 = 0x0800, /**< V8 architecture */
ARCH_V8r3 = 0x0803, /**< V8.3 architecture */
+ ARCH_AA64 = 0x0864, /**< Min v8r3 plus additional AA64 PE features */
+ ARCH_V8_max = ARCH_AA64,
} ocsd_arch_version_t;
// macros for arch version comparisons.
-#define OCSD_IS_V8_ARCH(arch) ((arch >= ARCH_V8) && (arch <= ARCH_V8r3))
-#define OCSD_MIN_V8_ARCH(arch) (arch >= ARCH_V8)
+#define OCSD_IS_V8_ARCH(arch) ((arch >= ARCH_V8) && (arch <= ARCH_V8_max))
+#define OCSD_IS_ARCH_MINVER(arch, min_arch) (arch >= min_arch)
/** Core Profile */
typedef enum _ocsd_core_profile {
@@ -336,8 +338,10 @@ typedef enum _ocsd_isa
*/
typedef enum _ocsd_sec_level
{
- ocsd_sec_secure, /**< Core is in secure state */
- ocsd_sec_nonsecure /**< Core is in non-secure state */
+ ocsd_sec_secure, /**< Core is in secure state */
+ ocsd_sec_nonsecure, /**< Core is in non-secure state */
+ ocsd_sec_root, /**< PE FEAT_RME: Core is in root state. */
+ ocsd_sec_realm, /**< PE FEAT_RME: Core is in realm state. */
} ocsd_sec_level ;
/** Exception level type
@@ -352,7 +356,7 @@ typedef enum _ocsd_ex_level
} ocsd_ex_level;
-/** instruction types - significant for waypoint calculaitons */
+/** instruction types - significant for waypoint calculations */
typedef enum _ocsd_instr_type {
OCSD_INSTR_OTHER, /**< Other instruction - not significant for waypoints. */
OCSD_INSTR_BR, /**< Immediate Branch instruction */
@@ -360,6 +364,7 @@ typedef enum _ocsd_instr_type {
OCSD_INSTR_ISB, /**< Barrier : ISB instruction */
OCSD_INSTR_DSB_DMB, /**< Barrier : DSB or DMB instruction */
OCSD_INSTR_WFI_WFE, /**< WFI or WFE traced as direct branch */
+ OCSD_INSTR_TSTART, /**< PE Arch feature FEAT_TME - TSTART instruction */
} ocsd_instr_type;
/** instruction sub types - addiitonal information passed to the output packets
@@ -521,10 +526,11 @@ typedef struct _ocsd_file_mem_region {
(common flags share bitfield with pkt processor common flags and create flags)
@{*/
-#define OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS 0x00000100 /**< throw error on bad packets input (default is to unsync and wait) */
+#define OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS 0x00000100 /**< throw error on bad packets input (default is to warn) */
+#define OCSD_OPFLG_PKTDEC_HALT_BAD_PKTS 0x00000200 /**< halt decoder on bad packets (default is to log error and continue by resetting decoder and wait for sync */
/** mask to combine all common packet processor operational control flags */
-#define OCSD_OPFLG_PKTDEC_COMMON (OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS)
+#define OCSD_OPFLG_PKTDEC_COMMON (OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS | OCSD_OPFLG_PKTDEC_HALT_BAD_PKTS)
/** @}*/
@@ -547,6 +553,7 @@ typedef struct _ocsd_file_mem_region {
#define OCSD_BUILTIN_DCD_ETMV4I "ETMV4I" /**< ETMv4 instruction decoder */
#define OCSD_BUILTIN_DCD_ETMV4D "ETMV4D" /**< ETMv4 data decoder */
#define OCSD_BUILTIN_DCD_PTM "PTM" /**< PTM decoder */
+#define OCSD_BUILTIN_DCD_ETE "ETE" /**< ETE decoder */
/*! Trace Protocol Builtin Types + extern
*/
@@ -559,6 +566,7 @@ typedef enum _ocsd_trace_protocol_t {
OCSD_PROTOCOL_ETMV4D, /**< ETMV4 data trace protocol decoder. */
OCSD_PROTOCOL_PTM, /**< PTM program flow instruction trace protocol decoder. */
OCSD_PROTOCOL_STM, /**< STM system trace protocol decoder. */
+ OCSD_PROTOCOL_ETE, /**< ETE trace protocol decoder */
/* others to be added here */
OCSD_PROTOCOL_BUILTIN_END, /**< Invalid protocol - built-in protocol types end marker */
@@ -627,6 +635,56 @@ typedef struct _ocsd_swt_info {
/** @}*/
+/** @name Demux Statistics
+
+ Contains statistics for the CoreSight frame demultiplexor.
+
+ Counts total bytes sent to decoders registered against a trace ID, bytes in the input stream that are
+ associated with a trace ID that has no registered decoder, and frame bytes that are not trace data, but
+ are used to decode the frames - ID bytes, sync bytes etc.
+@{*/
+
+typedef struct _ocsd_demux_stats {
+ uint64_t valid_id_bytes; /**< number of bytes associated with an ID that has a registered decoder */
+ uint64_t no_id_bytes; /**< number of bytes associated with an ID that has no decoder */
+ uint64_t reserved_id_bytes; /**< number of bytes associated with reserved IDs */
+ uint64_t unknown_id_bytes; /**< bytes processed before ID seen in input frames */
+ uint64_t frame_bytes; /**< number of non-data bytes used for frame de-mux - ID bytes, sync etc */
+} ocsd_demux_stats_t;
+
+/** @}*/
+
+/** @name Decode statistics
+
+ Contains statistics for bytes decoded by the packet decoder, if statistics are supported.
+
+ Stats block instantiated in the base class - derived protocol specific decoder must initialise and
+ use as required.
+
+ The single channel block contains the stats for the requested channel via the API call.
+
+ The global demux block contains the totals for all channels and non-data bytes used in CoreSight
+ frame demux. This block will show identical data for every requested channel via the API.
+
+@{*/
+
+typedef struct _ocsd_decode_stats {
+ uint32_t version; /**< library version number */
+ uint16_t revision; /**< revision number - defines the structure version for the stats. */
+ /* single channel block */
+ uint64_t channel_total; /**< total bytes processed for this channel */
+ uint64_t channel_unsynced; /**< number of unsynced bytes processed on this channel */
+ uint32_t bad_header_errs; /**< number of bad packet header errors */
+ uint32_t bad_sequence_errs; /**< number of bad packet sequence errors */
+
+ ocsd_demux_stats_t demux; /**< global demux stats block */
+} ocsd_decode_stats_t;
+
+#define OCSD_STATS_REVISION 0x1
+
+/** @}*/
+
+
/** @}*/
#endif // ARM_OCSD_IF_TYPES_H_INCLUDED
diff --git a/decoder/include/opencsd/ocsd_if_version.h b/decoder/include/opencsd/ocsd_if_version.h
index 38baa02e8b48..41033f0675ed 100644
--- a/decoder/include/opencsd/ocsd_if_version.h
+++ b/decoder/include/opencsd/ocsd_if_version.h
@@ -42,9 +42,9 @@
/** @name Library Versioning
@{*/
-#define OCSD_VER_MAJOR 0x0 /**< Library Major Version */
-#define OCSD_VER_MINOR 0xE /**< Library Minor Version */
-#define OCSD_VER_PATCH 0x2 /**< Library Patch Version */
+#define OCSD_VER_MAJOR 0x1 /**< Library Major Version */
+#define OCSD_VER_MINOR 0x4 /**< Library Minor Version */
+#define OCSD_VER_PATCH 0x0 /**< Library Patch Version */
/** Library version number - MMMMnnpp format.
MMMM = major version,
@@ -53,7 +53,7 @@
*/
#define OCSD_VER_NUM ((OCSD_VER_MAJOR << 16) | (OCSD_VER_MINOR << 8) | OCSD_VER_PATCH)
-#define OCSD_VER_STRING "0.14.2" /**< Library Version string */
+#define OCSD_VER_STRING "1.4.0" /**< Library Version string */
#define OCSD_LIB_NAME "OpenCSD Library" /**< Library name string */
#define OCSD_LIB_SHORT_NAME "OCSD" /**< Library Short name string */
/** @}*/
diff --git a/decoder/include/opencsd/stm/trc_pkt_proc_stm.h b/decoder/include/opencsd/stm/trc_pkt_proc_stm.h
index 909ac0cb0566..bc4391bfebfb 100644
--- a/decoder/include/opencsd/stm/trc_pkt_proc_stm.h
+++ b/decoder/include/opencsd/stm/trc_pkt_proc_stm.h
@@ -239,7 +239,8 @@ inline void TrcPktProcStm::checkSyncNibble()
if((m_nibble == 0) && (m_num_F_nibbles >= 21))
{
- m_is_sync = true; //this nibble marks a sync sequence - keep the F nibble count
+ m_is_sync = true; //this nibble marks a sync sequence
+ m_num_F_nibbles = 21; // set the F nibble count - lose any extra as unsynced data.
}
else
{
diff --git a/decoder/include/opencsd/trc_gen_elem_types.h b/decoder/include/opencsd/trc_gen_elem_types.h
index 1a285a064b63..99194d118438 100644
--- a/decoder/include/opencsd/trc_gen_elem_types.h
+++ b/decoder/include/opencsd/trc_gen_elem_types.h
@@ -60,7 +60,10 @@ typedef enum _ocsd_gen_trc_elem_t
OCSD_GEN_TRC_ELEM_TIMESTAMP, /*!< Timestamp - preceding elements happeded before this time. */
OCSD_GEN_TRC_ELEM_CYCLE_COUNT, /*!< Cycle count - cycles since last cycle count value - associated with a preceding instruction range. */
OCSD_GEN_TRC_ELEM_EVENT, /*!< Event - trigger or numbered event */
- OCSD_GEN_TRC_ELEM_SWTRACE, /*!< Software trace packet - may contain data payload. */
+ OCSD_GEN_TRC_ELEM_SWTRACE, /*!< Software trace packet - may contain data payload. STM / ITM hardware trace with channel protocol */
+ OCSD_GEN_TRC_ELEM_SYNC_MARKER, /*!< Synchronisation marker - marks position in stream of an element that is output later. */
+ OCSD_GEN_TRC_ELEM_MEMTRANS, /*!< Trace indication of transactional memory operations. */
+ OCSD_GEN_TRC_ELEM_INSTRUMENTATION, /*!< PE instrumentation trace - PE generated SW trace, application dependent protocol. */
OCSD_GEN_TRC_ELEM_CUSTOM, /*!< Fully custom packet type - used by none-ARM architecture decoders */
} ocsd_gen_trc_elem_t;
@@ -86,6 +89,27 @@ typedef enum _unsync_info_t {
UNSYNC_EOT, /**< end of trace - no additional info */
} unsync_info_t;
+typedef enum _trace_sync_marker_t {
+ ELEM_MARKER_TS, /**< Marker for timestamp element */
+} trace_sync_marker_t;
+
+typedef struct _trace_marker_payload_t {
+ trace_sync_marker_t type; /**< type of sync marker */
+ uint32_t value; /**< sync marker value - usage depends on type */
+} trace_marker_payload_t;
+
+typedef enum _memtrans_t {
+ OCSD_MEM_TRANS_TRACE_INIT,/**< Trace started while PE in transactional state */
+ OCSD_MEM_TRANS_START, /**< Trace after this packet is part of a transactional memory sequence */
+ OCSD_MEM_TRANS_COMMIT, /**< Transactional memory sequence valid. */
+ OCSD_MEM_TRANS_FAIL, /**< Transactional memory sequence failed - operations since start of transaction have been unwound. */
+} trace_memtrans_t;
+
+typedef struct _sw_ite_t {
+ uint8_t el; /**< exception level for PE sw instrumentation instruction */
+ uint64_t value; /**< payload for PE sw instrumentation instruction */
+} trace_sw_ite_t;
+
typedef struct _ocsd_generic_trace_elem {
ocsd_gen_trc_elem_t elem_type; /**< Element type - remaining data interpreted according to this value */
ocsd_isa isa; /**< instruction set for executed instructions */
@@ -122,6 +146,9 @@ typedef struct _ocsd_generic_trace_elem {
ocsd_swt_info_t sw_trace_info; /**< software trace packet info */
uint32_t num_instr_range; /**< number of instructions covered by range packet (for T32 this cannot be calculated from en-st/i_size) */
unsync_info_t unsync_eot_info; /**< additional information for unsync / end-of-trace packets. */
+ trace_marker_payload_t sync_marker; /**< marker element - sync later element to position in stream */
+ trace_memtrans_t mem_trans; /**< memory transaction packet - transaction event */
+ trace_sw_ite_t sw_ite; /**< PE sw instrumentation using FEAT_ITE */
};
const void *ptr_extended_data; /**< pointer to extended data buffer (data trace, sw trace payload) / custom structure */
diff --git a/decoder/source/c_api/ocsd_c_api.cpp b/decoder/source/c_api/ocsd_c_api.cpp
index 4824c427e3d1..750c847e78c8 100644
--- a/decoder/source/c_api/ocsd_c_api.cpp
+++ b/decoder/source/c_api/ocsd_c_api.cpp
@@ -234,8 +234,24 @@ OCSD_C_API ocsd_err_t ocsd_dt_attach_packet_callback( const dcd_tree_handle_t h
return err;
}
-/*** Decode tree set element output */
+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)
+{
+ DecodeTree *pDT = static_cast(handle);
+
+ return pDT->getDecoderStats(CSID, p_stats_block);
+}
+OCSD_C_API ocsd_err_t ocsd_dt_reset_decode_stats(const dcd_tree_handle_t handle,
+ const unsigned char CSID)
+{
+ DecodeTree *pDT = static_cast(handle);
+
+ return pDT->resetDecoderStats(CSID);
+}
+
+/*** Decode tree set element output */
OCSD_C_API ocsd_err_t ocsd_dt_set_gen_elem_outfn(const dcd_tree_handle_t handle, FnTraceElemIn pFn, const void *p_context)
{
@@ -470,6 +486,39 @@ OCSD_C_API ocsd_err_t ocsd_dt_set_pkt_protocol_printer(const dcd_tree_handle_t h
return err;
}
+OCSD_C_API void ocsd_err_str(const ocsd_err_t err, char *buffer, const int buffer_size)
+{
+ std::string err_str;
+ err_str = ocsdError::getErrorString(ocsdError(OCSD_ERR_SEV_ERROR, err));
+ strncpy(buffer, err_str.c_str(), buffer_size - 1);
+ buffer[buffer_size - 1] = 0;
+}
+
+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)
+{
+ ocsdError *p_err;
+ ocsd_err_t err = OCSD_OK;
+ std::string err_str;
+
+ p_err = DecodeTree::getDefaultErrorLogger()->GetLastError();
+ if (p_err)
+ {
+ *index = p_err->getErrorIndex();
+ *chan_id = p_err->getErrorChanID();
+ err_str = p_err->getErrorString(ocsdError(p_err));
+ strncpy(message, err_str.c_str(), message_len - 1);
+ message[message_len - 1] = 0;
+ err = p_err->getErrorCode();
+ }
+ else
+ {
+ message[0] = 0;
+ *index = OCSD_BAD_TRC_INDEX;
+ *chan_id = OCSD_BAD_CS_SRC_ID;
+ }
+ return err;
+}
+
/*******************************************************************************/
/* C API local fns */
/*******************************************************************************/
diff --git a/decoder/source/ete/trc_cmp_cfg_ete.cpp b/decoder/source/ete/trc_cmp_cfg_ete.cpp
new file mode 100644
index 000000000000..474cb2f7914a
--- /dev/null
+++ b/decoder/source/ete/trc_cmp_cfg_ete.cpp
@@ -0,0 +1,98 @@
+/*
+* \file trc_cmp_cfg_ete.cpp
+* \brief OpenCSD : ETE config class
+*
+* \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.
+*/
+
+#include "opencsd/ete/trc_cmp_cfg_ete.h"
+
+ETEConfig::ETEConfig() : EtmV4Config()
+{
+ m_ete_cfg.reg_idr0 = 0x28000EA1;
+ m_ete_cfg.reg_idr1 = 0x4100FFF3;
+ m_ete_cfg.reg_idr2 = 0x00000488;
+ m_ete_cfg.reg_idr8 = 0;
+ m_ete_cfg.reg_configr = 0xC1;
+ m_ete_cfg.reg_traceidr = 0;
+ m_ete_cfg.arch_ver = ARCH_AA64;
+ m_ete_cfg.core_prof = profile_CortexA;
+ m_ete_cfg.reg_devarch = 0x47705A13;
+ copyV4();
+}
+
+ETEConfig::ETEConfig(const ocsd_ete_cfg *cfg_regs) : EtmV4Config()
+{
+ m_ete_cfg = *cfg_regs;
+ copyV4();
+}
+
+ETEConfig::~ETEConfig()
+{
+
+}
+
+//! copy assignment operator for base structure into class.
+ETEConfig & ETEConfig::operator=(const ocsd_ete_cfg *p_cfg)
+{
+ m_ete_cfg = *p_cfg;
+ copyV4();
+ return *this;
+}
+
+//! 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; };
+
+// ete superset of etmv4 - move info to underlying structure.
+void ETEConfig::copyV4()
+{
+ // copy over 1:1 regs
+ m_cfg.reg_idr0 = m_ete_cfg.reg_idr0;
+ m_cfg.reg_idr1 = m_ete_cfg.reg_idr1;
+ m_cfg.reg_idr2 = m_ete_cfg.reg_idr2;
+ m_cfg.reg_idr8 = m_ete_cfg.reg_idr8;
+ m_cfg.reg_idr9 = 0;
+ m_cfg.reg_idr10 = 0;
+ m_cfg.reg_idr11 = 0;
+ m_cfg.reg_idr12 = 0;
+ m_cfg.reg_idr13 = 0;
+ m_cfg.reg_configr = m_ete_cfg.reg_configr;
+ m_cfg.reg_traceidr = m_ete_cfg.reg_traceidr;
+ m_cfg.core_prof = m_ete_cfg.core_prof;
+ m_cfg.arch_ver = m_ete_cfg.arch_ver;
+
+ // override major / minor version as part of devarch
+ m_MajVer = (uint8_t)((m_ete_cfg.reg_devarch & 0xF000) >> 12);
+ m_MinVer = (uint8_t)((m_ete_cfg.reg_devarch & 0xF0000) >> 16);
+}
+
+/* End of File trc_cmp_cfg_ete.cpp */
diff --git a/decoder/source/etmv3/trc_pkt_elem_etmv3.cpp b/decoder/source/etmv3/trc_pkt_elem_etmv3.cpp
index f1e411f72423..74034c3c3e8f 100644
--- a/decoder/source/etmv3/trc_pkt_elem_etmv3.cpp
+++ b/decoder/source/etmv3/trc_pkt_elem_etmv3.cpp
@@ -659,7 +659,7 @@ void EtmV3TrcPacket::getExcepStr(std::string &excepStr) const
"IRQ4", "IRQ5", "IRQ6", "IRQ7",
"IRQ0","usage Fault","NMI","SVC",
"DebugMonitor", "Mem Manage","PendSV","SysTick",
- "Reserved","PE Reset","Reserved","HardFault"
+ "Reserved","PE Reset","Reserved","HardFault",
"Reserved","BusFault","Reserved","Reserved"
};
diff --git a/decoder/source/etmv4/trc_cmp_cfg_etmv4.cpp b/decoder/source/etmv4/trc_cmp_cfg_etmv4.cpp
index 9f5b37396b46..6f8bf790d293 100644
--- a/decoder/source/etmv4/trc_cmp_cfg_etmv4.cpp
+++ b/decoder/source/etmv4/trc_cmp_cfg_etmv4.cpp
@@ -98,7 +98,7 @@ void EtmV4Config::CalcVMIDSize()
uint32_t vmidszF = (m_cfg.reg_idr2 >> 10) & 0x1F;
if(vmidszF == 1)
m_VMIDSize = 8;
- else if(MinVersion() > 0)
+ else if(FullVersion() > 0x40)
{
if(vmidszF == 2)
m_VMIDSize = 16;
diff --git a/decoder/source/etmv4/trc_etmv4_stack_elem.cpp b/decoder/source/etmv4/trc_etmv4_stack_elem.cpp
index 8e9ba9ac43ca..a5d889413eb2 100644
--- a/decoder/source/etmv4/trc_etmv4_stack_elem.cpp
+++ b/decoder/source/etmv4/trc_etmv4_stack_elem.cpp
@@ -128,6 +128,40 @@ TrcStackQElem *EtmV4P0Stack::createQElem(const ocsd_etmv4_i_pkt_type root_pkt, c
return pElem;
}
+TrcStackElemMarker *EtmV4P0Stack::createMarkerElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const trace_marker_payload_t &marker)
+{
+ TrcStackElemMarker *pElem = new (std::nothrow) TrcStackElemMarker(root_pkt, root_index);
+ if (pElem)
+ {
+ pElem->setMarker(marker);
+ push_front(pElem);
+ }
+ return pElem;
+}
+
+TrcStackElemAddr *EtmV4P0Stack::createSrcAddrElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_addr_val_t &addr_val)
+{
+ TrcStackElemAddr *pElem = new (std::nothrow) TrcStackElemAddr(root_pkt, root_index, true);
+ if (pElem)
+ {
+ pElem->setAddr(addr_val);
+ push_front(pElem);
+ }
+ return pElem;
+}
+
+TrcStackElemITE *EtmV4P0Stack::createITEElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const trace_sw_ite_t &ite)
+{
+ TrcStackElemITE *pElem = new (std::nothrow) TrcStackElemITE(root_pkt, root_index);
+ if (pElem)
+ {
+ pElem->setITE(ite);
+ push_front(pElem);
+ }
+ return pElem;
+}
+
+
// iteration functions
void EtmV4P0Stack::from_front_init()
{
@@ -150,6 +184,10 @@ void EtmV4P0Stack::erase_curr_from_front()
erase_iter = m_iter;
erase_iter--;
m_P0_stack.erase(erase_iter);
+
+ // explicitly delete the item here as the caller can no longer reference it.
+ // fixes memory leak from github issue #52
+ delete *erase_iter;
}
diff --git a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
index 393046ba23d1..89c45052868c 100644
--- a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
+++ b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
@@ -39,7 +39,8 @@
#define DCD_NAME "DCD_ETMV4"
-static const uint32_t ETMV4_SUPPORTED_DECODE_OP_FLAGS = OCSD_OPFLG_PKTDEC_COMMON;
+static const uint32_t ETMV4_SUPPORTED_DECODE_OP_FLAGS = OCSD_OPFLG_PKTDEC_COMMON |
+ ETE_OPFLG_PKTDEC_SRCADDR_N_ATOMS;
TrcPktDecodeEtmV4I::TrcPktDecodeEtmV4I()
: TrcPktDecodeBase(DCD_NAME)
@@ -101,6 +102,14 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::processPacket()
m_curr_state = DECODE_PKTS;
m_return_stack.flush();
}
+ /* ETE spec allows early event packets. */
+ else if ((m_config->MajVersion() >= 0x5) &&
+ (m_curr_packet_in->getType() == ETM4_PKT_I_EVENT))
+ {
+ err = decodePacket();
+ if (err)
+ resp = OCSD_RESP_FATAL_INVALID_DATA;
+ }
bPktDone = true;
break;
@@ -261,6 +270,7 @@ void TrcPktDecodeEtmV4I::resetDecoder()
m_out_elem.resetElemStack();
m_last_IS = 0;
clearElemRes();
+ m_ete_first_ts_marker = false;
// elements associated with data trace
#ifdef DATA_TRACE_SUPPORTED
@@ -358,7 +368,25 @@ ocsd_err_t TrcPktDecodeEtmV4I::decodePacket()
if (m_P0_stack.createAddrElem(m_curr_packet_in->getType(), m_index_curr_pkt, addr) == 0)
bAllocErr = true;
- is_addr = true;
+ is_addr = true; // may be waiting for target address from indirect branch
+ }
+ break;
+
+ case ETE_PKT_I_SRC_ADDR_MATCH:
+ case ETE_PKT_I_SRC_ADDR_S_IS0:
+ case ETE_PKT_I_SRC_ADDR_S_IS1:
+ case ETE_PKT_I_SRC_ADDR_L_32IS0:
+ case ETE_PKT_I_SRC_ADDR_L_32IS1:
+ case ETE_PKT_I_SRC_ADDR_L_64IS0:
+ case ETE_PKT_I_SRC_ADDR_L_64IS1:
+ {
+ etmv4_addr_val_t addr;
+
+ addr.val = m_curr_packet_in->getAddrVal();
+ addr.isa = m_curr_packet_in->getAddrIS();
+ if (m_P0_stack.createSrcAddrElem(m_curr_packet_in->getType(), m_index_curr_pkt, addr) == 0)
+ bAllocErr = true;
+ m_curr_spec_depth++;
}
break;
@@ -438,16 +466,26 @@ ocsd_err_t TrcPktDecodeEtmV4I::decodePacket()
}
break;
+ case ETE_PKT_I_TS_MARKER:
+ {
+ trace_marker_payload_t marker;
+ marker.type = ELEM_MARKER_TS;
+ marker.value = 0;
+ if (m_P0_stack.createMarkerElem(m_curr_packet_in->getType(), m_index_curr_pkt, marker) == 0)
+ bAllocErr = true;
+ }
+ break;
+
case ETM4_PKT_I_BAD_SEQUENCE:
- err = handleBadPacket("Bad byte sequence in packet.");
+ err = handleBadPacket("Bad byte sequence in packet.", m_index_curr_pkt);
break;
case ETM4_PKT_I_BAD_TRACEMODE:
- err = handleBadPacket("Invalid packet type for trace mode.");
+ err = handleBadPacket("Invalid packet type for trace mode.", m_index_curr_pkt);
break;
case ETM4_PKT_I_RESERVED:
- err = handleBadPacket("Reserved packet header");
+ err = handleBadPacket("Reserved packet header", m_index_curr_pkt);
break;
// speculation
@@ -502,8 +540,44 @@ ocsd_err_t TrcPktDecodeEtmV4I::decodePacket()
}
break;
+ /* transactional memory packets */
+ case ETE_PKT_I_TRANS_ST:
+ {
+ if (m_P0_stack.createParamElemNoParam(P0_TRANS_START, m_config->commTransP0(), m_curr_packet_in->getType(), m_index_curr_pkt) == 0)
+ bAllocErr = true;
+ if (m_config->commTransP0())
+ m_curr_spec_depth++;
+ }
+ break;
+
+ case ETE_PKT_I_TRANS_COMMIT:
+ {
+ if (m_P0_stack.createParamElemNoParam(P0_TRANS_COMMIT, false, m_curr_packet_in->getType(), m_index_curr_pkt) == 0)
+ bAllocErr = true;
+ }
+ break;
+
+ case ETE_PKT_I_TRANS_FAIL:
+ {
+ if (m_P0_stack.createParamElemNoParam(P0_TRANS_FAIL, false, m_curr_packet_in->getType(), m_index_curr_pkt) == 0)
+ bAllocErr = true;
+ }
+ break;
+
+ /* PE Instrumentation packet */
+ case ETE_PKT_I_ITE:
+ {
+ trace_sw_ite_t ite_pkt;
+
+ ite_pkt.el = m_curr_packet_in->getITE_EL();
+ ite_pkt.value = m_curr_packet_in->getITE_value();
+ if (m_P0_stack.createITEElem(m_curr_packet_in->getType(), m_index_curr_pkt, ite_pkt) == 0)
+ bAllocErr = true;
+ }
+ break;
+
/*** presently unsupported packets ***/
- /* conditional instruction tracing */
+ /* conditional instruction tracing */
case ETM4_PKT_I_COND_FLUSH:
case ETM4_PKT_I_COND_I_F1:
case ETM4_PKT_I_COND_I_F2:
@@ -525,14 +599,16 @@ ocsd_err_t TrcPktDecodeEtmV4I::decodePacket()
//resp = OCSD_RESP_FATAL_INVALID_DATA;
#endif
err = OCSD_ERR_UNSUPP_DECODE_PKT;
- LogError(ocsdError(sev, err, "Data trace releated, unsupported packet type."));
+ if (sev == OCSD_ERR_SEV_WARN)
+ LogError(ocsdError(sev, err, "Data trace related, unsupported packet type."));
+ else
+ err = handlePacketSeqErr(err, m_index_curr_pkt, "Data trace related, unsupported packet type.");
}
break;
default:
// any other packet - bad packet error
- err = OCSD_ERR_BAD_DECODE_PKT;
- LogError(ocsdError(OCSD_ERR_SEV_ERROR,err,"Unknown packet type."));
+ err = handleBadPacket("Unknown packet type.", m_index_curr_pkt);
break;
}
@@ -566,6 +642,9 @@ void TrcPktDecodeEtmV4I::doTraceInfoPacket()
m_trace_info = m_curr_packet_in->getTraceInfo();
m_cc_threshold = m_curr_packet_in->getCCThreshold();
m_curr_spec_depth = m_curr_packet_in->getCurrSpecDepth();
+ /* put a trans marker in stack if started in trans state */
+ if (m_trace_info.bits.in_trans_state)
+ m_P0_stack.createParamElemNoParam(P0_TRANS_TRACE_INIT, false, m_curr_packet_in->getType(), m_index_curr_pkt);
// elements associated with data trace
#ifdef DATA_TRACE_SUPPORTED
@@ -592,14 +671,18 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::resolveElements()
if (m_elem_res.P0_commit)
err = commitElements();
- if (!err && m_elem_res.P0_cancel)
- err = cancelElements();
+ // allow for early flush on context element
+ if (!m_elem_res.P0_commit) {
- if (!err && m_elem_res.mispredict)
- err = mispredictAtom();
-
- if (!err && m_elem_res.discard)
- err = discardElements();
+ if (!err && m_elem_res.P0_cancel)
+ err = cancelElements();
+
+ if (!err && m_elem_res.mispredict)
+ err = mispredictAtom();
+
+ if (!err && m_elem_res.discard)
+ err = discardElements();
+ }
if (err != OCSD_OK)
resp = OCSD_RESP_FATAL_INVALID_DATA;
@@ -634,10 +717,11 @@ ocsd_err_t TrcPktDecodeEtmV4I::commitElements()
int num_commit_req = m_elem_res.P0_commit;
ocsd_trc_index_t err_idx = 0;
TrcStackElem *pElem = 0; // stacked element pointer
+ bool contextFlush = false;
err = m_out_elem.resetElemStack();
- while(m_elem_res.P0_commit && !err)
+ while(m_elem_res.P0_commit && !err && !contextFlush)
{
if (m_P0_stack.size() > 0)
{
@@ -646,7 +730,7 @@ ocsd_err_t TrcPktDecodeEtmV4I::commitElements()
switch (pElem->getP0Type())
{
- // indicates a trace restart - beginning of trace or discontinuiuty
+ // indicates a trace restart - beginning of trace or discontinuiuty
case P0_TRC_ON:
err = m_out_elem.addElemType(pElem->getRootIndex(), OCSD_GEN_TRC_ELEM_TRACE_ON);
if (!err)
@@ -661,7 +745,7 @@ ocsd_err_t TrcPktDecodeEtmV4I::commitElements()
{
TrcStackElemAddr *pAddrElem = dynamic_cast(pElem);
m_return_stack.clear_pop_pending(); // address removes the need to pop the indirect address target from the stack
- if(pAddrElem)
+ if (pAddrElem)
{
SetInstrInfoInAddrISA(pAddrElem->getAddr().val, pAddrElem->getAddr().isa);
m_need_addr = false;
@@ -672,15 +756,24 @@ ocsd_err_t TrcPktDecodeEtmV4I::commitElements()
case P0_CTXT:
{
TrcStackElemCtxt *pCtxtElem = dynamic_cast(pElem);
- if(pCtxtElem)
+ if (pCtxtElem)
{
etmv4_context_t ctxt = pCtxtElem->getContext();
// check this is an updated context
if(ctxt.updated)
{
err = m_out_elem.addElem(pElem->getRootIndex());
- if (!err)
+ if (!err) {
updateContext(pCtxtElem, outElem());
+
+ // updated context - need to force this to be output to the client so correct memory
+ // context can be used.
+ contextFlush = true;
+
+ // invalidate memory accessor cacheing - force next memory access out to client to
+ // ensure that the correct memory context is in play when decoding subsequent atoms.
+ invalidateMemAccCache();
+ }
}
}
}
@@ -693,11 +786,15 @@ ocsd_err_t TrcPktDecodeEtmV4I::commitElements()
err = processTS_CC_EventElem(pElem);
break;
+ case P0_MARKER:
+ err = processMarkerElem(pElem);
+ break;
+
case P0_ATOM:
{
TrcStackElemAtom *pAtomElem = dynamic_cast(pElem);
- if(pAtomElem)
+ if (pAtomElem)
{
while(!pAtomElem->isEmpty() && m_elem_res.P0_commit && !err)
{
@@ -709,13 +806,13 @@ ocsd_err_t TrcPktDecodeEtmV4I::commitElements()
// if address and context do instruction trace follower.
// otherwise skip atom and reduce committed elements
- if(!m_need_ctxt && !m_need_addr)
+ if (!m_need_ctxt && !m_need_addr)
{
err = processAtom(atom);
}
m_elem_res.P0_commit--; // mark committed
}
- if(!pAtomElem->isEmpty())
+ if (!pAtomElem->isEmpty())
bPopElem = false; // don't remove if still atoms to process.
}
}
@@ -746,9 +843,27 @@ ocsd_err_t TrcPktDecodeEtmV4I::commitElements()
m_elem_res.P0_commit--;
break;
+ case P0_SRC_ADDR:
+ err = processSourceAddress();
+ m_elem_res.P0_commit--;
+ break;
+
case P0_Q:
err = processQElement();
m_elem_res.P0_commit--;
+ break;
+
+ case P0_TRANS_START:
+ if (m_config->commTransP0())
+ m_elem_res.P0_commit--;
+ case P0_TRANS_COMMIT:
+ case P0_TRANS_FAIL:
+ case P0_TRANS_TRACE_INIT:
+ err = processTransElem(pElem);
+ break;
+
+ case P0_ITE:
+ err = processITEElem(pElem);
break;
}
@@ -757,9 +872,8 @@ ocsd_err_t TrcPktDecodeEtmV4I::commitElements()
}
else
{
- // too few elements for commit operation - decode error.
- err = OCSD_ERR_COMMIT_PKT_OVERRUN;
- LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_COMMIT_PKT_OVERRUN,err_idx,m_CSID,"Not enough elements to commit"));
+ // too few elements for commit operation - decode error.
+ err = handlePacketSeqErr(OCSD_ERR_COMMIT_PKT_OVERRUN, err_idx, "Not enough elements to commit");
}
}
@@ -779,7 +893,7 @@ ocsd_err_t TrcPktDecodeEtmV4I::returnStackPop()
if (m_return_stack.overflow())
{
err = OCSD_ERR_RET_STACK_OVERFLOW;
- LogError(ocsdError(OCSD_ERR_SEV_ERROR, err, "Trace Return Stack Overflow."));
+ err = handlePacketSeqErr(err, OCSD_BAD_TRC_INDEX, "Trace Return Stack Overflow.");
}
else
{
@@ -824,6 +938,25 @@ ocsd_err_t TrcPktDecodeEtmV4I::commitElemOnEOT()
case P0_CTXT:
break;
+ // trans
+ // P0 trans - clear and stop, otherwise skip
+ case P0_TRANS_START:
+ if (m_config->commTransP0())
+ m_P0_stack.delete_all();
+ break;
+
+ // non-speculative trans fail / commit - could appear at EoT after valid trace
+ // but without a subsequent P0 that would force output.
+ case P0_TRANS_FAIL:
+ case P0_TRANS_COMMIT:
+ if (m_max_spec_depth == 0 || m_curr_spec_depth == 0)
+ err = processTransElem(pElem);
+ break;
+
+ // others - skip non P0
+ case P0_TRANS_TRACE_INIT:
+ break;
+
// output
case P0_EVENT:
case P0_TS:
@@ -831,6 +964,14 @@ ocsd_err_t TrcPktDecodeEtmV4I::commitElemOnEOT()
case P0_TS_CC:
err = processTS_CC_EventElem(pElem);
break;
+
+ case P0_MARKER:
+ err = processMarkerElem(pElem);
+ break;
+
+ case P0_ITE:
+ err = processITEElem(pElem);
+ break;
}
m_P0_stack.delete_back();
}
@@ -886,6 +1027,8 @@ ocsd_err_t TrcPktDecodeEtmV4I::cancelElements()
case P0_TS:
case P0_CC:
case P0_TS_CC:
+ case P0_MARKER:
+ case P0_ITE:
m_P0_stack.pop_front(false);
temp.push_back(pElem);
break;
@@ -895,6 +1038,8 @@ ocsd_err_t TrcPktDecodeEtmV4I::cancelElements()
break;
}
}
+ if (m_P0_stack.size() == 0)
+ P0StackDone = true;
}
}
// may have some unseen elements
@@ -908,21 +1053,23 @@ ocsd_err_t TrcPktDecodeEtmV4I::cancelElements()
{
// too few elements for commit operation - decode error.
err = OCSD_ERR_COMMIT_PKT_OVERRUN;
- LogError(ocsdError(OCSD_ERR_SEV_ERROR, err, m_index_curr_pkt, m_CSID, "Not enough elements to cancel"));
+ err = handlePacketSeqErr(err, m_index_curr_pkt, "Not enough elements to cancel");
m_elem_res.P0_cancel = 0;
break;
}
-
- if (temp.size())
+ }
+
+ /* restore any saved elements that are unaffected by cancel. */
+ if (temp.size())
+ {
+ while (temp.size())
{
- while (temp.size())
- {
- pElem = temp.back();
- m_P0_stack.push_front(pElem);
- temp.pop_back(false);
- }
+ pElem = temp.back();
+ m_P0_stack.push_front(pElem);
+ temp.pop_back(false);
}
}
+
m_curr_spec_depth -= num_cancel_req - m_elem_res.P0_cancel;
return err;
}
@@ -964,7 +1111,8 @@ ocsd_err_t TrcPktDecodeEtmV4I::mispredictAtom()
if (!bFoundAtom && !m_unseen_spec_elem)
{
err = OCSD_ERR_COMMIT_PKT_OVERRUN;
- LogError(ocsdError(OCSD_ERR_SEV_ERROR, err, m_index_curr_pkt, m_CSID, "Not found mispredict atom"));
+ err = handlePacketSeqErr(err, m_index_curr_pkt, "Not found mispredict atom");
+ //LogError(ocsdError(OCSD_ERR_SEV_ERROR, err, m_index_curr_pkt, m_CSID, "Not found mispredict atom"));
}
m_elem_res.mispredict = false;
return err;
@@ -980,7 +1128,12 @@ ocsd_err_t TrcPktDecodeEtmV4I::discardElements()
while ((m_P0_stack.size() > 0) && !err)
{
pElem = m_P0_stack.back();
- err = processTS_CC_EventElem(pElem);
+ if (pElem->getP0Type() == P0_MARKER)
+ err = processMarkerElem(pElem);
+ else if (pElem->getP0Type() == P0_MARKER)
+ err = processITEElem(pElem);
+ else
+ err = processTS_CC_EventElem(pElem);
m_P0_stack.delete_back();
}
@@ -1002,6 +1155,8 @@ ocsd_err_t TrcPktDecodeEtmV4I::discardElements()
ocsd_err_t TrcPktDecodeEtmV4I::processTS_CC_EventElem(TrcStackElem *pElem)
{
ocsd_err_t err = OCSD_OK;
+ // ignore ts for ETE if not seen first TS marker on systems that use this.
+ bool bPermitTS = !m_config->eteHasTSMarker() || m_ete_first_ts_marker;
switch (pElem->getP0Type())
{
@@ -1016,7 +1171,7 @@ ocsd_err_t TrcPktDecodeEtmV4I::processTS_CC_EventElem(TrcStackElem *pElem)
case P0_TS:
{
TrcStackElemParam *pParamElem = dynamic_cast(pElem);
- if (pParamElem)
+ if (pParamElem && bPermitTS)
err = addElemTS(pParamElem, false);
}
break;
@@ -1032,7 +1187,7 @@ ocsd_err_t TrcPktDecodeEtmV4I::processTS_CC_EventElem(TrcStackElem *pElem)
case P0_TS_CC:
{
TrcStackElemParam *pParamElem = dynamic_cast(pElem);
- if (pParamElem)
+ if (pParamElem && bPermitTS)
err = addElemTS(pParamElem, true);
}
break;
@@ -1041,6 +1196,46 @@ ocsd_err_t TrcPktDecodeEtmV4I::processTS_CC_EventElem(TrcStackElem *pElem)
}
+ocsd_err_t TrcPktDecodeEtmV4I::processMarkerElem(TrcStackElem *pElem)
+{
+ ocsd_err_t err = OCSD_OK;
+ TrcStackElemMarker *pMarkerElem = dynamic_cast(pElem);
+
+ if (m_config->eteHasTSMarker() && (pMarkerElem->getMarker().type == ELEM_MARKER_TS))
+ m_ete_first_ts_marker = true;
+
+ if (!err)
+ {
+ err = m_out_elem.addElemType(pElem->getRootIndex(), OCSD_GEN_TRC_ELEM_SYNC_MARKER);
+ if (!err)
+ m_out_elem.getCurrElem().setSyncMarker(pMarkerElem->getMarker());
+ }
+ return err;
+}
+
+ocsd_err_t TrcPktDecodeEtmV4I::processTransElem(TrcStackElem *pElem)
+{
+ ocsd_err_t err = m_out_elem.addElemType(pElem->getRootIndex(), OCSD_GEN_TRC_ELEM_MEMTRANS);
+ if (!err)
+ {
+ outElem().setTransactionType((trace_memtrans_t)((int)OCSD_MEM_TRANS_FAIL -
+ ((int)P0_TRANS_FAIL - (int)pElem->getP0Type())));
+ }
+ return err;
+}
+
+ocsd_err_t TrcPktDecodeEtmV4I::processITEElem(TrcStackElem *pElem)
+{
+ ocsd_err_t err = OCSD_OK;
+ TrcStackElemITE *pITEElem = dynamic_cast(pElem);
+
+ err = m_out_elem.addElemType(pElem->getRootIndex(), OCSD_GEN_TRC_ELEM_INSTRUMENTATION);
+ if (!err) {
+ outElem().setITEInfo(pITEElem->getITE());
+ }
+ return err;
+}
+
ocsd_err_t TrcPktDecodeEtmV4I::addElemCC(TrcStackElemParam *pParamElem)
{
ocsd_err_t err = OCSD_OK;
@@ -1078,16 +1273,22 @@ ocsd_err_t TrcPktDecodeEtmV4I::addElemEvent(TrcStackElemParam *pParamElem)
return err;
}
-void TrcPktDecodeEtmV4I::setElemTraceRange(OcsdTraceElement &elemIn, const instr_range_t &addr_range,
- const bool executed, ocsd_trc_index_t index)
+void TrcPktDecodeEtmV4I::setElemTraceRange(OcsdTraceElement &elemIn, const instr_range_t &addr_range,
+ const bool executed, ocsd_trc_index_t index)
+{
+ setElemTraceRangeInstr(elemIn, addr_range, executed, index, m_instr_info);
+}
+
+void TrcPktDecodeEtmV4I::setElemTraceRangeInstr(OcsdTraceElement &elemIn, const instr_range_t &addr_range,
+ const bool executed, ocsd_trc_index_t index, ocsd_instr_info &instr)
{
elemIn.setType(OCSD_GEN_TRC_ELEM_INSTR_RANGE);
- elemIn.setLastInstrInfo(executed, m_instr_info.type, m_instr_info.sub_type, m_instr_info.instr_size);
- elemIn.setISA(m_instr_info.isa);
- elemIn.setLastInstrCond(m_instr_info.is_conditional);
+ elemIn.setLastInstrInfo(executed, instr.type, instr.sub_type, instr.instr_size);
+ elemIn.setISA(instr.isa);
+ elemIn.setLastInstrCond(instr.is_conditional);
elemIn.setAddrRange(addr_range.st_addr, addr_range.en_addr, addr_range.num_instr);
if (executed)
- m_instr_info.isa = m_instr_info.next_isa;
+ instr.isa = instr.next_isa;
}
ocsd_err_t TrcPktDecodeEtmV4I::processAtom(const ocsd_atm_val atom)
@@ -1096,6 +1297,7 @@ ocsd_err_t TrcPktDecodeEtmV4I::processAtom(const ocsd_atm_val atom)
TrcStackElem *pElem = m_P0_stack.back(); // get the atom element
WP_res_t WPRes;
instr_range_t addr_range;
+ bool ETE_ERET = false;
// new element for this processed atom
if ((err = m_out_elem.addElem(pElem->getRootIndex())) != OCSD_OK)
@@ -1114,7 +1316,8 @@ ocsd_err_t TrcPktDecodeEtmV4I::processAtom(const ocsd_atm_val atom)
}
else
{
- LogError(ocsdError(OCSD_ERR_SEV_ERROR,err,pElem->getRootIndex(),m_CSID,"Error processing atom packet."));
+ err = handlePacketSeqErr(err, pElem->getRootIndex(), "Error processing atom packet.");
+ //LogError(ocsdError(OCSD_ERR_SEV_ERROR,err,pElem->getRootIndex(),m_CSID,"Error processing atom packet."));
return err;
}
}
@@ -1144,10 +1347,22 @@ ocsd_err_t TrcPktDecodeEtmV4I::processAtom(const ocsd_atm_val atom)
if (m_instr_info.is_link)
m_return_stack.push(nextAddr,m_instr_info.isa);
m_return_stack.set_pop_pending(); // need to know next packet before we know what is to happen
+
+ /* ETE does not have ERET trace packets - however to maintain the illusion if we see an ERET
+ output a gen elem ERET packet */
+ if (isETEConfig() && (m_instr_info.sub_type == OCSD_S_INSTR_V8_ERET))
+ ETE_ERET = true;
}
break;
}
setElemTraceRange(outElem(), addr_range, (atom == ATOM_E), pElem->getRootIndex());
+
+ if (ETE_ERET)
+ {
+ err = m_out_elem.addElemType(pElem->getRootIndex(), OCSD_GEN_TRC_ELEM_EXCEPTION_RET);
+ if (err)
+ return err;
+ }
}
else
{
@@ -1182,55 +1397,64 @@ ocsd_err_t TrcPktDecodeEtmV4I::processException()
TrcStackElemAddr *pAddressElem = 0;
TrcStackElemCtxt *pCtxtElem = 0;
bool branch_target = false; // exception address implies prior branch target address
- ocsd_vaddr_t excep_ret_addr;
+ ocsd_vaddr_t excep_ret_addr = 0;
ocsd_trc_index_t excep_pkt_index;
WP_res_t WPRes = WP_NOT_FOUND;
+ bool ETE_resetPkt = false;
// grab the exception element off the stack
pExceptElem = dynamic_cast(m_P0_stack.back()); // get the exception element
excep_pkt_index = pExceptElem->getRootIndex();
branch_target = pExceptElem->getPrevSame();
+ if (pExceptElem->getRootPkt() == ETE_PKT_I_PE_RESET)
+ ETE_resetPkt = true;
m_P0_stack.pop_back(); // remove the exception element
- pElem = m_P0_stack.back(); // look at next element.
- if(pElem->getP0Type() == P0_CTXT)
+ // ETE reset has no follow up address, the rest of the exceptions do....
+ if (!ETE_resetPkt)
{
- pCtxtElem = dynamic_cast(pElem);
- m_P0_stack.pop_back(); // remove the context element
- pElem = m_P0_stack.back(); // next one should be an address element
- }
-
- if(pElem->getP0Type() != P0_ADDR)
- {
- // no following address element - indicate processing error.
- LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_BAD_PACKET_SEQ, excep_pkt_index,m_CSID,"Address missing in exception packet."));
- return OCSD_ERR_BAD_PACKET_SEQ;
- }
- else
- {
- // extract address
- pAddressElem = static_cast(pElem);
- excep_ret_addr = pAddressElem->getAddr().val;
-
- // see if there is an address + optional context element implied
- // prior to the exception.
- if (branch_target)
+ pElem = m_P0_stack.back(); // look at next element.
+ if (pElem->getP0Type() == P0_CTXT)
{
- // this was a branch target address - update current setting
- bool b64bit = m_instr_info.isa == ocsd_isa_aarch64;
- if (pCtxtElem) {
- b64bit = pCtxtElem->getContext().SF;
- }
-
- // as the exception address was also a branch target address then update the
- // current maintained address value. This also means that there is no range to
- // output before the exception packet.
- m_instr_info.instr_addr = excep_ret_addr;
- m_instr_info.isa = (pAddressElem->getAddr().isa == 0) ?
- (b64bit ? ocsd_isa_aarch64 : ocsd_isa_arm) : ocsd_isa_thumb2;
- m_need_addr = false;
+ pCtxtElem = dynamic_cast(pElem);
+ m_P0_stack.pop_back(); // remove the context element
+ pElem = m_P0_stack.back(); // next one should be an address element
}
- }
+
+ if (pElem->getP0Type() != P0_ADDR)
+ {
+ // no following address element - indicate processing error.
+
+ err = handlePacketSeqErr(OCSD_ERR_BAD_PACKET_SEQ, m_index_curr_pkt, "Address missing in exception packet.");
+ //LogError(ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_BAD_PACKET_SEQ, excep_pkt_index, m_CSID, "Address missing in exception packet."));
+ return err;
+ }
+ else
+ {
+ // extract address
+ pAddressElem = static_cast(pElem);
+ excep_ret_addr = pAddressElem->getAddr().val;
+
+ // see if there is an address + optional context element implied
+ // prior to the exception.
+ if (branch_target)
+ {
+ // this was a branch target address - update current setting
+ bool b64bit = m_instr_info.isa == ocsd_isa_aarch64;
+ if (pCtxtElem) {
+ b64bit = pCtxtElem->getContext().SF;
+ }
+
+ // as the exception address was also a branch target address then update the
+ // current maintained address value. This also means that there is no range to
+ // output before the exception packet.
+ m_instr_info.instr_addr = excep_ret_addr;
+ m_instr_info.isa = (pAddressElem->getAddr().isa == 0) ?
+ (b64bit ? ocsd_isa_aarch64 : ocsd_isa_arm) : ocsd_isa_thumb2;
+ m_need_addr = false;
+ }
+ }
+ }
// need to output something - set up an element
if ((err = m_out_elem.addElem(excep_pkt_index)))
@@ -1246,69 +1470,72 @@ ocsd_err_t TrcPktDecodeEtmV4I::processException()
return err;
}
- // if the preferred return address is not the end of the last output range...
- if (m_instr_info.instr_addr != excep_ret_addr)
- {
- bool range_out = false;
- instr_range_t addr_range;
-
- // look for match to return address.
- err = traceInstrToWP(addr_range, WPRes, true, excep_ret_addr);
-
- if(err != OCSD_OK)
+ if (!ETE_resetPkt)
+ {
+ // if the preferred return address is not the end of the last output range...
+ if (m_instr_info.instr_addr != excep_ret_addr)
{
- if(err == OCSD_ERR_UNSUPPORTED_ISA)
+ bool range_out = false;
+ instr_range_t addr_range;
+
+ // look for match to return address.
+ err = traceInstrToWP(addr_range, WPRes, true, excep_ret_addr);
+
+ if (err != OCSD_OK)
{
- m_need_addr = true;
- m_need_ctxt = true;
- LogError(ocsdError(OCSD_ERR_SEV_WARN,err, excep_pkt_index,m_CSID,"Warning: unsupported instruction set processing exception packet."));
+ if (err == OCSD_ERR_UNSUPPORTED_ISA)
+ {
+ m_need_addr = true;
+ m_need_ctxt = true;
+ LogError(ocsdError(OCSD_ERR_SEV_WARN, err, excep_pkt_index, m_CSID, "Warning: unsupported instruction set processing exception packet."));
+ }
+ else
+ {
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR, err, excep_pkt_index, m_CSID, "Error processing exception packet."));
+ }
+ return err;
}
- else
- {
- LogError(ocsdError(OCSD_ERR_SEV_ERROR,err, excep_pkt_index,m_CSID,"Error processing exception packet."));
- }
- return err;
- }
- if(WPFound(WPRes))
- {
- // waypoint address found - output range
- setElemTraceRange(outElem(), addr_range, true, excep_pkt_index);
- range_out = true;
- }
- else
- {
- // no waypoint - likely inaccessible memory range.
- m_need_addr = true; // need an address update
-
- if(addr_range.st_addr != addr_range.en_addr)
+ if (WPFound(WPRes))
{
- // some trace before we were out of memory access range
+ // waypoint address found - output range
setElemTraceRange(outElem(), addr_range, true, excep_pkt_index);
range_out = true;
}
+ else
+ {
+ // no waypoint - likely inaccessible memory range.
+ m_need_addr = true; // need an address update
+
+ if (addr_range.st_addr != addr_range.en_addr)
+ {
+ // some trace before we were out of memory access range
+ setElemTraceRange(outElem(), addr_range, true, excep_pkt_index);
+ range_out = true;
+ }
+ }
+
+ // used the element need another for NACC or EXCEP.
+ if (range_out)
+ {
+ if ((err = m_out_elem.addElem(excep_pkt_index)))
+ return err;
+ }
}
- // used the element need another for NACC or EXCEP.
- if (range_out)
+ // watchpoint walk resulted in inaccessible memory call...
+ if (WPNacc(WPRes))
{
+
+ outElem().setType(OCSD_GEN_TRC_ELEM_ADDR_NACC);
+ outElem().st_addr = m_instr_info.instr_addr;
+
+ // used the element - need another for the final exception packet.
if ((err = m_out_elem.addElem(excep_pkt_index)))
return err;
}
}
-
- // watchpoint walk resulted in inaccessible memory call...
- if (WPNacc(WPRes))
- {
-
- outElem().setType(OCSD_GEN_TRC_ELEM_ADDR_NACC);
- outElem().st_addr = m_instr_info.instr_addr;
- // used the element - need another for the final exception packet.
- if ((err = m_out_elem.addElem(excep_pkt_index)))
- return err;
- }
-
// output exception element.
outElem().setType(OCSD_GEN_TRC_ELEM_EXCEPTION);
@@ -1453,6 +1680,163 @@ ocsd_err_t TrcPktDecodeEtmV4I::processQElement()
return err;
}
+ocsd_err_t TrcPktDecodeEtmV4I::processSourceAddress()
+{
+ ocsd_err_t err = OCSD_OK;
+ TrcStackElemAddr *pElem = dynamic_cast(m_P0_stack.back()); // get the address element
+ etmv4_addr_val_t srcAddr = pElem->getAddr();
+ uint32_t opcode, bytesReq = 4;
+ ocsd_vaddr_t currAddr = m_instr_info.instr_addr; // get the latest decoded address.
+ instr_range_t out_range;
+ bool bSplitRangeOnN = getComponentOpMode() & ETE_OPFLG_PKTDEC_SRCADDR_N_ATOMS ? true : false;
+
+ // check we can read instruction @ source address
+ err = accessMemory(srcAddr.val, getCurrMemSpace(), &bytesReq, (uint8_t *)&opcode);
+ if (err != OCSD_OK)
+ {
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR, err, pElem->getRootIndex(), m_CSID, "Mem access error processing source address packet."));
+ return err;
+ }
+
+ if (bytesReq != 4)
+ {
+ // can't access - no bytes returned - output nacc.
+ err = m_out_elem.addElemType(pElem->getRootIndex(), OCSD_GEN_TRC_ELEM_ADDR_NACC);
+ outElem().setAddrStart(srcAddr.val);
+ return err;
+ }
+
+ // analyze opcode @ source address.
+ m_instr_info.opcode = opcode;
+ m_instr_info.instr_addr = srcAddr.val;
+ err = instrDecode(&m_instr_info);
+ if (err != OCSD_OK)
+ {
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR, err, pElem->getRootIndex(), m_CSID, "Instruction decode error processing source address packet."));
+ return err;
+ }
+ m_instr_info.instr_addr += m_instr_info.instr_size;
+
+ // initial instruction count for the range.
+ out_range.num_instr = 1;
+
+ // calculate range traced...
+ if (m_need_addr || (currAddr > srcAddr.val))
+ {
+ // we were waiting for a target address, or missing trace
+ // that indicates how we got to the source address.
+ m_need_addr = false;
+ out_range.st_addr = srcAddr.val;
+ }
+ else
+ out_range.st_addr = currAddr;
+ out_range.en_addr = m_instr_info.instr_addr;
+
+ // count instructions
+ if (out_range.en_addr - out_range.st_addr > m_instr_info.instr_size)
+ {
+ if ((m_instr_info.isa != ocsd_isa_thumb2) && !bSplitRangeOnN)
+ {
+ // all 4 byte instructions - just calculate...
+ out_range.num_instr = (uint32_t)(out_range.en_addr - out_range.st_addr) / 4;
+ }
+ else
+ {
+ // need to count T32 - 2 or 4 byte instructions or we are spotting N atoms
+ ocsd_instr_info instr; // going back to start of range so make a copy of info.
+ bool bMemAccErr = false;
+
+ instr.instr_addr = out_range.st_addr;
+ instr.isa = m_instr_info.isa;
+ instr.pe_type = m_instr_info.pe_type;
+ instr.dsb_dmb_waypoints = m_instr_info.dsb_dmb_waypoints;
+ instr.wfi_wfe_branch = m_instr_info.wfi_wfe_branch;
+ out_range.num_instr = 0;
+
+ while ((instr.instr_addr < out_range.en_addr) && !bMemAccErr)
+ {
+ bytesReq = 4;
+ err = accessMemory(instr.instr_addr, getCurrMemSpace(), &bytesReq, (uint8_t *)&opcode);
+ if (err != OCSD_OK)
+ {
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR, err, pElem->getRootIndex(), m_CSID, "Mem access error processing source address packet."));
+ return err;
+ }
+
+ if (bytesReq == 4)
+ {
+ instr.opcode = opcode;
+ err = instrDecode(&instr);
+ if (err != OCSD_OK)
+ {
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR, err, pElem->getRootIndex(), m_CSID, "Instruction decode error processing source address packet."));
+ return err;
+ }
+
+ instr.instr_addr += instr.instr_size;
+ out_range.num_instr++;
+
+ /* if we are doing N atom ranges ...*/
+ if (bSplitRangeOnN && (instr.instr_addr < out_range.en_addr))
+ {
+ if (instr.type != OCSD_INSTR_OTHER)
+ {
+ instr_range_t mid_range = out_range;
+ mid_range.en_addr = instr.instr_addr;
+
+ err = m_out_elem.addElem(pElem->getRootIndex());
+ if (err)
+ return err;
+ setElemTraceRangeInstr(outElem(), mid_range, false, pElem->getRootIndex(), instr);
+
+ out_range.st_addr = mid_range.en_addr;
+ out_range.num_instr = 0;
+ }
+ }
+ }
+ else
+ {
+ // something inaccessible between last and current...
+ bMemAccErr = true;
+
+ err = m_out_elem.addElemType(pElem->getRootIndex(), OCSD_GEN_TRC_ELEM_ADDR_NACC);
+ if (err)
+ return err;
+ outElem().setAddrStart(srcAddr.val);
+
+ // force range to the one instruction
+ out_range.num_instr = 1;
+ out_range.st_addr = srcAddr.val;
+ out_range.en_addr = m_instr_info.instr_addr; // instr after the decoded instruction @ srcAddr.
+ }
+ }
+ }
+ }
+
+ // got to the source address - output trace range, and instruction as E atom.
+ switch (m_instr_info.type)
+ {
+ case OCSD_INSTR_BR:
+ if (m_instr_info.is_link)
+ m_return_stack.push(m_instr_info.instr_addr, m_instr_info.isa);
+ m_instr_info.instr_addr = m_instr_info.branch_addr;
+ break;
+
+ case OCSD_INSTR_BR_INDIRECT:
+ m_need_addr = true; // indirect branch taken - need new address.
+ if (m_instr_info.is_link)
+ m_return_stack.push(m_instr_info.instr_addr, m_instr_info.isa);
+ m_return_stack.set_pop_pending(); // need to know next packet before we know what is to happen
+ break;
+ }
+ m_instr_info.isa = m_instr_info.next_isa;
+
+ // set the trace range element.
+ m_out_elem.addElem(pElem->getRootIndex());
+ setElemTraceRange(outElem(), out_range, true, pElem->getRootIndex());
+ return err;
+}
+
void TrcPktDecodeEtmV4I::SetInstrInfoInAddrISA(const ocsd_vaddr_t addr_val, const uint8_t isa)
{
m_instr_info.instr_addr = addr_val;
@@ -1518,7 +1902,10 @@ void TrcPktDecodeEtmV4I::updateContext(TrcStackElemCtxt *pCtxtElem, OcsdTraceEle
m_is_64bit = (ctxt.SF != 0);
elem.context.bits64 = ctxt.SF;
m_is_secure = (ctxt.NS == 0);
- elem.context.security_level = ctxt.NS ? ocsd_sec_nonsecure : ocsd_sec_secure;
+ if (ctxt.NSE)
+ elem.context.security_level = ctxt.NS ? ocsd_sec_realm : ocsd_sec_root;
+ else
+ elem.context.security_level = ctxt.NS ? ocsd_sec_nonsecure : ocsd_sec_secure;
elem.context.exception_level = (ocsd_ex_level)ctxt.EL;
elem.context.el_valid = 1;
if(ctxt.updated_c)
@@ -1537,27 +1924,42 @@ void TrcPktDecodeEtmV4I::updateContext(TrcStackElemCtxt *pCtxtElem, OcsdTraceEle
m_need_ctxt = false;
}
-ocsd_err_t TrcPktDecodeEtmV4I::handleBadPacket(const char *reason)
+ocsd_err_t TrcPktDecodeEtmV4I::handleBadPacket(const char *reason, ocsd_trc_index_t index /* = OCSD_BAD_TRC_INDEX */)
{
- ocsd_err_t err = OCSD_OK;
+ ocsd_err_severity_t sev = OCSD_ERR_SEV_WARN;
+ if (getComponentOpMode() & OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS)
+ sev = OCSD_ERR_SEV_ERROR;
- if(getComponentOpMode() & OCSD_OPFLG_PKTDEC_ERROR_BAD_PKTS)
+ return handlePacketErr(OCSD_ERR_BAD_DECODE_PKT, sev, index, reason);
+}
+
+ocsd_err_t TrcPktDecodeEtmV4I::handlePacketSeqErr(ocsd_err_t err, ocsd_trc_index_t index, const char *reason)
+{
+ return handlePacketErr(err, OCSD_ERR_SEV_ERROR, index, reason);
+}
+
+ocsd_err_t TrcPktDecodeEtmV4I::handlePacketErr(ocsd_err_t err, ocsd_err_severity_t sev, ocsd_trc_index_t index, const char *reason)
+{
+ bool resetOnBadPackets = true;
+
+ if(getComponentOpMode() & OCSD_OPFLG_PKTDEC_HALT_BAD_PKTS)
+ resetOnBadPackets = false;
+
+ LogError(ocsdError(sev, err, index, getCoreSightTraceID(), reason));
+
+ if (resetOnBadPackets)
{
- // error out - stop decoding
- err = OCSD_ERR_BAD_DECODE_PKT;
- LogError(ocsdError(OCSD_ERR_SEV_ERROR,err,reason));
- }
- else
- {
- LogError(ocsdError(OCSD_ERR_SEV_WARN, OCSD_ERR_BAD_DECODE_PKT, reason));
// switch to unsync - clear decode state
resetDecoder();
m_curr_state = NO_SYNC;
m_unsync_eot_info = UNSYNC_BAD_PACKET;
+ err = OCSD_OK;
}
return err;
+
}
+
inline ocsd_mem_space_acc_t TrcPktDecodeEtmV4I::getCurrMemSpace()
{
static ocsd_mem_space_acc_t SMemSpace[] = {
diff --git a/decoder/source/etmv4/trc_pkt_elem_etmv4i.cpp b/decoder/source/etmv4/trc_pkt_elem_etmv4i.cpp
index 853fde499a1b..825b5f79e41b 100644
--- a/decoder/source/etmv4/trc_pkt_elem_etmv4i.cpp
+++ b/decoder/source/etmv4/trc_pkt_elem_etmv4i.cpp
@@ -38,6 +38,7 @@
EtmV4ITrcPacket::EtmV4ITrcPacket()
{
+ protocol_version = 0x42; // min protocol version.
}
EtmV4ITrcPacket::~EtmV4ITrcPacket()
@@ -101,6 +102,8 @@ void EtmV4ITrcPacket::toString(std::string &str) const
contextStr(ctxtStr);
case ETM4_PKT_I_ADDR_L_32IS0:
case ETM4_PKT_I_ADDR_L_32IS1:
+ case ETE_PKT_I_SRC_ADDR_L_32IS0:
+ case ETE_PKT_I_SRC_ADDR_L_32IS1:
trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true, (v_addr.pkt_bits < 32) ? v_addr.pkt_bits : 0);
str += "; Addr=" + valStr + "; " + ctxtStr;
break;
@@ -110,6 +113,8 @@ void EtmV4ITrcPacket::toString(std::string &str) const
contextStr(ctxtStr);
case ETM4_PKT_I_ADDR_L_64IS0:
case ETM4_PKT_I_ADDR_L_64IS1:
+ case ETE_PKT_I_SRC_ADDR_L_64IS0:
+ case ETE_PKT_I_SRC_ADDR_L_64IS1:
trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true, (v_addr.pkt_bits < 64) ? v_addr.pkt_bits : 0);
str += "; Addr=" + valStr + "; " + ctxtStr;
break;
@@ -121,11 +126,14 @@ void EtmV4ITrcPacket::toString(std::string &str) const
case ETM4_PKT_I_ADDR_S_IS0:
case ETM4_PKT_I_ADDR_S_IS1:
+ case ETE_PKT_I_SRC_ADDR_S_IS0:
+ case ETE_PKT_I_SRC_ADDR_S_IS1:
trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true, v_addr.pkt_bits);
str += "; Addr=" + valStr;
break;
case ETM4_PKT_I_ADDR_MATCH:
+ case ETE_PKT_I_SRC_ADDR_MATCH:
addrMatchIdx(valStr);
str += ", " + valStr;
trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true);
@@ -161,7 +169,10 @@ void EtmV4ITrcPacket::toString(std::string &str) const
{
std::ostringstream oss;
oss << "; INFO=" << std::hex << "0x" << trace_info.val;
- oss << " { CC." << std::dec << trace_info.bits.cc_enabled << " }";
+ oss << " { CC." << std::dec << trace_info.bits.cc_enabled;
+ if (isETE())
+ oss << ", TSTATE." << std::dec << trace_info.bits.in_trans_state;
+ oss << " }";
if (trace_info.bits.cc_enabled)
oss << "; CC_THRESHOLD=" << std::hex << "0x" << cc_threshold;
str += oss.str();
@@ -264,6 +275,14 @@ void EtmV4ITrcPacket::toString(std::string &str) const
}
}
break;
+
+ case ETE_PKT_I_ITE:
+ {
+ std::ostringstream oss;
+ oss << "; EL" << std::dec << (int)ite_pkt.el << "; Payload=0x" << std::hex << ite_pkt.value;
+ str += oss.str();
+ }
+ break;
}
}
@@ -349,6 +368,16 @@ const char *EtmV4ITrcPacket::packetTypeName(const ocsd_etmv4_i_pkt_type type, co
pName = "I_EXCEPT_RTN";
pDesc = "Exception Return.";
break;
+
+ case ETE_PKT_I_TRANS_ST:
+ pName = "I_TRANS_ST";
+ pDesc = "Transaction Start.";
+ break;
+
+ case ETE_PKT_I_TRANS_COMMIT:
+ pName = "I_TRANS_COMMIT";
+ pDesc = "Transaction Commit.";
+ break;
case ETM4_PKT_I_CCNT_F1:
pName = "I_CCNT_F1";
@@ -481,6 +510,11 @@ const char *EtmV4ITrcPacket::packetTypeName(const ocsd_etmv4_i_pkt_type type, co
pDesc = "Address & Context, Long, 64 bit, IS1.";
break;
+ case ETE_PKT_I_TS_MARKER:
+ pName = "I_TS_MARKER";
+ pDesc = "Timestamp Marker";
+ break;
+
case ETM4_PKT_I_ADDR_MATCH:
pName = "I_ADDR_MATCH";
pDesc = "Exact Address Match.";
@@ -521,6 +555,41 @@ const char *EtmV4ITrcPacket::packetTypeName(const ocsd_etmv4_i_pkt_type type, co
pDesc = "Q Packet.";
break;
+ case ETE_PKT_I_SRC_ADDR_MATCH:
+ pName = "I_SRC_ADDR_MATCH";
+ pDesc = "Exact Source Address Match.";
+ break;
+
+ case ETE_PKT_I_SRC_ADDR_S_IS0:
+ pName = "I_SRC_ADDR_S_IS0";
+ pDesc = "Source Address, Short, IS0.";
+ break;
+
+ case ETE_PKT_I_SRC_ADDR_S_IS1:
+ pName = "I_SRC_ADDR_S_IS1";
+ pDesc = "Source Address, Short, IS1.";
+ break;
+
+ case ETE_PKT_I_SRC_ADDR_L_32IS0:
+ pName = "I_SCR_ADDR_L_32IS0";
+ pDesc = "Source Address, Long, 32 bit, IS0.";
+ break;
+
+ case ETE_PKT_I_SRC_ADDR_L_32IS1:
+ pName = "I_SRC_ADDR_L_32IS1";
+ pDesc = "Source Address, Long, 32 bit, IS1.";
+ break;
+
+ case ETE_PKT_I_SRC_ADDR_L_64IS0:
+ pName = "I_SRC_ADDR_L_64IS0";
+ pDesc = "Source Address, Long, 64 bit, IS0.";
+ break;
+
+ case ETE_PKT_I_SRC_ADDR_L_64IS1:
+ pName = "I_SRC_ADDR_L_64IS1";
+ pDesc = "Source Address, Long, 64 bit, IS1.";
+ break;
+
case ETM4_PKT_I_ATOM_F6:
pName = "I_ATOM_F6";
pDesc = "Atom format 6.";
@@ -566,6 +635,21 @@ const char *EtmV4ITrcPacket::packetTypeName(const ocsd_etmv4_i_pkt_type type, co
pDesc = "Overflow.";
break;
+ case ETE_PKT_I_PE_RESET:
+ pName = "I_PE_RESET";
+ pDesc = "PE Reset.";
+ break;
+
+ case ETE_PKT_I_TRANS_FAIL:
+ pName = "I_TRANS_FAIL";
+ pDesc = "Transaction Fail.";
+ break;
+
+ case ETE_PKT_I_ITE:
+ pName = "I_ITE";
+ pDesc = "Instrumentation";
+ break;
+
default:
break;
}
diff --git a/decoder/source/etmv4/trc_pkt_proc_etmv4i.cpp b/decoder/source/etmv4/trc_pkt_proc_etmv4i.cpp
index d8c7d84667d1..d767bdc85643 100644
--- a/decoder/source/etmv4/trc_pkt_proc_etmv4i.cpp
+++ b/decoder/source/etmv4/trc_pkt_proc_etmv4i.cpp
@@ -45,6 +45,9 @@
static const uint32_t ETMV4_SUPPORTED_OP_FLAGS = OCSD_OPFLG_PKTPROC_COMMON;
+// test defines - if testing with ETMv4 sources, disable error on ERET.
+// #define ETE_TRACE_ERET_AS_IGNORE
+
/* trace etmv4 packet processing class */
TrcPktProcEtmV4I::TrcPktProcEtmV4I() : TrcPktProcBase(ETMV4I_PKTS_NAME),
m_isInit(false),
@@ -70,7 +73,9 @@ ocsd_err_t TrcPktProcEtmV4I::onProtocolConfig()
InitProcessorState();
m_config = *TrcPktProcBase::getProtocolConfig();
BuildIPacketTable(); // packet table based on config
+ m_curr_packet.setProtocolVersion(m_config.FullVersion());
m_isInit = true;
+ statsInit();
return OCSD_OK;
}
@@ -152,6 +157,10 @@ ocsd_datapath_resp_t TrcPktProcEtmV4I::processData( const ocsd_trc_index_t inde
(err.getErrorCode() == OCSD_ERR_INVALID_PCKT_HDR))
{
// send invalid packets up the pipe to let the next stage decide what to do.
+ if (err.getErrorCode() == OCSD_ERR_INVALID_PCKT_HDR)
+ statsAddBadHdrCount(1);
+ else
+ statsAddBadSeqCount(1);
m_process_state = SEND_PKT;
done = false;
}
@@ -171,6 +180,7 @@ ocsd_datapath_resp_t TrcPktProcEtmV4I::processData( const ocsd_trc_index_t inde
}
} while (!done);
+ statsAddTotalCount(m_trcIn.processed());
*numBytesProcessed = m_trcIn.processed();
return resp;
}
@@ -241,8 +251,8 @@ ocsd_datapath_resp_t TrcPktProcEtmV4I::outputUnsyncedRawPacket()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
-
- outputRawPacketToMonitor(m_packet_index,&m_curr_packet,m_dump_unsynced_bytes,&m_currPacketData[0]);
+ statsAddUnsyncCount(m_dump_unsynced_bytes);
+ outputRawPacketToMonitor(m_packet_index,&m_curr_packet,m_dump_unsynced_bytes,&m_currPacketData[0]);
if(!m_sent_notsync_packet)
{
@@ -290,6 +300,7 @@ void TrcPktProcEtmV4I::iPktNoPayload(const uint8_t lastByte)
switch(m_curr_packet.type)
{
case ETM4_PKT_I_ADDR_MATCH:
+ case ETE_PKT_I_SRC_ADDR_MATCH:
m_curr_packet.setAddressExactMatch(lastByte & 0x3);
break;
@@ -307,6 +318,8 @@ void TrcPktProcEtmV4I::iPktNoPayload(const uint8_t lastByte)
case ETM4_PKT_I_EXCEPT_RTN:
case ETM4_PKT_I_TRACE_ON:
case ETM4_PKT_I_FUNC_RET:
+ case ETE_PKT_I_TRANS_ST:
+ case ETE_PKT_I_TRANS_COMMIT:
case ETM4_PKT_I_IGNORE:
default: break;
}
@@ -437,6 +450,8 @@ void TrcPktProcEtmV4I::iPktTraceInfo(const uint8_t lastByte)
m_tinfo_sections.sectFlags |= (lastByte & 0x80) ? 0 : TINFO_SPEC_SECT;
else if(!(m_tinfo_sections.sectFlags & TINFO_CYCT_SECT))
m_tinfo_sections.sectFlags |= (lastByte & 0x80) ? 0 : TINFO_CYCT_SECT;
+ else if (!(m_tinfo_sections.sectFlags & TINFO_WNDW_SECT))
+ m_tinfo_sections.sectFlags |= (lastByte & 0x80) ? 0 : TINFO_WNDW_SECT;
}
// all sections accounted for?
@@ -469,6 +484,11 @@ void TrcPktProcEtmV4I::iPktTraceInfo(const uint8_t lastByte)
idx += extractContField(m_currPacketData,idx,fieldVal);
m_curr_packet.setTraceInfoCyct(fieldVal);
}
+ if ((presSect & TINFO_WNDW_SECT) && (idx < m_currPacketData.size()))
+ {
+ idx += extractContField(m_currPacketData, idx, fieldVal);
+ /* Trace commit window unsupported in current ETE versions */
+ }
m_process_state = SEND_PKT;
m_first_trace_info = true;
}
@@ -502,8 +522,11 @@ void TrcPktProcEtmV4I::iPktTimestamp(const uint8_t lastByte)
{
int idx = 1;
uint64_t tsVal;
- int ts_bytes = extractContField64(m_currPacketData, idx, tsVal);
- int ts_bits = ts_bytes < 7 ? ts_bytes * 7 : 64;
+ int ts_bytes = extractTSField64(m_currPacketData, idx, tsVal);
+ int ts_bits;
+
+ // if ts_bytes 8 or less, then cont bits on each byte, otherwise full 64 bit value for 9 bytes
+ ts_bits = ts_bytes < 9 ? ts_bytes * 7 : 64;
if(!m_curr_packet.pkt_valid.bits.ts_valid && m_first_trace_info)
ts_bits = 64; // after trace info, missing bits are all 0.
@@ -534,6 +557,13 @@ void TrcPktProcEtmV4I::iPktException(const uint8_t lastByte)
case 1: m_excep_size = 3; break;
case 2: if((lastByte & 0x80) == 0x00)
m_excep_size = 2;
+ // ETE exception reset or trans failed
+ if (m_config.MajVersion() >= 0x5)
+ {
+ excep_type = (m_currPacketData[1] >> 1) & 0x1F;
+ if ((excep_type == 0x0) || (excep_type == 0x18))
+ m_excep_size = 3;
+ }
break;
}
@@ -553,6 +583,18 @@ void TrcPktProcEtmV4I::iPktException(const uint8_t lastByte)
m_curr_packet.setExceptionInfo(excep_type,addr_interp,m_fault_pending, m_type);
m_process_state = SEND_PKT;
+ // ETE exception reset or trans failed
+ if (m_config.MajVersion() >= 0x5)
+ {
+ if ((excep_type == 0x0) || (excep_type == 0x18))
+ {
+ m_curr_packet.set64BitAddress(0, 0);
+ if (excep_type == 0x18)
+ m_curr_packet.setType(ETE_PKT_I_TRANS_FAIL);
+ else
+ m_curr_packet.setType(ETE_PKT_I_PE_RESET);
+ }
+ }
// allow the standard address packet handlers to process the address packet field for the exception.
}
}
@@ -833,7 +875,7 @@ void TrcPktProcEtmV4I::extractAndSetContextInfo(const std::vector &buff
// on input, buffer index points at the info byte - always present
uint8_t infoByte = m_currPacketData[st_idx];
- m_curr_packet.setContextInfo(true, (infoByte & 0x3), (infoByte >> 5) & 0x1, (infoByte >> 4) & 0x1);
+ m_curr_packet.setContextInfo(true, (infoByte & 0x3), (infoByte >> 5) & 0x1, (infoByte >> 4) & 0x1, (infoByte >> 3) & 0x1);
// see if there are VMID and CID bytes, and how many.
int nVMID_bytes = ((infoByte & 0x40) == 0x40) ? (m_config.vmidSize()/8) : 0;
@@ -937,7 +979,8 @@ void TrcPktProcEtmV4I::iPktShortAddr(const uint8_t lastByte)
{
m_addr_done = false;
m_addrIS = 0;
- if (lastByte == ETM4_PKT_I_ADDR_S_IS1)
+ if ((lastByte == ETM4_PKT_I_ADDR_S_IS1) ||
+ (lastByte == ETE_PKT_I_SRC_ADDR_S_IS1))
m_addrIS = 1;
}
else if(!m_addr_done)
@@ -988,14 +1031,18 @@ void TrcPktProcEtmV4I::iPktLongAddr(const uint8_t lastByte)
switch(m_curr_packet.type)
{
case ETM4_PKT_I_ADDR_L_32IS1:
+ case ETE_PKT_I_SRC_ADDR_L_32IS1:
m_addrIS = 1;
case ETM4_PKT_I_ADDR_L_32IS0:
+ case ETE_PKT_I_SRC_ADDR_L_32IS0:
m_addrBytes = 4;
break;
case ETM4_PKT_I_ADDR_L_64IS1:
+ case ETE_PKT_I_SRC_ADDR_L_64IS1:
m_addrIS = 1;
case ETM4_PKT_I_ADDR_L_64IS0:
+ case ETE_PKT_I_SRC_ADDR_L_64IS0:
m_addrBytes = 8;
m_bAddr64bit = true;
break;
@@ -1203,6 +1250,23 @@ void TrcPktProcEtmV4I::iAtom(const uint8_t lastByte)
m_process_state = SEND_PKT;
}
+void TrcPktProcEtmV4I::iPktITE(const uint8_t /* lastByte */)
+{
+ uint64_t value;
+ int shift = 0;
+
+ /* packet is always 10 bytes, Header, EL info byte, 8 bytes payload */
+ if (m_currPacketData.size() == 10) {
+ value = 0;
+ for (int i = 2; i < 10; i++) {
+ value |= ((uint64_t)m_currPacketData[i]) << shift;
+ shift += 8;
+ }
+ m_curr_packet.setITE(m_currPacketData[1], value);
+ m_process_state = SEND_PKT;
+ }
+}
+
// header byte processing is table driven.
void TrcPktProcEtmV4I::BuildIPacketTable()
{
@@ -1247,7 +1311,35 @@ void TrcPktProcEtmV4I::BuildIPacketTable()
// b0000 0111 - exception return
m_i_table[0x07].pkt_type = ETM4_PKT_I_EXCEPT_RTN;
- m_i_table[0x07].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
+ if (m_config.MajVersion() >= 0x5) // not valid for ETE
+ {
+#ifdef ETE_TRACE_ERET_AS_IGNORE
+ m_i_table[0x07].pkt_type = ETM4_PKT_I_IGNORE;
+ m_i_table[0x07].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
+#else
+ m_i_table[0x07].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg;
+#endif
+ }
+ else
+ m_i_table[0x07].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
+
+ // b00001010, b00001011 ETE TRANS packets
+ // b00001001 - ETE sw instrumentation packet
+ if (m_config.MajVersion() >= 0x5)
+ {
+ m_i_table[0x0A].pkt_type = ETE_PKT_I_TRANS_ST;
+ m_i_table[0x0A].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
+
+ m_i_table[0x0B].pkt_type = ETE_PKT_I_TRANS_COMMIT;
+ m_i_table[0x0B].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
+
+ // FEAT_ITE - sw instrumentation packet
+ if (m_config.MinVersion() >= 0x3)
+ {
+ m_i_table[0x09].pkt_type = ETE_PKT_I_ITE;
+ m_i_table[0x09].pptkFn = &TrcPktProcEtmV4I::iPktITE;
+ }
+ }
// b0000 110x - cycle count f2
// b0000 111x - cycle count f1
@@ -1443,6 +1535,12 @@ void TrcPktProcEtmV4I::BuildIPacketTable()
m_i_table[0x85+i].pptkFn = &TrcPktProcEtmV4I::iPktAddrCtxt;
}
+ // 0b1000 1000 - ETE 1.1 TS Marker. also ETMv4.6
+ if(m_config.FullVersion() >= 0x46)
+ {
+ m_i_table[0x88].pkt_type = ETE_PKT_I_TS_MARKER;
+ m_i_table[0x88].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
+ }
// 0b1001 0000 to b1001 0010 - exact match addr
for(int i = 0; i < 3; i++)
{
@@ -1492,6 +1590,30 @@ void TrcPktProcEtmV4I::BuildIPacketTable()
}
}
+ // b10110000 - b10111001 - ETE src address packets
+ if (m_config.FullVersion() >= 0x50)
+ {
+ for (int i = 0; i < 3; i++)
+ {
+ m_i_table[0xB0 + i].pkt_type = ETE_PKT_I_SRC_ADDR_MATCH;
+ m_i_table[0xB0 + i].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
+ }
+
+ m_i_table[0xB4].pkt_type = ETE_PKT_I_SRC_ADDR_S_IS0;
+ m_i_table[0xB4].pptkFn = &TrcPktProcEtmV4I::iPktShortAddr;
+ m_i_table[0xB5].pkt_type = ETE_PKT_I_SRC_ADDR_S_IS1;
+ m_i_table[0xB5].pptkFn = &TrcPktProcEtmV4I::iPktShortAddr;
+
+ m_i_table[0xB6].pkt_type = ETE_PKT_I_SRC_ADDR_L_32IS0;
+ m_i_table[0xB6].pptkFn = &TrcPktProcEtmV4I::iPktLongAddr;
+ m_i_table[0xB7].pkt_type = ETE_PKT_I_SRC_ADDR_L_32IS1;
+ m_i_table[0xB7].pptkFn = &TrcPktProcEtmV4I::iPktLongAddr;
+ m_i_table[0xB8].pkt_type = ETE_PKT_I_SRC_ADDR_L_64IS0;
+ m_i_table[0xB8].pptkFn = &TrcPktProcEtmV4I::iPktLongAddr;
+ m_i_table[0xB9].pkt_type = ETE_PKT_I_SRC_ADDR_L_64IS1;
+ m_i_table[0xB9].pptkFn = &TrcPktProcEtmV4I::iPktLongAddr;
+ }
+
// Atom Packets - all no payload but have specific pattern generation fn
for(int i = 0xC0; i <= 0xD4; i++) // atom f6
{
@@ -1559,20 +1681,33 @@ void TrcPktProcEtmV4I::BuildIPacketTable()
return idx;
}
-unsigned TrcPktProcEtmV4I::extractContField64(const std::vector &buffer, const unsigned st_idx, uint64_t &value, const unsigned byte_limit /*= 9*/)
+unsigned TrcPktProcEtmV4I::extractTSField64(const std::vector &buffer, const unsigned st_idx, uint64_t &value)
{
+ const unsigned max_byte_idx = 8; /* the 9th byte, index 8, will use full 8 bits for value */
unsigned idx = 0;
bool lastByte = false;
uint8_t byteVal;
+ uint8_t byteValMask = 0x7f;
+
+ /* init value */
value = 0;
- while(!lastByte && (idx < byte_limit)) // max 9 bytes for 64 bit value;
+ while(!lastByte) // max 9 bytes for 64 bit value;
{
if(buffer.size() > (st_idx + idx))
{
// each byte has seven bits + cont bit
byteVal = buffer[(st_idx + idx)];
- lastByte = (byteVal & 0x80) != 0x80;
- value |= ((uint64_t)(byteVal & 0x7F)) << (idx * 7);
+
+ /* detect the final byte - which uses full 8 bits as value */
+ if (idx == max_byte_idx)
+ {
+ byteValMask = 0xFF; /* last byte of 9, no cont bit */
+ lastByte = true;
+ }
+ else
+ lastByte = (byteVal & 0x80) != 0x80;
+
+ value |= ((uint64_t)(byteVal & byteValMask)) << (idx * 7);
idx++;
}
else
@@ -1580,6 +1715,7 @@ unsigned TrcPktProcEtmV4I::extractContField64(const std::vector &buffer
throwBadSequenceError("Invalid 64 bit continuation fields in packet");
}
}
+ // index is the count of bytes used here.
return idx;
}
diff --git a/decoder/source/i_dec/trc_i_decode.cpp b/decoder/source/i_dec/trc_i_decode.cpp
index 614fc1d8b45c..0e0589512002 100644
--- a/decoder/source/i_dec/trc_i_decode.cpp
+++ b/decoder/source/i_dec/trc_i_decode.cpp
@@ -42,7 +42,7 @@ ocsd_err_t TrcIDecode::DecodeInstruction(ocsd_instr_info *instr_info)
struct decode_info info;
info.instr_sub_type = OCSD_S_INSTR_NONE;
- info.arch_version = (uint16_t)(instr_info->pe_type.arch);
+ info.arch_version = instr_info->pe_type.arch;
switch(instr_info->isa)
{
@@ -136,14 +136,12 @@ ocsd_err_t TrcIDecode::DecodeA64(ocsd_instr_info *instr_info, struct decode_info
if(inst_A64_is_indirect_branch_link(instr_info->opcode, &instr_info->is_link, info))
{
instr_info->type = OCSD_INSTR_BR_INDIRECT;
-// instr_info->is_link = inst_A64_is_branch_and_link(instr_info->opcode);
}
else if(inst_A64_is_direct_branch_link(instr_info->opcode, &instr_info->is_link, info))
{
inst_A64_branch_destination(instr_info->instr_addr,instr_info->opcode,&branchAddr);
instr_info->type = OCSD_INSTR_BR;
instr_info->branch_addr = (ocsd_vaddr_t)branchAddr;
-// instr_info->is_link = inst_A64_is_branch_and_link(instr_info->opcode);
}
else if((barrier = inst_A64_barrier(instr_info->opcode)) != ARM_BARRIER_NONE)
{
@@ -160,12 +158,15 @@ ocsd_err_t TrcIDecode::DecodeA64(ocsd_instr_info *instr_info, struct decode_info
break;
}
}
- else if (instr_info->wfi_wfe_branch)
+ else if (instr_info->wfi_wfe_branch &&
+ inst_A64_wfiwfe(instr_info->opcode, info))
{
- if (inst_A64_wfiwfe(instr_info->opcode))
- {
- instr_info->type = OCSD_INSTR_WFI_WFE;
- }
+ instr_info->type = OCSD_INSTR_WFI_WFE;
+ }
+ else if (OCSD_IS_ARCH_MINVER(info->arch_version, ARCH_AA64))
+ {
+ if (inst_A64_Tstart(instr_info->opcode))
+ instr_info->type = OCSD_INSTR_TSTART;
}
instr_info->is_conditional = inst_A64_is_conditional(instr_info->opcode);
diff --git a/decoder/source/i_dec/trc_idec_arminst.cpp b/decoder/source/i_dec/trc_idec_arminst.cpp
index 3652e84921f3..76951fd38183 100644
--- a/decoder/source/i_dec/trc_idec_arminst.cpp
+++ b/decoder/source/i_dec/trc_idec_arminst.cpp
@@ -244,8 +244,9 @@ int inst_A64_is_direct_branch_link(uint32_t inst, uint8_t *is_link, struct decod
int is_direct_branch = 1;
if ((inst & 0x7c000000) == 0x34000000) {
/* CB, TB */
- } else if ((inst & 0xff000010) == 0x54000000) {
+ } else if ((inst & 0xff000000) == 0x54000000) {
/* B */
+ /* BC 8.8 / 9.3 arch - bit 4 = 1'b1 */
} else if ((inst & 0x7c000000) == 0x14000000) {
/* B, BL imm */
if (inst & 0x80000000) {
@@ -258,11 +259,26 @@ int inst_A64_is_direct_branch_link(uint32_t inst, uint8_t *is_link, struct decod
return is_direct_branch;
}
-int inst_A64_wfiwfe(uint32_t inst)
+int inst_A64_wfiwfe(uint32_t inst, struct decode_info *info)
{
/* WFI, WFE may be traced as branches in etm 4.3++ */
if ((inst & 0xffffffdf) == 0xd503205f)
return 1;
+
+ /* new feature introduced post v8.3 */
+ if (OCSD_IS_ARCH_MINVER(info->arch_version, ARCH_AA64))
+ {
+ /* WFIT / WFET for later archs */
+ if ((inst & 0xffffffc0) == 0xd5031000)
+ return 1;
+ }
+ return 0;
+}
+
+int inst_A64_Tstart(uint32_t inst)
+{
+ if ((inst & 0xffffffe0) == 0xd5233060)
+ return 1;
return 0;
}
@@ -288,7 +304,7 @@ int inst_A64_is_indirect_branch_link(uint32_t inst, uint8_t *is_link, struct dec
} else if ((inst & 0xffffffff) == 0xd69f03e0) {
/* ERET */
info->instr_sub_type = OCSD_S_INSTR_V8_ERET;
- } else if (info->arch_version >= 0x0803) {
+ } else if (OCSD_IS_ARCH_MINVER(info->arch_version, ARCH_V8r3)) {
/* new pointer auth instr for v8.3 arch */
if ((inst & 0xffdff800) == 0xd71f0800) {
/* BRAA, BRAB, BLRAA, BLRBB */
@@ -399,8 +415,9 @@ int inst_A64_branch_destination(uint64_t addr, uint32_t inst, uint64_t *pnpc)
{
uint64_t npc;
int is_direct_branch = 1;
- if ((inst & 0xff000010) == 0x54000000) {
+ if ((inst & 0xff000000) == 0x54000000) {
/* B */
+ /* BC */
npc = addr + ((int32_t)((inst & 0x00ffffe0) << 8) >> 11);
} else if ((inst & 0x7c000000) == 0x14000000) {
/* B, BL imm */
@@ -484,7 +501,7 @@ int inst_A64_is_branch_and_link(uint32_t inst, struct decode_info *info)
} else if ((inst & 0xfc000000) == 0x94000000) {
/* BL */
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
- } else if (info->arch_version >= 0x0803) {
+ } else if (OCSD_IS_ARCH_MINVER(info->arch_version, ARCH_V8r3)) {
/* new pointer auth instr for v8.3 arch */
if ((inst & 0xfffff800) == 0xd73f0800) {
/* BLRAA, BLRBB */
@@ -553,8 +570,9 @@ int inst_A64_is_conditional(uint32_t inst)
if ((inst & 0x7c000000) == 0x34000000) {
/* CB, TB */
return 1;
- } else if ((inst & 0xff000010) == 0x54000000) {
+ } else if ((inst & 0xff000000) == 0x54000000) {
/* B.cond */
+ /* BC.cond */
return 1;
}
return 0;
diff --git a/decoder/source/mem_acc/trc_mem_acc_mapper.cpp b/decoder/source/mem_acc/trc_mem_acc_mapper.cpp
index 53edfe1a1616..dc07a1ed5a25 100644
--- a/decoder/source/mem_acc/trc_mem_acc_mapper.cpp
+++ b/decoder/source/mem_acc/trc_mem_acc_mapper.cpp
@@ -119,6 +119,14 @@ ocsd_err_t TrcMemAccMapper::ReadTargetMemory(const ocsd_vaddr_t address, const u
return err;
}
+void TrcMemAccMapper::InvalidateMemAccCache(const uint8_t /* cs_trace_id */)
+{
+ // default mapper does not use cs_trace_id for cache invalidation.
+ if (m_cache.enabled())
+ m_cache.invalidateAll();
+ m_acc_curr = 0;
+}
+
void TrcMemAccMapper::RemoveAllAccessors()
{
TrcMemAccessorBase *pAcc = 0;
diff --git a/decoder/source/ocsd_dcd_tree.cpp b/decoder/source/ocsd_dcd_tree.cpp
index be15e36e9cb3..8e29269d1690 100644
--- a/decoder/source/ocsd_dcd_tree.cpp
+++ b/decoder/source/ocsd_dcd_tree.cpp
@@ -101,6 +101,13 @@ DecodeTree::DecodeTree() :
{
for(int i = 0; i < 0x80; i++)
m_decode_elements[i] = 0;
+
+ // reset the global demux stats.
+ m_demux_stats.frame_bytes = 0;
+ m_demux_stats.no_id_bytes = 0;
+ m_demux_stats.valid_id_bytes = 0;
+ m_demux_stats.unknown_id_bytes = 0;
+ m_demux_stats.reserved_id_bytes = 0;
}
DecodeTree::~DecodeTree()
@@ -486,6 +493,62 @@ ocsd_err_t DecodeTree::removeDecoder(const uint8_t CSID)
return err;
}
+ocsd_err_t DecodeTree::getDecoderStats(const uint8_t CSID, ocsd_decode_stats_t **p_stats_block)
+{
+ ocsd_err_t err = OCSD_OK;
+ TrcPktProcI *pPktProc = getPktProcI(CSID);
+ if (!pPktProc)
+ return OCSD_ERR_INVALID_PARAM_VAL;
+ err = pPktProc->getStatsBlock(p_stats_block);
+ if (err == OCSD_OK) {
+ // copy in the global demux stats.
+ (*p_stats_block)->demux.frame_bytes = m_demux_stats.frame_bytes;
+ (*p_stats_block)->demux.no_id_bytes = m_demux_stats.no_id_bytes;
+ (*p_stats_block)->demux.valid_id_bytes = m_demux_stats.valid_id_bytes;
+ (*p_stats_block)->demux.unknown_id_bytes = m_demux_stats.unknown_id_bytes;
+ (*p_stats_block)->demux.reserved_id_bytes = m_demux_stats.reserved_id_bytes;
+ }
+ return err;
+}
+
+ocsd_err_t DecodeTree::resetDecoderStats(const uint8_t CSID)
+{
+ TrcPktProcI *pPktProc = getPktProcI(CSID);
+ if (!pPktProc)
+ return OCSD_ERR_INVALID_PARAM_VAL;
+ pPktProc->resetStats();
+
+ // reset the global demux stats.
+ m_demux_stats.frame_bytes = 0;
+ m_demux_stats.no_id_bytes = 0;
+ m_demux_stats.valid_id_bytes = 0;
+ m_demux_stats.unknown_id_bytes = 0;
+ m_demux_stats.reserved_id_bytes = 0;
+ return OCSD_OK;
+}
+
+TrcPktProcI *DecodeTree::getPktProcI(const uint8_t CSID)
+{
+ TrcPktProcI *pPktProc = 0;
+ TraceComponent *pComp, *pAssoc;
+ DecodeTreeElement *pElem = getDecoderElement(CSID);
+
+ if (pElem)
+ {
+ pComp = pElem->getDecoderHandle();
+ if (pComp)
+ {
+ /* if this is a full decoder then the associated component is the packet processor */
+ pAssoc = pComp->getAssocComponent();
+ if (pAssoc)
+ pPktProc = dynamic_cast(pAssoc);
+ else
+ pPktProc = dynamic_cast(pComp);
+ }
+ }
+ return pPktProc;
+}
+
DecodeTreeElement * DecodeTree::getDecoderElement(const uint8_t CSID) const
{
DecodeTreeElement *ret_elem = 0;
@@ -511,7 +574,7 @@ DecodeTreeElement *DecodeTree::getNextElement(uint8_t &elemID)
if(m_decode_elem_iter < 0x80)
{
// find a none zero entry or end of range
- while((m_decode_elements[m_decode_elem_iter] == 0) && (m_decode_elem_iter < 0x80))
+ while((m_decode_elem_iter < 0x80) && (m_decode_elements[m_decode_elem_iter] == 0))
m_decode_elem_iter++;
// return entry unless end of range
@@ -527,7 +590,7 @@ DecodeTreeElement *DecodeTree::getNextElement(uint8_t &elemID)
bool DecodeTree::initialise(const ocsd_dcd_tree_src_t type, uint32_t formatterCfgFlags)
{
- bool initOK = true;
+ ocsd_err_t err;
m_dcd_tree_type = type;
if(type == OCSD_TRC_SRC_FRAME_FORMATTED)
{
@@ -535,14 +598,19 @@ bool DecodeTree::initialise(const ocsd_dcd_tree_src_t type, uint32_t formatterCf
m_frame_deformatter_root = new (std::nothrow) TraceFormatterFrameDecoder();
if(m_frame_deformatter_root)
{
- m_frame_deformatter_root->Configure(formatterCfgFlags);
+ if (m_frame_deformatter_root->Init() != OCSD_OK)
+ return false;
m_frame_deformatter_root->getErrLogAttachPt()->attach(DecodeTree::s_i_error_logger);
+ err = m_frame_deformatter_root->Configure(formatterCfgFlags);
+ if (err != OCSD_OK)
+ return false;
m_i_decoder_root = dynamic_cast(m_frame_deformatter_root);
+ m_frame_deformatter_root->SetDemuxStatsBlock(&m_demux_stats);
}
else
- initOK = false;
+ return false;
}
- return initOK;
+ return true;
}
void DecodeTree::setSingleRoot(TrcPktProcI *pComp)
@@ -621,6 +689,7 @@ ocsd_err_t DecodeTree::addPacketPrinter(uint8_t CSID, bool bMonitor, ItemPrinter
switch (protocol)
{
case OCSD_PROTOCOL_ETMV4I:
+ case OCSD_PROTOCOL_ETE:
{
PacketPrinter *pTPrinter = dynamic_cast *>(pPrinter);
if (bMonitor)
diff --git a/decoder/source/ocsd_error.cpp b/decoder/source/ocsd_error.cpp
index 74e9e4977f60..ee01064a3476 100644
--- a/decoder/source/ocsd_error.cpp
+++ b/decoder/source/ocsd_error.cpp
@@ -229,4 +229,25 @@ void ocsdError::appendErrorDetails(std::string &errStr, const ocsdError &error)
errStr = oss.str();
}
+
+const char* ocsdDataRespStr::getStr()
+{
+ static const char* szRespStr[] = {
+ "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."
+ };
+ if ((m_type < OCSD_RESP_CONT) || (m_type > OCSD_RESP_FATAL_SYS_ERR))
+ return "Unknown OCSD_RESP type.";
+ return szRespStr[m_type];
+}
+
/* End of File ocsd_error.cpp */
diff --git a/decoder/source/ocsd_gen_elem_stack.cpp b/decoder/source/ocsd_gen_elem_stack.cpp
index bb758427a9b8..66fe75d9899a 100644
--- a/decoder/source/ocsd_gen_elem_stack.cpp
+++ b/decoder/source/ocsd_gen_elem_stack.cpp
@@ -42,6 +42,7 @@ OcsdGenElemStack::OcsdGenElemStack() :
m_curr_elem_idx(0),
m_send_elem_idx(0),
m_CSID(0),
+ m_sendIf(NULL),
m_is_init(false)
{
diff --git a/decoder/source/ocsd_lib_dcd_register.cpp b/decoder/source/ocsd_lib_dcd_register.cpp
index adb042dcadff..0233c89eaa06 100644
--- a/decoder/source/ocsd_lib_dcd_register.cpp
+++ b/decoder/source/ocsd_lib_dcd_register.cpp
@@ -39,13 +39,15 @@
#include "opencsd/etmv3/trc_dcd_mngr_etmv3.h"
#include "opencsd/ptm/trc_dcd_mngr_ptm.h"
#include "opencsd/stm/trc_dcd_mngr_stm.h"
+#include "opencsd/ete/trc_dcd_mngr_ete.h"
// create array of built-in decoders to register with library
static built_in_decoder_info_t sBuiltInArray[] = {
CREATE_BUILTIN_ENTRY(DecoderMngrEtmV4I,OCSD_BUILTIN_DCD_ETMV4I),
CREATE_BUILTIN_ENTRY(DecoderMngrEtmV3, OCSD_BUILTIN_DCD_ETMV3),
CREATE_BUILTIN_ENTRY(DecoderMngrPtm, OCSD_BUILTIN_DCD_PTM),
- CREATE_BUILTIN_ENTRY(DecoderMngrStm, OCSD_BUILTIN_DCD_STM)
+ CREATE_BUILTIN_ENTRY(DecoderMngrStm, OCSD_BUILTIN_DCD_STM),
+ CREATE_BUILTIN_ENTRY(DecoderMngrETE, OCSD_BUILTIN_DCD_ETE)
//{ 0, 0, 0}
};
@@ -90,7 +92,6 @@ OcsdLibDcdRegister::~OcsdLibDcdRegister()
m_pLastTypedDecoderMngr = 0;
}
-
const ocsd_err_t OcsdLibDcdRegister::registerDecoderTypeByName(const std::string &name, IDecoderMngr *p_decoder_fact)
{
if(isRegisteredDecoder(name))
diff --git a/decoder/source/pkt_printers/trc_print_fact.cpp b/decoder/source/pkt_printers/trc_print_fact.cpp
index 52dcb6b3e1ac..6b5df1f472e0 100644
--- a/decoder/source/pkt_printers/trc_print_fact.cpp
+++ b/decoder/source/pkt_printers/trc_print_fact.cpp
@@ -55,8 +55,9 @@ ItemPrinter *PktPrinterFact::createProtocolPrinter(std::vector &p
{
ItemPrinter *pPrinter = 0;
switch (protocol)
- {
+ {
case OCSD_PROTOCOL_ETMV4I:
+ case OCSD_PROTOCOL_ETE:
pPrinter = new (std::nothrow) PacketPrinter(CSID);
break;
case OCSD_PROTOCOL_ETMV3:
diff --git a/decoder/source/ptm/trc_pkt_proc_ptm.cpp b/decoder/source/ptm/trc_pkt_proc_ptm.cpp
index 7c90b62e6413..668a14b73df0 100644
--- a/decoder/source/ptm/trc_pkt_proc_ptm.cpp
+++ b/decoder/source/ptm/trc_pkt_proc_ptm.cpp
@@ -224,6 +224,7 @@ void TrcPktProcPtm::InitProcessorState()
m_waitASyncSOPkt = false;
m_bAsyncRawOp = false;
m_bOPNotSyncPkt = false;
+ m_excepAltISA = 0;
m_curr_packet.ResetState();
InitPacketState();
@@ -559,7 +560,7 @@ void TrcPktProcPtm::pktWPointUpdate()
m_gotExcepBytes = false; // mark as not got all required exception bytes thus far
m_numExcepBytes = 0; // 0 read in
- m_addrPktIsa = ocsd_isa_unknown; // not set by this packet as yet
+ m_addrPktIsa = ocsd_isa_unknown; // not set by this packet as yet
}
// collect all the bytes needed
@@ -567,10 +568,12 @@ void TrcPktProcPtm::pktWPointUpdate()
{
if(readByte(currByte))
{
+
byteIdx = m_currPacketData.size() - 1;
if(!m_gotAddrBytes)
{
- if(byteIdx < 4)
+ // byteIdx for address byte will run from 1 to 5 - first 4 my have continuation or not.
+ if(byteIdx <= 4)
{
// address bytes 1 - 4;
// ISA stays the same
diff --git a/decoder/source/trc_core_arch_map.cpp b/decoder/source/trc_core_arch_map.cpp
index a26f79db996e..f25ab1e5ddfa 100644
--- a/decoder/source/trc_core_arch_map.cpp
+++ b/decoder/source/trc_core_arch_map.cpp
@@ -72,17 +72,6 @@ static ap_map_elem_t ap_map_array[] =
{ "Cortex-M4", { ARCH_V7, profile_CortexM } }
};
-static ap_map_elem_t arch_map_array[] =
-{
- { "ARMv7-A", { ARCH_V7, profile_CortexA } },
- { "ARMv7-R", { ARCH_V7, profile_CortexR } },
- { "ARMv7-M", { ARCH_V7, profile_CortexM } },
- { "ARMv8-A", { ARCH_V8, profile_CortexA } },
- { "ARMv8.3-A", { ARCH_V8r3, profile_CortexA } },
- { "ARMv8-R", { ARCH_V8, profile_CortexR } },
- { "ARMv8-M", { ARCH_V8, profile_CortexM } },
-};
-
CoreArchProfileMap::CoreArchProfileMap()
{
unsigned i;
@@ -90,10 +79,99 @@ CoreArchProfileMap::CoreArchProfileMap()
{
core_profiles[ap_map_array[i].name] = ap_map_array[i].ap;
}
- for (i = 0; i < sizeof(arch_map_array) / sizeof(_ap_map_elements); i++)
- {
- arch_profiles[arch_map_array[i].name] = arch_map_array[i].ap;
- }
}
+ocsd_arch_profile_t CoreArchProfileMap::getArchProfile(const std::string &coreName)
+{
+ ocsd_arch_profile_t ap = { ARCH_UNKNOWN, profile_Unknown };
+ bool bFound = false;
+
+ std::map::const_iterator it;
+
+ /* match against the core name map. */
+ it = core_profiles.find(coreName);
+ if (it != core_profiles.end())
+ {
+ ap = it->second;
+ bFound = true;
+ }
+
+ /* try a pattern match on core name - pick up ARMvM[.m]-P and ARM-{aa|AA}64[-P] */
+ if (!bFound)
+ ap = getPatternMatchCoreName(coreName);
+
+ return ap;
+}
+ocsd_arch_profile_t CoreArchProfileMap::getPatternMatchCoreName(const std::string &coreName)
+{
+ ocsd_arch_profile_t ap = { ARCH_UNKNOWN, profile_Unknown };
+ size_t pos;
+
+ /* look for ARMvM[.m]-P */
+ pos = coreName.find("ARMv");
+ if (pos == 0)
+ {
+ int majver = coreName[4] - '0';
+ int minver = 0;
+ int dotoffset = 0;
+
+ pos = coreName.find_first_of(".");
+ if (pos == 5) {
+ minver = coreName[6] - '0';
+ dotoffset = 2;
+ }
+ else if (pos != std::string::npos)
+ return ap;
+
+ if (majver == 7)
+ ap.arch = ARCH_V7;
+ else if (majver >= 8) {
+ ap.arch = ARCH_AA64; /* default to 8.3+*/
+ if (majver == 8) {
+ if (minver < 3)
+ ap.arch = ARCH_V8;
+ else if (minver == 3)
+ ap.arch = ARCH_V8r3;
+ }
+ }
+ else
+ return ap; /* no valid version - return unknown */
+
+ if (coreName.find_first_of("-", 4) == (size_t)(5 + dotoffset)) {
+ int profile_idx = 6 + dotoffset;
+ if (coreName[profile_idx] == 'A')
+ ap.profile = profile_CortexA;
+ else if (coreName[profile_idx] == 'R')
+ ap.profile = profile_CortexR;
+ else if (coreName[profile_idx] == 'M')
+ ap.profile = profile_CortexM;
+ else
+ ap.arch = ARCH_UNKNOWN; /*reset arch, return unknown*/
+ }
+ else
+ ap.arch = ARCH_UNKNOWN; /*reset arch, return unknown*/
+ return ap;
+ }
+
+ /* look for ARM-{AA|aa}64[-P] */
+ pos = coreName.find("ARM-");
+ if (pos == 0)
+ {
+ pos = coreName.find("aa64");
+ if (pos != 4)
+ pos = coreName.find("AA64");
+ if (pos == 4)
+ {
+ ap.arch = ARCH_AA64;
+ ap.profile = profile_CortexA;
+ if (coreName.find_first_of("-", 7) == 8) {
+ if (coreName[9] == 'R')
+ ap.profile = profile_CortexR;
+ else if (coreName[9] == 'M')
+ ap.profile = profile_CortexM;
+ }
+ }
+ }
+ return ap;
+}
/* End of File trc_core_arch_map.cpp */
diff --git a/decoder/source/trc_frame_deformatter.cpp b/decoder/source/trc_frame_deformatter.cpp
index 4d46854a655b..3b2aead875ca 100644
--- a/decoder/source/trc_frame_deformatter.cpp
+++ b/decoder/source/trc_frame_deformatter.cpp
@@ -54,7 +54,8 @@ TraceFmtDcdImpl::TraceFmtDcdImpl() : TraceComponent(DEFORMATTER_NAME),
m_use_force_sync(false),
m_alignment(16), // assume frame aligned data as default.
m_b_output_packed_raw(false),
- m_b_output_unpacked_raw(false)
+ m_b_output_unpacked_raw(false),
+ m_pStatsBlock(0)
{
resetStateParams();
@@ -244,7 +245,12 @@ ocsd_datapath_resp_t TraceFmtDcdImpl::processTraceData(
if(m_trc_curr_idx != index) // none continuous trace data - throw an error.
throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_DFMTR_NOTCONTTRACE,index);
}
-
+
+ // record the incoming block for extraction routines to use.
+ m_in_block_base = pDataBlock;
+ m_in_block_size = dataBlockSize;
+ m_in_block_processed = 0;
+
if(dataBlockSize % m_alignment) // must be correctly aligned data
{
ocsdError err(OCSD_ERR_SEV_ERROR, OCSD_ERR_INVALID_PARAM_VAL);
@@ -254,11 +260,6 @@ ocsd_datapath_resp_t TraceFmtDcdImpl::processTraceData(
throw ocsdError(&err);
}
- // record the incoming block for extraction routines to use.
- m_in_block_base = pDataBlock;
- m_in_block_size = dataBlockSize;
- m_in_block_processed = 0;
-
// processing loop...
if(checkForSync())
{
@@ -324,12 +325,18 @@ ocsd_err_t TraceFmtDcdImpl::DecodeConfigure(uint32_t flags)
}
else
{
+ // alightment is the multiple of bytes the buffer size must be.
m_cfgFlags = flags;
+
+ // using memory aligned buffers, the formatter always outputs 16 byte frames so enforce
+ // this on the input
m_alignment = 16;
- if(flags & OCSD_DFRMTR_HAS_FSYNCS)
- m_alignment = 4;
- else if(flags & OCSD_DFRMTR_HAS_HSYNCS)
+ // if we have HSYNCS then always align to 2 byte buffers
+ if(flags & OCSD_DFRMTR_HAS_HSYNCS)
m_alignment = 2;
+ // otherwise FSYNCS only can have 4 byte aligned buffers.
+ else if(flags & OCSD_DFRMTR_HAS_FSYNCS)
+ m_alignment = 4;
}
return err;
}
@@ -344,6 +351,7 @@ void TraceFmtDcdImpl::resetStateParams()
// current frame processing
m_ex_frm_n_bytes = 0;
+ m_b_fsync_start_eob = false;
m_trc_curr_idx_sof = OCSD_BAD_TRC_INDEX;
}
@@ -415,20 +423,23 @@ void TraceFmtDcdImpl::outputUnsyncedBytes(uint32_t /*num_bytes*/)
//**TBD:
}
-int TraceFmtDcdImpl::checkForResetFSyncPatterns()
+ocsd_err_t TraceFmtDcdImpl::checkForResetFSyncPatterns(uint32_t &f_sync_bytes)
{
const uint32_t FSYNC_PATTERN = 0x7FFFFFFF; // LE host pattern for FSYNC
bool check_for_fsync = true;
int num_fsyncs = 0;
- const uint8_t *dataPtr = m_in_block_base + m_in_block_processed;
+ uint32_t bytes_processed = m_in_block_processed;
+ const uint8_t *dataPtr = m_in_block_base + bytes_processed;
+ ocsd_err_t err = OCSD_OK;
- while (check_for_fsync && (m_in_block_processed < m_in_block_size))
+ while (check_for_fsync && (bytes_processed < m_in_block_size))
{
// look for consecutive fsyncs as padding or for reset downstream - both cases will reset downstream....
if (*((uint32_t *)(dataPtr)) == FSYNC_PATTERN)
{
dataPtr += sizeof(uint32_t);
- num_fsyncs++;
+ num_fsyncs++;
+ bytes_processed += sizeof(uint32_t);
}
else
check_for_fsync = false;
@@ -436,7 +447,6 @@ int TraceFmtDcdImpl::checkForResetFSyncPatterns()
if (num_fsyncs)
{
- printf("Frame deformatter: Found %d FSYNCS\n",num_fsyncs);
if ((num_fsyncs % 4) == 0)
{
// reset the upstream decoders
@@ -449,32 +459,40 @@ int TraceFmtDcdImpl::checkForResetFSyncPatterns()
}
else
{
- // TBD: throw processing error, none frame size block of fsyncs
+ err = OCSD_ERR_DFMTR_BAD_FHSYNC;
}
}
- return num_fsyncs * 4;
+ f_sync_bytes += num_fsyncs * 4;
+ return err;
}
-
+/* Extract a single frame from the input buffer. */
bool TraceFmtDcdImpl::extractFrame()
{
const uint32_t FSYNC_PATTERN = 0x7FFFFFFF; // LE host pattern for FSYNC
const uint16_t HSYNC_PATTERN = 0x7FFF; // LE host pattern for HSYNC
+ const uint16_t FSYNC_START = 0xFFFF; // LE host pattern for start 2 bytes of fsync
-
- bool cont_process = true; // continue processing after extraction.
+ ocsd_err_t err;
uint32_t f_sync_bytes = 0; // skipped f sync bytes
uint32_t h_sync_bytes = 0; // skipped h sync bytes
uint32_t ex_bytes = 0; // extracted this pass (may be filling out part frame)
+ uint32_t buf_left = m_in_block_size - m_in_block_processed; // bytes remaining in buffer this pass.
- // memory aligned sources are always multiples of frames, aligned to start.
+ // last call was end of input block - but carried on to process full frame.
+ // exit early here.
+ if (!buf_left)
+ return false;
+
+ // memory aligned input data is forced to be always multiples of 16 byte frames, aligned to start.
if( m_cfgFlags & OCSD_DFRMTR_FRAME_MEM_ALIGN)
{
// some linux drivers (e.g. for perf) will insert FSYNCS to pad or differentiate
- // between blocks of aligned data, always in frame aligned complete 16 byte frames.
+ // between blocks of aligned data, always in frame aligned complete 16 byte frames.
+ // we need to skip past these frames, resetting as we go.
if (m_cfgFlags & OCSD_DFRMTR_RESET_ON_4X_FSYNC)
{
- f_sync_bytes = checkForResetFSyncPatterns();
+ err = checkForResetFSyncPatterns(f_sync_bytes);
/* in this case the FSYNC pattern is output on both packed and unpacked cases */
if (f_sync_bytes && (m_b_output_packed_raw || m_b_output_unpacked_raw))
@@ -486,77 +504,96 @@ bool TraceFmtDcdImpl::extractFrame()
m_in_block_base + m_in_block_processed,
0);
}
+
+ // throw processing error, none frame size block of fsyncs
+ if (err)
+ throw ocsdError(OCSD_ERR_SEV_ERROR, err, m_trc_curr_idx, "Incorrect FSYNC frame reset pattern");
+
+ buf_left -= f_sync_bytes;
}
- if((m_in_block_processed+f_sync_bytes) == m_in_block_size)
+ if (buf_left)
{
- m_ex_frm_n_bytes = 0;
- cont_process = false; // end of input data.
- }
- else
- {
- // always a complete frame.
- m_ex_frm_n_bytes = OCSD_DFRMTR_FRAME_SIZE;
- memcpy(m_ex_frm_data, m_in_block_base + m_in_block_processed + f_sync_bytes, m_ex_frm_n_bytes);
- m_trc_curr_idx_sof = m_trc_curr_idx + f_sync_bytes;
- ex_bytes = OCSD_DFRMTR_FRAME_SIZE;
+ // always a complete frame - the input data has to be 16 byte multiple alignment.
+ m_ex_frm_n_bytes = OCSD_DFRMTR_FRAME_SIZE;
+ memcpy(m_ex_frm_data, m_in_block_base + m_in_block_processed + f_sync_bytes, m_ex_frm_n_bytes);
+ m_trc_curr_idx_sof = m_trc_curr_idx + f_sync_bytes;
+ ex_bytes = OCSD_DFRMTR_FRAME_SIZE;
}
}
else
{
// extract data accounting for frame syncs and hsyncs if present.
// we know we are aligned at this point - could be FSYNC or HSYNCs here.
+ // HSYNC present, library forces input to be aligned 2 byte multiples
+ // FSYNC - w/o HSYNCs, forces input to be aligned 4 byte multiples.
// check what we a looking for
- bool hasFSyncs = ((m_cfgFlags & OCSD_DFRMTR_HAS_FSYNCS) == OCSD_DFRMTR_HAS_FSYNCS);
- bool hasHSyncs = ((m_cfgFlags & OCSD_DFRMTR_HAS_HSYNCS) == OCSD_DFRMTR_HAS_HSYNCS);
+ bool hasFSyncs = ((m_cfgFlags & OCSD_DFRMTR_HAS_FSYNCS) == OCSD_DFRMTR_HAS_FSYNCS);
+ bool hasHSyncs = ((m_cfgFlags & OCSD_DFRMTR_HAS_HSYNCS) == OCSD_DFRMTR_HAS_HSYNCS);
+
+ const uint8_t* dataPtr = m_in_block_base + m_in_block_processed;
+ uint16_t data_pair_val;
- const uint8_t *dataPtr = m_in_block_base+m_in_block_processed;
- const uint8_t *eodPtr = m_in_block_base+m_in_block_size;
-
- cont_process = (bool)(dataPtr < eodPtr);
-
// can have FSYNCS at start of frame (in middle is an error).
- if(hasFSyncs && cont_process && (m_ex_frm_n_bytes == 0))
+ if (hasFSyncs && (m_ex_frm_n_bytes == 0))
{
- while((*((uint32_t *)(dataPtr)) == FSYNC_PATTERN) && cont_process)
+ // was there an fsync start at the end of the last buffer?
+ if (m_b_fsync_start_eob) {
+ // last 2 of FSYNC look like HSYNC
+ if (*(uint16_t*)(dataPtr) != HSYNC_PATTERN)
+ {
+ // this means 0xFFFF followed by something else - invalid ID + ????
+ throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_DFMTR_BAD_FHSYNC, m_trc_curr_idx, "Bad FSYNC pattern before frame or invalid ID.(0x7F)");
+ }
+ else
+ {
+ f_sync_bytes += 2;
+ buf_left -= 2;
+ dataPtr += 2;
+ }
+ m_b_fsync_start_eob = false;
+ }
+
+ // regular fsync checks
+ while ((buf_left >= 4) && (*((uint32_t*)(dataPtr)) == FSYNC_PATTERN))
{
f_sync_bytes += 4;
dataPtr += 4;
- cont_process = (bool)(dataPtr < eodPtr);
+ buf_left -= 4;
+ }
+
+ // handle possible part fsync at the end of a buffer
+ if (buf_left == 2)
+ {
+ if (*(uint16_t*)(dataPtr) == FSYNC_START)
+ {
+ f_sync_bytes += 2;
+ buf_left -= 2;
+ dataPtr += 2;
+ m_b_fsync_start_eob = true;
+ }
}
}
- // not an FSYNC
- while((m_ex_frm_n_bytes < OCSD_DFRMTR_FRAME_SIZE) && cont_process)
+ // process remaining data in pairs of bytes
+ while ((m_ex_frm_n_bytes < OCSD_DFRMTR_FRAME_SIZE) && buf_left)
{
- // check for illegal out of sequence FSYNC
- if((m_ex_frm_n_bytes % 4) == 0)
- {
- if(*((uint32_t *)(dataPtr)) == FSYNC_PATTERN)
- {
- // throw an illegal FSYNC error
- throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_DFMTR_BAD_FHSYNC, m_trc_curr_idx, "Bad FSYNC in frame.");
- }
- }
-
// mark start of frame after FSyncs
- if(m_ex_frm_n_bytes == 0)
+ if (m_ex_frm_n_bytes == 0)
m_trc_curr_idx_sof = m_trc_curr_idx + f_sync_bytes;
m_ex_frm_data[m_ex_frm_n_bytes] = dataPtr[0];
- m_ex_frm_data[m_ex_frm_n_bytes+1] = dataPtr[1];
- m_ex_frm_n_bytes+=2;
- ex_bytes +=2;
+ m_ex_frm_data[m_ex_frm_n_bytes + 1] = dataPtr[1];
+
+ data_pair_val = *((uint16_t*)(dataPtr));
// check pair is not HSYNC
- if(*((uint16_t *)(dataPtr)) == HSYNC_PATTERN)
+ if (data_pair_val == HSYNC_PATTERN)
{
- if(hasHSyncs)
+ if (hasHSyncs)
{
- m_ex_frm_n_bytes-=2;
- ex_bytes -= 2;
- h_sync_bytes+=2;
+ h_sync_bytes += 2;
}
else
{
@@ -564,22 +601,27 @@ bool TraceFmtDcdImpl::extractFrame()
throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_DFMTR_BAD_FHSYNC, m_trc_curr_idx, "Bad HSYNC in frame.");
}
}
+ // can't have a start of FSYNC here / illegal trace ID
+ else if (data_pair_val == FSYNC_START)
+ {
+ throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_DFMTR_BAD_FHSYNC, m_trc_curr_idx, "Bad FSYNC start in frame or invalid ID (0x7F).");
+ }
+ else
+ {
+ m_ex_frm_n_bytes += 2;
+ ex_bytes += 2;
+ }
+ buf_left -= 2;
dataPtr += 2;
- cont_process = (bool)(dataPtr < eodPtr);
}
-
- // if we hit the end of data but still have a complete frame waiting,
- // need to continue processing to allow it to be used.
- if(!cont_process && (m_ex_frm_n_bytes == OCSD_DFRMTR_FRAME_SIZE))
- cont_process = true;
}
// total bytes processed this pass
uint32_t total_processed = ex_bytes + f_sync_bytes + h_sync_bytes;
// output raw data on raw frame channel - packed raw.
- if (((m_ex_frm_n_bytes == OCSD_DFRMTR_FRAME_SIZE) || !cont_process) && m_b_output_packed_raw)
+ if (((m_ex_frm_n_bytes == OCSD_DFRMTR_FRAME_SIZE) || (buf_left == 0)) && m_b_output_packed_raw)
{
outputRawMonBytes( OCSD_OP_DATA,
m_trc_curr_idx,
@@ -595,7 +637,11 @@ bool TraceFmtDcdImpl::extractFrame()
// update index past the processed data
m_trc_curr_idx += total_processed;
- return cont_process;
+ // update any none trace data byte stats
+ addToFrameStats((uint64_t)(f_sync_bytes + h_sync_bytes));
+
+ // if we are exiting with a full frame then signal processing to continue
+ return (bool)(m_ex_frm_n_bytes == OCSD_DFRMTR_FRAME_SIZE);
}
bool TraceFmtDcdImpl::unpackFrame()
@@ -604,6 +650,7 @@ bool TraceFmtDcdImpl::unpackFrame()
uint8_t frameFlagBit = 0x1;
uint8_t newSrcID = OCSD_BAD_CS_SRC_ID;
bool PrevIDandIDChange = false;
+ uint64_t noneDataBytes = 0;
// init output processing
m_out_data_idx = 0;
@@ -650,6 +697,7 @@ bool TraceFmtDcdImpl::unpackFrame()
/// TBD - ID indexing in here.
}
+ noneDataBytes++;
}
else
// it's just data
@@ -671,6 +719,7 @@ bool TraceFmtDcdImpl::unpackFrame()
{
// no matter if change or not, no associated data in byte 15 anyway so just set.
m_curr_src_ID = (m_ex_frm_data[14] >> 1) & 0x7f;
+ noneDataBytes++;
}
// it's data
else
@@ -678,6 +727,9 @@ bool TraceFmtDcdImpl::unpackFrame()
m_out_data[m_out_data_idx].data[m_out_data[m_out_data_idx].valid++] = m_ex_frm_data[14] | ((frameFlagBit & m_ex_frm_data[15]) ? 0x1 : 0x0);
}
m_ex_frm_n_bytes = 0; // mark frame as empty;
+
+ noneDataBytes++; // byte 15 is always non-data.
+ addToFrameStats(noneDataBytes); // update the non data byte stats.
return true;
}
@@ -716,6 +768,8 @@ bool TraceFmtDcdImpl::outputFrame()
m_out_data[m_out_processed].data + m_out_data[m_out_processed].used,
&bytes_used));
+ addToIDStats((uint64_t)bytes_used);
+
if(!dataPathCont())
{
cont_processing = false;
@@ -739,7 +793,12 @@ bool TraceFmtDcdImpl::outputFrame()
m_out_data[m_out_processed].valid,
m_out_data[m_out_processed].data,
m_out_data[m_out_processed].id);
- }
+ }
+
+ if (isReservedID(m_out_data[m_out_processed].id))
+ addToReservedIDStats((uint64_t)m_out_data[m_out_processed].valid);
+ else
+ addToNoIDStats((uint64_t)m_out_data[m_out_processed].valid);
m_out_processed++; // skip past this data.
}
}
@@ -754,13 +813,44 @@ bool TraceFmtDcdImpl::outputFrame()
m_out_data[m_out_processed].valid,
m_out_data[m_out_processed].data,
m_out_data[m_out_processed].id);
- }
+ }
+ addToUnknownIDStats((uint64_t)m_out_data[m_out_processed].valid);
m_out_processed++; // skip past this data.
}
}
return cont_processing;
}
+
+void TraceFmtDcdImpl::addToIDStats(uint64_t val)
+{
+ if (m_pStatsBlock)
+ m_pStatsBlock->valid_id_bytes += val;
+}
+void TraceFmtDcdImpl::addToNoIDStats(uint64_t val)
+{
+ if (m_pStatsBlock)
+ m_pStatsBlock->no_id_bytes += val;
+}
+
+void TraceFmtDcdImpl::addToFrameStats(uint64_t val)
+{
+ if (m_pStatsBlock)
+ m_pStatsBlock->frame_bytes += val;
+}
+
+void TraceFmtDcdImpl::addToUnknownIDStats(uint64_t val)
+{
+ if (m_pStatsBlock)
+ m_pStatsBlock->unknown_id_bytes += val;
+}
+
+void TraceFmtDcdImpl::addToReservedIDStats(uint64_t val)
+{
+ if (m_pStatsBlock)
+ m_pStatsBlock->reserved_id_bytes += val;
+}
+
/***************************************************************/
/* interface */
/***************************************************************/
@@ -819,21 +909,27 @@ componentAttachPt *TraceFormatterFrameDecoder::getErrLogAttachPt
return (m_pDecoder != 0) ? m_pDecoder->getErrorLogAttachPt() : 0;
}
-/* configuration - set operational mode for incoming stream (has FSYNCS etc) */
-ocsd_err_t TraceFormatterFrameDecoder::Configure(uint32_t cfg_flags)
+ocsd_err_t TraceFormatterFrameDecoder::Init()
{
- if(!m_pDecoder)
- {
- if(m_instNum >= 0)
+ if (!m_pDecoder)
+ {
+ if (m_instNum >= 0)
m_pDecoder = new (std::nothrow) TraceFmtDcdImpl(m_instNum);
else
m_pDecoder = new (std::nothrow) TraceFmtDcdImpl();
- if(!m_pDecoder) return OCSD_ERR_MEM;
+ if (!m_pDecoder) return OCSD_ERR_MEM;
}
- m_pDecoder->DecodeConfigure(cfg_flags);
return OCSD_OK;
}
+/* configuration - set operational mode for incoming stream (has FSYNCS etc) */
+ocsd_err_t TraceFormatterFrameDecoder::Configure(uint32_t cfg_flags)
+{
+ if (!m_pDecoder)
+ return OCSD_ERR_NOT_INIT;
+ return m_pDecoder->DecodeConfigure(cfg_flags);
+}
+
const uint32_t TraceFormatterFrameDecoder::getConfigFlags() const
{
uint32_t flags = 0;
@@ -865,5 +961,10 @@ ocsd_datapath_resp_t TraceFormatterFrameDecoder::Flush()
return (m_pDecoder == 0) ? OCSD_RESP_FATAL_NOT_INIT : m_pDecoder->Flush();
}
+void TraceFormatterFrameDecoder::SetDemuxStatsBlock(ocsd_demux_stats_t *pStatsBlock)
+{
+ if (m_pDecoder)
+ m_pDecoder->SetDemuxStatsBlock(pStatsBlock);
+}
/* End of File trc_frame_deformatter.cpp */
diff --git a/decoder/source/trc_frame_deformatter_impl.h b/decoder/source/trc_frame_deformatter_impl.h
index e1fc17ab259f..3571d5f2fc47 100644
--- a/decoder/source/trc_frame_deformatter_impl.h
+++ b/decoder/source/trc_frame_deformatter_impl.h
@@ -75,6 +75,8 @@ private:
ocsd_err_t DecodeConfigure(uint32_t flags);
ocsd_err_t SetForcedSyncIndex(ocsd_trc_index_t index, bool bSet);
+ void SetDemuxStatsBlock(ocsd_demux_stats_t *pStatsBlock) { m_pStatsBlock = pStatsBlock; };
+
private:
ocsd_datapath_resp_t executeNoneDataOpAllIDs(ocsd_datapath_op_t op, const ocsd_trc_index_t index = 0);
ocsd_datapath_resp_t processTraceData(const ocsd_trc_index_t index,
@@ -113,12 +115,20 @@ private:
void setRawChanFilterAll(bool bEnable);
const bool rawChanEnabled(const uint8_t id) const;
- int checkForResetFSyncPatterns();
+ ocsd_err_t checkForResetFSyncPatterns(uint32_t &f_sync_bytes);
friend class TraceFormatterFrameDecoder;
- // attachment points
+ // stats updates
+ void addToIDStats(uint64_t val);
+ void addToNoIDStats(uint64_t val);
+ void addToFrameStats(uint64_t val);
+ void addToUnknownIDStats(uint64_t val);
+ void addToReservedIDStats(uint64_t val);
+
+ bool isReservedID(uint8_t ID) { return ((ID == 0) || (ID >= 0x70)); };
+ // attachment points
componentAttachPt m_IDStreams[128];
componentAttachPt m_RawTraceFrame;
@@ -142,12 +152,18 @@ private:
// incoming frame buffer
uint8_t m_ex_frm_data[OCSD_DFRMTR_FRAME_SIZE]; // buffer the current frame in case we have to stop part way through
int m_ex_frm_n_bytes; // number of valid bytes in the current frame (extraction)
+ bool m_b_fsync_start_eob; // flag to indicate that the end of the last buffer was a pair of bytes
+ // (0xffff) that could only validly be the start and FSYNC.
ocsd_trc_index_t m_trc_curr_idx_sof; // trace source index at start of frame.
- // channel output data - can never be more than a frame of data for a single ID.
- out_chan_data m_out_data[7]; // can only be 8 ID changes in a frame, but last on has no associated data so 7 possible data blocks
+ /* channel output data - can never be more than a frame of data for a single ID.
+ * 8 possible ID changes per frame. Although the final one can have no associated data, a pathological
+ * case exists with 7 ID changes, all data associated with a previous frame, except for last
+ * ID / data byte which is data. Not possible with normal hardware but guard against corrupt input.
+ */
+ out_chan_data m_out_data[8]; // output data for a given ID
int m_out_data_idx; // number of out_chan_data frames used.
- int m_out_processed; // number of complete out_chan_data frames output.
+ int m_out_processed; // number of complete out_chan_data frames output.
/* local copy of input buffer pointers*/
const uint8_t *m_in_block_base;
@@ -159,6 +175,8 @@ private:
bool m_b_output_unpacked_raw;
bool m_raw_chan_enable[128];
+
+ ocsd_demux_stats_t *m_pStatsBlock;
};
diff --git a/decoder/source/trc_gen_elem.cpp b/decoder/source/trc_gen_elem.cpp
index e1774203ebc5..c94c5a7c6848 100644
--- a/decoder/source/trc_gen_elem.cpp
+++ b/decoder/source/trc_gen_elem.cpp
@@ -54,7 +54,10 @@ static const char *s_elem_descs[][2] =
{"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 - numbered event or trigger"},
- {"OCSD_GEN_TRC_ELEM_SWTRACE","Software trace packet - may contain data payload."},
+ {"OCSD_GEN_TRC_ELEM_SWTRACE","Software trace packet - may contain data payload. STM / ITM hardware trace with channel protocol."},
+ {"OCSD_GEN_TRC_ELEM_SYNC_MARKER","Synchronisation marker - marks position in stream of an element that is output later."},
+ {"OCSD_GEN_TRC_ELEM_MEMTRANS","Trace indication of transactional memory operations."},
+ {"OCSD_GEN_TRC_ELEM_INSTRUMENTATION", "PE instrumentation trace - PE generated SW trace, application dependent protocol."},
{"OCSD_GEN_TRC_ELEM_CUSTOM","Fully custom packet type."}
};
@@ -64,7 +67,8 @@ static const char *instr_type[] = {
"iBR ",
"ISB ",
"DSB.DMB",
- "WFI.WFE"
+ "WFI.WFE",
+ "TSTART"
};
#define T_SIZE (sizeof(instr_type) / sizeof(const char *))
@@ -105,6 +109,16 @@ static const char *s_unsync_reason[] = {
"bad-packet", // UNSYNC_BAD_PACKET - bad packet at input - resync to restart.
"end-of-trace", // UNSYNC_EOT - end of trace info.
};
+static const char *s_transaction_type[] = {
+ "Init",
+ "Start",
+ "Commit",
+ "Fail"
+};
+
+static const char *s_marker_t[] = {
+ "Timestamp marker", // ELEM_MARKER_TS
+};
void OcsdTraceElement::toString(std::string &str) const
{
@@ -158,7 +172,14 @@ void OcsdTraceElement::toString(std::string &str) const
{
oss << "EL" << std::dec << (int)(context.exception_level);
}
- oss << (context.security_level == ocsd_sec_secure ? "S; " : "N; ") << (context.bits64 ? "64-bit; " : "32-bit; ");
+ switch (context.security_level)
+ {
+ case ocsd_sec_secure: oss << "S; "; break;
+ case ocsd_sec_nonsecure: oss << "N; "; break;
+ case ocsd_sec_root: oss << "Root; "; break;
+ case ocsd_sec_realm: oss << "Realm; "; break;
+ }
+ oss << (context.bits64 ? "64-bit; " : "32-bit; ");
if(context.vmid_valid)
oss << "VMID=0x" << std::hex << context.vmid << "; ";
if(context.ctxt_id_valid)
@@ -190,6 +211,19 @@ void OcsdTraceElement::toString(std::string &str) const
oss << " [" << s_unsync_reason[unsync_eot_info] << "]";
break;
+ case OCSD_GEN_TRC_ELEM_SYNC_MARKER:
+ oss << " [" << s_marker_t[sync_marker.type] << "(0x" << std::setfill('0') << std::setw(8) << std::hex << sync_marker.value << ")]";
+ break;
+
+ case OCSD_GEN_TRC_ELEM_MEMTRANS:
+ if (mem_trans <= OCSD_MEM_TRANS_FAIL)
+ oss << s_transaction_type[mem_trans];
+ break;
+
+ case OCSD_GEN_TRC_ELEM_INSTRUMENTATION:
+ oss << "EL" << std::dec << (int)sw_ite.el << "; 0x" << std::setfill('0') << std::setw(16) << std::hex << sw_ite.value;
+ break;
+
default: break;
}
if(has_cc)
diff --git a/decoder/source/trc_printable_elem.cpp b/decoder/source/trc_printable_elem.cpp
index 88c7bb226f41..2b60c030d53f 100644
--- a/decoder/source/trc_printable_elem.cpp
+++ b/decoder/source/trc_printable_elem.cpp
@@ -52,8 +52,6 @@ void trcPrintableElem::getValStr(std::string &valStr, const int valTotalBitSize,
assert((valTotalBitSize >= 4) && (valTotalBitSize <= 64));
- uint64_t LimitMask = ~0ULL;
- LimitMask >>= 64-valTotalBitSize;
valStr = "0x";
if(asHex)
diff --git a/decoder/tests/auto-fdo/autofdo.md b/decoder/tests/auto-fdo/autofdo.md
index 69ed1520eda8..5d55cd05db77 100644
--- a/decoder/tests/auto-fdo/autofdo.md
+++ b/decoder/tests/auto-fdo/autofdo.md
@@ -87,12 +87,12 @@ kernel and many targets are using older kernels. To enable CoreSight trace
on these targets, Arm have provided backports of the latest CoreSight
drivers and ETM strobing patch at:
-
+
This repository can be cloned with:
```
-git clone git://linux-arm.org/linux-coresight-backports.git
+git clone https://git.gitlab.arm.com/linux-arm/linux-coresight-backports.git
```
You can include these backports in your kernel by either merging the
@@ -433,10 +433,50 @@ sudo ./set_strobing.sh 5000 10000
perf record -e cs_etm/@tmc_etr0/u --per-thread -- "
perf inject -i perf.data -o inj.data --itrace=i100000il
create_llvm_prof -binary=/path/to/binary -profile=inj.data -out=program.llvmprof
+clang -O2 -fprofile-sample-use=program.llvmprof -o program program.c
```
Use `create_gcov` for gcc.
+## High Level Summary for recoding on Arm board and decoding on different host
+
+1. (on Arm board)
+
+ sudo ./set_strobing.sh 5000 10000
+ perf record -e cs_etm/@tmc_etr0/u --per-thread -- .
+ If you specify `-N, --no-buildid-cache`, perf will just take care of recording the target binary and nothing will be copied.
If you don't specify it, any recorded dynamic library will be copied to ~/.debug in the board.
+
+2. (on Arm board) `perf archive` which saves all the found libraries in a tar (internally, it looks into perf.data file and performs a lookup using perf-buildid-list --with-hits)
+3. (on host) `scp` to copy perf.data and the .tar file generated from `perf archive`.
+4. (on host) Run `tar xvf perf_data.tar.bz2 -C ~/.debug` to populate the buildid-cache
+5. (on host) Double check the setup is correct:
+
+ a. `perf buildid-list -i perf.data` gives you the list of dynamic libraries buildids whose trace has been recorded and saved in perf.data.
+ b. `perf buildid-cache --list` lists the dynamic libraries in the buildid cache that will be used by `perf inject`.
+ Make sure the output of (a) and (b) overlaps as in buildid value for those binaries you are interested into optimizing with afdo.
+
+6. (on host) `perf inject -i perf.data -o inj.data --itrace=i100000il` will check for the dynamic libraries using the buildid inside the buildid-cache and post-process the trace.
buildids have to be the same, otherwise it won't be possible to post-process the trace.
+
+7. (on host) `create_llvm_prof -binary=/path/to/binary -profile=inj.data -out=program.llvmprof` takes the output from perf-inject and tranforms it into a format that the compiler can read.
+8. (on host) `clang -O2 -fprofile-sample-use=program.llvmprof -o program program.c` to make clang use the produced profile.
+ If you are confident enough that your profile is accurate, you can add the `-fprofile-sample-accurate` flag, which will penalize all the callsites without corresponding profile, marking them as cold.
+
+If you are using the same host for both building the binary to be traced and re-building it with afdo:
+
+1. You won't need to copy back any dynamic libraries from the board (since you already have them), and can use `--no-buildid-cache` when recording
+2. You have to make sure the relevant dynamic libraries to be optimized are present in the buildid-cache.
+
+You can easily add a dynamic library manually into the build-id cache by running:
+
+`perf buildid-cache --add -vvv`
+
+You can easily check what is currently contained in you buildid-cache by running:
+
+`perf buildid-cache --list`
+
+You can check the buildid of a given binary/dynamic library:
+
+`file `
## References
diff --git a/decoder/tests/build/linux/c_api_pkt_print_test/makefile b/decoder/tests/build/linux/c_api_pkt_print_test/makefile
index b0b56044e032..f1108e4d3439 100644
--- a/decoder/tests/build/linux/c_api_pkt_print_test/makefile
+++ b/decoder/tests/build/linux/c_api_pkt_print_test/makefile
@@ -51,12 +51,12 @@ OBJECTS = $(BUILD_DIR)/c_api_pkt_print_test.o
LIBS = -L$(LIB_TARGET_DIR) -l$(LIB_BASE_NAME) -l$(LIB_CAPI_NAME) \
-L$(LIB_TEST_TARGET_DIR) -l_echo_test_dcd
-all: build_dir copy_libs
+all: copy_libs
test_app: $(BIN_TEST_TARGET_DIR)/$(PROG)
- $(BIN_TEST_TARGET_DIR)/$(PROG): $(OBJECTS)
+ $(BIN_TEST_TARGET_DIR)/$(PROG): $(OBJECTS) | build_dir
mkdir -p $(BIN_TEST_TARGET_DIR)
$(LINKER) $(LDFLAGS) $(OBJECTS) -Wl,--start-group $(LIBS) -Wl,--end-group -o $(BIN_TEST_TARGET_DIR)/$(PROG)
cp $(LIB_TARGET_DIR)/*.so .
@@ -77,7 +77,7 @@ DEPS := $(OBJECTS:%.o=%.d)
-include $(DEPS)
## object compile
-$(BUILD_DIR)/%.o : %.c
+$(BUILD_DIR)/%.o : %.c | build_dir
$(CC) $(CFLAGS) $(CC_INCLUDES) -MMD $< -o $@
#### clean
diff --git a/decoder/tests/build/linux/echo_test_dcd_lib/makefile b/decoder/tests/build/linux/echo_test_dcd_lib/makefile
index 31ca38fe12ed..8c255a85aba2 100644
--- a/decoder/tests/build/linux/echo_test_dcd_lib/makefile
+++ b/decoder/tests/build/linux/echo_test_dcd_lib/makefile
@@ -48,9 +48,9 @@ CC_INCLUDES = \
OBJECTS = $(BUILD_DIR)/ext_dcd_echo_test.o \
$(BUILD_DIR)/ext_dcd_echo_test_fact.o
-all: build_dir $(LIB_TEST_TARGET_DIR)/$(LIB_NAME).a
+all: $(LIB_TEST_TARGET_DIR)/$(LIB_NAME).a
-$(LIB_TEST_TARGET_DIR)/$(LIB_NAME).a: $(OBJECTS)
+$(LIB_TEST_TARGET_DIR)/$(LIB_NAME).a: $(OBJECTS) | build_dir
mkdir -p $(LIB_TEST_TARGET_DIR)
$(LIB) $(ARFLAGS) $(LIB_TEST_TARGET_DIR)/$(LIB_NAME).a $(OBJECTS)
@@ -64,7 +64,7 @@ DEPS := $(OBJECTS:%.o=%.d)
-include $(DEPS)
## object compile
-$(BUILD_DIR)/%.o : %.c
+$(BUILD_DIR)/%.o : %.c | build_dir
$(CC) $(CFLAGS) $(CC_INCLUDES) -MMD $< -o $@
#### clean
diff --git a/decoder/tests/build/linux/frame_demux_test/makefile b/decoder/tests/build/linux/frame_demux_test/makefile
new file mode 100644
index 000000000000..29c75a00138a
--- /dev/null
+++ b/decoder/tests/build/linux/frame_demux_test/makefile
@@ -0,0 +1,88 @@
+########################################################
+# Copyright 2022 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.
+#
+#################################################################################
+
+########
+# opencsd: makefile for the frame demux test program
+#
+
+CXX := $(MASTER_CXX)
+LINKER := $(MASTER_LINKER)
+
+PROG = frame-demux-test
+
+BUILD_DIR=./$(PLAT_DIR)
+
+VPATH = $(OCSD_TESTS)/source
+
+CXX_INCLUDES = \
+ -I$(OCSD_TESTS)/source \
+ -I$(OCSD_INCLUDE)
+
+OBJECTS = $(BUILD_DIR)/frame_demux_test.o
+
+LIBS = -L$(LIB_TEST_TARGET_DIR) -L$(LIB_TARGET_DIR) -l$(LIB_BASE_NAME)
+
+all: copy_libs
+
+test_app: $(BIN_TEST_TARGET_DIR)/$(PROG)
+
+
+ $(BIN_TEST_TARGET_DIR)/$(PROG): $(OBJECTS) | build_dir
+ mkdir -p $(BIN_TEST_TARGET_DIR)
+ $(LINKER) $(LDFLAGS) $(OBJECTS) -Wl,--start-group $(LIBS) -Wl,--end-group -o $(BIN_TEST_TARGET_DIR)/$(PROG)
+
+build_dir:
+ mkdir -p $(BUILD_DIR)
+
+.PHONY: copy_libs
+copy_libs: $(BIN_TEST_TARGET_DIR)/$(PROG)
+ cp $(LIB_TARGET_DIR)/*.so* $(BIN_TEST_TARGET_DIR)/.
+
+
+
+#### build rules
+## object dependencies
+DEPS := $(OBJECTS:%.o=%.d)
+
+-include $(DEPS)
+
+## object compile
+$(BUILD_DIR)/%.o : %.cpp | build_dir
+ $(CXX) $(CXXFLAGS) $(CXX_INCLUDES) -MMD $< -o $@
+
+#### clean
+.PHONY: clean
+clean :
+ -rm $(BIN_TEST_TARGET_DIR)/$(PROG) $(OBJECTS)
+ -rm $(DEPS)
+ -rm $(BIN_TEST_TARGET_DIR)/*.so*
+ -rmdir $(BUILD_DIR)
+
+# end of file makefile
diff --git a/decoder/tests/build/linux/mem_buffer_eg/makefile b/decoder/tests/build/linux/mem_buffer_eg/makefile
index 850ed497dafa..79395217a3c0 100644
--- a/decoder/tests/build/linux/mem_buffer_eg/makefile
+++ b/decoder/tests/build/linux/mem_buffer_eg/makefile
@@ -51,12 +51,12 @@ OBJECTS = $(BUILD_DIR)/mem_buff_demo.o
LIBS = -L$(LIB_TEST_TARGET_DIR) -lsnapshot_parser \
-L$(LIB_TARGET_DIR) -l$(LIB_BASE_NAME)
-all: build_dir copy_libs
+all: copy_libs
test_app: $(BIN_TEST_TARGET_DIR)/$(PROG)
- $(BIN_TEST_TARGET_DIR)/$(PROG): $(OBJECTS)
+ $(BIN_TEST_TARGET_DIR)/$(PROG): $(OBJECTS) | build_dir
mkdir -p $(BIN_TEST_TARGET_DIR)
$(LINKER) $(LDFLAGS) $(OBJECTS) -Wl,--start-group $(LIBS) -Wl,--end-group -o $(BIN_TEST_TARGET_DIR)/$(PROG)
@@ -76,7 +76,7 @@ DEPS := $(OBJECTS:%.o=%.d)
-include $(DEPS)
## object compile
-$(BUILD_DIR)/%.o : %.cpp
+$(BUILD_DIR)/%.o : %.cpp | build_dir
$(CXX) $(CXXFLAGS) $(CXX_INCLUDES) -MMD $< -o $@
#### clean
diff --git a/decoder/tests/build/linux/snapshot_parser_lib/makefile b/decoder/tests/build/linux/snapshot_parser_lib/makefile
index 295bab61780e..ae566eba98e5 100644
--- a/decoder/tests/build/linux/snapshot_parser_lib/makefile
+++ b/decoder/tests/build/linux/snapshot_parser_lib/makefile
@@ -63,9 +63,9 @@ OBJECTS=$(BUILD_DIR)/device_info.o \
$(BUILD_DIR)/snapshot_reader.o \
$(BUILD_DIR)/ss_to_dcdtree.o
-all: build_dir $(LIB_TEST_TARGET_DIR)/$(LIB_NAME).a
+all: $(LIB_TEST_TARGET_DIR)/$(LIB_NAME).a
-$(LIB_TEST_TARGET_DIR)/$(LIB_NAME).a: $(OBJECTS)
+$(LIB_TEST_TARGET_DIR)/$(LIB_NAME).a: $(OBJECTS) | build_dir
mkdir -p $(LIB_TEST_TARGET_DIR)
$(LIB) $(ARFLAGS) $(LIB_TEST_TARGET_DIR)/$(LIB_NAME).a $(OBJECTS)
@@ -80,7 +80,7 @@ DEPS := $(OBJECTS:%.o=%.d)
-include $(DEPS)
## object compile
-$(BUILD_DIR)/%.o : %.cpp
+$(BUILD_DIR)/%.o : %.cpp | build_dir
$(CXX) $(CXXFLAGS) $(CXX_INCLUDES) -MMD $< -o $@
### clean
diff --git a/decoder/tests/build/linux/trc_pkt_lister/makefile b/decoder/tests/build/linux/trc_pkt_lister/makefile
index 54ce27d351a6..df0af0a10737 100644
--- a/decoder/tests/build/linux/trc_pkt_lister/makefile
+++ b/decoder/tests/build/linux/trc_pkt_lister/makefile
@@ -36,6 +36,7 @@ CXX := $(MASTER_CXX)
LINKER := $(MASTER_LINKER)
PROG = trc_pkt_lister
+PROG_S = trc_pkt_lister_s
BUILD_DIR=./$(PLAT_DIR)
@@ -51,19 +52,28 @@ OBJECTS = $(BUILD_DIR)/trc_pkt_lister.o
LIBS = -L$(LIB_TEST_TARGET_DIR) -lsnapshot_parser \
-L$(LIB_TARGET_DIR) -l$(LIB_BASE_NAME)
-all: build_dir copy_libs
+all: copy_libs
test_app: $(BIN_TEST_TARGET_DIR)/$(PROG)
- $(BIN_TEST_TARGET_DIR)/$(PROG): $(OBJECTS)
+ $(BIN_TEST_TARGET_DIR)/$(PROG): $(OBJECTS) | build_dir
mkdir -p $(BIN_TEST_TARGET_DIR)
$(LINKER) $(LDFLAGS) $(OBJECTS) -Wl,--start-group $(LIBS) -Wl,--end-group -o $(BIN_TEST_TARGET_DIR)/$(PROG)
+$(BIN_TEST_TARGET_DIR)/$(PROG_S): $(OBJECTS) | build_dir
+ mkdir -p $(BIN_TEST_TARGET_DIR)
+ $(LINKER) -static $(LDFLAGS) $(OBJECTS) -Wl,--start-group $(LIBS) -Wl,--end-group -o $(BIN_TEST_TARGET_DIR)/$(PROG_S)
+
+
+
build_dir:
mkdir -p $(BUILD_DIR)
.PHONY: copy_libs
+ifdef TEST_STATIC_LINKING
+copy_libs: $(BIN_TEST_TARGET_DIR)/$(PROG_S)
+endif
copy_libs: $(BIN_TEST_TARGET_DIR)/$(PROG)
cp $(LIB_TARGET_DIR)/*.so* $(BIN_TEST_TARGET_DIR)/.
@@ -76,13 +86,16 @@ DEPS := $(OBJECTS:%.o=%.d)
-include $(DEPS)
## object compile
-$(BUILD_DIR)/%.o : %.cpp
+$(BUILD_DIR)/%.o : %.cpp | build_dir
$(CXX) $(CXXFLAGS) $(CXX_INCLUDES) -MMD $< -o $@
#### clean
.PHONY: clean
clean :
-rm $(BIN_TEST_TARGET_DIR)/$(PROG) $(OBJECTS)
+ifdef TEST_STATIC_LINKING
+ -rm $(BIN_TEST_TARGET_DIR)/$(PROG_S)
+endif
-rm $(DEPS)
-rm $(BIN_TEST_TARGET_DIR)/*.so*
-rmdir $(BUILD_DIR)
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/Release-dll/c_api_pkt_print_test-dl.exe.recipe b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/Release-dll/c_api_pkt_print_test-dl.exe.recipe
new file mode 100644
index 000000000000..2e84a2a7e0ae
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/Release-dll/c_api_pkt_print_test-dl.exe.recipe
@@ -0,0 +1,11 @@
+
+
+
+
+ C:\work\OpenCSD\ocsd-linaro\decoder\tests\bin\win32\rel\c_api_pkt_print_test-dl.exe
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/Release-dll/c_api_pkt_print_test.exe.recipe b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/Release-dll/c_api_pkt_print_test.exe.recipe
new file mode 100644
index 000000000000..d6a9f40abd65
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/Release-dll/c_api_pkt_print_test.exe.recipe
@@ -0,0 +1,11 @@
+
+
+
+
+ C:\work\OpenCSD\ocsd-linaro\decoder\tests\bin\win32\rel\c_api_pkt_print_test.exe
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/Release-dll/c_api_pkt_print_test.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/Release-dll/c_api_pkt_print_test.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/Release-dll/c_api_pkt_print_test_dll.exe.recipe b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/Release-dll/c_api_pkt_print_test_dll.exe.recipe
new file mode 100644
index 000000000000..9607cfe1b87e
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/Release-dll/c_api_pkt_print_test_dll.exe.recipe
@@ -0,0 +1,11 @@
+
+
+
+
+ C:\work\OpenCSD\ocsd-linaro\decoder\tests\bin\win32\rel\c_api_pkt_print_test_dll.exe
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/Release/c_api_pkt_print_test.exe.recipe b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/Release/c_api_pkt_print_test.exe.recipe
new file mode 100644
index 000000000000..d6a9f40abd65
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/Release/c_api_pkt_print_test.exe.recipe
@@ -0,0 +1,11 @@
+
+
+
+
+ C:\work\OpenCSD\ocsd-linaro\decoder\tests\bin\win32\rel\c_api_pkt_print_test.exe
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/Release/c_api_pkt_print_test.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/Release/c_api_pkt_print_test.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/c_api_pkt_print_test.vcxproj b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/c_api_pkt_print_test.vcxproj
new file mode 100644
index 000000000000..985a84e709c2
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/c_api_pkt_print_test.vcxproj
@@ -0,0 +1,347 @@
+
+
+
+
+ debug-dll
+ Win32
+
+
+ debug-dll
+ x64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release-dll
+ Win32
+
+
+ Release-dll
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+
+
+
+ {3AC169DA-E156-4D16-95DF-73D7302A5606}
+ Win32Proj
+ c_api_pkt_print_test
+ 10.0
+
+
+
+ Application
+ true
+ MultiByte
+ v143
+
+
+ Application
+ true
+ MultiByte
+ v143
+ true
+
+
+ Application
+ true
+ MultiByte
+ v143
+
+
+ Application
+ true
+ MultiByte
+ v143
+
+
+ Application
+ false
+ true
+ MultiByte
+ v143
+
+
+ Application
+ false
+ true
+ MultiByte
+ v143
+
+
+ Application
+ false
+ true
+ MultiByte
+ v143
+
+
+ Application
+ false
+ true
+ MultiByte
+ v143
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ ..\..\..\bin\win$(PlatformArchitecture)\dbg\
+
+
+ true
+ ..\..\..\bin\win$(PlatformArchitecture)\dbg\
+ $(ProjectName)_dll
+
+
+ true
+ ..\..\..\bin\win$(PlatformArchitecture)\dbg\
+
+
+ true
+ ..\..\..\bin\win$(PlatformArchitecture)\dbg\
+ $(ProjectName)_dll
+
+
+ false
+ ..\..\..\bin\win$(PlatformArchitecture)\rel\
+
+
+ false
+ ..\..\..\bin\win$(PlatformArchitecture)\rel\
+ $(ProjectName)_dll
+
+
+ false
+ ..\..\..\bin\win$(PlatformArchitecture)\rel\
+
+
+ false
+ ..\..\..\bin\win$(PlatformArchitecture)\rel\
+ $(ProjectName)_dll
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;OCSD_USE_STATIC_C_API;%(PreprocessorDefinitions)
+ ..\..\..\..\include;..\..\..\..\tests\ext_dcd_test_eg\c_api_echo_test
+
+
+ Console
+ true
+ ..\..\..\..\lib\win$(PlatformArchitecture)\dbg\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\dbg\
+ lib$(LIB_CAPI_NAME).lib;lib$(LIB_BASE_NAME).lib;ext_dcd_echo_test.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ ..\..\..\..\include;..\..\..\..\tests\ext_dcd_test_eg\c_api_echo_test
+
+
+ Console
+ true
+ ..\..\..\..\lib\win$(PlatformArchitecture)\dbg\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\dbg\
+ lib$(LIB_CAPI_NAME).lib;ext_dcd_echo_test.lib;%(AdditionalDependencies)
+
+
+ copy ..\..\..\..\lib\win32\dbg\*.dll ..\..\..\bin\win32\dbg\.
+
+
+ false
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;OCSD_USE_STATIC_C_API;%(PreprocessorDefinitions)
+ ..\..\..\..\include;..\..\..\..\tests\ext_dcd_test_eg\c_api_echo_test
+
+
+ Console
+ true
+ lib$(LIB_CAPI_NAME).lib;lib$(LIB_BASE_NAME).lib;ext_dcd_echo_test.lib;%(AdditionalDependencies)
+ ..\..\..\..\lib\win$(PlatformArchitecture)\dbg\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\dbg\
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ ..\..\..\..\include;..\..\..\..\tests\ext_dcd_test_eg\c_api_echo_test
+
+
+ Console
+ true
+ lib$(LIB_CAPI_NAME).lib;ext_dcd_echo_test.lib;%(AdditionalDependencies)
+ ..\..\..\..\lib\win$(PlatformArchitecture)\dbg\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\dbg\
+
+
+ false
+
+
+ copy ..\..\..\..\lib\win64\dbg\*.dll ..\..\..\bin\win64\dbg\.
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;OCSD_USE_STATIC_C_API;%(PreprocessorDefinitions)
+ ..\..\..\..\include;..\..\..\..\tests\ext_dcd_test_eg\c_api_echo_test
+
+
+ Console
+ true
+ true
+ true
+ ..\..\..\..\lib\win$(PlatformArchitecture)\rel\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\rel\
+ lib$(LIB_CAPI_NAME).lib;lib$(LIB_BASE_NAME).lib;ext_dcd_echo_test.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ ..\..\..\..\include;..\..\..\..\tests\ext_dcd_test_eg\c_api_echo_test
+
+
+ Console
+ true
+ true
+ true
+ ..\..\..\..\lib\win$(PlatformArchitecture)\rel\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\rel\
+ lib$(LIB_CAPI_NAME).lib;ext_dcd_echo_test.lib;%(AdditionalDependencies)
+
+
+ false
+
+
+ copy ..\..\..\..\lib\win32\rel\*.dll ..\..\..\bin\win32\rel\.
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;OCSD_USE_STATIC_C_API;%(PreprocessorDefinitions)
+ ..\..\..\..\include;..\..\..\..\tests\ext_dcd_test_eg\c_api_echo_test
+
+
+ Console
+ true
+ true
+ true
+ ..\..\..\..\lib\win$(PlatformArchitecture)\rel\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\rel\
+ lib$(LIB_CAPI_NAME).lib;lib$(LIB_BASE_NAME).lib;ext_dcd_echo_test.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ ..\..\..\..\include;..\..\..\..\tests\ext_dcd_test_eg\c_api_echo_test
+
+
+ Console
+ true
+ true
+ true
+ ..\..\..\..\lib\win$(PlatformArchitecture)\rel\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\rel\
+ lib$(LIB_CAPI_NAME).lib;ext_dcd_echo_test.lib;%(AdditionalDependencies)
+
+
+ false
+
+
+ copy ..\..\..\..\lib\win64\rel\*.dll ..\..\..\bin\win64\rel\.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/c_api_pkt_print_test.vcxproj.filters b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/c_api_pkt_print_test.vcxproj.filters
new file mode 100644
index 000000000000..e8fc90b49ed5
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/c_api_pkt_print_test.vcxproj.filters
@@ -0,0 +1,22 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/debug-dll/c_api_pkt_print_test.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/debug-dll/c_api_pkt_print_test.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/debug-dll/c_api_pkt_print_test_dll.exe.recipe b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/debug-dll/c_api_pkt_print_test_dll.exe.recipe
new file mode 100644
index 000000000000..96aa2daede23
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/debug-dll/c_api_pkt_print_test_dll.exe.recipe
@@ -0,0 +1,11 @@
+
+
+
+
+ C:\work\OpenCSD\ocsd-linaro\decoder\tests\bin\win32\dbg\c_api_pkt_print_test_dll.exe
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/x64/Release-dll/c_api_pkt_print_test.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/x64/Release-dll/c_api_pkt_print_test.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/x64/Release-dll/c_api_pkt_print_test_dll.exe.recipe b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/x64/Release-dll/c_api_pkt_print_test_dll.exe.recipe
new file mode 100644
index 000000000000..35c848c55b0d
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/x64/Release-dll/c_api_pkt_print_test_dll.exe.recipe
@@ -0,0 +1,11 @@
+
+
+
+
+ C:\work\OpenCSD\ocsd-linaro\decoder\tests\bin\win64\rel\c_api_pkt_print_test_dll.exe
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/x64/Release/c_api_pkt_print_test.exe.recipe b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/x64/Release/c_api_pkt_print_test.exe.recipe
new file mode 100644
index 000000000000..6707fc0fedbb
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/x64/Release/c_api_pkt_print_test.exe.recipe
@@ -0,0 +1,11 @@
+
+
+
+
+ C:\work\OpenCSD\ocsd-linaro\decoder\tests\bin\win64\rel\c_api_pkt_print_test.exe
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/x64/Release/c_api_pkt_print_test.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/x64/Release/c_api_pkt_print_test.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/x64/debug-dll/c_api_pkt_print_test.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/x64/debug-dll/c_api_pkt_print_test.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/x64/debug-dll/c_api_pkt_print_test_dll.exe.recipe b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/x64/debug-dll/c_api_pkt_print_test_dll.exe.recipe
new file mode 100644
index 000000000000..63d719b6744f
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/x64/debug-dll/c_api_pkt_print_test_dll.exe.recipe
@@ -0,0 +1,11 @@
+
+
+
+
+ C:\work\OpenCSD\ocsd-linaro\decoder\tests\bin\win64\dbg\c_api_pkt_print_test_dll.exe
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/ext_dcd_echo_test/Release/ext_dcd_echo_test.lib.recipe b/decoder/tests/build/win-vs2022/ext_dcd_echo_test/Release/ext_dcd_echo_test.lib.recipe
new file mode 100644
index 000000000000..a53f9611dce7
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/ext_dcd_echo_test/Release/ext_dcd_echo_test.lib.recipe
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/ext_dcd_echo_test/Release/ext_dcd_echo_test.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/ext_dcd_echo_test/Release/ext_dcd_echo_test.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/ext_dcd_echo_test/ext_dcd_echo_test.vcxproj b/decoder/tests/build/win-vs2022/ext_dcd_echo_test/ext_dcd_echo_test.vcxproj
new file mode 100644
index 000000000000..74b8e1ad40ed
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/ext_dcd_echo_test/ext_dcd_echo_test.vcxproj
@@ -0,0 +1,291 @@
+
+
+
+
+ Debug-dll
+ Win32
+
+
+ Debug-dll
+ x64
+
+
+ Debug
+ Win32
+
+
+ Release-dll
+ Win32
+
+
+ Release-dll
+ x64
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {46219A32-8178-41C1-B3B1-B5A6E547515F}
+ Win32Proj
+ ext_dcd_echo_test
+ 10.0
+
+
+
+ StaticLibrary
+ true
+ v143
+ MultiByte
+
+
+ StaticLibrary
+ true
+ v143
+ MultiByte
+
+
+ StaticLibrary
+ false
+ v143
+ true
+ MultiByte
+
+
+ StaticLibrary
+ false
+ v143
+ true
+ MultiByte
+
+
+ StaticLibrary
+ true
+ v143
+ MultiByte
+
+
+ StaticLibrary
+ true
+ v143
+ MultiByte
+
+
+ StaticLibrary
+ false
+ v143
+ true
+ MultiByte
+
+
+ StaticLibrary
+ false
+ v143
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\..\..\lib\win$(PlatformArchitecture)\dbg\
+
+
+ ..\..\..\lib\win$(PlatformArchitecture)\dbg\
+
+
+ ..\..\..\lib\win$(PlatformArchitecture)\rel\
+
+
+ ..\..\..\lib\win$(PlatformArchitecture)\rel\
+
+
+ ..\..\..\lib\win$(PlatformArchitecture)\rel\
+
+
+ ..\..\..\lib\win$(PlatformArchitecture)\rel\
+
+
+ ..\..\..\lib\win$(PlatformArchitecture)\dbg\
+
+
+ ..\..\..\lib\win$(PlatformArchitecture)\dbg\
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ false
+ ..\..\..\..\include;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ false
+ ..\..\..\..\include;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+
+
+
+
+
+
+ Level3
+ Disabled
+ _DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ ..\..\..\..\include;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+
+
+
+
+
+
+ Level3
+ Disabled
+ _DEBUG;_LIB;%(PreprocessorDefinitions)
+ ..\..\..\..\include;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ ..\..\..\..\include;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ ..\..\..\..\include;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ ..\..\..\..\include;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ NDEBUG;_LIB;%(PreprocessorDefinitions)
+ ..\..\..\..\include;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/ext_dcd_echo_test/ext_dcd_echo_test.vcxproj.filters b/decoder/tests/build/win-vs2022/ext_dcd_echo_test/ext_dcd_echo_test.vcxproj.filters
new file mode 100644
index 000000000000..10fc54c1caa4
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/ext_dcd_echo_test/ext_dcd_echo_test.vcxproj.filters
@@ -0,0 +1,33 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/ext_dcd_echo_test/x64/Release/ext_dcd_echo_test.lib.recipe b/decoder/tests/build/win-vs2022/ext_dcd_echo_test/x64/Release/ext_dcd_echo_test.lib.recipe
new file mode 100644
index 000000000000..a53f9611dce7
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/ext_dcd_echo_test/x64/Release/ext_dcd_echo_test.lib.recipe
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/ext_dcd_echo_test/x64/Release/ext_dcd_echo_test.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/ext_dcd_echo_test/x64/Release/ext_dcd_echo_test.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/frame_demux_test/Win32/Release/frame_demux_test.exe.recipe b/decoder/tests/build/win-vs2022/frame_demux_test/Win32/Release/frame_demux_test.exe.recipe
new file mode 100644
index 000000000000..b85a437eb594
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/frame_demux_test/Win32/Release/frame_demux_test.exe.recipe
@@ -0,0 +1,11 @@
+
+
+
+
+ C:\work\OpenCSD\ocsd-linaro\decoder\tests\bin\win32\rel\frame_demux_test.exe
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/frame_demux_test/Win32/Release/frame_demux_test.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/frame_demux_test/Win32/Release/frame_demux_test.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/frame_demux_test/frame_demux_test.vcxproj b/decoder/tests/build/win-vs2022/frame_demux_test/frame_demux_test.vcxproj
new file mode 100644
index 000000000000..117f9f94e062
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/frame_demux_test/frame_demux_test.vcxproj
@@ -0,0 +1,172 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {98ee9884-a4eb-4c75-a911-dfedf992754f}
+ framedemuxtest
+ 10.0
+
+
+
+ Application
+ true
+ v143
+ Unicode
+ true
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+ ..\..\..\bin\win$(PlatformArchitecture)\dbg\
+ $(Platform)\$(Configuration)\
+
+
+ false
+ ..\..\..\bin\win$(PlatformArchitecture)\rel\
+ $(Platform)\$(Configuration)\
+
+
+ true
+
+
+ false
+ ..\..\..\bin\win$(PlatformArchitecture)\rel\
+
+
+
+ Level3
+ false
+ WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ ..\..\..\..\include
+
+
+ ProgramDatabase
+
+
+ Console
+ true
+ ..\..\..\..\lib\win$(PlatformArchitecture)\dbg\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\dbg\
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ ..\..\..\..\include
+
+
+ Console
+ true
+ true
+ true
+ ..\..\..\..\lib\win$(PlatformArchitecture)\rel\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\rel\
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ ..\..\..\..\include
+
+
+ Console
+ true
+ ..\..\..\..\lib\win$(PlatformArchitecture)\dbg\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\dbg\
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ ..\..\..\..\include
+
+
+ Console
+ true
+ true
+ true
+ ..\..\..\..\lib\win$(PlatformArchitecture)\rel\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\rel\
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/frame_demux_test/frame_demux_test.vcxproj.filters b/decoder/tests/build/win-vs2022/frame_demux_test/frame_demux_test.vcxproj.filters
new file mode 100644
index 000000000000..8069d24a8e06
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/frame_demux_test/frame_demux_test.vcxproj.filters
@@ -0,0 +1,22 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/frame_demux_test/x64/Release/frame_demux_test.exe.recipe b/decoder/tests/build/win-vs2022/frame_demux_test/x64/Release/frame_demux_test.exe.recipe
new file mode 100644
index 000000000000..c98207c230e7
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/frame_demux_test/x64/Release/frame_demux_test.exe.recipe
@@ -0,0 +1,11 @@
+
+
+
+
+ C:\work\OpenCSD\ocsd-linaro\decoder\tests\bin\win64\rel\frame_demux_test.exe
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/frame_demux_test/x64/Release/frame_demux_test.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/frame_demux_test/x64/Release/frame_demux_test.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/mem-buffer-eg/Win32/Release/mem-buffer-eg.exe.recipe b/decoder/tests/build/win-vs2022/mem-buffer-eg/Win32/Release/mem-buffer-eg.exe.recipe
new file mode 100644
index 000000000000..f1b64a06e5aa
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/mem-buffer-eg/Win32/Release/mem-buffer-eg.exe.recipe
@@ -0,0 +1,11 @@
+
+
+
+
+ C:\work\OpenCSD\ocsd-linaro\decoder\tests\bin\win32\rel\mem-buffer-eg.exe
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/mem-buffer-eg/Win32/Release/mem-buffer-eg.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/mem-buffer-eg/Win32/Release/mem-buffer-eg.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/mem-buffer-eg/mem-buffer-eg.vcxproj b/decoder/tests/build/win-vs2022/mem-buffer-eg/mem-buffer-eg.vcxproj
new file mode 100644
index 000000000000..66de3347413f
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/mem-buffer-eg/mem-buffer-eg.vcxproj
@@ -0,0 +1,293 @@
+
+
+
+
+ Debug-dll
+ Win32
+
+
+ Debug-dll
+ x64
+
+
+ Debug
+ Win32
+
+
+ Release-dll
+ Win32
+
+
+ Release-dll
+ x64
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+
+
+
+ {BC090130-2C53-4CF6-8AD4-37BF72B8D01A}
+ membuffereg
+ 10.0
+
+
+
+ Application
+ true
+ v143
+ MultiByte
+
+
+ Application
+ true
+ v143
+ MultiByte
+
+
+ Application
+ false
+ v143
+ true
+ MultiByte
+
+
+ Application
+ false
+ v143
+ true
+ MultiByte
+
+
+ Application
+ true
+ v143
+ MultiByte
+
+
+ Application
+ true
+ v143
+ MultiByte
+
+
+ Application
+ false
+ v143
+ true
+ MultiByte
+
+
+ Application
+ false
+ v143
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\..\..\bin\win$(PlatformArchitecture)\dbg\
+ $(Platform)\$(Configuration)\
+
+
+ ..\..\..\bin\win$(PlatformArchitecture)\dbg\
+ $(Platform)\$(Configuration)\
+
+
+ ..\..\..\bin\win$(PlatformArchitecture)\rel\
+ $(Platform)\$(Configuration)\
+
+
+ ..\..\..\bin\win$(PlatformArchitecture)\rel\
+ $(Platform)\$(Configuration)\
+
+
+ ..\..\..\bin\win$(PlatformArchitecture)\rel\
+
+
+ ..\..\..\bin\win$(PlatformArchitecture)\rel\
+
+
+ ..\..\..\bin\win$(PlatformArchitecture)\dbg\
+
+
+ ..\..\..\bin\win$(PlatformArchitecture)\dbg\
+
+
+
+ Level3
+ Disabled
+
+
+ ..\..\..\..\include
+ WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+
+
+ ..\..\..\..\lib\win$(PlatformArchitecture)\dbg\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\dbg\
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ true
+
+
+
+
+ Level3
+ Disabled
+
+
+ ..\..\..\..\include
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+
+
+ ..\..\..\..\lib\win$(PlatformArchitecture)\dbg\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\dbg\
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ true
+
+
+
+
+ Level3
+ Disabled
+ false
+ ..\..\..\..\include
+ WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;;%(PreprocessorDefinitions)
+
+
+ ..\..\..\..\lib\win$(PlatformArchitecture)\dbg\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\dbg\
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+ Disabled
+ false
+ ..\..\..\..\include
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+
+
+ ..\..\..\..\lib\win$(PlatformArchitecture)\dbg\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\dbg\
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+
+
+ ..\..\..\..\include
+ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+
+
+ true
+ true
+ ..\..\..\..\lib\win$(PlatformArchitecture)\rel\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\rel\
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+
+
+ ..\..\..\..\include
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+
+
+ true
+ true
+ ..\..\..\..\lib\win$(PlatformArchitecture)\rel\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\rel\
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ false
+ ..\..\..\..\include
+ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+
+
+ true
+ true
+ ..\..\..\..\lib\win$(PlatformArchitecture)\rel\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\rel\
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ false
+ ..\..\..\..\include
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+
+
+ true
+ true
+ ..\..\..\..\lib\win$(PlatformArchitecture)\rel\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\rel\
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/mem-buffer-eg/mem-buffer-eg.vcxproj.filters b/decoder/tests/build/win-vs2022/mem-buffer-eg/mem-buffer-eg.vcxproj.filters
new file mode 100644
index 000000000000..ce99a9eb1d73
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/mem-buffer-eg/mem-buffer-eg.vcxproj.filters
@@ -0,0 +1,22 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/mem-buffer-eg/x64/Release/mem-buffer-eg.exe.recipe b/decoder/tests/build/win-vs2022/mem-buffer-eg/x64/Release/mem-buffer-eg.exe.recipe
new file mode 100644
index 000000000000..1f4bcbb09bff
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/mem-buffer-eg/x64/Release/mem-buffer-eg.exe.recipe
@@ -0,0 +1,11 @@
+
+
+
+
+ C:\work\OpenCSD\ocsd-linaro\decoder\tests\bin\win64\rel\mem-buffer-eg.exe
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/mem-buffer-eg/x64/Release/mem-buffer-eg.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/mem-buffer-eg/x64/Release/mem-buffer-eg.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/snapshot_parser_lib/Release-dll/snapshot_parser_lib.lib.recipe b/decoder/tests/build/win-vs2022/snapshot_parser_lib/Release-dll/snapshot_parser_lib.lib.recipe
new file mode 100644
index 000000000000..a53f9611dce7
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/snapshot_parser_lib/Release-dll/snapshot_parser_lib.lib.recipe
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/snapshot_parser_lib/Release-dll/snapshot_parser_lib.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/snapshot_parser_lib/Release-dll/snapshot_parser_lib.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/snapshot_parser_lib/Win32/Release/snapshot_parser_lib.lib.recipe b/decoder/tests/build/win-vs2022/snapshot_parser_lib/Win32/Release/snapshot_parser_lib.lib.recipe
new file mode 100644
index 000000000000..a53f9611dce7
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/snapshot_parser_lib/Win32/Release/snapshot_parser_lib.lib.recipe
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/snapshot_parser_lib/Win32/Release/snapshot_parser_lib.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/snapshot_parser_lib/Win32/Release/snapshot_parser_lib.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/snapshot_parser_lib/snapshot_parser_lib.vcxproj b/decoder/tests/build/win-vs2022/snapshot_parser_lib/snapshot_parser_lib.vcxproj
new file mode 100644
index 000000000000..0b67d0c90a42
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/snapshot_parser_lib/snapshot_parser_lib.vcxproj
@@ -0,0 +1,316 @@
+
+
+
+
+ Debug-dll
+ Win32
+
+
+ Debug-dll
+ x64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release-dll
+ Win32
+
+
+ Release-dll
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {DE1F395D-4F53-42FB-8AEF-993A4BF7E411}
+ Win32Proj
+ snapshot_parser_lib
+ 10.0
+
+
+
+ StaticLibrary
+ true
+ MultiByte
+ v143
+
+
+ StaticLibrary
+ true
+ MultiByte
+ v143
+
+
+ StaticLibrary
+ true
+ MultiByte
+ v143
+
+
+ StaticLibrary
+ true
+ MultiByte
+ v143
+
+
+ StaticLibrary
+ false
+ true
+ MultiByte
+ v143
+
+
+ StaticLibrary
+ false
+ true
+ MultiByte
+ v143
+
+
+ StaticLibrary
+ false
+ true
+ MultiByte
+ v143
+
+
+ StaticLibrary
+ false
+ true
+ MultiByte
+ v143
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\..\..\lib\win$(PlatformArchitecture)\dbg\
+
+
+ ..\..\..\lib\win$(PlatformArchitecture)\dbg\
+
+
+ ..\..\..\lib\win$(PlatformArchitecture)\rel\
+
+
+ ..\..\..\lib\win$(PlatformArchitecture)\rel\
+
+
+ ..\..\..\lib\win$(PlatformArchitecture)\dbg\
+ $(Platform)\$(Configuration)\
+
+
+ ..\..\..\lib\win$(PlatformArchitecture)\dbg\
+ $(Platform)\$(Configuration)\
+
+
+ ..\..\..\lib\win$(PlatformArchitecture)\rel\
+ $(Platform)\$(Configuration)\
+
+
+ ..\..\..\lib\win$(PlatformArchitecture)\rel\
+ $(Platform)\$(Configuration)\
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ ../../../snapshot_parser_lib/include;../../../../include;%(AdditionalIncludeDirectories)
+ $(OutDir)$(TargetName)_vc$(PlatformToolsetVersion).pdb
+
+
+ Windows
+ true
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ ../../../snapshot_parser_lib/include;../../../../include;%(AdditionalIncludeDirectories)
+ $(OutDir)$(TargetName)_vc$(PlatformToolsetVersion).pdb
+
+
+ Windows
+ true
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ ../../../snapshot_parser_lib/include;../../../../include;%(AdditionalIncludeDirectories)
+ false
+ $(OutDir)$(TargetName)_vc$(PlatformToolsetVersion).pdb
+
+
+ Windows
+ true
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ ../../../snapshot_parser_lib/include;../../../../include;%(AdditionalIncludeDirectories)
+ false
+ $(OutDir)$(TargetName)_vc$(PlatformToolsetVersion).pdb
+
+
+ Windows
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ ../../../snapshot_parser_lib/include;../../../../include;%(AdditionalIncludeDirectories)
+ $(OutDir)$(TargetName)_vc$(PlatformToolsetVersion).pdb
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ ../../../snapshot_parser_lib/include;../../../../include;%(AdditionalIncludeDirectories)
+ $(OutDir)$(TargetName)_vc$(PlatformToolsetVersion).pdb
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ ../../../snapshot_parser_lib/include;../../../../include;%(AdditionalIncludeDirectories)
+ $(OutDir)$(TargetName)_vc$(PlatformToolsetVersion).pdb
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ ../../../snapshot_parser_lib/include;../../../../include;%(AdditionalIncludeDirectories)
+ $(OutDir)$(TargetName)_vc$(PlatformToolsetVersion).pdb
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/snapshot_parser_lib/snapshot_parser_lib.vcxproj.filters b/decoder/tests/build/win-vs2022/snapshot_parser_lib/snapshot_parser_lib.vcxproj.filters
new file mode 100644
index 000000000000..86d406797c3e
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/snapshot_parser_lib/snapshot_parser_lib.vcxproj.filters
@@ -0,0 +1,72 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/snapshot_parser_lib/x64/Release/snapshot_parser_lib.lib.recipe b/decoder/tests/build/win-vs2022/snapshot_parser_lib/x64/Release/snapshot_parser_lib.lib.recipe
new file mode 100644
index 000000000000..a53f9611dce7
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/snapshot_parser_lib/x64/Release/snapshot_parser_lib.lib.recipe
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/snapshot_parser_lib/x64/Release/snapshot_parser_lib.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/snapshot_parser_lib/x64/Release/snapshot_parser_lib.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/trc_pkt_lister/Release-dll/trc_pkt_lister.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/trc_pkt_lister/Release-dll/trc_pkt_lister.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/trc_pkt_lister/Win32/Release/trc_pkt_lister.exe.recipe b/decoder/tests/build/win-vs2022/trc_pkt_lister/Win32/Release/trc_pkt_lister.exe.recipe
new file mode 100644
index 000000000000..7aa56e8c0be9
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/trc_pkt_lister/Win32/Release/trc_pkt_lister.exe.recipe
@@ -0,0 +1,11 @@
+
+
+
+
+ C:\work\OpenCSD\ocsd-linaro\decoder\tests\bin\win32\rel\trc_pkt_lister.exe
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/trc_pkt_lister/Win32/Release/trc_pkt_lister.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/trc_pkt_lister/Win32/Release/trc_pkt_lister.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/build/win-vs2022/trc_pkt_lister/trc_pkt_lister.vcxproj b/decoder/tests/build/win-vs2022/trc_pkt_lister/trc_pkt_lister.vcxproj
new file mode 100644
index 000000000000..e1daff7a9c4f
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/trc_pkt_lister/trc_pkt_lister.vcxproj
@@ -0,0 +1,327 @@
+
+
+
+
+ Debug-dll
+ Win32
+
+
+ Debug-dll
+ x64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release-dll
+ Win32
+
+
+ Release-dll
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {18ABC652-AB11-4993-9491-1A7FB7117339}
+ Win32Proj
+ trc_pkt_lister
+ 10.0
+
+
+
+ Application
+ true
+ MultiByte
+ v143
+ false
+
+
+ Application
+ true
+ MultiByte
+ v143
+
+
+ Application
+ true
+ MultiByte
+ v143
+
+
+ Application
+ true
+ MultiByte
+ v143
+
+
+ Application
+ false
+ true
+ MultiByte
+ v143
+
+
+ Application
+ false
+ true
+ MultiByte
+ v143
+
+
+ Application
+ false
+ true
+ MultiByte
+ v143
+
+
+ Application
+ false
+ true
+ MultiByte
+ v143
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ ..\..\..\bin\win$(PlatformArchitecture)\dbg\
+ $(Platform)\$(Configuration)\
+
+
+ true
+ ..\..\..\bin\win$(PlatformArchitecture)\dbg\
+ $(Platform)\$(Configuration)\
+
+
+ true
+ ..\..\..\bin\win$(PlatformArchitecture)\dbg\
+
+
+ true
+ ..\..\..\bin\win$(PlatformArchitecture)\dbg\
+
+
+ false
+ ..\..\..\bin\win$(PlatformArchitecture)\rel\
+ $(Platform)\$(Configuration)\
+
+
+ false
+ ..\..\..\bin\win$(PlatformArchitecture)\rel\
+ $(Platform)\$(Configuration)\
+
+
+ false
+ ..\..\..\bin\win$(PlatformArchitecture)\rel\
+
+
+ false
+ ..\..\..\bin\win$(PlatformArchitecture)\rel\
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ ..\..\..\..\include;..\..\..\snapshot_parser_lib\include
+
+
+ Console
+ true
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ ..\..\..\..\lib\win$(PlatformArchitecture)\dbg\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\dbg\
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ ..\..\..\..\include;..\..\..\snapshot_parser_lib\include
+
+
+ Console
+ true
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ ..\..\..\..\lib\win$(PlatformArchitecture)\dbg\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\dbg\
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ ..\..\..\..\include;..\..\..\snapshot_parser_lib\include
+
+
+ Console
+ true
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ ..\..\..\..\lib\win$(PlatformArchitecture)\dbg\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\dbg\
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ ..\..\..\..\include;..\..\..\snapshot_parser_lib\include
+
+
+ Console
+ true
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ ..\..\..\..\lib\win$(PlatformArchitecture)\dbg\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\dbg\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ ..\..\..\..\include;..\..\..\snapshot_parser_lib\include
+
+
+ Console
+ true
+ true
+ true
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ ..\..\..\..\lib\win$(PlatformArchitecture)\rel\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\rel\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ ..\..\..\..\include;..\..\..\snapshot_parser_lib\include
+
+
+ Console
+ true
+ true
+ true
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ ..\..\..\..\lib\win$(PlatformArchitecture)\rel\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\rel\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ ..\..\..\..\include;..\..\..\snapshot_parser_lib\include
+
+
+ Console
+ true
+ true
+ true
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ ..\..\..\..\lib\win$(PlatformArchitecture)\rel\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\rel\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ ..\..\..\..\include;..\..\..\snapshot_parser_lib\include
+
+
+ Console
+ true
+ true
+ true
+ lib$(LIB_BASE_NAME).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ ..\..\..\..\lib\win$(PlatformArchitecture)\rel\;..\..\..\..\tests\lib\win$(PlatformArchitecture)\rel\
+
+
+
+
+
+
+
+ {de1f395d-4f53-42fb-8aef-993a4bf7e411}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/trc_pkt_lister/trc_pkt_lister.vcxproj.filters b/decoder/tests/build/win-vs2022/trc_pkt_lister/trc_pkt_lister.vcxproj.filters
new file mode 100644
index 000000000000..9f44406f52d6
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/trc_pkt_lister/trc_pkt_lister.vcxproj.filters
@@ -0,0 +1,27 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/trc_pkt_lister/x64/Release/trc_pkt_lister.exe.recipe b/decoder/tests/build/win-vs2022/trc_pkt_lister/x64/Release/trc_pkt_lister.exe.recipe
new file mode 100644
index 000000000000..69966dcb8834
--- /dev/null
+++ b/decoder/tests/build/win-vs2022/trc_pkt_lister/x64/Release/trc_pkt_lister.exe.recipe
@@ -0,0 +1,11 @@
+
+
+
+
+ C:\work\OpenCSD\ocsd-linaro\decoder\tests\bin\win64\rel\trc_pkt_lister.exe
+
+
+
+
+
+
\ No newline at end of file
diff --git a/decoder/tests/build/win-vs2022/trc_pkt_lister/x64/Release/trc_pkt_lister.vcxproj.FileListAbsolute.txt b/decoder/tests/build/win-vs2022/trc_pkt_lister/x64/Release/trc_pkt_lister.vcxproj.FileListAbsolute.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/decoder/tests/run_pkt_decode_single.bash b/decoder/tests/run_pkt_decode_single.bash
new file mode 100755
index 000000000000..30252402fdf9
--- /dev/null
+++ b/decoder/tests/run_pkt_decode_single.bash
@@ -0,0 +1,77 @@
+#!/bin/bash
+#################################################################################
+# Copyright 2018 ARM. 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.
+#
+#################################################################################
+# OpenCSD library: run single test
+#
+#
+#################################################################################
+# Usage options:-
+# * default: run test on binary + libs in ./bin/linux64/rel
+# run_pkt_decode_tests.bash
+#
+# * use installed opencsd libraries & program
+# run_pkt_decode_tests.bash use-installed
+#
+#
+
+OUT_DIR=./results
+SNAPSHOT_DIR=./snapshots
+BIN_DIR=./bin/linux64/rel/
+
+TEST="a57_single_step"
+
+mkdir -p ${OUT_DIR}
+
+if [ "$1" == "use-installed" ]; then
+ BIN_DIR=""
+ shift
+fi
+
+if [ "$1" != "" ]; then
+ TEST=$1
+ shift
+fi
+
+echo "Running trc_pkt_lister on single snapshot ${TEST}"
+
+
+if [ "${BIN_DIR}" != "" ]; then
+ echo "Tests using BIN_DIR = ${BIN_DIR}"
+ export LD_LIBRARY_PATH=${BIN_DIR}.
+ echo "LD_LIBRARY_PATH set to ${BIN_DIR}"
+else
+ echo "Tests using installed binaries"
+fi
+
+# === test the decode set ===
+${BIN_DIR}trc_pkt_lister -ss_dir "${SNAPSHOT_DIR}/${TEST}" $@ -decode -logfilename "${OUT_DIR}/${TEST}.ppl"
+echo "Done : Return $?"
+
+
diff --git a/decoder/tests/run_pkt_decode_tests-ete.bash b/decoder/tests/run_pkt_decode_tests-ete.bash
new file mode 100755
index 000000000000..a9fe0cc36e07
--- /dev/null
+++ b/decoder/tests/run_pkt_decode_tests-ete.bash
@@ -0,0 +1,117 @@
+#!/bin/bash
+#################################################################################
+# Copyright 2019 ARM. 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.
+#
+#################################################################################
+# OpenCSD library: Test script.
+#
+# Test script to run packet lister on each of the snapshots retained with the repository.
+# No attempt is made to compare output results to previous versions, (output formatting
+# may change due to bugfix / enhancements) or assess the validity of the trace output.
+#
+#################################################################################
+# Usage options:-
+# * default: run tests on binary + libs in ./bin/linux64/rel
+# run_pkt_decode_tests.bash
+#
+# * use installed opencsd libraries & program
+# run_pkt_decode_tests.bash use-installed
+#
+# * use supplied path for binary + libs (must have trailing /)
+# run_pkt_decode_tests.bash //
+#
+
+OUT_DIR=./results-ete
+SNAPSHOT_DIR=./snapshots-ete
+BIN_DIR=./bin/linux64/rel/
+
+# directories for tests using full decode
+declare -a test_dirs_decode=( "001-ack_test"
+ "002-ack_test_scr"
+ "ete-bc-instr"
+ "ete_ip"
+ "ete-ite-instr"
+ "ete_mem"
+ "ete_spec_1"
+ "ete_spec_2"
+ "ete_spec_3"
+ "event_test"
+ "infrastructure"
+ "q_elem"
+ "src_addr"
+ "tme_simple"
+ "tme_tcancel"
+ "tme_test"
+ "trace_file_cid_vmid"
+ "trace_file_vmid"
+ "ts_bit64_set"
+ "ts_marker"
+ )
+
+
+# directories for tests using I_SRC_ADDR_range option
+declare -a test_dirs_decode_src_addr_opt=( "002-ack_test_scr"
+ "ete_ip"
+ "src_addr"
+ )
+
+
+echo "Running trc_pkt_lister on snapshot directories."
+
+mkdir -p ${OUT_DIR}
+
+if [ "$1" == "use-installed" ]; then
+ BIN_DIR=""
+ shift
+elif [ "$1" == "-bindir" ]; then
+ BIN_DIR=$2
+ shift
+ shift
+fi
+
+echo "Tests using BIN_DIR = ${BIN_DIR}"
+
+if [ "${BIN_DIR}" != "" ]; then
+ export LD_LIBRARY_PATH=${BIN_DIR}.
+ echo "LD_LIBRARY_PATH set to ${BIN_DIR}"
+fi
+
+# === test the decode set ===
+for test_dir in "${test_dirs_decode[@]}"
+do
+ echo "Testing $test_dir..."
+ ${BIN_DIR}trc_pkt_lister -ss_dir "${SNAPSHOT_DIR}/$test_dir" $@ -decode -logfilename "${OUT_DIR}/$test_dir.ppl"
+ echo "Done : Return $?"
+done
+
+for test_dir_n in "${test_dirs_decode_src_addr_opt[@]}"
+do
+ echo "Testing with -src_addr_n $test_dir_n..."
+ ${BIN_DIR}trc_pkt_lister -ss_dir "${SNAPSHOT_DIR}/$test_dir_n" $@ -decode -src_addr_n -logfilename "${OUT_DIR}/${test_dir_n}_src_addr_N.ppl"
+ echo "Done : Return $?"
+done
diff --git a/decoder/tests/run_pkt_decode_tests.bash b/decoder/tests/run_pkt_decode_tests.bash
index 09f642b097c8..27a855e92899 100755
--- a/decoder/tests/run_pkt_decode_tests.bash
+++ b/decoder/tests/run_pkt_decode_tests.bash
@@ -40,10 +40,10 @@
# run_pkt_decode_tests.bash
#
# * use installed opencsd libraries & program
-# run_pkt_decode_tests.bash use-installed
+# run_pkt_decode_tests.bash use-installed
#
# * use supplied path for binary + libs (must have trailing /)
-# run_pkt_decode_tests.bash //
+# run_pkt_decode_tests.bash -bindir //
#
OUT_DIR=./results
@@ -62,6 +62,7 @@ declare -a test_dirs_decode=( "juno-ret-stck"
"stm_only"
"stm_only-2"
"stm_only-juno"
+ "stm-issue-27"
"TC2"
"Snowball"
"test-file-mem-offsets"
@@ -74,8 +75,11 @@ mkdir -p ${OUT_DIR}
if [ "$1" == "use-installed" ]; then
BIN_DIR=""
-elif [ "$1" != "" ]; then
- BIN_DIR=$1
+ shift
+elif [ "$1" == "-bindir" ]; then
+ BIN_DIR=$2
+ shift
+ shift
fi
echo "Tests using BIN_DIR = ${BIN_DIR}"
@@ -89,17 +93,17 @@ fi
for test_dir in "${test_dirs_decode[@]}"
do
echo "Testing $test_dir..."
- ${BIN_DIR}trc_pkt_lister -ss_dir "${SNAPSHOT_DIR}/$test_dir" -decode -logfilename "${OUT_DIR}/$test_dir.ppl"
+ ${BIN_DIR}trc_pkt_lister -ss_dir "${SNAPSHOT_DIR}/$test_dir" $@ -decode -logfilename "${OUT_DIR}/$test_dir.ppl"
echo "Done : Return $?"
done
# === test a packet only example ===
echo "Testing init-short-addr..."
-${BIN_DIR}trc_pkt_lister -ss_dir "${SNAPSHOT_DIR}/init-short-addr" -pkt_mon -logfilename "${OUT_DIR}/init-short-addr.ppl"
+${BIN_DIR}trc_pkt_lister -ss_dir "${SNAPSHOT_DIR}/init-short-addr" $@ -pkt_mon -logfilename "${OUT_DIR}/init-short-addr.ppl"
# === test the TPIU deformatter ===
echo "Testing a55-test-tpiu..."
-${BIN_DIR}trc_pkt_lister -ss_dir "${SNAPSHOT_DIR}/a55-test-tpiu" -dstream_format -o_raw_packed -o_raw_unpacked -logfilename "${OUT_DIR}/a55-test-tpiu.ppl"
+${BIN_DIR}trc_pkt_lister -ss_dir "${SNAPSHOT_DIR}/a55-test-tpiu" $@ -dstream_format -o_raw_packed -o_raw_unpacked -logfilename "${OUT_DIR}/a55-test-tpiu.ppl"
echo "Done : Return $?"
# === test the C-API lib - this test prog is not installed ===
@@ -110,3 +114,12 @@ if [ "$1" != "use-installed" ]; then
echo "moving result file."
mv ./c_api_test.log ./${OUT_DIR}/c_api_test.ppl
fi
+
+# === run the Frame decoder test - program not installed ===
+if [ "$1" != "use-installed" ]; then
+ echo "Running Frame demux test"
+ ${BIN_DIR}frame-demux-test > /dev/null
+ echo "Done : Return $?"
+ echo "moving result file."
+ mv ./frame_demux_test.ppl ./${OUT_DIR}/.
+fi
diff --git a/decoder/tests/snapshot_parser_lib/include/snapshot_parser.h b/decoder/tests/snapshot_parser_lib/include/snapshot_parser.h
index 8b9171255d0c..9e5b37189099 100644
--- a/decoder/tests/snapshot_parser_lib/include/snapshot_parser.h
+++ b/decoder/tests/snapshot_parser_lib/include/snapshot_parser.h
@@ -135,9 +135,9 @@ namespace Parser
std::vector GetBufferNameList(ParsedTrace &metadata);
- static ITraceErrorLog *s_pErrorLogger = 0;
- static ocsd_hndl_err_log_t s_errlog_handle = 0;
- static bool s_verbose_logging = true;
+ //static ITraceErrorLog *s_pErrorLogger = 0;
+ //static ocsd_hndl_err_log_t s_errlog_handle = 0;
+ //static bool s_verbose_logging = true;
void SetIErrorLogger(ITraceErrorLog *i_err_log);
void SetVerboseLogging(bool verbose);
diff --git a/decoder/tests/snapshot_parser_lib/include/snapshot_parser_util.h b/decoder/tests/snapshot_parser_lib/include/snapshot_parser_util.h
index 815afe9267d9..d4fd6cd952ad 100644
--- a/decoder/tests/snapshot_parser_lib/include/snapshot_parser_util.h
+++ b/decoder/tests/snapshot_parser_lib/include/snapshot_parser_util.h
@@ -35,6 +35,7 @@
#ifndef ARM_SNAPSHOT_PARSER_UTIL_H_INCLUDED
#define ARM_SNAPSHOT_PARSER_UTIL_H_INCLUDED
+#include
#include
#include
#include
diff --git a/decoder/tests/snapshot_parser_lib/include/ss_key_value_names.h b/decoder/tests/snapshot_parser_lib/include/ss_key_value_names.h
index 6e3a301dae50..ad0823b556a0 100644
--- a/decoder/tests/snapshot_parser_lib/include/ss_key_value_names.h
+++ b/decoder/tests/snapshot_parser_lib/include/ss_key_value_names.h
@@ -58,6 +58,10 @@ const char * const ETMv4RegIDR11("TRCIDR11");
const char * const ETMv4RegIDR12("TRCIDR12");
const char * const ETMv4RegIDR13("TRCIDR13");
+/*** ETE ***/
+const char *const ETEProtocol("ETE");
+const char *const ETERegDevArch("TRCDEVARCH");
+
/*** ETMv3/PTM ***/
const char * const ETMv3Protocol("ETM3");
const char * const PTMProtocol("PTM1");
diff --git a/decoder/tests/snapshot_parser_lib/include/ss_to_dcdtree.h b/decoder/tests/snapshot_parser_lib/include/ss_to_dcdtree.h
index a84e1843881f..3c85f9d152da 100644
--- a/decoder/tests/snapshot_parser_lib/include/ss_to_dcdtree.h
+++ b/decoder/tests/snapshot_parser_lib/include/ss_to_dcdtree.h
@@ -52,7 +52,7 @@ public:
void initialise(SnapShotReader *m_pReader, ITraceErrorLog *m_pErrLogInterface);
- bool createDecodeTree(const std::string &SourceBufferName, bool bPacketProcOnly);
+ bool createDecodeTree(const std::string &SourceBufferName, bool bPacketProcOnly, uint32_t add_create_flags = 0);
void destroyDecodeTree();
DecodeTree *getDecodeTree() const { return m_pDecodeTree; };
const char *getBufferFileName() const { return m_BufferFileName.c_str(); };
@@ -66,6 +66,7 @@ private:
bool createETMv4Decoder(const std::string &coreName, Parser::Parsed *devSrc, const bool bDataChannel = false);
bool createETMv3Decoder(const std::string &coreName, Parser::Parsed *devSrc);
bool createPTMDecoder(const std::string &coreName, Parser::Parsed *devSrc);
+ bool createETEDecoder(const std::string &coreName, Parser::Parsed *devSrc);
// TBD add etmv4d
// create a decoder related to a software trace source (ITM, STM)
@@ -91,7 +92,7 @@ private:
void processDumpfiles(std::vector &dumps);
-
+ uint32_t m_add_create_flags;
bool m_bInit;
DecodeTree *m_pDecodeTree;
diff --git a/decoder/tests/snapshot_parser_lib/source/snapshot_parser.cpp b/decoder/tests/snapshot_parser_lib/source/snapshot_parser.cpp
index 6e62d1e200c2..4570700dd4c8 100644
--- a/decoder/tests/snapshot_parser_lib/source/snapshot_parser.cpp
+++ b/decoder/tests/snapshot_parser_lib/source/snapshot_parser.cpp
@@ -49,6 +49,10 @@ using namespace Parser;
#include "opencsd.h"
+static ITraceErrorLog *s_pErrorLogger = 0;
+static ocsd_hndl_err_log_t s_errlog_handle = 0;
+static bool s_verbose_logging = true;
+
/*************************************************************************
* Note, this file handles the parsring of the general (device specific)
* ini file and the (much smaller) device_list file
diff --git a/decoder/tests/snapshot_parser_lib/source/ss_to_dcdtree.cpp b/decoder/tests/snapshot_parser_lib/source/ss_to_dcdtree.cpp
index 4eeec732c15b..902ce566f44e 100644
--- a/decoder/tests/snapshot_parser_lib/source/ss_to_dcdtree.cpp
+++ b/decoder/tests/snapshot_parser_lib/source/ss_to_dcdtree.cpp
@@ -45,6 +45,7 @@ CreateDcdTreeFromSnapShot::CreateDcdTreeFromSnapShot() :
m_BufferFileName("")
{
m_errlog_handle = 0;
+ m_add_create_flags = 0;
}
CreateDcdTreeFromSnapShot::~CreateDcdTreeFromSnapShot()
@@ -63,8 +64,9 @@ void CreateDcdTreeFromSnapShot::initialise(SnapShotReader *pReader, ITraceErrorL
}
}
-bool CreateDcdTreeFromSnapShot::createDecodeTree(const std::string &SourceName, bool bPacketProcOnly)
+bool CreateDcdTreeFromSnapShot::createDecodeTree(const std::string &SourceName, bool bPacketProcOnly, uint32_t add_create_flags)
{
+ m_add_create_flags = add_create_flags;
if(m_bInit)
{
if(!m_pReader->snapshotReadOK())
@@ -236,6 +238,10 @@ bool CreateDcdTreeFromSnapShot::createPEDecoder(const std::string &coreName, Par
{
bCreatedDecoder = createPTMDecoder(coreName,devSrc);
}
+ else if (devTypeName == ETEProtocol)
+ {
+ bCreatedDecoder = createETEDecoder(coreName, devSrc);
+ }
return bCreatedDecoder;
}
@@ -277,7 +283,7 @@ bool CreateDcdTreeFromSnapShot::createETMv4Decoder(const std::string &coreName,
EtmV4Config configObj(&config);
const char *decoderName = bDataChannel ? OCSD_BUILTIN_DCD_ETMV4D : OCSD_BUILTIN_DCD_ETMV4I;
- err = m_pDecodeTree->createDecoder(decoderName, m_bPacketProcOnly ? OCSD_CREATE_FLG_PACKET_PROC : OCSD_CREATE_FLG_FULL_DECODER,&configObj);
+ err = m_pDecodeTree->createDecoder(decoderName, m_add_create_flags | (m_bPacketProcOnly ? OCSD_CREATE_FLG_PACKET_PROC : OCSD_CREATE_FLG_FULL_DECODER),&configObj);
if(err == OCSD_OK)
createdDecoder = true;
@@ -291,6 +297,53 @@ bool CreateDcdTreeFromSnapShot::createETMv4Decoder(const std::string &coreName,
return createdDecoder;
}
+bool CreateDcdTreeFromSnapShot::createETEDecoder(const std::string &coreName, Parser::Parsed *devSrc)
+{
+ bool createdDecoder = false;
+ bool configOK = true;
+
+ // generate the config data from the device data.
+ ocsd_ete_cfg config;
+
+ // ete regs are same names Etmv4 in places...
+ regs_to_access_t regs_to_access[] = {
+ { ETMv4RegCfg, true, &config.reg_configr, 0 },
+ { ETMv4RegIDR, true, &config.reg_traceidr, 0 },
+ { ETMv4RegIDR0, true, &config.reg_idr0, 0 },
+ { ETMv4RegIDR1, false, &config.reg_idr1, 0x4100F403 },
+ { ETMv4RegIDR2, true, &config.reg_idr2, 0 },
+ { ETMv4RegIDR8, false, &config.reg_idr8, 0 },
+ { ETERegDevArch, false, &config.reg_devarch, 0x47705A13 },
+ };
+
+ // extract registers
+ configOK = getRegisters(devSrc->regDefs, sizeof(regs_to_access) / sizeof(regs_to_access_t), regs_to_access);
+
+ // extract core profile
+ if (configOK)
+ configOK = getCoreProfile(coreName, config.arch_ver, config.core_prof);
+
+ // good config - generate the decoder on the tree.
+ if (configOK)
+ {
+ ocsd_err_t err = OCSD_OK;
+ ETEConfig configObj(&config);
+ const char *decoderName = OCSD_BUILTIN_DCD_ETE;
+
+ err = m_pDecodeTree->createDecoder(decoderName, m_add_create_flags | (m_bPacketProcOnly ? OCSD_CREATE_FLG_PACKET_PROC : OCSD_CREATE_FLG_FULL_DECODER), &configObj);
+
+ if (err == OCSD_OK)
+ createdDecoder = true;
+ else
+ {
+ std::string msg = "Snapshot processor : failed to create " + (std::string)decoderName + " decoder on decode tree.";
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR, err, msg));
+ }
+ }
+
+ return createdDecoder;
+}
+
// create an ETMv3 decoder based on the register values in the deviceN.ini file.
bool CreateDcdTreeFromSnapShot::createETMv3Decoder(const std::string &coreName, Parser::Parsed *devSrc)
{
diff --git a/decoder/tests/snapshots-ete/001-ack_test/ETE_0_s1.ini b/decoder/tests/snapshots-ete/001-ack_test/ETE_0_s1.ini
new file mode 100644
index 000000000000..85938730c344
--- /dev/null
+++ b/decoder/tests/snapshots-ete/001-ack_test/ETE_0_s1.ini
@@ -0,0 +1,15 @@
+[device]
+name=ETE_0_s1
+class=trace_source
+type=ETE
+
+
+[regs]
+TRCCONFIGR=0x1
+TRCTRACEIDR=0x2
+TRCDEVARCH=0x47705a13
+TRCIDR0=0x8000aa1
+TRCIDR1=0x4100fff0
+TRCIDR2=0xc0001088
+TRCIDR8=0x000
+
diff --git a/decoder/tests/snapshots-ete/001-ack_test/bindir/OTHERS_exec b/decoder/tests/snapshots-ete/001-ack_test/bindir/OTHERS_exec
new file mode 100644
index 0000000000000000000000000000000000000000..84f1043736bc4268c4cd9c8360bff93ada2f2ee1
GIT binary patch
literal 271012
zcmeF44_ur_o&V?A-87qoHk)?SV!AfFgj$lKr7hZx#qvPtl`1MGT#mEcWl5-wS87Si
zX=zH)
z;9>XKKR_z2K6$;!d!L!_d}p3{=6Rl(`F@|7$wlmCu#45C$L2~tbu;}H
z(%%mHv!&26{T0&R4*IjLp=0{v`3KBfUYw+I<}g;Y+#|}O{O+RPl&A7rb}MpMuE?5k
z9#_73&&iD@dGD6XMA>Yn%5U3NI2676o=7^i?^bb+X2$Gl_${RC7TIx%pU0I%Z5c{0
zqq?FzE|{-8bm5JHlNTg;?~HnbZZ5O&%>pIwN$JXSGL_v)d2rdAsZ2LhnX;)&IlM0D
z*ha^z`LRjp-$>=WQq?t;?r)~kk-ns<@cXC3N#A7@&huZ+cJJM2TK=S}M|-||NQPh2
zF4D6xtj-E4UtX^~?n-%PecGr#_%-Bl4~3O}Dw3@r4vW-R5S-*<^~NHYeIuSe#AhRm)h)+aBfpae9vNy!i1(^?0hRcPM3j
ztfhNs5!*Wz_6rJ2rLgN+gA&G{m#3F^wG3U;)$+>fu9i0*l@CsCVD-Vp
z^1&2l>stgluFpirD;0fzKc&yauI#fZVU1H^W|CW`gnd;Lc4Z&G=V#{C)xzr}Jj_IL
zM<*wrVRWw2#3xT?7f~J2Ge^pjPi7BD%6)C3=W6am{>d#Cc5(mYWYKa;lPyaZ_ft7P
zx6`Uz$7?FxrJ>jDJ!Nu4f7d`j+xhm&O?TFVguWMfC~4)SYYrZjJu*xu4e3FaPhvc=G??=FRU{)Sl(x9_&{Ol#p2xjYc|4}%@$ywi
z4zla2PdvKX)bR3ET`eq0J}IGIR#QFl`e)v1MPGQiU8_WW6i(@^66L14440Lz74>oF
zl8Eox{lr4`
z%a3>OVm^MHa}66mvP`@qdA>IKTVdn*+m!p%M6zZ&rsvEdGuTgzBeB2YI*(Pu9orp#dC*0
zfB3x;Tugs-AM$%HxR|bKiSNWRx{uU*h>>poeBkxM?^&*gKSS7C_;1_x`?oxN??Vr5
zxjCcMDgJ%X`O!~5{6J~tw(ZVOf5y3?aMMQT0}qznOOabYUHLE%;|ZL1ZT{%Z&h4e2
zDJ#GCA?H%2QM5I>qPsszK{|7LVtotHk)l
zN#_x7JlA!V7?-S^l8ru|+iw?omrluE`tjU;l;`4m)UwYU&n=@*(}FS2
zOf6AIJkhjZz%x^eI?mt&h8g3gXj(AZnW;r@tfP!jqiMlN=Yvi)|CmFQnOZJ=do;!$
zhW*K~KfM!ec*gkSk8S*s6={EB-y}Pa`CJ#-Dz1n9iO<)}wChaUm4al0;&Z%OTh(h6
zmL4`%X{GVO4Ll6?twEaaUc`h=DWDna4AOXj+vWK9h3j5LX`Ut~EBf@uIWJOtbi38G
zz3iJLm#E!}#szk^G3%6M|J2^+ZehjTZo%sz)|lo>N~6Rxi&FlTWOKNj!c<${_9m
z*|NBegxj+C_~+jc&ga6Pp?XSW4787I_nxcy7%$S6<)U$rE!EWU3F_;IkA1kUYTc?x
zTh{etYx&YG<{5j(zT&)z~KswydmK*|J>d>kqC`#}CnMS%VmByf`HreeBbP
zvCmJYWYw`x)+MuLb)h`pp2}n9*rz91JN6Ov63>=Ziu(B4l+Ng59~Z_xd#7ae$38BM
zeQKxVW{!P!Q+W8;XFrX7swiBNXWFdxQ`O@7L@ME)3JT$H8Qkp6|nONrT#9C2+(
zjPl{OHmCiu?=Z?o+UQVh>a*>iPMK|Pf&FJ@-#Y5}C;u-CHRB(RmRXH|qH3Ad_$Qi{
z7~>x?sF^Y5h^8gh_(zFLNXzWTKherEyYWvnEwdZ{%+xa5_7z`#YW!0aU-r^V81@
z|IYBg<35qI_hB@~KYwiFpF1MQKVC8Z*-zsi?U?2V)Gxn@`sZ5vOOV3WDPdwV9Qvd^0^(@l%?scp8kC!qa?((g?r2=``PrUR&
zbkD{=u4^sJc%6KAvS?hPH>Oy5P2`xuM)UnUHi%W
zqwn8KWshf1$yq7<(YmH&qmLOnBoBn4^63_-+*V8-Afs+w415JgX7YGyYGiCUV(
zMj_5P4rjN{ZWt2gZg}ZN0#oCUOQ+J%WYmCB14a!PHDJ_$Q3FN|7&TzjfKdZR4d~WD
z>eV7xrA(%K#%#-NPtmt!^v~zy|4aNo`e$4IMX&OMy^CB57@K5y-?vzkMk3?06}@V_
zNE7{kHN9`S$d$3Rh0rnAz5VTEDjCz8Tk5)syITQspl-Bg=O+eGWbSZ=uUKU6McU
zU(?s&i(Y=FlT)X=X2$)f$|;nmgx>NWYQAbao-UtbMtg}?km>Ya^m3W$^ta78zu(X|
zvcIA4&TnL_A!xqp&~NZ9EDsNvO^4Px*p+8rV7H_^w)EOTv-J>{-5MslMP?Vbk!?Yd
zPm|Z)n31#An!}E-{t$h0C$sux8PeJ%X}ik=I+TtbR2eFR`%o9tumd%IjT8tUfo19jCbUjDA~b?v?U5
z&d)DsUUEqJ&Y9BXTG{a+g{`x&hh*{Cs-x%0z2-o5D@
z)z#%6l{@OL|M9B(SFq!|$d~M&Tt8aXDwO5;1yN9t4
zn5b@CRQ@!pxDFm>{eUTz?d0c^MrD10bhvEncycU)F~=7mM|OBrkX@Wmzd%Wm*)Oea5_%b9oM73}L9pOU;AZNch|D~PvH*#2D-
zeUrXY`EL9ly;9pYuf4vRSi@}f^iuB(ZDZqSwy^QD_ptGE|I9jvH?i^a`&j3z&$7-7
z=ysr&;I4rA}dsye-1~z^=n~lGGJAD&>8yo-fhslPsN9z3Wa^e$GXXqYzoJrX)
z1|K9{dvZF1=4I$LTsh8TvWv4DORV2cMNYJGqVr
zNymdZo#*J-DlJ=j{u$!+KV5akY+bkZG5O@#E%Nx?i`Y1qdG%>7bH&mNPjQ)_uNv7y
zG^H(7W$%{Qc!2Ugvq2tTC&}Z(+4A@nDd}A3ntiMC8M}@99a6h$v;NBxs)y_sLnKG_
zG5#`@+xsE!Mi)Ic!3O%ES
ze@TQ>-7DcwQ}{DEooAlT={$R%+_~2E<5iSyUFa#P^V~Lhd^_DEs~52yYMH(&F?;BV
z91->lQO+xgi@pU(Xx5?uns1V4u
zhe!uoOJ_lxt^zgnbMy&o7aW5u+G)EE>5cN(9h*geqBF8
zvb$(qhGEM8{1&;hPP%-lRZ3b)Wq3b-?$EV35xS9$^WPzor*j@ZL&u>TiFBOCb=@zI
zpPj7U%cP}Gx)#afDI|0D1~&dzGSvsgow*U-0WPM)kn!m6vhq8ko3l
z>$*=Xx~ZMr&N|QB#yVesUY14ix0Bx6#^SMLXBFP2T2uNdJud
z7K{6YU-LtnJovq{mHwXB=0WcWp2xu$c~~hAZJl{F`new^k5leXIuCyC>baga)4ASC
z=Xw+C{IWLB>qMSk*5t|4vpXp5tyB*;$(@gJd4B)$`&9BPWn4n%slBgPUrzVlzlr-%
zxo1e0-!s~>GCDtg-n=gELs`}9;#J;{)8&1cm-j|0?+vW81og(BIfFM+nQo9fi?!$A
z6=k|xeb(q)n}~X&dr>V*p3ZfVwfckm#W{!R=l5N>UUu2E-uH!{BgJX2iE@r>=p0wG
z&NU>fJZI<`b!H8*o|d
z^}NPAf%*dx&v(8y41YgRU33QNy>h3^)bJ<|3wy`VfIlKF_hp$%OYfAAUO{>4ylcKd
zbsw&epW9sCHK~-2pErNkbV+Q))kE)^t61k!`Zid54V1dLO77fFvi!XgTFyG3#I^8J
zT@O;+>E&|gmo(QxZ3oITjoJmZgWGsHmFEeiQLo=4Nb?)&PllgYB6U3Mr23%u1Ecqa
zMDL4d?=Us+yn|-y15q1S&MRqs{b{p2-be50XK2izmH%6k7tj0Z&UMVIyvwxjtItwA
z@2ha#{N0*Dx^I(62Zb?u2T~b*AO6Jq>t*WGP`|OB`i=Dy7`sfqz>dF3YY7EuU7dnwI~
zJSgqpV%9lnrm~sk&NGXteAR=suSL?SU*TS
zL+8uKK)ikOKH(Xv6W;DR==yOvx>hHw6qmM$Dd}9)e+W`N@pkynB*WwAef$XBLyxRp
zPw$g&h;!oKql75^-8?;=&smB;V_v$B|6WRImQwyajdDJeeuTG6$V(&>q;egl_WSpI
z>`B+{&1>n}m?d%THkgjTxq*$-eR5)nt$O2GiPle}@dEWhP9%};%jx;_6-rBMREhe_
zTVJn^9e7_WbOY5B^-XxYJwyGIvs7>AsNRO@y>*_R?XS|a{Q^BF2dOSbs4gxpW1SBr
z@jiaR$+J`r>O(yl+C}N9A5%`@OKDBHa}@qzY1xx!AEodOa_6Tgd>M@iUZZomU%K+i
zbDyJddI$1ndppGi@1nLq{UPPOLC?~&^t`vySn@Tx1{=R1pL~tRA*U(+<=f=(AU&4{
zsm|Y|zPgfz>YhJ;&n^>bDDTegQrgm~w70VH*KU=^U%QFU^-)=QHz@Zw=~_)|2cDt6
z=-u?3;P3oNst-F102_?z3)R{a_)ZO^*>n^qI0m)xHI%|x(*aSd>@ZbT6%sPkN@eaSGUNWKa$oios#nJ%_F5$E8xzo}hW@q4(1HpQbq!KF%3lLwe{wJx~4qz2vW|
z=p@;*Yvge{uRXlJmFE+M@naX&J>6@(?mPK2?TeI#k8M=>kMQ=KEqA6Zp=VlHn)6DU
z%h&A;OLM=P=JLoirzuT2$p=3!j}Lx?-hWv%mcs8Ke@Ol7~H
z&h;y#_ivW4M|c=NE|soO%AQN-{}-f_x6#mI>5g8NW?)PMuW#+xc~+Jo$S;
zd5-hv?jn+9X)<2f^x-ArZAnJ&9B_SckMDL2VPl$*koa+8h=
zVdduU2(`>68rPhmcYlcP$GBSM2f9
z`43YX@9(QMX_D5xo8)P{KmIDoe~aWUko>o#<$L@~Xda5^!N;sqd0f731ywXwkL2o8-JDSpCNz6x^f#gR>{sPHeB>4-{iao&>M9w{OudlX)OGnq;pwH
z_mJ}3SRz020FS3MZ*Jr73bXRAu-eRR)*bTrr>i9&TlookZrrWRWzjrpQBAhV&ii`2
zuXu)@*J}q;>#1)w?xg1(43!~DJ?(z~P6DqTfmI{W>l
zG)McJM{^F2F3ug}>G*v7cFNC6c@5G$H}A*sx#EyS<5!et$(r38Y2IfKpTp3G1!;c#
zDhl6{O=}EMT0YPJ*YtZItvRmF_wzohs-NERnOy&V(qBk&sxG#2MJG?A_G{HXGw+vL
z=^j_kf$pU|sX?}m9u07B9)&*{V_65%Wx0fw!{eLxSVe`NB%7x9}zQFnacE!S;|1TFf
z|B7oC_WVDw!1>>@!1+&_Eyroj_8{Zm-c_yIMEgPP2-02`*~M&!hkQt~OGJM{DuTs)wu}z%WcDCc2-=#EZY)3h#gY5{At{~q7!fdHm^E$m;
zqJ1DtvHYVmET@I9=V~bWf7}6!RN@VREJAe
z0A=>MJe=n@;pW(h@(=PItp?7(a
z>71$9ymR@cZEkkuwvoq9<}&l1JX#~w%d%cYlSX^t1=SAQ%FZcZhfg=mgWi4A2eAU_Mv~7Jz+rF{Ec#oKUkSJ!tN{IB3)l|^LEC3VdOMg5IzT6w3Z{YSU`BTAsumtpi4PXb@3yy%J;21aovPXn|3upzCKpSWWlR*dQ1XIB@FdfVQ
zGeI|)1tN>fUAZW+=6?|Z1{puEp%4)bOD%Vo63
zA?^DVpgsWk+0pSAlw*17xKhMZ9wNR}#M3diMJam&q8@nu%%)#{$tKDltsL9f1ABMz
za**Da$@g~~yH7dh{VJZ%YQE>*&LHDLjSb!oza2piOdu>+#cqyyqw@bhru
zJY3rINWpoeOrM8LYjkk=$o4Px>(kzAd_506SqXavMr#AP?6YBQ`g1ed^y(+B2y1Im
z^0A3BMbGDfuzc=|ozDT0k91&qZ$jCr-_CQKqHeYKpSEsfr>NVAdUT4q*4|Gu)9IgU
zjuZ8-sT*xNejQ@{vCaDBkv5||nrA56tX~Fcb7UI`&y&%%BQj8E%feCjKb0`*makQDnPxWZ7T>
z*K07cJf2|ubfv+_bb$oYb?K#x)4ro!=edTP=zcMiAD>k+|2UUyu6&Fi-d6PP9TVL<
z@zcd_$0oXmT$E=nOViI+=l(JA`JI?)BJ<>H&c;lm(`KX9=Wfy!@4WTyt>+R*r+1$n
zO(31#J-7Sj1j?y%pFEd9I=y@GXaecf^*pqxN;Q?=m?{-aE+q@)Lz8
z`7>kl>rw;n^Yi&Qb$*ijFz~o)^3T?b8>BuskKavxFyZm5>ASdLK0cuSYzp1?X8Kd-
z6wlv&Q>?SI&WkarQ1D#9wJo}A&UYzFZ
zhuegnSo7>$&(KlXcC(J2bN?jtv~tosd$5H_^X&d+BF(dVpA+#;nnzdX*-Lfi***Su
z#yop&M&k4ADL1`+=h^$85c4MkAbrQF%!h}-904c5q$fqXBCrJ94px9wU=8R48^LC<73=^5U@zDQ2EhJ{K3KrFg{7S&>UU@LeG90ILh5#>t)ZJ-@Y1|6UiOa;@xbT9+V1l?d3
zD1-T6Iamocf_|_Y>;*@_G0^dpD1R!L50-#lumS7jG6HEouz;rMJ%mm$F7AS*xU_Mv?wmdD$*9P{117IQKiojy91oVK7;4!cd><0%x
zTfN9H58Me>fnKl%tOe^pAJ_x3y+WTGtN>fUAZW+=AI)$x@v|EEL8-4z}%NjYq
z&F99|`R}7EBID!DfA1fD`^Qa&E-lvh1^2Uf9Fy;EPHZnkJGu#Xa1Y(8CojacIfE&
zQ=9)jx>HKn&-}U1k?h;l&%FQZV*X?R41ysrd7p@PfKD(C%mCe>4CaG{U=dghdcYd6
z5lr@r{G6Z{tOY~h2si;I?HB2az!GpfSOHdnHJ}e{1e?KDumcQ$y1K0uff+OH4I0jCD>>EPA1+;=mpbfNx
z$)E#tf~jB{m=0!unV=iY0%b4{%m)j=mP4X^ZD1cb02V^72rLFmKo8gm9s~QpesBP^
zwTS%kz@1u1K0>Qfqt+V
zWZx9!$pp89>bT07|2F2od0R02zl9H_a$gwp-^Tp6;s34sy^s3dNR-C>w=w@6tF0LG
z-^Tp6)~DC-|Bn2|GS>a0#u@(KM-IMtA^QBcWR9HQ*3N&MXr0s9`hO3;^7fhk?zkm#
z{`)5s7C!&|GYZqrfB%$@=Q97z=X%S!W!vwTN6vrC6t{m>|io
z{QUP;Du?ByY!+==oEd|IY1V3D1A01W5MnI{*EzV*X?R41ysr
z`MVAJ`8LfVLwdzdUd!SOt2)8n70u1ASl*$O1y28>|3Z
zz#wSH`Q(FDpckwGYr#6u2R49>U=!#En?ZI|lqVD14yyfTWB%Ki|K@GMnEy8BznM+n
zhs^N*PJB+n@c*9a=WEP=8}r|4Uqg?^{I@axZOnhu8o%>gi^!P&K63Etv(e|jbKcO8
zQ~kelFPr`Rw`=h2Gygr79y$NL?7flm-&atWcK-WvI-bk?H=pY*OOkCLSQ$+RSnLWEttT`su+4M8_sl4mOK0Bqyu00jFh83Gw^$C}S
z_LHxYo@LCmhxSXa_g=+lJ5t&c=uN4?`Kt*V3yAf7WP}e>xF5g&gUe8UkJ7bgMEcyfc~_{(NiU-}EF;leLz{~h}F(MjvlNc2bk>9nucz8A%4nlan*
zFM5@U3ihsa&PkT{eTy||Br-nxY9S~750~>Tr(IZ;e`^cznk{34r*B5yIm4OA$ziWZ>|K#e0z5cf^aQ==3&VTy5%&e*Xe`MOrhVTF5
zr?nTe^JtG86EUCmy&PplY$M6hem{IozZ>aTSv&AIL|TK;&(ra}bfdg@}E6cGBK$>iUi9K0Sd!RMMbLdX%;C%~jX&J$sb(`cwMM#e5%l&P4n~_})FHlO&tKK0l{vUsD?M
z9LlA=h_+CEw9jeLHd;?~my_1aq~AYa_wId(*6VlCZ@&J0Zuvcm+Cf*`Uy82i;%+SOM06wV)4d2M>cmFa#!@
zhJMfu%3v8-4*I}mum>Cf*~`!ey1@dl0;~iZK|k0H_JSke80Z)h`cuJtun?>St3W^4
z0``J^;26mM7ka^Tuy$C4`@lxf4;HF&U;rEgGhPwtw}Ta6CAbr81%qG+O#8J+Ujq8T
zZg31t4+%LB*a#j2t!G5M4DJNmz#%aCtdJ`JyNAAz$8i~jMY}HQT1nA#PS?Su-|vX;
z%f#y|YT0a}zZ0))^W6g}yq>jtA%(~BwyM_2Z1Yupf})+Tx>jVg^W}A=^aRxPP>J
z7RAyReqMpF=O-US@N#zHxyg^!XSY9!?0y|t=jNI33RSObGxmtn=w(r4C0$wleJJ$y
zdx7)zlq~q7w@S}QX`BAaK1n!H$$oqm{>+t)q+GdN`
z6VjOy<(ZTcsgp&Km2_l1QDjSXWaTKbIXbe=HBrjDMyI?{WF;M0rz?tHmyX^jvXYLh
zCyH#Tj;tI-Hb+PHD7|;$?O&z$zIrZ!bb9Zu6nY=U%TMn;W=bHP-aBos{(S0tg|~nH
zXOi8gV(y0|M_%8#>}RItYoakn%=|ExQTq@<@)u!j#Vt(ozowLzp4&0g>pbgI;-qou
zq{)qwCPydD);MWOb<*sPlcriH&Cxh%x^&VQ>)HP4tY>Q)jB}3+M&8pY^p1&jU%7PN
zHKsUe^xk`0qxT+6p?6!%^H~#F2c|e_^xlgp^iGPIkIuWv6eo?|dva@>
zGQYG;`UPPfe@NNASMcdu_s3l+Q=3PGT3Gv_~Ev
zXNK>`_s~mPpVO`uu1mYWow_&QS6|c0$p?k6;q=!H*;-b+G~==bK1T6KL294
zZ>oc29ASI&WzoKSS#kE}bC8T9%HDjD`ReV>_lcB9-_$Y+3tyYzJ_^(NrhbZ!XZohj
zJO|abtJ_--Y^?@AchT``=t&Yxx;3o@@sA2--Hdk95!%2
zY~UW)z-8FLgPgE|e@@2+?tcf`z>f}?6dO2aqBij7ewElBe1;8N_`34GZTMgR?}fc2
z2s*~ZaVl62R)Ry|FgOZMfR=HQJ_)pg$)E#F1wCLTX#GEt-VWA)b>IYOd0oiKU?JE6
z2Ebmh4-A4Ka1@*XtrJ484RnC1U41q}!
z^n-3t2Ft*5&<8eyJ>USyOwb3q!2+-XtOOfDKiCcSf+OG<=r9ZYsbD@>2v&kspdV}j
zd%-?%3}hDQ1=GRWWg^@MHiCYzP?ZA%;24;(NTlBmR)Ce@POudWf*~;NGLgOn^nu;r
z7?{3T$a%m<@EB;dig+2^3ATYlVDb_nR{(m!b}$4wmI}E-umzhVCtHaElmJ?%H3whfhx=Dg$D-*x7_oe89K>7
-gtX3?B94c(_A{Qk8qy>
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