Hi,
On Thu, 4 Apr 2019 at 04:36, Mathieu Poirier mathieu.poirier@linaro.org wrote:
Configure timestamps to be emitted at regular intervals in the trace stream to temporally correlate instructions executed on different CPUs.
Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org
drivers/hwtracing/coresight/coresight-etm4x.c | 101 +++++++++++++++++- 1 file changed, 100 insertions(+), 1 deletion(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index d64192c29860..46d337fd8442 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -204,6 +204,90 @@ static void etm4_enable_hw_smp_call(void *info) arg->rc = etm4_enable_hw(arg->drvdata); }
+/*
- The goal of function etm4_config_timestamp_event() is to configure a
 
- counter that will tell the tracer to emit a timestamp packet when it
 
- reaches zero. This is done in order to get a more fine grained idea
 
- of when instructions are executed so that they can be correlated
 
- with execution on other CPUs.
 
- To do this the counter itself is configured to self reload and
 
- TRCRSCTLR1 (always true) used to get the counter to decrement. From
 
- there a resource selector is configured with the counter and the
 
- timestamp control register to use the resource selector to trigger the
 
- event that will insert a timestamp packet in the stream.
 - */
 +static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata) +{
int ctridx, ret = -EINVAL;int counter, rselector;u32 val = 0;struct etmv4_config *config = &drvdata->config;/* No point in trying if we don't have at least one counter */if (!drvdata->nr_cntr)goto out;/* Find a counter that hasn't been initialised */for (ctridx = 0; ctridx < drvdata->nr_cntr; ctridx++)if (config->cntr_val[ctridx] == 0)break;/* All the counters have been configured already, bail out */if (ctridx == drvdata->nr_cntr) {pr_debug("%s: no available counter found\n", __func__);ret = -ENOSPC;goto out;}/** Searching for an available resource selector to use, starting at* '2' since every implementation has at least 2 resource selector.* ETMIDR4 gives the number of resource selector _pairs_,* hence multiply by 2.*/for (rselector = 2; rselector < drvdata->nr_resource * 2; rselector++)if (!config->res_ctrl[rselector])break;if (rselector == drvdata->nr_resource * 2) {pr_debug("%s: no available resource selector found\n", __func__);ret = -ENOSPC;goto out;}/* Remember what counter we used */counter = 1 << ctridx;/** Initialise original and reload counter value to the smallest* possible value in order to get as much precision as we can.*/config->cntr_val[ctridx] = 1;config->cntrldvr[ctridx] = 1;/* Set the trace counter control register */val = 0x1 << 16 | /* Bit 16, reload counter automatically */0x0 << 7 | /* Select single resource selector */0x1; /* Resource selector 1, i.e always true */config->cntr_ctrl[ctridx] = val;val = 0x2 << 16 | /* Group 0b0010 - Counter and sequencers */counter << 0; /* Counter to use */config->res_ctrl[rselector] = val;val = 0x0 << 7 | /* Select single resource selector */rselector; /* Resource selector */config->ts_ctrl = val;ret = 0;+out:
return ret;+}
static int etm4_parse_event_config(struct etmv4_drvdata *drvdata, struct perf_event *event) { @@ -239,9 +323,24 @@ static int etm4_parse_event_config(struct etmv4_drvdata *drvdata, /* TRM: Must program this for cycacc to work */ config->ccctlr = ETM_CYC_THRESHOLD_DEFAULT; }
if (attr->config & BIT(ETM_OPT_TS))
if (attr->config & BIT(ETM_OPT_TS)) {/** Configure timestamps to be emitted at regular intervals in* order to correlate instructions executed on different CPUs* (CPU-wide trace scenarios).*/ret = etm4_config_timestamp_event(drvdata);/** No need to go further if timestamp intervals can't* be configured.*/if (ret)goto out;/* bit[11], Global timestamp tracing bit */ config->cfg |= BIT(11);}
Here you are committing _all_ timestamp usage to be the "hi-freq" timestamp required for all CPU - wide perf support. This increases the amount of non-instruction trace - and my not be desirable in all cases - especially if cycle counts are live as well. Perhaps define a new ETM_OPT_FREQ_TS which will switch on TS + trigger counters, and leave ETM_OPT_TS for standard timestamps.
Mike
if (attr->config & BIT(ETM_OPT_CTXTID)) /* bit[6], Context ID tracing bit */-- 2.17.1
CoreSight mailing list CoreSight@lists.linaro.org https://lists.linaro.org/mailman/listinfo/coresight