On Fri, Sep 22, 2017 at 04:03:31AM -0500, Tor Jeremiassen wrote:
Each decoded trace sample encodes the execution of a sequence of instructions between to "waypoints", typically a branch target and the next taken branch. This sample has to be converted into a perf sample struct before it can be passed on to the perf subsystem.
This patch adds two functions that take a decoded trace packet and populate the perf sample structure and pass it on to perf session event processing. It also adds a function in the decoder library interface to return a decoded trace packet.
Is it me or the title of the patch doesn't really match the description? Am I missing something?
Signed-off-by: Tor Jeremiassen tor@ti.com
tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 21 ++++++++ tools/perf/util/cs-etm-decoder/cs-etm-decoder.h | 3 ++ tools/perf/util/cs-etm.c | 64 +++++++++++++++++++++++++ tools/perf/util/cs-etm.h | 2 + 4 files changed, 90 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 cfd18ec..e46ce59 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -86,6 +86,27 @@ int cs_etm_decoder__add_mem_access_cb(struct cs_etm_decoder *decoder, return 0; } +int cs_etm_decoder__get_packet(struct cs_etm_decoder *decoder,
struct cs_etm_packet *packet)
+{
- if (!decoder)
return -CS_ETM_ERR_PARAM;
- if (decoder->packet_count == 0)
return -CS_ETM_ERR_NODATA;
- if (!packet)
return -CS_ETM_ERR_PARAM;
- *packet = decoder->packet_buffer[decoder->head];
- decoder->head = (decoder->head + 1) & (MAX_BUFFER - 1);
- decoder->packet_count--;
- return 0;
+}
const struct cs_etm_state * cs_etm_decoder__process_data_block(struct cs_etm_decoder *decoder, uint64_t indx, const uint8_t *buf, 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 b53dbed..259059b 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h @@ -126,6 +126,9 @@ int cs_etm_decoder__add_mem_access_cb(struct cs_etm_decoder *decoder, uint64_t start, uint64_t end, cs_etm_mem_cb_type cb_func); +int cs_etm_decoder__get_packet(struct cs_etm_decoder *decoder,
struct cs_etm_packet *packet);
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 0516301..72c4c9d 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -334,6 +334,70 @@ static int cs_etm__setup_queues(struct cs_etm_auxtrace *etm) return 0; } +/*
- The cs etm packet encodes an instruction range between a branch target
- and the next taken branch. Generate sample accordingly.
- */
+static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
struct cs_etm_packet *packet)
+{
- int ret = 0;
- struct cs_etm_auxtrace *etm = etmq->etm;
- union perf_event *event = etmq->event_buf;
- struct perf_sample sample = {.ip = 0,};
- uint64_t start_addr = packet->start_addr;
- uint64_t end_addr = packet->end_addr;
- event->sample.header.type = PERF_RECORD_SAMPLE;
- event->sample.header.misc = PERF_RECORD_MISC_USER;
- event->sample.header.size = sizeof(struct perf_event_header);
- sample.ip = start_addr;
- sample.pid = etmq->pid;
- sample.tid = etmq->tid;
- sample.addr = end_addr;
- sample.id = etmq->etm->instructions_id;
- sample.stream_id = etmq->etm->instructions_id;
- /* approximate the period to be the number of words in the range */
- sample.period = (end_addr - start_addr) >> 2;
- sample.cpu = packet->cpu;
- sample.flags = 0;
- sample.insn_len = 1;
- sample.cpumode = event->header.misc;
- ret = perf_session__deliver_synth_event(etm->session, event, &sample);
- if (ret)
pr_err(
"CS ETM Trace: failed to deliver instruction event, error %d\n",
ret);
- return ret;
+}
+int cs_etm__sample(struct cs_etm_queue *etmq) +{
- struct cs_etm_packet packet;
- int err;
- err = cs_etm_decoder__get_packet(etmq->decoder, &packet);
- /* if there is no sample, it returns err = -1, no real error */
- if (err)
return err;
- /*
* if the packet contains an instruction range, generate
* an instruction sequence event
*/
- if (packet.sample_type & CS_ETM_RANGE) {
err = cs_etm__synth_instruction_sample(etmq, &packet);
if (err)
return err;
- }
- return 0;
+}
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 d1cb049..aa7e0d4 100644 --- a/tools/perf/util/cs-etm.h +++ b/tools/perf/util/cs-etm.h @@ -108,4 +108,6 @@ struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm, int cs_etm__update_queues(struct cs_etm_auxtrace *etm); +int cs_etm__sample(struct cs_etm_queue *etmq);
#endif
2.7.4
CoreSight mailing list CoreSight@lists.linaro.org https://lists.linaro.org/mailman/listinfo/coresight