The trace is decoded by a separate trace decoder library. This patch adds a function that gets a block of trace data and calls the decoder library interface code to decode the trace data. The decoded trace packets are returned in calls to call-back functions that were passed in when the decoder was configured.
Signed-off-by: Tor Jeremiassen tor@ti.com --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 15 +++++++++ tools/perf/util/cs-etm-decoder/cs-etm-decoder.h | 2 ++ tools/perf/util/cs-etm.c | 44 +++++++++++++++++++++++++ tools/perf/util/cs-etm.h | 2 ++ 4 files changed, 63 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 27cf6c2..73218a9 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -76,6 +76,21 @@ int cs_etm_decoder__add_mem_access_cb(struct cs_etm_decoder *decoder, return 0; }
+int cs_etm_decoder__reset(struct cs_etm_decoder *decoder) +{ + ocsd_datapath_resp_t dp_ret; + + if (!decoder) + return -CS_ETM_ERR_PARAM; + + dp_ret = ocsd_dt_process_data(decoder->dcd_tree, OCSD_OP_RESET, + 0, 0, NULL, NULL); + if (OCSD_DATA_RESP_IS_FATAL(dp_ret)) + return -CS_ETM_ERR_DECODER; + + return 0; +} + int cs_etm_decoder__get_packet(struct cs_etm_decoder *decoder, struct cs_etm_packet *packet) { 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 47d9bcf..fb21f6c 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h @@ -124,6 +124,8 @@ int cs_etm_decoder__add_mem_access_cb(struct cs_etm_decoder *decoder, int cs_etm_decoder__get_packet(struct cs_etm_decoder *decoder, struct cs_etm_packet *packet);
+int cs_etm_decoder__reset(struct cs_etm_decoder *decoder); + int cs_etm_decoder__create_etmv4i_decoder(struct cs_etm_decoder_params *d_params, struct cs_etm_trace_params *t_params, diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index d9d3eeb..4073238 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -475,6 +475,50 @@ int cs_etm__sample(struct cs_etm_queue *etmq) return 0; }
+int cs_etm__run_decoder(struct cs_etm_queue *etmq) +{ + struct cs_etm_buffer buffer; + size_t buffer_used; + int err = 0; + + /* Go through each buffer in the queue and decode them one by one */ +more: + buffer_used = 0; + memset(&buffer, 0, sizeof(buffer)); + err = cs_etm__get_trace(&buffer, etmq); + if (err <= 0) + return err; + /* + * cannot assume consecutive blocks in the data file are contiguous + * trace as will have start/stopped. Reset the decoder to force re-sync + */ + err = cs_etm_decoder__reset(etmq->decoder); + if (err != 0) + return err; + + /* run trace decoder until buffer consumed or end of trace */ + do { + size_t processed = 0; + + etmq->state = cs_etm_decoder__process_data_block( + etmq->decoder, + etmq->offset, + &buffer.buf[buffer_used], + buffer.len - buffer_used, + &processed); + err = (!etmq->state) ? -1 : etmq->state->err; + etmq->offset += processed; + buffer_used += processed; + if (err) + return err; + cs_etm__sample(etmq); + + } while (!etmq->eot && (buffer.len > buffer_used)); + +goto more; + return err; +} + int cs_etm__update_queues(struct cs_etm_auxtrace *etm) { if (etm->queues.new_data) { diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h index 54d667c..9bf0c2b 100644 --- a/tools/perf/util/cs-etm.h +++ b/tools/perf/util/cs-etm.h @@ -114,4 +114,6 @@ int cs_etm__sample(struct cs_etm_queue *etmq); int cs_etm__get_trace(struct cs_etm_buffer *buff, struct cs_etm_queue *etmq);
+int cs_etm__run_decoder(struct cs_etm_queue *etmq); + #endif