aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-02-17 03:24:18 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-02-17 03:24:18 +0000
commita58c021a45e9dbac9f965a9f4a79e40d5debd2e0 (patch)
treefbb4a50a3164452c160d7f8660d4996df7859c82
parentf43c9468c2cf4c073c29c097a16b54a01dfbb4c8 (diff)
parenta99a76cfe180577a3a4f5e0ecbc3025057d6f6bd (diff)
downloadOpenCSD-android13-frc-networking-release.tar.gz
Snap for 8191477 from a99a76cfe180577a3a4f5e0ecbc3025057d6f6bd to tm-frc-networking-releaset_frc_net_330443000android13-frc-networking-release
Change-Id: If5f2931d8068946dc12a9f1d36afdb904bf154bc
-rw-r--r--Android.bp1
-rw-r--r--METADATA6
-rw-r--r--README.md22
-rw-r--r--decoder/build/linux/makefile1
-rw-r--r--decoder/build/linux/rctdl_c_api_lib/makefile2
-rw-r--r--decoder/docs/doxygen_config.dox2
-rw-r--r--decoder/docs/prog_guide/prog_guide_main.md23
-rw-r--r--decoder/include/common/ocsd_dcd_mngr.h6
-rw-r--r--decoder/include/common/ocsd_dcd_tree.h29
-rw-r--r--decoder/include/common/trc_frame_deformatter.h4
-rw-r--r--decoder/include/common/trc_pkt_proc_base.h48
-rw-r--r--decoder/include/opencsd/c_api/ocsd_c_api_types.h1
-rw-r--r--decoder/include/opencsd/c_api/opencsd_c_api.h52
-rw-r--r--decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h15
-rw-r--r--decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h8
-rw-r--r--decoder/include/opencsd/ocsd_if_types.h55
-rw-r--r--decoder/include/opencsd/ocsd_if_version.h4
-rw-r--r--decoder/source/c_api/ocsd_c_api.cpp51
-rw-r--r--decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp96
-rw-r--r--decoder/source/etmv4/trc_pkt_proc_etmv4i.cpp14
-rw-r--r--decoder/source/ocsd_dcd_tree.cpp66
-rw-r--r--decoder/source/ocsd_gen_elem_stack.cpp1
-rw-r--r--decoder/source/ptm/trc_pkt_proc_ptm.cpp1
-rw-r--r--decoder/source/trc_frame_deformatter.cpp60
-rw-r--r--decoder/source/trc_frame_deformatter_impl.h14
-rw-r--r--decoder/source/trc_printable_elem.cpp2
-rwxr-xr-xdecoder/tests/run_pkt_decode_single.bash7
-rwxr-xr-xdecoder/tests/run_pkt_decode_tests-ete.bash11
-rwxr-xr-xdecoder/tests/run_pkt_decode_tests.bash17
-rw-r--r--decoder/tests/snapshot_parser_lib/include/snapshot_parser.h6
-rw-r--r--decoder/tests/snapshot_parser_lib/source/snapshot_parser.cpp4
-rw-r--r--decoder/tests/source/c_api_pkt_print_test.c140
-rw-r--r--decoder/tests/source/mem_buff_demo.cpp9
-rw-r--r--decoder/tests/source/trc_pkt_lister.cpp63
34 files changed, 726 insertions, 115 deletions
diff --git a/Android.bp b/Android.bp
index 448a8b4..6e8884c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -75,6 +75,7 @@ cc_library_static {
"decoder/source/*.cpp",
"decoder/source/etmv3/*.cpp",
"decoder/source/etmv4/*.cpp",
+ "decoder/source/ete/*.cpp",
"decoder/source/i_dec/*.cpp",
"decoder/source/mem_acc/*.cpp",
"decoder/source/pkt_printers/*.cpp",
diff --git a/METADATA b/METADATA
index 74f35ca..256f7cb 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@ third_party {
type: GIT
value: "https://github.com/Linaro/OpenCSD.git"
}
- version: "v1.0.0"
+ version: "v1.2.0"
license_type: RESTRICTED
last_upgrade_date {
year: 2021
- month: 1
- day: 8
+ month: 10
+ day: 13
}
}
diff --git a/README.md b/README.md
index bdedf3f..97b32ed 100644
--- a/README.md
+++ b/README.md
@@ -27,12 +27,12 @@ Releases will appear on the master branch in the git repository with an appropri
CoreSight Trace Component Support.
----------------------------------
-_Current Version 1.0.0_
+_Current Version 1.2.0_
### Current support:
- ETE (v1.1) instruction trace - packet processing and packet decode.
-- ETMv4 (v4.5 [A/R profile] v4.4 [M profile]) instruction trace - packet processing and packet decode.
+- ETMv4 (v4.6 [A/R profile] v4.4 [M profile]) instruction trace - packet processing and packet decode.
- PTM (v1.1) instruction trace - packet processing and packet decode.
- ETMv3 (v3.5) instruction trace - packet processing and packet decode.
- ETMv3 (v3.5) data trace - packet processing.
@@ -239,6 +239,24 @@ Version and Modification Information
- __Bugfix__: build: Fix clean install, and remove static lib build test from main makefile to
dev makefile only. (github issue #33)
+- _Version 1.1.0_:
+ - __Update__: ETM v4.6 support.
+ - __Update__: C-API - add API functions to get last error and convert error code to string.
+ - __Bugfix__: ETMv4/ETE - fix loop problem in commit elements.
+ - __Bugfix__: ETMv4/ETE - make error handling consistent.
+ - __Bugfix__: Add Pull request #36 from github (Ross Burton)
+ - __Bugfix__: Add Pull request #37 from github (Ian Rogers)
+
+- _Version 1.1.1_:
+ - __Bugfix__: Fix include and install for ETE decoder headers.
+
+- _Version 1.2.0_:
+ - __Update__: Add API for counting packet decode statistics, and Frame debmux statistics.
+ - __Update__: Update test scripts to allow additional command line options to be passed.
+ - __Bugfix__: Fix various build warnings.
+ - __Bugfix__: Remove unused variable (github issue #38 from Yi Kong)
+ - __Bugfix__: Remove noisy printf (James Clark)
+ - __Bugfix__: Fix documentation issues (github issues #39 & #40 from rbresalier)
Licence Information
===================
diff --git a/decoder/build/linux/makefile b/decoder/build/linux/makefile
index f63868c..54dd031 100644
--- a/decoder/build/linux/makefile
+++ b/decoder/build/linux/makefile
@@ -133,6 +133,7 @@ endif
$(INSTALL) --mode=755 $(BIN_TEST_TARGET_DIR)/trc_pkt_lister $(INSTALL_BIN_DIR)/
install_man:
+ mkdir -p $(INSTALL_MAN_DIR)
$(INSTALL) --mode=644 $(OCSD_ROOT)/docs/man/trc_pkt_lister.1 $(INSTALL_MAN_DIR)/
diff --git a/decoder/build/linux/rctdl_c_api_lib/makefile b/decoder/build/linux/rctdl_c_api_lib/makefile
index a0bd5a3..7b4055d 100644
--- a/decoder/build/linux/rctdl_c_api_lib/makefile
+++ b/decoder/build/linux/rctdl_c_api_lib/makefile
@@ -113,6 +113,8 @@ install_inc:
$(INSTALL) --mode=0644 $(INST_INC_SRC)/etmv3/trc_pkt_types_etmv3.h $(INST_INC_DST)/etmv3/
$(INSTALL) -d --mode=0755 $(INST_INC_DST)/etmv4
$(INSTALL) --mode=0644 $(INST_INC_SRC)/etmv4/trc_pkt_types_etmv4.h $(INST_INC_DST)/etmv4/
+ $(INSTALL) -d --mode=0755 $(INST_INC_DST)/ete
+ $(INSTALL) --mode=0644 $(INST_INC_SRC)/ete/trc_pkt_types_ete.h $(INST_INC_DST)/ete/
$(INSTALL) -d --mode=0755 $(INST_INC_DST)/c_api
$(INSTALL) --mode=0644 $(INST_INC_SRC)/c_api/ocsd_c_api_types.h $(INST_INC_DST)/c_api/
$(INSTALL) --mode=0644 $(INST_INC_SRC)/c_api/opencsd_c_api.h $(INST_INC_DST)/c_api/
diff --git a/decoder/docs/doxygen_config.dox b/decoder/docs/doxygen_config.dox
index 65c8931..6d2f02c 100644
--- a/decoder/docs/doxygen_config.dox
+++ b/decoder/docs/doxygen_config.dox
@@ -38,7 +38,7 @@ PROJECT_NAME = "OpenCSD - CoreSight Trace Decode Library"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.0.0
+PROJECT_NUMBER = 1.2.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/decoder/docs/prog_guide/prog_guide_main.md b/decoder/docs/prog_guide/prog_guide_main.md
index d0e2e7c..9504bdc 100644
--- a/decoder/docs/prog_guide/prog_guide_main.md
+++ b/decoder/docs/prog_guide/prog_guide_main.md
@@ -138,9 +138,17 @@ The error logger can be attached to an output logger - ocsdMsgLogger - which can
error, or other error messages, out to screen or logging file. Errors can be filtered according to a severity rating,
defined by @ref ocsd_err_severity_t.
-The DecodeTree will use a default error logger from the library - with a message logger
-that will output to `stderr`. Client applications can adjust the configuration of this error logger and
-message logger, or provide their own configured error logger / message logger pair.
+The DecodeTree can use a default error logger from the library - with a message logger that will output to `stderr`.
+
+Client applications can create and adjust the configuration of this error logger and message logger by getting and intialising
+ the logger.
+
+~~~{.cpp}
+ // ** Initialise default error logger.
+ DecodeTree::getDefaultErrorLogger()->initErrorLogger(verbosity,true);
+~~~
+
+Alternatively clients may provide their own configured error logger / message logger pair.
The test program `trc_pkt_lister` provides a customised version of an `ocsdMsgLogger` / `ocsdDefaultErrorLogger` pair
to ensure that messages and errors are logged to the screen and a file of its choice. This logger is eventually
@@ -301,15 +309,19 @@ types to be managed by a memory access mapper:-
~~~{.cpp}
class DecodeTree {
- ///...
+ // ...
+ ocsd_err_t createMemAccMapper(memacc_mapper_t type = MEMACC_MAP_GLOBAL);
+ // ...
ocsd_err_t addBufferMemAcc(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t *p_mem_buffer, const uint32_t mem_length);
ocsd_err_t addBinFileMemAcc(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const std::string &filepath);
ocsd_err_t addBinFileRegionMemAcc(const ocsd_file_mem_region_t *region_array, const int num_regions, const ocsd_mem_space_acc_t mem_space, const std::string &filepath); */
ocsd_err_t addCallbackMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, const ocsd_mem_space_acc_t mem_space, Fn_MemAcc_CB p_cb_func, const void *p_context);
- ///...
+ // ...
}
~~~
+The `createMemAccMapper()` function must be called to create the mapper, before the `add...MemAcc()` calls are used.
+
It is further possible to differentiate between memory image access objects by the memory space for which they are valid. If it is known that a certain code image
is present in secure EL3, then an image can be associated with the @ref ocsd_mem_space_acc_t type value @ref OCSD_MEM_SPACE_EL3, which will allow another image to be
present at the same address but a different exception level. However, for the majority of systems, such detailed knowledge of the code is not available, or
@@ -324,6 +336,7 @@ The C-API contains a similar set of calls to set up memory access objects:-
OCSD_C_API ocsd_err_t ocsd_dt_add_callback_mem_acc(const dcd_tree_handle_t handle, const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, const ocsd_mem_space_acc_t mem_space, Fn_MemAcc_CB p_cb_func, const void *p_context);
~~~
+Note that the C-API will automatically create a default mapper when the first memory access object is added.
### Adding the output callbacks ###
diff --git a/decoder/include/common/ocsd_dcd_mngr.h b/decoder/include/common/ocsd_dcd_mngr.h
index 3b9ba97..34c4ef1 100644
--- a/decoder/include/common/ocsd_dcd_mngr.h
+++ b/decoder/include/common/ocsd_dcd_mngr.h
@@ -80,16 +80,16 @@ public:
private:
- ocsd_trace_protocol_t m_builtInProtocol; //!< Protocol ID if built in type.
+ const ocsd_trace_protocol_t m_builtInProtocol; //!< Protocol ID if built in type.
};
template <class P, class Pt, class Pc>
-DecoderMngrBase<P,Pt,Pc>::DecoderMngrBase(const std::string &decoderTypeName, ocsd_trace_protocol_t builtInProtocol)
+ DecoderMngrBase<P,Pt,Pc>::DecoderMngrBase(const std::string &decoderTypeName, ocsd_trace_protocol_t builtInProtocol) :
+ m_builtInProtocol(builtInProtocol)
{
OcsdLibDcdRegister *pDcdReg = OcsdLibDcdRegister::getDecoderRegister();
if(pDcdReg)
pDcdReg->registerDecoderTypeByName(decoderTypeName,this);
- m_builtInProtocol = builtInProtocol;
}
template <class P, class Pt, class Pc>
diff --git a/decoder/include/common/ocsd_dcd_tree.h b/decoder/include/common/ocsd_dcd_tree.h
index e4e74f2..b1c3dc6 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/trc_frame_deformatter.h b/decoder/include/common/trc_frame_deformatter.h
index e4297a4..b6476a2 100644
--- a/decoder/include/common/trc_frame_deformatter.h
+++ b/decoder/include/common/trc_frame_deformatter.h
@@ -85,9 +85,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_pkt_proc_base.h b/decoder/include/common/trc_pkt_proc_base.h
index 3098a3d..8ed7d83 100644
--- a/decoder/include/common/trc_pkt_proc_base.h
+++ b/decoder/include/common/trc_pkt_proc_base.h
@@ -43,6 +43,7 @@
#include "trc_component.h"
#include "comp_attach_pt_t.h"
+#include "opencsd/ocsd_if_version.h"
/** @defgroup ocsd_pkt_proc OpenCSD Library : Packet Processors.
@brief Classes providing Protocol Packet Processing capability.
@@ -76,6 +77,8 @@ public:
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed) = 0;
+ virtual ocsd_err_t getStatsBlock(ocsd_decode_stats_t **pp_stats) = 0;
+ virtual void resetStats() = 0;
protected:
/* implementation packet processing interface */
@@ -155,6 +158,10 @@ public:
//!< Get the configuration for the decoder.
virtual const Pc *getProtocolConfig() const { return m_config; };
+/* stats block access - derived class must init stats for the block to be returned. */
+ virtual ocsd_err_t getStatsBlock(ocsd_decode_stats_t **pp_stats);
+ virtual void resetStats(); /* reset the counts - operates separately from decoder reset. */
+
protected:
/* data output functions */
@@ -183,6 +190,14 @@ protected:
const bool checkInit(); // return true if init (configured and at least one output sink attached), false otherwise.
+ /* stats block updates - called by derived protocol specific decoder */
+ void statsAddTotalCount(const uint64_t count) { m_stats.channel_total += count; };
+ void statsAddUnsyncCount(const uint64_t count) { m_stats.channel_unsynced += count; };
+ void statsAddBadSeqCount(const uint32_t count) { m_stats.bad_sequence_errs += count; };
+ void statsAddBadHdrCount(const uint32_t count) { m_stats.bad_header_errs += count; };
+ void statsInit() { m_stats_init = true; }; /* mark stats as in use */
+
+
private:
/* decode control */
ocsd_datapath_resp_t Reset(const ocsd_trc_index_t index);
@@ -195,20 +210,29 @@ private:
componentAttachPt<ITrcPktIndexer<Pt>> m_pkt_indexer_i;
bool m_b_is_init;
+
+ /* decode statistics block */
+ ocsd_decode_stats_t m_stats;
+ bool m_stats_init; /*< true if the specific decoder is using the stats */
+
};
template<class P,class Pt, class Pc> TrcPktProcBase<P, Pt, Pc>::TrcPktProcBase(const char *component_name) :
TrcPktProcI(component_name),
m_config(0),
- m_b_is_init(false)
+ m_b_is_init(false),
+ m_stats_init(false)
{
+ resetStats();
}
template<class P,class Pt, class Pc> TrcPktProcBase<P, Pt, Pc>::TrcPktProcBase(const char *component_name, int instIDNum) :
TrcPktProcI(component_name, instIDNum),
m_config(0),
- m_b_is_init(false)
+ m_b_is_init(false),
+ m_stats_init(false)
{
+ resetStats();
}
template<class P,class Pt, class Pc> TrcPktProcBase<P, Pt, Pc>::~TrcPktProcBase()
@@ -405,6 +429,26 @@ template<class P,class Pt, class Pc> const bool TrcPktProcBase<P, Pt, Pc>::check
return m_b_is_init;
}
+template<class P,class Pt, class Pc> ocsd_err_t TrcPktProcBase<P, Pt, Pc>::getStatsBlock(ocsd_decode_stats_t **pp_stats)
+{
+
+ *pp_stats = &m_stats;
+ return m_stats_init ? OCSD_OK : OCSD_ERR_NOT_INIT;
+}
+
+template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::resetStats()
+{
+ m_stats.version = OCSD_VER_NUM;
+ m_stats.revision = OCSD_STATS_REVISION;
+ m_stats.channel_total = 0;
+ m_stats.channel_unsynced = 0;
+ m_stats.bad_header_errs = 0;
+ m_stats.bad_sequence_errs = 0;
+ m_stats.demux.frame_bytes = 0;
+ m_stats.demux.no_id_bytes = 0;
+ m_stats.demux.valid_id_bytes = 0;
+}
+
/** @}*/
#endif // ARM_TRC_PKT_PROC_BASE_H_INCLUDED
diff --git a/decoder/include/opencsd/c_api/ocsd_c_api_types.h b/decoder/include/opencsd/c_api/ocsd_c_api_types.h
index cde351f..7f9b4ba 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 90201d4..ebbba87 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/etmv4/trc_cmp_cfg_etmv4.h b/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h
index e46b71d..223dbda 100644
--- a/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h
+++ b/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h
@@ -153,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,
@@ -436,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_pkt_decode_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
index 607e21d..65230ff 100644
--- a/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
+++ b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
@@ -101,7 +101,13 @@ protected:
ocsd_err_t processTransElem(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);
diff --git a/decoder/include/opencsd/ocsd_if_types.h b/decoder/include/opencsd/ocsd_if_types.h
index 4b6e17e..5628fec 100644
--- a/decoder/include/opencsd/ocsd_if_types.h
+++ b/decoder/include/opencsd/ocsd_if_types.h
@@ -524,10 +524,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)
/** @}*/
@@ -632,6 +633,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 1a932a2..d6f5849 100644
--- a/decoder/include/opencsd/ocsd_if_version.h
+++ b/decoder/include/opencsd/ocsd_if_version.h
@@ -43,7 +43,7 @@
/** @name Library Versioning
@{*/
#define OCSD_VER_MAJOR 0x1 /**< Library Major Version */
-#define OCSD_VER_MINOR 0x0 /**< Library Minor Version */
+#define OCSD_VER_MINOR 0x2 /**< Library Minor Version */
#define OCSD_VER_PATCH 0x0 /**< Library Patch Version */
/** Library version number - MMMMnnpp format.
@@ -53,7 +53,7 @@
*/
#define OCSD_VER_NUM ((OCSD_VER_MAJOR << 16) | (OCSD_VER_MINOR << 8) | OCSD_VER_PATCH)
-#define OCSD_VER_STRING "1.0.0" /**< Library Version string */
+#define OCSD_VER_STRING "1.2.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/source/c_api/ocsd_c_api.cpp b/decoder/source/c_api/ocsd_c_api.cpp
index 4824c42..750c847 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<DecodeTree *>(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<DecodeTree *>(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/etmv4/trc_pkt_decode_etmv4i.cpp b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
index e4caf0a..015a2f5 100644
--- a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
+++ b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
@@ -477,15 +477,15 @@ ocsd_err_t TrcPktDecodeEtmV4I::decodePacket()
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
@@ -568,7 +568,7 @@ ocsd_err_t TrcPktDecodeEtmV4I::decodePacket()
/* ETE commit window - not supported in current ETE versions - blocked by packet processor */
case ETE_PKT_I_COMMIT_WIN_MV:
err = OCSD_ERR_UNSUPP_DECODE_PKT;
- LogError(ocsdError(OCSD_ERR_SEV_ERROR, err, "ETE Commit Window Move, unsupported packet type."));
+ err = handlePacketSeqErr(err, m_index_curr_pkt, "ETE Commit Window Move, unsupported packet type.");
break;
/* conditional instruction tracing */
case ETM4_PKT_I_COND_FLUSH:
@@ -592,14 +592,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 related, 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;
}
@@ -845,9 +847,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");
}
}
@@ -867,7 +868,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
{
@@ -1007,6 +1008,8 @@ ocsd_err_t TrcPktDecodeEtmV4I::cancelElements()
break;
}
}
+ if (m_P0_stack.size() == 0)
+ P0StackDone = true;
}
}
// may have some unseen elements
@@ -1020,21 +1023,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;
}
@@ -1076,7 +1081,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;
@@ -1266,7 +1272,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;
}
}
@@ -1372,9 +1379,11 @@ ocsd_err_t TrcPktDecodeEtmV4I::processException()
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;
+ // 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
{
@@ -1635,7 +1644,7 @@ ocsd_err_t TrcPktDecodeEtmV4I::processSourceAddress()
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;
+ 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);
@@ -1868,27 +1877,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)
- {
- // error out - stop decoding
- err = OCSD_ERR_BAD_DECODE_PKT;
- LogError(ocsdError(OCSD_ERR_SEV_ERROR,err,reason));
- }
- else
+ 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)
{
- 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_proc_etmv4i.cpp b/decoder/source/etmv4/trc_pkt_proc_etmv4i.cpp
index 81ae9d7..07b372c 100644
--- a/decoder/source/etmv4/trc_pkt_proc_etmv4i.cpp
+++ b/decoder/source/etmv4/trc_pkt_proc_etmv4i.cpp
@@ -75,6 +75,7 @@ ocsd_err_t TrcPktProcEtmV4I::onProtocolConfig()
BuildIPacketTable(); // packet table based on config
m_curr_packet.setProtocolVersion(m_config.FullVersion());
m_isInit = true;
+ statsInit();
return OCSD_OK;
}
@@ -156,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;
}
@@ -175,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;
}
@@ -245,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)
{
@@ -1501,8 +1507,8 @@ void TrcPktProcEtmV4I::BuildIPacketTable()
m_i_table[0x85+i].pptkFn = &TrcPktProcEtmV4I::iPktAddrCtxt;
}
- // 0b1000 1000 - ETE 1.1 TS Marker
- if (m_config.MajVersion() >= 0x5)
+ // 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;
diff --git a/decoder/source/ocsd_dcd_tree.cpp b/decoder/source/ocsd_dcd_tree.cpp
index 5dafba9..b423f7d 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<TrcPktProcI *>(pAssoc);
+ else
+ pPktProc = dynamic_cast<TrcPktProcI *>(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
@@ -538,6 +601,7 @@ bool DecodeTree::initialise(const ocsd_dcd_tree_src_t type, uint32_t formatterCf
m_frame_deformatter_root->Configure(formatterCfgFlags);
m_frame_deformatter_root->getErrLogAttachPt()->attach(DecodeTree::s_i_error_logger);
m_i_decoder_root = dynamic_cast<ITrcDataIn*>(m_frame_deformatter_root);
+ m_frame_deformatter_root->SetDemuxStatsBlock(&m_demux_stats);
}
else
initOK = false;
diff --git a/decoder/source/ocsd_gen_elem_stack.cpp b/decoder/source/ocsd_gen_elem_stack.cpp
index bb75842..66fe75d 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/ptm/trc_pkt_proc_ptm.cpp b/decoder/source/ptm/trc_pkt_proc_ptm.cpp
index 7c90b62..a7419b0 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();
diff --git a/decoder/source/trc_frame_deformatter.cpp b/decoder/source/trc_frame_deformatter.cpp
index 4d46854..dc12e3f 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();
@@ -436,7 +437,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
@@ -595,6 +595,9 @@ bool TraceFmtDcdImpl::extractFrame()
// update index past the processed data
m_trc_curr_idx += total_processed;
+ // update any none trace data byte stats
+ addToFrameStats((uint64_t)(f_sync_bytes + h_sync_bytes));
+
return cont_process;
}
@@ -604,6 +607,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 +654,7 @@ bool TraceFmtDcdImpl::unpackFrame()
/// TBD - ID indexing in here.
}
+ noneDataBytes++;
}
else
// it's just data
@@ -671,6 +676,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 +684,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 +725,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 +750,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 +770,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 */
/***************************************************************/
@@ -865,5 +912,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 e1fc17a..8d19bdb 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,
@@ -117,8 +119,16 @@ private:
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<ITrcDataIn> m_IDStreams[128];
componentAttachPt<ITrcRawFrameIn> m_RawTraceFrame;
@@ -159,6 +169,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_printable_elem.cpp b/decoder/source/trc_printable_elem.cpp
index 88c7bb2..2b60c03 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/run_pkt_decode_single.bash b/decoder/tests/run_pkt_decode_single.bash
index b4ca58f..3025240 100755
--- a/decoder/tests/run_pkt_decode_single.bash
+++ b/decoder/tests/run_pkt_decode_single.bash
@@ -34,10 +34,10 @@
#################################################################################
# Usage options:-
# * default: run test on binary + libs in ./bin/linux64/rel
-# run_pkt_decode_tests.bash <test>
+# run_pkt_decode_tests.bash <test> <options>
#
# * use installed opencsd libraries & program
-# run_pkt_decode_tests.bash use-installed <test>
+# run_pkt_decode_tests.bash use-installed <test> <options>
#
#
@@ -56,6 +56,7 @@ fi
if [ "$1" != "" ]; then
TEST=$1
+ shift
fi
echo "Running trc_pkt_lister on single snapshot ${TEST}"
@@ -70,7 +71,7 @@ else
fi
# === test the decode set ===
-${BIN_DIR}trc_pkt_lister -ss_dir "${SNAPSHOT_DIR}/${TEST}" -decode -logfilename "${OUT_DIR}/${TEST}.ppl"
+${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
index c00631e..1b8c762 100755
--- a/decoder/tests/run_pkt_decode_tests-ete.bash
+++ b/decoder/tests/run_pkt_decode_tests-ete.bash
@@ -84,8 +84,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}"
@@ -99,13 +102,13 @@ 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
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"
+ ${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 d9b7c8a..9ecb034 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 <options>
#
# * use supplied path for binary + libs (must have trailing /)
-# run_pkt_decode_tests.bash <custom>/<path>/
+# run_pkt_decode_tests.bash -bindir <custom>/<path>/ <options>
#
OUT_DIR=./results
@@ -75,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}"
@@ -90,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 ===
diff --git a/decoder/tests/snapshot_parser_lib/include/snapshot_parser.h b/decoder/tests/snapshot_parser_lib/include/snapshot_parser.h
index 8b91712..9e5b371 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<std::string> 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/source/snapshot_parser.cpp b/decoder/tests/snapshot_parser_lib/source/snapshot_parser.cpp
index 6e62d1e..4570700 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/source/c_api_pkt_print_test.c b/decoder/tests/source/c_api_pkt_print_test.c
index 02c589e..fa9f48d 100644
--- a/decoder/tests/source/c_api_pkt_print_test.c
+++ b/decoder/tests/source/c_api_pkt_print_test.c
@@ -116,6 +116,12 @@ static int test_printstr = 0;
/* test the library printer API */
static int test_lib_printers = 0;
+/* test the last error / error code api */
+static int test_error_api = 0;
+
+/* log statistics */
+static int stats = 0;
+
/* Process command line options - choose the operation to use for the test. */
static int process_cmd_line(int argc, char *argv[])
{
@@ -124,52 +130,52 @@ static int process_cmd_line(int argc, char *argv[])
while(idx < argc)
{
- if(strcmp(argv[idx],"-decode_only") == 0)
+ if (strcmp(argv[idx], "-decode_only") == 0)
{
op = TEST_PKT_DECODEONLY;
}
- else if(strcmp(argv[idx],"-decode") == 0)
+ else if (strcmp(argv[idx], "-decode") == 0)
{
op = TEST_PKT_DECODE;
}
- else if(strcmp(argv[idx],"-id") == 0)
+ else if (strcmp(argv[idx], "-id") == 0)
{
idx++;
- if(idx < argc)
+ if (idx < argc)
{
- test_trc_id_override = (uint8_t)(strtoul(argv[idx],0,0));
- printf("ID override = 0x%02X\n",test_trc_id_override);
+ test_trc_id_override = (uint8_t)(strtoul(argv[idx], 0, 0));
+ printf("ID override = 0x%02X\n", test_trc_id_override);
}
}
- else if(strcmp(argv[idx],"-etmv3") == 0)
+ else if (strcmp(argv[idx], "-etmv3") == 0)
{
- test_protocol = OCSD_PROTOCOL_ETMV3;
+ test_protocol = OCSD_PROTOCOL_ETMV3;
selected_snapshot = tc2_snapshot;
mem_dump_address = mem_dump_address_tc2;
}
- else if(strcmp(argv[idx],"-ptm") == 0)
+ else if (strcmp(argv[idx], "-ptm") == 0)
{
- test_protocol = OCSD_PROTOCOL_PTM;
+ test_protocol = OCSD_PROTOCOL_PTM;
selected_snapshot = tc2_snapshot;
mem_dump_address = mem_dump_address_tc2;
}
- else if(strcmp(argv[idx],"-stm") == 0)
+ else if (strcmp(argv[idx], "-stm") == 0)
{
test_protocol = OCSD_PROTOCOL_STM;
trace_data_filename = stmtrace_data_filename;
}
- else if(strcmp(argv[idx],"-test_cb") == 0)
+ else if (strcmp(argv[idx], "-test_cb") == 0)
{
using_mem_acc_cb = 1;
use_region_file = 0;
}
else if (strcmp(argv[idx], "-test_cb_id") == 0)
- {
+ {
using_mem_acc_cb = 1;
use_region_file = 0;
using_mem_acc_cb_id = 1;
}
- else if(strcmp(argv[idx],"-test_region_file") == 0)
+ else if (strcmp(argv[idx], "-test_region_file") == 0)
{
use_region_file = 1;
using_mem_acc_cb = 0;
@@ -182,6 +188,10 @@ static int process_cmd_line(int argc, char *argv[])
{
frame_raw_unpacked = 1;
}
+ else if (strcmp(argv[idx], "-stats") == 0)
+ {
+ stats = 1;
+ }
else if (strcmp(argv[idx], "-raw_packed") == 0)
{
frame_raw_packed = 1;
@@ -194,10 +204,10 @@ static int process_cmd_line(int argc, char *argv[])
{
test_lib_printers = 1;
}
- else if(strcmp(argv[idx],"-ss_path") == 0)
+ else if (strcmp(argv[idx], "-ss_path") == 0)
{
idx++;
- if((idx >= argc) || (strlen(argv[idx]) == 0))
+ if ((idx >= argc) || (strlen(argv[idx]) == 0))
{
printf("-ss_path: Missing path parameter or zero length\n");
return -1;
@@ -205,14 +215,18 @@ static int process_cmd_line(int argc, char *argv[])
else
{
len = strlen(argv[idx]);
- if(len > (MAX_TRACE_FILE_PATH_LEN - 32))
+ if (len > (MAX_TRACE_FILE_PATH_LEN - 32))
{
printf("-ss_path: path too long\n");
return -1;
}
usr_snapshot_path = argv[idx];
}
-
+
+ }
+ else if (strcmp(argv[idx], "-test_err_api") == 0)
+ {
+ test_error_api = 1;
}
else if(strcmp(argv[idx],"-help") == 0)
{
@@ -641,6 +655,7 @@ static ocsd_err_t create_decoder_etmv4(dcd_tree_handle_t dcd_tree_h)
{
trace_config.reg_traceidr = (uint32_t)test_trc_id_override;
}
+ test_trc_id_override = trace_config.reg_traceidr; /* remember what ID we actually used */
trace_config.reg_idr0 = 0x28000EA1;
trace_config.reg_idr1 = 0x4100F403;
@@ -676,6 +691,7 @@ static ocsd_err_t create_decoder_etmv3(dcd_tree_handle_t dcd_tree_h)
{
trace_config_etmv3.reg_trc_id = (uint32_t)test_trc_id_override;
}
+ test_trc_id_override = trace_config_etmv3.reg_trc_id; /* remember what ID we actually used */
/* create an ETMV3 decoder - no context needed as we have a single stream to a single handler. */
return create_generic_decoder(dcd_tree_h,OCSD_BUILTIN_DCD_ETMV3,(void *)&trace_config_etmv3,0);
@@ -701,6 +717,7 @@ static ocsd_err_t create_decoder_ptm(dcd_tree_handle_t dcd_tree_h)
{
trace_config_ptm.reg_trc_id = (uint32_t)test_trc_id_override;
}
+ test_trc_id_override = trace_config_ptm.reg_trc_id; /* remember what ID we actually used */
/* create an PTM decoder - no context needed as we have a single stream to a single handler. */
return create_generic_decoder(dcd_tree_h,OCSD_BUILTIN_DCD_PTM,(void *)&trace_config_ptm,0);
@@ -747,6 +764,7 @@ static ocsd_err_t create_decoder_extern(dcd_tree_handle_t dcd_tree_h)
{
trace_cfg_ext.cs_id = (uint32_t)test_trc_id_override;
}
+ test_trc_id_override = trace_cfg_ext.cs_id;
/* create an external decoder - no context needed as we have a single stream to a single handler. */
return create_generic_decoder(dcd_tree_h, EXT_DCD_NAME, (void *)&trace_cfg_ext, 0);
@@ -874,6 +892,28 @@ ocsd_err_t process_data_block(dcd_tree_handle_t dcd_tree_h, int block_index, uin
return ret;
}
+void print_statistics(dcd_tree_handle_t dcdtree_handle)
+{
+ ocsd_decode_stats_t *p_stats = 0;
+ ocsd_err_t err;
+
+ sprintf(packet_str, "\nReading packet decoder statistics for ID:0x%02x...\n", test_trc_id_override);
+ ocsd_def_errlog_msgout(packet_str);
+
+ err = ocsd_dt_get_decode_stats(dcdtree_handle, test_trc_id_override, &p_stats);
+ if (!err && p_stats)
+ {
+ sprintf(packet_str, "Total Bytes %ld; Unsynced Bytes: %ld\nBad Header Errors: %d; Bad sequence errors: %d\n", p_stats->channel_total,
+ p_stats->channel_unsynced, p_stats->bad_header_errs, p_stats->bad_sequence_errs);
+ ocsd_dt_reset_decode_stats(dcdtree_handle, test_trc_id_override);
+ }
+ else
+ {
+ sprintf(packet_str, "Not available for this ID.\n");
+ }
+ ocsd_def_errlog_msgout(packet_str);
+}
+
int process_trace_data(FILE *pf)
{
ocsd_err_t ret = OCSD_OK;
@@ -936,7 +976,9 @@ int process_trace_data(FILE *pf)
if(ret == OCSD_OK)
ocsd_dt_process_data(dcdtree_handle, OCSD_OP_EOT, 0,0,NULL,NULL);
-
+ if (stats) {
+ print_statistics(dcdtree_handle);
+ }
/* shut down the mem acc CB if in use. */
if(using_mem_acc_cb)
{
@@ -955,6 +997,57 @@ int process_trace_data(FILE *pf)
return (int)ret;
}
+#define ERR_BUFFER_SIZE 256
+int test_err_api()
+{
+ dcd_tree_handle_t dcdtree_handle = C_API_INVALID_TREE_HANDLE;
+ ocsd_err_t ret = OCSD_OK, err_test;
+ ocsd_trc_index_t index = 0, err_index = 0;
+ uint8_t cs_id;
+ char err_buffer[ERR_BUFFER_SIZE];
+
+ /* Create a decode tree for this source data.
+ source data is frame formatted, memory aligned from an ETR (no frame syncs) so create tree accordingly
+ */
+ dcdtree_handle = ocsd_create_dcd_tree(OCSD_TRC_SRC_SINGLE, OCSD_DFRMTR_FRAME_MEM_ALIGN);
+
+ if (dcdtree_handle != C_API_INVALID_TREE_HANDLE)
+ {
+
+ ret = create_decoder(dcdtree_handle);
+ if (ret == OCSD_OK)
+ {
+ /* attach the generic trace element output callback */
+ if (test_lib_printers)
+ ret = ocsd_dt_set_gen_elem_printer(dcdtree_handle);
+ else
+ ret = ocsd_dt_set_gen_elem_outfn(dcdtree_handle, gen_trace_elem_print, 0);
+ }
+
+
+ /* raw print and str print cb options tested in their init functions */
+ if (ret == OCSD_OK)
+ ret = test_printstr_cb(dcdtree_handle);
+
+ if (ret == OCSD_OK)
+ ret = attach_raw_printers(dcdtree_handle);
+
+ /* feed some duff data into a decoder to provoke an error! */
+ uint8_t trace_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x60, 0x71 };
+
+ if (ret == OCSD_OK)
+ ret = process_data_block(dcdtree_handle, index, trace_data, sizeof(trace_data));
+
+ ocsd_err_str(ret, err_buffer, ERR_BUFFER_SIZE);
+ printf("testing error API for code %d: %s\n", ret, err_buffer);
+ err_test = ocsd_get_last_err(&err_index, &cs_id, err_buffer, ERR_BUFFER_SIZE);
+ printf("get last error:\ncode = 0x%02x; trace index %d; cs_id 0x%02x;\nstring: %s\n", err_test, err_index, cs_id, err_buffer);
+
+ }
+ return ret;
+}
+
int main(int argc, char *argv[])
{
FILE *trace_data;
@@ -1012,9 +1105,12 @@ int main(int argc, char *argv[])
ocsd_def_errlog_msgout(message);
/* process the trace data */
- if(ret == 0)
- ret = process_trace_data(trace_data);
-
+ if (ret == 0) {
+ if (test_error_api)
+ ret = test_err_api();
+ else
+ ret = process_trace_data(trace_data);
+ }
/* close the data file */
fclose(trace_data);
}
diff --git a/decoder/tests/source/mem_buff_demo.cpp b/decoder/tests/source/mem_buff_demo.cpp
index cacc227..052870f 100644
--- a/decoder/tests/source/mem_buff_demo.cpp
+++ b/decoder/tests/source/mem_buff_demo.cpp
@@ -126,6 +126,7 @@ static int initDataBuffers()
FILE *fp;
std::string filename;
long size;
+ size_t bytes_read;
/* the file names to create the data buffers */
#ifdef _WIN32
@@ -158,8 +159,10 @@ static int initDataBuffers()
return OCSD_ERR_MEM;
}
rewind(fp);
- fread(input_trace_data, 1, input_trace_data_size, fp);
+ bytes_read = fread(input_trace_data, 1, input_trace_data_size, fp);
fclose(fp);
+ if (bytes_read < (size_t)input_trace_data_size)
+ return OCSD_ERR_FILE_ERROR;
/* load up a memory image */
filename = default_base_snapshot_path;
@@ -178,8 +181,10 @@ static int initDataBuffers()
return OCSD_ERR_MEM;
}
rewind(fp);
- fread(program_image_buffer, 1, program_image_size, fp);
+ bytes_read = fread(program_image_buffer, 1, program_image_size, fp);
fclose(fp);
+ if (bytes_read < (size_t)program_image_size)
+ return OCSD_ERR_FILE_ERROR;
program_image_address = mem_dump_address;
return OCSD_OK;
}
diff --git a/decoder/tests/source/trc_pkt_lister.cpp b/decoder/tests/source/trc_pkt_lister.cpp
index 6c8614e..9760351 100644
--- a/decoder/tests/source/trc_pkt_lister.cpp
+++ b/decoder/tests/source/trc_pkt_lister.cpp
@@ -74,6 +74,7 @@ static bool dstream_format = false;
static bool tpiu_format = false;
static bool has_hsync = false;
static bool src_addr_n = false;
+static bool stats = false;
int main(int argc, char* argv[])
{
@@ -195,6 +196,7 @@ void print_help()
oss << "-o_raw_unpacked Output raw unpacked trace data per ID\n";
oss << "-test_waits <N> Force wait from packet printer for N packets - test the wait/flush mechanisms for the decoder\n";
oss << "-src_addr_n ETE protocol: Split source address ranges on N atoms\n";
+ oss << "-stats Output packet processing statistics (if available).\n";
oss << "\nOutput:\n";
oss << " Setting any of these options cancels the default output to file & stdout,\n using _only_ the options supplied.\n\n";
oss << "-logstdout Output to stdout -> console.\n";
@@ -396,6 +398,10 @@ bool process_cmd_line_opts(int argc, char* argv[])
{
src_addr_n = true;
}
+ else if (strcmp(argv[optIdx], "-stats") == 0)
+ {
+ stats = true;
+ }
else if((strcmp(argv[optIdx], "-help") == 0) || (strcmp(argv[optIdx], "--help") == 0) || (strcmp(argv[optIdx], "-h") == 0))
{
print_help();
@@ -536,6 +542,60 @@ void ConfigureFrameDeMux(DecodeTree *dcd_tree, RawFramePrinter **framePrinter)
}
}
+void PrintDecodeStats(DecodeTree *dcd_tree)
+{
+ uint8_t elemID;
+ std::ostringstream oss;
+ ocsd_decode_stats_t *pStats = 0;
+ ocsd_err_t err;
+ bool gotDemuxStats = false;
+ ocsd_demux_stats_t demux_stats;
+
+ oss << "\nReading packet decoder statistics....\n\n";
+ logger.LogMsg(oss.str());
+
+ DecodeTreeElement *pElement = dcd_tree->getFirstElement(elemID);
+ while (pElement)
+ {
+ oss.str("");
+ err = dcd_tree->getDecoderStats(elemID, &pStats);
+ if (!err && pStats)
+ {
+ oss << "Decode stats ID 0x" << std::hex << (uint32_t)elemID << "\n";
+ oss << "Total Bytes: " << std::dec << pStats->channel_total << "; Unsynced Bytes: " << std::dec << pStats->channel_unsynced << "\n";
+ oss << "Bad Header Errors: " << std::dec << pStats->bad_header_errs << "; Bad Sequence Errors: " << std::dec << pStats->bad_sequence_errs << "\n";
+
+ // demux stats same for all IDs - grab them at the first opportunity..
+ if (!gotDemuxStats) {
+ memcpy(&demux_stats, &pStats->demux, sizeof(ocsd_demux_stats_t));
+ gotDemuxStats = true;
+ }
+
+ }
+ else
+ oss << "Decode stats unavailable on Trace ID 0x" << std::hex << (uint32_t)elemID << "\n";
+
+
+ logger.LogMsg(oss.str());
+ pElement = dcd_tree->getNextElement(elemID);
+ }
+
+ // if we have copied over the stats and there is at least 1 frame byte (impossible for there to be 0 if demuxing)
+ if (gotDemuxStats && demux_stats.frame_bytes) {
+ uint64_t total = demux_stats.valid_id_bytes + demux_stats.no_id_bytes + demux_stats.unknown_id_bytes +
+ demux_stats.reserved_id_bytes + demux_stats.frame_bytes;
+ oss.str("");
+ oss << "\nFrame Demux Stats\n";
+ oss << "Trace data bytes sent to registered ID decoders: " << std::dec << demux_stats.valid_id_bytes << "\n";
+ oss << "Trace data bytes without registered ID decoders: " << std::dec << demux_stats.no_id_bytes << "\n";
+ oss << "Trace data bytes with unknown ID: " << std::dec << demux_stats.unknown_id_bytes << "\n";
+ oss << "Trace data bytes with reserved ID: " << std::dec << demux_stats.reserved_id_bytes << "\n";
+ oss << "Frame demux bytes, ID bytes and sync bytes: " << std::dec << demux_stats.frame_bytes << "\n";
+ oss << "Total bytes processed by frame demux: " << std::dec << total << "\n\n";
+ logger.LogMsg(oss.str());
+ }
+}
+
void ListTracePackets(ocsdDefaultErrorLogger &err_logger, SnapShotReader &reader, const std::string &trace_buffer_name)
{
CreateDcdTreeFromSnapShot tree_creator;
@@ -679,7 +739,8 @@ void ListTracePackets(ocsdDefaultErrorLogger &err_logger, SnapShotReader &reader
std::ostringstream oss;
oss << "Trace Packet Lister : Trace buffer done, processed " << trace_index << " bytes.\n";
logger.LogMsg(oss.str());
-
+ if (stats)
+ PrintDecodeStats(dcd_tree);
}
else
{