aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--decoder/include/common/ocsd_dcd_tree.h3
-rw-r--r--decoder/include/common/trc_frame_deformatter.h4
-rw-r--r--decoder/include/common/trc_pkt_proc_base.h3
-rw-r--r--decoder/include/opencsd/ocsd_if_types.h27
-rw-r--r--decoder/source/ocsd_dcd_tree.cpp27
-rw-r--r--decoder/source/trc_frame_deformatter.cpp59
-rw-r--r--decoder/source/trc_frame_deformatter_impl.h14
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;
};