diff options
-rw-r--r-- | decoder/include/common/ocsd_dcd_tree.h | 3 | ||||
-rw-r--r-- | decoder/include/common/trc_frame_deformatter.h | 4 | ||||
-rw-r--r-- | decoder/include/common/trc_pkt_proc_base.h | 3 | ||||
-rw-r--r-- | decoder/include/opencsd/ocsd_if_types.h | 27 | ||||
-rw-r--r-- | decoder/source/ocsd_dcd_tree.cpp | 27 | ||||
-rw-r--r-- | decoder/source/trc_frame_deformatter.cpp | 59 | ||||
-rw-r--r-- | decoder/source/trc_frame_deformatter_impl.h | 14 |
7 files changed, 132 insertions, 5 deletions
diff --git a/decoder/include/common/ocsd_dcd_tree.h b/decoder/include/common/ocsd_dcd_tree.h index a7297b2ffeea..b1c3dc601cab 100644 --- a/decoder/include/common/ocsd_dcd_tree.h +++ b/decoder/include/common/ocsd_dcd_tree.h @@ -441,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 e4297a41e8fd..b6476a268e53 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 501397b51595..8ed7d83b2d5a 100644 --- a/decoder/include/common/trc_pkt_proc_base.h +++ b/decoder/include/common/trc_pkt_proc_base.h @@ -444,6 +444,9 @@ template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::resetStats( 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; } /** @}*/ diff --git a/decoder/include/opencsd/ocsd_if_types.h b/decoder/include/opencsd/ocsd_if_types.h index e6fcd45f6e41..5628fec63bee 100644 --- a/decoder/include/opencsd/ocsd_if_types.h +++ b/decoder/include/opencsd/ocsd_if_types.h @@ -633,6 +633,25 @@ 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. @@ -640,15 +659,23 @@ typedef struct _ocsd_swt_info { 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 diff --git a/decoder/source/ocsd_dcd_tree.cpp b/decoder/source/ocsd_dcd_tree.cpp index 88e675c1c8be..b423f7d4eab9 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() @@ -488,10 +495,20 @@ ocsd_err_t DecodeTree::removeDecoder(const uint8_t CSID) 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; - return pPktProc->getStatsBlock(p_stats_block); + 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) @@ -500,6 +517,13 @@ ocsd_err_t DecodeTree::resetDecoderStats(const uint8_t 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; } @@ -577,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/trc_frame_deformatter.cpp b/decoder/source/trc_frame_deformatter.cpp index 4d46854a655b..4f7c40357e7b 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(); @@ -595,6 +596,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 +608,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 +655,7 @@ bool TraceFmtDcdImpl::unpackFrame() /// TBD - ID indexing in here. } + noneDataBytes++; } else // it's just data @@ -671,6 +677,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 +685,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 +726,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 +751,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 +771,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 +913,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..8d19bdb68083 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; }; |