in coresight/coresight-etm4x-core.c [607:697]
static int etm4_parse_event_config(struct coresight_device *csdev,
struct perf_event *event)
{
int ret = 0;
struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
struct etmv4_config *config = &drvdata->config;
struct perf_event_attr *attr = &event->attr;
unsigned long cfg_hash;
int preset;
/* Clear configuration from previous run */
memset(config, 0, sizeof(struct etmv4_config));
if (attr->exclude_kernel)
config->mode = ETM_MODE_EXCL_KERN;
if (attr->exclude_user)
config->mode = ETM_MODE_EXCL_USER;
/* Always start from the default config */
etm4_set_default_config(config);
/* Configure filters specified on the perf cmd line, if any. */
ret = etm4_set_event_filters(drvdata, event);
if (ret)
goto out;
/* Go from generic option to ETMv4 specifics */
if (attr->config & BIT(ETM_OPT_CYCACC)) {
config->cfg |= BIT(4);
/* TRM: Must program this for cycacc to work */
config->ccctlr = ETM_CYC_THRESHOLD_DEFAULT;
}
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);
}
if (attr->config & BIT(ETM_OPT_CTXTID))
/* bit[6], Context ID tracing bit */
config->cfg |= BIT(ETM4_CFG_BIT_CTXTID);
/*
* If set bit ETM_OPT_CTXTID2 in perf config, this asks to trace VMID
* for recording CONTEXTIDR_EL2. Do not enable VMID tracing if the
* kernel is not running in EL2.
*/
if (attr->config & BIT(ETM_OPT_CTXTID2)) {
if (!is_kernel_in_hyp_mode()) {
ret = -EINVAL;
goto out;
}
config->cfg |= BIT(ETM4_CFG_BIT_VMID) | BIT(ETM4_CFG_BIT_VMID_OPT);
}
/* return stack - enable if selected and supported */
if ((attr->config & BIT(ETM_OPT_RETSTK)) && drvdata->retstack)
/* bit[12], Return stack enable bit */
config->cfg |= BIT(12);
/*
* Set any selected configuration and preset.
*
* This extracts the values of PMU_FORMAT_ATTR(configid) and PMU_FORMAT_ATTR(preset)
* in the perf attributes defined in coresight-etm-perf.c.
* configid uses bits 63:32 of attr->config2, preset uses bits 3:0 of attr->config.
* A zero configid means no configuration active, preset = 0 means no preset selected.
*/
if (attr->config2 & GENMASK_ULL(63, 32)) {
cfg_hash = (u32)(attr->config2 >> 32);
preset = attr->config & 0xF;
ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset);
}
out:
return ret;
}