This set _should_ add support for ETMv3/PTM1.1 trace decoding. It was produced close to two years ago on top of a code base that no longer exist. At the time though, it did work.
So I've rebased the work to the current coresight next branch. It apply and compiles cleanly but other than that, I can't offer any guarantee of proper operation. I am currently traveling and don't have access to a platform where it can be tested. Even if I was, I do not have the bandwidth to work on the feature.
As such I am releasing it on this list, in the hope that it can help someone get started with trace decoding on ETMv3/PTM1.1.
Let me know how bad it crashes.
Mathieu
Mathieu Poirier (3): perf tools: Add configuration for ETMv3 trace protocol perf tools: Add support for ETMv3 trace decoding perf tools: Add support for PTMv1.1 decoding
tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 31 +++++++++++ tools/perf/util/cs-etm-decoder/cs-etm-decoder.h | 9 +++ tools/perf/util/cs-etm.c | 73 ++++++++++++++++++++----- 3 files changed, 99 insertions(+), 14 deletions(-)
This patch deals with the proper initialisation of configuration parameters for the ETMv3 trace protocol in order to properly handle packets generated by tracers following this specification.
Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.h | 8 ++++ tools/perf/util/cs-etm.c | 54 ++++++++++++++++++------- 2 files changed, 48 insertions(+), 14 deletions(-)
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 612b5755f742..c0c67c919093 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h @@ -43,6 +43,13 @@ struct cs_etm_queue; typedef u32 (*cs_etm_mem_cb_type)(struct cs_etm_queue *, u64, size_t, u8 *);
+struct cs_etmv3_trace_params { + u32 reg_ctrl; + u32 reg_trc_id; + u32 reg_ccer; + u32 reg_idr; +}; + struct cs_etmv4_trace_params { u32 reg_idr0; u32 reg_idr1; @@ -55,6 +62,7 @@ struct cs_etmv4_trace_params { struct cs_etm_trace_params { int protocol; union { + struct cs_etmv3_trace_params etmv3; struct cs_etmv4_trace_params etmv4; }; }; diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 2ae640257fdb..17edc22e1b5b 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -122,15 +122,28 @@ static void cs_etm__dump_event(struct cs_etm_auxtrace *etm, /* 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].etmv4.reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0]; - t_params[i].etmv4.reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1]; - t_params[i].etmv4.reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2]; - t_params[i].etmv4.reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8]; - t_params[i].etmv4.reg_configr = + if (etm->metadata[i][CS_ETM_MAGIC] == __perf_cs_etmv3_magic) { + t_params[i].protocol = CS_ETM_PROTO_ETMV3; + t_params[i].etmv3.reg_ctrl = + etm->metadata[i][CS_ETM_ETMCR]; + t_params[i].etmv3.reg_trc_id = + etm->metadata[i][CS_ETM_ETMTRACEIDR]; + } else if (etm->metadata[i][CS_ETM_MAGIC] == + __perf_cs_etmv4_magic) { + t_params[i].protocol = CS_ETM_PROTO_ETMV4i; + t_params[i].etmv4.reg_idr0 = + etm->metadata[i][CS_ETMV4_TRCIDR0]; + t_params[i].etmv4.reg_idr1 = + etm->metadata[i][CS_ETMV4_TRCIDR1]; + t_params[i].etmv4.reg_idr2 = + etm->metadata[i][CS_ETMV4_TRCIDR2]; + t_params[i].etmv4.reg_idr8 = + etm->metadata[i][CS_ETMV4_TRCIDR8]; + t_params[i].etmv4.reg_configr = etm->metadata[i][CS_ETMV4_TRCCONFIGR]; - t_params[i].etmv4.reg_traceidr = + t_params[i].etmv4.reg_traceidr = etm->metadata[i][CS_ETMV4_TRCTRACEIDR]; + } }
/* Set decoder parameters to simply print the trace packets */ @@ -342,15 +355,28 @@ static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm, goto out_free;
for (i = 0; i < etm->num_cpu; i++) { - t_params[i].protocol = CS_ETM_PROTO_ETMV4i; - t_params[i].etmv4.reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0]; - t_params[i].etmv4.reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1]; - t_params[i].etmv4.reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2]; - t_params[i].etmv4.reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8]; - t_params[i].etmv4.reg_configr = + if (etm->metadata[i][CS_ETM_MAGIC] == __perf_cs_etmv3_magic) { + t_params[i].protocol = CS_ETM_PROTO_ETMV3; + t_params[i].etmv3.reg_ctrl = + etm->metadata[i][CS_ETM_ETMCR]; + t_params[i].etmv3.reg_trc_id = + etm->metadata[i][CS_ETM_ETMTRACEIDR]; + } else if (etm->metadata[i][CS_ETM_MAGIC] == + __perf_cs_etmv4_magic) { + t_params[i].protocol = CS_ETM_PROTO_ETMV4i; + t_params[i].etmv4.reg_idr0 = + etm->metadata[i][CS_ETMV4_TRCIDR0]; + t_params[i].etmv4.reg_idr1 = + etm->metadata[i][CS_ETMV4_TRCIDR1]; + t_params[i].etmv4.reg_idr2 = + etm->metadata[i][CS_ETMV4_TRCIDR2]; + t_params[i].etmv4.reg_idr8 = + etm->metadata[i][CS_ETMV4_TRCIDR8]; + t_params[i].etmv4.reg_configr = etm->metadata[i][CS_ETMV4_TRCCONFIGR]; - t_params[i].etmv4.reg_traceidr = + t_params[i].etmv4.reg_traceidr = etm->metadata[i][CS_ETMV4_TRCTRACEIDR]; + } }
/* Set decoder parameters to simply print the trace packets */
Hi Mathieu,
On Wed, Sep 19, 2018 at 04:50:41PM -0600, Mathieu Poirier wrote:
This patch deals with the proper initialisation of configuration parameters for the ETMv3 trace protocol in order to properly handle packets generated by tracers following this specification.
Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org
tools/perf/util/cs-etm-decoder/cs-etm-decoder.h | 8 ++++ tools/perf/util/cs-etm.c | 54 ++++++++++++++++++------- 2 files changed, 48 insertions(+), 14 deletions(-)
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 612b5755f742..c0c67c919093 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h @@ -43,6 +43,13 @@ struct cs_etm_queue; typedef u32 (*cs_etm_mem_cb_type)(struct cs_etm_queue *, u64, size_t, u8 *); +struct cs_etmv3_trace_params {
- u32 reg_ctrl;
- u32 reg_trc_id;
- u32 reg_ccer;
- u32 reg_idr;
+};
struct cs_etmv4_trace_params { u32 reg_idr0; u32 reg_idr1; @@ -55,6 +62,7 @@ struct cs_etmv4_trace_params { struct cs_etm_trace_params { int protocol; union {
struct cs_etmv4_trace_params etmv4; };struct cs_etmv3_trace_params etmv3;
}; diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 2ae640257fdb..17edc22e1b5b 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -122,15 +122,28 @@ static void cs_etm__dump_event(struct cs_etm_auxtrace *etm, /* 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].etmv4.reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0];
t_params[i].etmv4.reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1];
t_params[i].etmv4.reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2];
t_params[i].etmv4.reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8];
t_params[i].etmv4.reg_configr =
if (etm->metadata[i][CS_ETM_MAGIC] == __perf_cs_etmv3_magic) {
t_params[i].protocol = CS_ETM_PROTO_ETMV3;
t_params[i].etmv3.reg_ctrl =
etm->metadata[i][CS_ETM_ETMCR];
t_params[i].etmv3.reg_trc_id =
etm->metadata[i][CS_ETM_ETMTRACEIDR];
Nitpick: we can see the two variables 't_params[i].etmv3.reg_ccer' and 't_params[i].etmv3.reg_idr' are missed to copy value from etm->metadata; on the other hand we need pass these two fields for decoder configuration in 0002 patch. Should here need to copy reg_ccer and reg_idr as well?
} else if (etm->metadata[i][CS_ETM_MAGIC] ==
__perf_cs_etmv4_magic) {
t_params[i].protocol = CS_ETM_PROTO_ETMV4i;
t_params[i].etmv4.reg_idr0 =
etm->metadata[i][CS_ETMV4_TRCIDR0];
t_params[i].etmv4.reg_idr1 =
etm->metadata[i][CS_ETMV4_TRCIDR1];
t_params[i].etmv4.reg_idr2 =
etm->metadata[i][CS_ETMV4_TRCIDR2];
t_params[i].etmv4.reg_idr8 =
etm->metadata[i][CS_ETMV4_TRCIDR8];
t_params[i].etmv4.reg_configr = etm->metadata[i][CS_ETMV4_TRCCONFIGR];
t_params[i].etmv4.reg_traceidr =
t_params[i].etmv4.reg_traceidr = etm->metadata[i][CS_ETMV4_TRCTRACEIDR];
}}
/* Set decoder parameters to simply print the trace packets */ @@ -342,15 +355,28 @@ static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm, goto out_free; for (i = 0; i < etm->num_cpu; i++) {
t_params[i].protocol = CS_ETM_PROTO_ETMV4i;
t_params[i].etmv4.reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0];
t_params[i].etmv4.reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1];
t_params[i].etmv4.reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2];
t_params[i].etmv4.reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8];
t_params[i].etmv4.reg_configr =
if (etm->metadata[i][CS_ETM_MAGIC] == __perf_cs_etmv3_magic) {
t_params[i].protocol = CS_ETM_PROTO_ETMV3;
t_params[i].etmv3.reg_ctrl =
etm->metadata[i][CS_ETM_ETMCR];
t_params[i].etmv3.reg_trc_id =
etm->metadata[i][CS_ETM_ETMTRACEIDR];
} else if (etm->metadata[i][CS_ETM_MAGIC] ==
__perf_cs_etmv4_magic) {
t_params[i].protocol = CS_ETM_PROTO_ETMV4i;
t_params[i].etmv4.reg_idr0 =
etm->metadata[i][CS_ETMV4_TRCIDR0];
t_params[i].etmv4.reg_idr1 =
etm->metadata[i][CS_ETMV4_TRCIDR1];
t_params[i].etmv4.reg_idr2 =
etm->metadata[i][CS_ETMV4_TRCIDR2];
t_params[i].etmv4.reg_idr8 =
etm->metadata[i][CS_ETMV4_TRCIDR8];
t_params[i].etmv4.reg_configr = etm->metadata[i][CS_ETMV4_TRCCONFIGR];
t_params[i].etmv4.reg_traceidr =
t_params[i].etmv4.reg_traceidr = etm->metadata[i][CS_ETMV4_TRCTRACEIDR];
}}
/* Set decoder parameters to simply print the trace packets */ -- 2.7.4
CoreSight mailing list CoreSight@lists.linaro.org https://lists.linaro.org/mailman/listinfo/coresight
On Mon, 24 Sep 2018 at 21:07, leo.yan@linaro.org wrote:
Hi Mathieu,
On Wed, Sep 19, 2018 at 04:50:41PM -0600, Mathieu Poirier wrote:
This patch deals with the proper initialisation of configuration parameters for the ETMv3 trace protocol in order to properly handle packets generated by tracers following this specification.
Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org
tools/perf/util/cs-etm-decoder/cs-etm-decoder.h | 8 ++++ tools/perf/util/cs-etm.c | 54 ++++++++++++++++++------- 2 files changed, 48 insertions(+), 14 deletions(-)
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 612b5755f742..c0c67c919093 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h @@ -43,6 +43,13 @@ struct cs_etm_queue; typedef u32 (*cs_etm_mem_cb_type)(struct cs_etm_queue *, u64, size_t, u8 *);
+struct cs_etmv3_trace_params {
u32 reg_ctrl;
u32 reg_trc_id;
u32 reg_ccer;
u32 reg_idr;
+};
struct cs_etmv4_trace_params { u32 reg_idr0; u32 reg_idr1; @@ -55,6 +62,7 @@ struct cs_etmv4_trace_params { struct cs_etm_trace_params { int protocol; union {
struct cs_etmv3_trace_params etmv3; struct cs_etmv4_trace_params etmv4; };
}; diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 2ae640257fdb..17edc22e1b5b 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -122,15 +122,28 @@ static void cs_etm__dump_event(struct cs_etm_auxtrace *etm, /* 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].etmv4.reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0];
t_params[i].etmv4.reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1];
t_params[i].etmv4.reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2];
t_params[i].etmv4.reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8];
t_params[i].etmv4.reg_configr =
if (etm->metadata[i][CS_ETM_MAGIC] == __perf_cs_etmv3_magic) {
t_params[i].protocol = CS_ETM_PROTO_ETMV3;
t_params[i].etmv3.reg_ctrl =
etm->metadata[i][CS_ETM_ETMCR];
t_params[i].etmv3.reg_trc_id =
etm->metadata[i][CS_ETM_ETMTRACEIDR];
Nitpick: we can see the two variables 't_params[i].etmv3.reg_ccer' and 't_params[i].etmv3.reg_idr' are missed to copy value from etm->metadata; on the other hand we need pass these two fields for decoder configuration in 0002 patch. Should here need to copy reg_ccer and reg_idr as well?
Really good observation - thanks for pointing that out.
Mathieu
} else if (etm->metadata[i][CS_ETM_MAGIC] ==
__perf_cs_etmv4_magic) {
t_params[i].protocol = CS_ETM_PROTO_ETMV4i;
t_params[i].etmv4.reg_idr0 =
etm->metadata[i][CS_ETMV4_TRCIDR0];
t_params[i].etmv4.reg_idr1 =
etm->metadata[i][CS_ETMV4_TRCIDR1];
t_params[i].etmv4.reg_idr2 =
etm->metadata[i][CS_ETMV4_TRCIDR2];
t_params[i].etmv4.reg_idr8 =
etm->metadata[i][CS_ETMV4_TRCIDR8];
t_params[i].etmv4.reg_configr = etm->metadata[i][CS_ETMV4_TRCCONFIGR];
t_params[i].etmv4.reg_traceidr =
t_params[i].etmv4.reg_traceidr = etm->metadata[i][CS_ETMV4_TRCTRACEIDR];
} } /* Set decoder parameters to simply print the trace packets */
@@ -342,15 +355,28 @@ static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm, goto out_free;
for (i = 0; i < etm->num_cpu; i++) {
t_params[i].protocol = CS_ETM_PROTO_ETMV4i;
t_params[i].etmv4.reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0];
t_params[i].etmv4.reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1];
t_params[i].etmv4.reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2];
t_params[i].etmv4.reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8];
t_params[i].etmv4.reg_configr =
if (etm->metadata[i][CS_ETM_MAGIC] == __perf_cs_etmv3_magic) {
t_params[i].protocol = CS_ETM_PROTO_ETMV3;
t_params[i].etmv3.reg_ctrl =
etm->metadata[i][CS_ETM_ETMCR];
t_params[i].etmv3.reg_trc_id =
etm->metadata[i][CS_ETM_ETMTRACEIDR];
} else if (etm->metadata[i][CS_ETM_MAGIC] ==
__perf_cs_etmv4_magic) {
t_params[i].protocol = CS_ETM_PROTO_ETMV4i;
t_params[i].etmv4.reg_idr0 =
etm->metadata[i][CS_ETMV4_TRCIDR0];
t_params[i].etmv4.reg_idr1 =
etm->metadata[i][CS_ETMV4_TRCIDR1];
t_params[i].etmv4.reg_idr2 =
etm->metadata[i][CS_ETMV4_TRCIDR2];
t_params[i].etmv4.reg_idr8 =
etm->metadata[i][CS_ETMV4_TRCIDR8];
t_params[i].etmv4.reg_configr = etm->metadata[i][CS_ETMV4_TRCCONFIGR];
t_params[i].etmv4.reg_traceidr =
t_params[i].etmv4.reg_traceidr = etm->metadata[i][CS_ETMV4_TRCTRACEIDR];
} } /* Set decoder parameters to simply print the trace packets */
-- 2.7.4
CoreSight mailing list CoreSight@lists.linaro.org https://lists.linaro.org/mailman/listinfo/coresight
Add support for the creation of packet printer and decoder for the ETMv3 trace architecture. That way traces generated by tracers adhering to that trace protocol can be handled properly by the perf infrastructure.
Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 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 938def6d0bb9..84a86d2f25c9 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -116,6 +116,19 @@ int cs_etm_decoder__get_packet(struct cs_etm_decoder *decoder, return 1; }
+static int cs_etm_decoder__gen_etmv3_config(struct cs_etm_trace_params *params, + ocsd_etmv3_cfg *config) +{ + config->reg_idr = params->etmv3.reg_idr; + config->reg_ctrl = params->etmv3.reg_ctrl; + config->reg_ccer = params->etmv3.reg_ccer; + config->reg_trc_id = params->etmv3.reg_trc_id; + config->arch_ver = ARCH_V7; + config->core_prof = profile_CortexA; + + return 0; +} + static void cs_etm_decoder__gen_etmv4_config(struct cs_etm_trace_params *params, ocsd_etmv4_cfg *config) { @@ -237,10 +250,16 @@ cs_etm_decoder__create_etm_packet_printer(struct cs_etm_trace_params *t_params, struct cs_etm_decoder *decoder) { const char *decoder_name; + ocsd_etmv3_cfg config_etmv3; ocsd_etmv4_cfg trace_config_etmv4; void *trace_config;
switch (t_params->protocol) { + case CS_ETM_PROTO_ETMV3: + cs_etm_decoder__gen_etmv3_config(t_params, &config_etmv3); + decoder_name = OCSD_BUILTIN_DCD_ETMV3; + trace_config = &config_etmv3; + break; case CS_ETM_PROTO_ETMV4i: cs_etm_decoder__gen_etmv4_config(t_params, &trace_config_etmv4); decoder_name = OCSD_BUILTIN_DCD_ETMV4I; @@ -398,11 +417,17 @@ static int cs_etm_decoder__create_etm_packet_decoder( struct cs_etm_decoder *decoder) { const char *decoder_name; + ocsd_etmv3_cfg config_etmv3; ocsd_etmv4_cfg trace_config_etmv4; void *trace_config; u8 csid;
switch (t_params->protocol) { + case CS_ETM_PROTO_ETMV3: + cs_etm_decoder__gen_etmv3_config(t_params, &config_etmv3); + decoder_name = OCSD_BUILTIN_DCD_ETMV3; + trace_config = &config_etmv3; + break; case CS_ETM_PROTO_ETMV4i: cs_etm_decoder__gen_etmv4_config(t_params, &trace_config_etmv4); decoder_name = OCSD_BUILTIN_DCD_ETMV4I;
This patch is re-using the mechanic set forth by ETMv3 to add support for PTM decoding. Configuration for both encoding protocol is similar but the generated stream itself is very different, hence requiring special handling.
Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 10 ++++++++-- tools/perf/util/cs-etm-decoder/cs-etm-decoder.h | 1 + tools/perf/util/cs-etm.c | 23 +++++++++++++++++++++-- 3 files changed, 30 insertions(+), 4 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 84a86d2f25c9..de8d792bc49d 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -256,8 +256,11 @@ cs_etm_decoder__create_etm_packet_printer(struct cs_etm_trace_params *t_params,
switch (t_params->protocol) { case CS_ETM_PROTO_ETMV3: + case CS_ETM_PROTO_PTM: cs_etm_decoder__gen_etmv3_config(t_params, &config_etmv3); - decoder_name = OCSD_BUILTIN_DCD_ETMV3; + decoder_name = (t_params->protocol == CS_ETM_PROTO_ETMV3) ? + OCSD_BUILTIN_DCD_ETMV3 : + OCSD_BUILTIN_DCD_PTM; trace_config = &config_etmv3; break; case CS_ETM_PROTO_ETMV4i: @@ -424,8 +427,11 @@ static int cs_etm_decoder__create_etm_packet_decoder(
switch (t_params->protocol) { case CS_ETM_PROTO_ETMV3: + case CS_ETM_PROTO_PTM: cs_etm_decoder__gen_etmv3_config(t_params, &config_etmv3); - decoder_name = OCSD_BUILTIN_DCD_ETMV3; + decoder_name = (t_params->protocol == CS_ETM_PROTO_ETMV3) ? + OCSD_BUILTIN_DCD_ETMV3 : + OCSD_BUILTIN_DCD_PTM; trace_config = &config_etmv3; break; case CS_ETM_PROTO_ETMV4i: 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 c0c67c919093..029e66b968a6 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h @@ -86,6 +86,7 @@ enum { CS_ETM_PROTO_ETMV3 = 1, CS_ETM_PROTO_ETMV4i, CS_ETM_PROTO_ETMV4d, + CS_ETM_PROTO_PTM, };
enum { diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 17edc22e1b5b..482bcc36b7d8 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -91,6 +91,19 @@ static int cs_etm__update_queues(struct cs_etm_auxtrace *etm); static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm, pid_t tid, u64 time_);
+/* PTMs ETMIDR [11:8] set to b0011 */ +#define ETMIDR_PTM_VERSION 0x00000300 + +static u32 cs_etm__get_v7_protocol_version(u32 etmidr) +{ + etmidr &= ETMIDR_PTM_VERSION; + + if (etmidr == ETMIDR_PTM_VERSION) + return ETMIDR_PTM_VERSION; + + return CS_ETM_PROTO_ETMV3; +} + static void cs_etm__packet_dump(const char *pkt_string) { const char *color = PERF_COLOR_BLUE; @@ -123,7 +136,10 @@ static void cs_etm__dump_event(struct cs_etm_auxtrace *etm, t_params = zalloc(sizeof(*t_params) * etm->num_cpu); for (i = 0; i < etm->num_cpu; i++) { if (etm->metadata[i][CS_ETM_MAGIC] == __perf_cs_etmv3_magic) { - t_params[i].protocol = CS_ETM_PROTO_ETMV3; + u32 etmidr = etm->metadata[i][CS_ETM_ETMIDR]; + + t_params[i].protocol = + cs_etm__get_v7_protocol_version(etmidr); t_params[i].etmv3.reg_ctrl = etm->metadata[i][CS_ETM_ETMCR]; t_params[i].etmv3.reg_trc_id = @@ -356,7 +372,10 @@ static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm,
for (i = 0; i < etm->num_cpu; i++) { if (etm->metadata[i][CS_ETM_MAGIC] == __perf_cs_etmv3_magic) { - t_params[i].protocol = CS_ETM_PROTO_ETMV3; + u32 etmidr = etm->metadata[i][CS_ETM_ETMIDR]; + + t_params[i].protocol = + cs_etm__get_v7_protocol_version(etmidr); t_params[i].etmv3.reg_ctrl = etm->metadata[i][CS_ETM_ETMCR]; t_params[i].etmv3.reg_trc_id =