The trace decoder library, after it has been initialized, works by being repeatedly called to process data and given a pointer into a data buffer. Each call consumes 0 or more of the buffer, and may result in one or more callbacks to the trace packet handler registered with the decoder. Multiple calls may occur as a trace stream atom can encode multiple branch events, and thus generate multiple trace packets in the decoded trace. The function returns a result code that determines whether it needs to be flushed or decoding can continue (up to the point at which the data buffer has been exhausted).
Signed-off-by: Tor Jeremiassen tor@ti.com --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 60 +++++++++++++++++++++++++ tools/perf/util/cs-etm-decoder/cs-etm-decoder.h | 5 +++ 2 files changed, 65 insertions(+)
diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c index e698387..b277835 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -45,3 +45,63 @@ struct cs_etm_decoder { uint32_t end_tail; struct list_head channel_list; }; + +const struct cs_etm_state * +cs_etm_decoder__process_data_block(struct cs_etm_decoder *decoder, + uint64_t indx, const uint8_t *buf, + size_t len, size_t *consumed) +{ + int ret = 0; + ocsd_datapath_resp_t dp_ret = decoder->prev_return; + size_t processed = 0; + + if (!decoder) + return NULL; + + if (decoder->packet_count > 0) { + decoder->state.err = ret; + *consumed = processed; + return &decoder->state; + } + + while ((processed < len) && (ret == 0)) { + if (OCSD_DATA_RESP_IS_WAIT(dp_ret)) { + dp_ret = ocsd_dt_process_data(decoder->dcd_tree, + OCSD_OP_FLUSH, + 0, + 0, + NULL, + NULL); + break; + } else if (OCSD_DATA_RESP_IS_CONT(dp_ret)) { + uint32_t count; + + dp_ret = ocsd_dt_process_data(decoder->dcd_tree, + OCSD_OP_DATA, + indx + processed, + len - processed, + &buf[processed], + &count); + processed += count; + } else { + ret = -CS_ETM_ERR_DECODER; + } + + } + /* + * Adjust the counts of processed and previously processed + * data based on the return code and previous return code.. + */ + if (OCSD_DATA_RESP_IS_WAIT(dp_ret)) { + if (OCSD_DATA_RESP_IS_CONT(decoder->prev_return)) + decoder->prev_processed = processed; + processed = 0; + } else if (OCSD_DATA_RESP_IS_WAIT(decoder->prev_return)) { + processed = decoder->prev_processed; + decoder->prev_processed = 0; + } + *consumed = processed; + decoder->prev_return = dp_ret; + decoder->state.err = ret; + return &decoder->state; +} diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h index ff4a2c6..9420f0f 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h @@ -104,4 +104,9 @@ enum { CS_ETM_OPERATION_PRINT = 1, CS_ETM_OPERATION_DECODE, }; + +const struct cs_etm_state * +cs_etm_decoder__process_data_block(struct cs_etm_decoder *decoder, + uint64_t indx, const uint8_t *buf, + size_t len, size_t *consumed); #endif /* INCLUDE__CS_ETM_DECODER_H__ */