Adds a list structure to the decoder data to allow each decoder CoreSight ID be associated with the callback context.
This allows the tracking of the source of the packets in the perf --dump command.
Signed-off-by: Mike Leach mike.leach@linaro.org --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 59 ++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 5 deletions(-)
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 9e733cd..c616455 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -18,6 +18,7 @@
#include <linux/err.h> #include <stdlib.h> +#include <linux/list.h>
#include "../cs-etm.h" #include "cs-etm-decoder.h" @@ -30,6 +31,13 @@
#define MAX_BUFFER 1024
+struct cs_etm_decoder; + +struct cs_etm_channel { + struct cs_etm_decoder *decoder; + unsigned char cs_id; + struct list_head chan_list; +};
struct cs_etm_decoder @@ -47,8 +55,10 @@ struct cs_etm_decoder uint32_t head; uint32_t tail; uint32_t end_tail; + struct list_head channel_list; };
+ static uint32_t cs_etm_decoder__mem_access(const void *context, const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, @@ -236,9 +246,10 @@ static ocsd_datapath_resp_t cs_etm_decoder__etmv4i_packet_printer( ocsd_datapath_resp_t ret = OCSD_RESP_CONT; char packet_str[PACKET_STR_LEN]; size_t offset; - struct cs_etm_decoder *decoder = (struct cs_etm_decoder *) context; + struct cs_etm_channel *channel = (struct cs_etm_channel *) context; + struct cs_etm_decoder *decoder = channel->decoder;
- sprintf(packet_str,"%ld: ", (long int) indx); + sprintf(packet_str, "%ld: id[%02X] ", (long int) indx, channel->cs_id); offset = strlen(packet_str);
switch(op) { @@ -250,10 +261,16 @@ static ocsd_datapath_resp_t cs_etm_decoder__etmv4i_packet_printer( ret = OCSD_RESP_FATAL_INVALID_PARAM; break; case OCSD_OP_EOT: - sprintf(packet_str,"**** END OF TRACE ****\n"); + sprintf(packet_str, "**** END OF TRACE id[%02X] ****", + channel->cs_id); break; case OCSD_OP_FLUSH: + sprintf(packet_str, "**** FLUSH DECODER id[%02X] ****", + channel->cs_id); + break; case OCSD_OP_RESET: + sprintf(packet_str+offset, "**** RESET DECODER ****"); + break; default: break; } @@ -262,7 +279,22 @@ static ocsd_datapath_resp_t cs_etm_decoder__etmv4i_packet_printer(
return ret; } - + +static struct cs_etm_channel *cs_etm_decoder__create_channel_item( + struct cs_etm_decoder *decoder, unsigned char cs_id) +{ + struct cs_etm_channel *chan; + + chan = (struct cs_etm_channel *)zalloc(sizeof(struct cs_etm_channel)); + if (chan == NULL) + return NULL; + + chan->decoder = decoder; + chan->cs_id = cs_id; + list_add(&(chan->chan_list), &(decoder->channel_list)); + return chan; +} + static int cs_etm_decoder__create_etmv4i_packet_printer(struct cs_etm_decoder_params *d_params, struct cs_etm_trace_params *t_params,
struct cs_etm_decoder *decoder) @@ -270,6 +302,7 @@ static int cs_etm_decoder__create_etmv4i_packet_printer(struct cs_etm_decoder_pa ocsd_etmv4_cfg trace_config; int ret = 0; unsigned char CSID; /* CSID extracted from the config data */ + struct cs_etm_channel *channel;
if (d_params->packet_printer == NULL) return -1; @@ -290,11 +323,15 @@ static int cs_etm_decoder__create_etmv4i_packet_printer(struct cs_etm_decoder_pa if (ret != 0) return -1;
+ channel = cs_etm_decoder__create_channel_item(decoder, CSID); + if (channel == NULL) + return -1; + ret = ocsd_dt_attach_packet_callback(decoder->dcd_tree, CSID, OCSD_C_API_CB_PKT_SINK, cs_etm_decoder__etmv4i_packet_printer, - decoder); + channel); return ret; }
@@ -471,6 +508,9 @@ struct cs_etm_decoder *cs_etm_decoder__new(uint32_t num_cpu, struct cs_etm_decod return NULL; }
+ /* init the channel list */ + INIT_LIST_HEAD(&(decoder->channel_list)); + decoder->state.data = d_params->data; decoder->prev_return = OCSD_RESP_CONT; cs_etm_decoder__clear_buffer(decoder); @@ -528,10 +568,19 @@ struct cs_etm_decoder *cs_etm_decoder__new(uint32_t num_cpu, struct cs_etm_decod
void cs_etm_decoder__free(struct cs_etm_decoder *decoder) { + struct cs_etm_channel *tmp; + struct list_head *pos, *q; + if (decoder == NULL) return;
ocsd_destroy_dcd_tree(decoder->dcd_tree); decoder->dcd_tree = NULL;
+ list_for_each_safe(pos, q, &(decoder->channel_list)) { + tmp = list_entry(pos, struct cs_etm_channel, chan_list); + list_del(pos); + free(tmp); + } + free(decoder); }