struct perf_cpu cpu)
{
int err;
- __u64 val;
- u64 contextid = evsel->core.attr.config &
- (perf_pmu__format_bits(cs_etm_pmu, "contextid") |
- perf_pmu__format_bits(cs_etm_pmu, "contextid1") |
- perf_pmu__format_bits(cs_etm_pmu, "contextid2"));
+ u64 ctxt, ctxt1, ctxt2;
+ __u64 trcidr2;
- if (!contextid)
+ evsel__get_config_val(evsel, "contextid", &ctxt);
+ evsel__get_config_val(evsel, "contextid1", &ctxt1);
+ evsel__get_config_val(evsel, "contextid2", &ctxt2);
+
+ if (!ctxt && !ctxt1 && !ctxt2)
return 0;
/* Not supported in etmv3 */
}
/* Get a handle on TRCIDR2 */
- err = cs_etm_get_ro(cs_etm_pmu, cpu, metadata_etmv4_ro[CS_ETMV4_TRCIDR2], &val);
+ err = cs_etm_get_ro(cs_etm_pmu, cpu, metadata_etmv4_ro[CS_ETMV4_TRCIDR2], &trcidr2);
if (err)
return err;
- if (contextid &
- perf_pmu__format_bits(cs_etm_pmu, "contextid1")) {
+ if (ctxt1) {
/*
* TRCIDR2.CIDSIZE, bit [9-5], indicates whether contextID
* tracing is supported:
* 0b00100 Maximum of 32-bit Context ID size.
* All other values are reserved.
*/
- if (BMVAL(val, 5, 9) != 0x4) {
+ if (BMVAL(trcidr2, 5, 9) != 0x4) {
pr_err("%s: CONTEXTIDR_EL1 isn't supported, disable with %s/contextid1=0/\n",
CORESIGHT_ETM_PMU_NAME, CORESIGHT_ETM_PMU_NAME);
return -EINVAL;
}
}
- if (contextid &
- perf_pmu__format_bits(cs_etm_pmu, "contextid2")) {
+ if (ctxt2) {
/*
* TRCIDR2.VMIDOPT[30:29] != 0 and
* TRCIDR2.VMIDSIZE[14:10] == 0b00100 (32bit virtual contextid)
* virtual context id is < 32bit.
* Any value of VMIDSIZE >= 4 (i.e, > 32bit) is fine for us.
*/
- if (!BMVAL(val, 29, 30) || BMVAL(val, 10, 14) < 4) {
+ if (!BMVAL(trcidr2, 29, 30) || BMVAL(trcidr2, 10, 14) < 4) {
pr_err("%s: CONTEXTIDR_EL2 isn't supported, disable with %s/contextid2=0/\n",
CORESIGHT_ETM_PMU_NAME, CORESIGHT_ETM_PMU_NAME);
return -EINVAL;
struct perf_cpu cpu)
{
int err;
- __u64 val;
+ u64 val;
+ __u64 trcidr0;
- if (!(evsel->core.attr.config &
- perf_pmu__format_bits(cs_etm_pmu, "timestamp")))
+ evsel__get_config_val(evsel, "timestamp", &val);
+ if (!val)
return 0;
if (cs_etm_get_version(cs_etm_pmu, cpu) == CS_ETMV3) {
}
/* Get a handle on TRCIRD0 */
- err = cs_etm_get_ro(cs_etm_pmu, cpu, metadata_etmv4_ro[CS_ETMV4_TRCIDR0], &val);
+ err = cs_etm_get_ro(cs_etm_pmu, cpu, metadata_etmv4_ro[CS_ETMV4_TRCIDR0], &trcidr0);
if (err)
return err;
* 0b00110 Implementation supports a maximum timestamp of 48bits.
* 0b01000 Implementation supports a maximum timestamp of 64bits.
*/
- val &= GENMASK(28, 24);
- if (!val) {
+ trcidr0 &= GENMASK(28, 24);
+ if (!trcidr0)
return -EINVAL;
- }
return 0;
}
return 0;
}
+/*
+ * If the sink name format "@sink_name" is used, lookup the sink by name to convert to
+ * "sinkid=sink_hash" format. If the user has already manually provided a hash then
+ * "sinkid" isn't overwritten. If neither are provided then the driver will pick the best
+ * sink.
+ */
static int cs_etm_set_sink_attr(struct perf_pmu *pmu,
struct evsel *evsel)
{
char msg[BUFSIZ], path[PATH_MAX], *sink;
struct evsel_config_term *term;
- int ret = -EINVAL;
u32 hash;
-
- if (evsel->core.attr.config2 & GENMASK(31, 0))
- return 0;
+ int ret;
list_for_each_entry(term, &evsel->config_terms, list) {
if (term->type != EVSEL__CONFIG_TERM_DRV_CFG)
return ret;
}
- evsel->core.attr.config2 |= hash;
+ evsel__set_config_if_unset(evsel, "sinkid", hash);
return 0;
}
- /*
- * No sink was provided on the command line - allow the CoreSight
- * system to look for a default
- */
return 0;
}