diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/arch/arm/util/cs-etm.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 2f595cd73da6..4f31cf0d1e6d 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -5,6 +5,7 @@ */ #include <api/fs/fs.h> +#include <linux/bits.h> #include <linux/bitops.h> #include <linux/compiler.h> #include <linux/coresight-pmu.h> @@ -22,6 +23,7 @@ #include "../../util/thread_map.h" #include "../../util/cs-etm.h" +#include <errno.h> #include <stdlib.h> #include <sys/stat.h> @@ -60,10 +62,48 @@ static int cs_etm_parse_snapshot_options(struct auxtrace_record *itr, return 0; } +static int cs_etm_set_sink_attr(struct perf_pmu *pmu, + struct perf_evsel *evsel) +{ + char msg[BUFSIZ], path[PATH_MAX], *sink; + struct perf_evsel_config_term *term; + int ret = -EINVAL; + u32 hash; + + if (evsel->attr.config2 & GENMASK(31, 0)) + return 0; + + list_for_each_entry(term, &evsel->config_terms, list) { + if (term->type != PERF_EVSEL__CONFIG_TERM_DRV_CFG) + continue; + + sink = term->val.drv_cfg; + snprintf(path, PATH_MAX, "sinks/%s", sink); + + ret = perf_pmu__scan_file(pmu, path, "%x", &hash); + if (ret != 1) { + pr_err("failed to set sink \"%s\" on event %s with %d (%s)\n", + sink, perf_evsel__name(evsel), errno, + str_error_r(errno, msg, sizeof(msg))); + return ret; + } + + evsel->attr.config2 |= hash; + return 0; + } + + /* + * No sink was provided on the command line - for _now_ treat + * this as an error. + */ + return ret; +} + static int cs_etm_recording_options(struct auxtrace_record *itr, struct perf_evlist *evlist, struct record_opts *opts) { + int ret; struct cs_etm_recording *ptr = container_of(itr, struct cs_etm_recording, itr); struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu; @@ -92,6 +132,10 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, if (!cs_etm_evsel) return 0; + ret = cs_etm_set_sink_attr(cs_etm_pmu, cs_etm_evsel); + if (ret) + return ret; + if (opts->use_clockid) { pr_err("Cannot use clockid (-k option) with %s\n", CORESIGHT_ETM_PMU_NAME); |