perf report may be called with the -D option to dump the raw trace in ASCII.
This patch adds two functions. One to print the string representation of a trace packet. The other takes an auxtrace buffer and instantiates a trace decoder configured only to parse the trace stream into trace packets and print the packets using the first function. Then pushes the trace data through the instantiated decoder to generate the output.
Signed-off-by: Tor Jeremiassen tor@ti.com --- tools/perf/util/cs-etm.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/cs-etm.h | 6 +++++ 2 files changed, 73 insertions(+)
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 85de61e..e5d02cf 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -81,6 +81,73 @@ struct cs_etm_queue { bool eot; };
+static void cs_etm__packet_dump(const char *pkt_string) +{ + const char *color = PERF_COLOR_BLUE; + + color_fprintf(stdout, color, " %s\n", pkt_string); + fflush(stdout); +} + +void cs_etm__dump_event(struct cs_etm_auxtrace *etm, + struct auxtrace_buffer *buffer) +{ + const char *color = PERF_COLOR_BLUE; + struct cs_etm_decoder_params d_params; + struct cs_etm_trace_params *t_params; + struct cs_etm_decoder *decoder; + size_t buffer_used = 0; + size_t i; + + fprintf(stdout, "\n"); + color_fprintf(stdout, color, + ". ... CoreSight ETM Trace data: size %zu bytes\n", + buffer->size); + + /* Use metadata to fill in trace parameters for trace decoder */ + t_params = zalloc(sizeof(*t_params) * etm->num_cpu); + for (i = 0; i < etm->num_cpu; i++) { + t_params[i].protocol = CS_ETM_PROTO_ETMV4i; + t_params[i].reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0]; + t_params[i].reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1]; + t_params[i].reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2]; + t_params[i].reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8]; + t_params[i].reg_configr = etm->metadata[i][CS_ETMV4_TRCCONFIGR]; + t_params[i].reg_traceidr = + etm->metadata[i][CS_ETMV4_TRCTRACEIDR]; + } + + /* Set decoder parameters to simply print the trace packets */ + d_params.packet_printer = cs_etm__packet_dump; + d_params.operation = CS_ETM_OPERATION_PRINT; + d_params.formatted = true; + d_params.fsyncs = false; + d_params.hsyncs = false; + d_params.frame_aligned = true; + + decoder = cs_etm_decoder__new(etm->num_cpu, &d_params, t_params); + + zfree(&t_params); + + if (!decoder) + return; + do { + size_t consumed; + const struct cs_etm_state *state; + + state = cs_etm_decoder__process_data_block( + decoder, buffer->offset, + &((uint8_t *)buffer->data)[buffer_used], + buffer->size - buffer_used, &consumed); + if (state && state->err) + break; + + buffer_used += consumed; + } while (buffer_used < buffer->size); + + cs_etm_decoder__free(decoder); +} + static int cs_etm__flush_events(struct perf_session *session, struct perf_tool *tool) { diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h index fb5a2de..6139280 100644 --- a/tools/perf/util/cs-etm.h +++ b/tools/perf/util/cs-etm.h @@ -90,4 +90,10 @@ static inline int cs_etm__process_auxtrace_info(union perf_event *event, } #endif
+struct cs_etm_auxtrace; +struct auxtrace_buffer; + +void cs_etm__dump_event(struct cs_etm_auxtrace *etm, + struct auxtrace_buffer *buffer); + #endif