On 13 June 2017 at 02:55, Mike Leach <mike.leach@linaro.org> wrote:
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 | 60 ++++++++++++++++++++++---
 1 file changed, 55 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 e72d207..bbe6923 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 cs_etm_channel   channel_list;

Here all "channel_list" is used for is to hold the list_head "chan_list".  As such this should be a "struct list_head" rather than a "struct cs_etm_channel".  

 
 };

+
 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,17 @@ 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, "**** RESET DECODER id[%02X] ****",
+                       channel->cs_id);
+               break;
         default:
                 break;
         }
@@ -262,7 +280,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.chan_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 +303,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 +324,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 +509,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.chan_list));
+
         decoder->state.data = d_params->data;
         decoder->prev_return = OCSD_RESP_CONT;
         cs_etm_decoder__clear_buffer(decoder);
@@ -527,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.chan_list)) {
+               tmp = list_entry(pos, struct cs_etm_channel, chan_list);
+               list_del(pos);
+               free(tmp);
+       }
+
         free(decoder);
 }
--
2.7.4