8 #include <linux/bitops.h> 9 #include <linux/compiler.h> 10 #include <linux/coresight-pmu.h> 11 #include <linux/kernel.h> 12 #include <linux/log2.h> 13 #include <linux/types.h> 16 #include "../../perf.h" 17 #include "../../util/auxtrace.h" 18 #include "../../util/cpumap.h" 19 #include "../../util/evlist.h" 20 #include "../../util/evsel.h" 21 #include "../../util/pmu.h" 22 #include "../../util/thread_map.h" 23 #include "../../util/cs-etm.h" 28 #define ENABLE_SINK_MAX 128 29 #define CS_BUS_DEVICE_PATH "/bus/coresight/devices/" 51 snapshot_size = strtoull(str, &endptr, 0);
52 if (*endptr || snapshot_size > SIZE_MAX)
70 struct perf_evsel *evsel, *cs_etm_evsel = NULL;
78 if (evsel->
attr.type == cs_etm_pmu->
type) {
80 pr_err(
"There may be only one %s event\n",
81 CORESIGHT_ETM_PMU_NAME);
85 evsel->
attr.sample_period = 1;
96 pr_err(
"Cannot use clockid (-k option) with %s\n",
97 CORESIGHT_ETM_PMU_NAME);
146 pr_err(
"Snapshot size %zu must not be greater than AUX area tracing mmap size %zu\n",
155 pr_err(
"Failed to calculate default snapshot size and/or AUX area tracing mmap pages\n");
180 pr_err(
"auxtrace too big, truncating to %d\n",
184 if (!is_power_of_2(sz)) {
185 pr_err(
"Invalid mmap size for %s: must be a power of 2\n",
186 CORESIGHT_ETM_PMU_NAME);
192 pr_debug2(
"%s snapshot size: %zu\n", CORESIGHT_ETM_PMU_NAME,
220 tracking_evsel->
attr.freq = 0;
221 tracking_evsel->
attr.sample_period = 1;
241 if (evsel->
attr.type == cs_etm_pmu->
type) {
250 config = evsel->
attr.config;
259 #define BIT(N) (1UL << (N)) 274 if (config_opts &
BIT(ETM_OPT_CYCACC))
275 config |=
BIT(ETM4_CFG_BIT_CYCACC);
276 if (config_opts &
BIT(ETM_OPT_TS))
277 config |=
BIT(ETM4_CFG_BIT_TS);
278 if (config_opts &
BIT(ETM_OPT_RETSTK))
279 config |=
BIT(ETM4_CFG_BIT_RETSTK);
289 int etmv3 = 0, etmv4 = 0;
349 snprintf(path,
PATH_MAX,
"cpu%d/%s",
364 unsigned int val = 0;
367 snprintf(pmu_path,
PATH_MAX,
"cpu%d/%s", cpu, path);
371 pr_err(
"%s: error reading: %s\n", __func__, pmu_path);
394 coresight_get_trace_id(cpu);
421 coresight_get_trace_id(cpu);
438 *offset += increment;
450 struct cpu_map *event_cpus = session->
evlist->
cpus;
464 cpu_map = online_cpus;
473 cpu_map = event_cpus;
478 type = cs_etm_pmu->
type;
489 for (i = 0; i <
cpu__max_cpu() && offset < priv_size; i++)
500 unsigned char *
data __maybe_unused,
503 pr_debug3(
"%s: mmap index %d old head %zu new head %zu size %zu\n",
504 __func__, idx, (
size_t)*old, (
size_t)*head, mm->
len);
540 return (((u64) rand() << 0) & 0x00000000FFFFFFFFull) |
541 (((u64) rand() << 32) & 0xFFFFFFFF00000000ull);
608 sysfs = sysfs__mountpoint();
615 if (stat(path, &st) < 0)
618 return fopen(path,
"w");
622 static int __printf(2, 3) cs_device__print_file(const
char *
name, const
char *
fmt, ...)
631 ret = vfprintf(file, fmt, args);
646 ret = cs_device__print_file(enable_sink,
"%d", 1);
size_t auxtrace_snapshot_size
#define CS_BUS_DEVICE_PATH
struct perf_evlist * evlist
int(* snapshot_start)(struct auxtrace_record *itr)
union perf_evsel_config_term::@112 val
#define CS_ETMV4_PRIV_SIZE
static const u64 __perf_cs_etmv3_magic
static bool cs_etm_is_etmv4(struct auxtrace_record *itr, int cpu)
static int cpu_map__nr(const struct cpu_map *map)
static u64 cs_etm_get_config(struct auxtrace_record *itr)
int(* snapshot_finish)(struct auxtrace_record *itr)
int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,...)
#define pr_debug2(fmt,...)
static const char * metadata_etmv4_ro[CS_ETMV4_PRIV_MAX]
size_t(* info_priv_size)(struct auxtrace_record *itr, struct perf_evlist *evlist)
static int term(yyscan_t scanner, int type)
#define perf_evsel__set_sample_bit(evsel, bit)
int perf_evsel__disable(struct perf_evsel *evsel)
static void cs_etm_recording_free(struct auxtrace_record *itr)
static const u64 __perf_cs_etmv4_magic
static int cs_etm_snapshot_start(struct auxtrace_record *itr)
int parse_events(struct perf_evlist *evlist, const char *str, struct parse_events_error *err)
struct auxtrace_record itr
struct perf_evlist * evlist
void cpu_map__put(struct cpu_map *map)
void perf_evlist__set_tracking_event(struct perf_evlist *evlist, struct perf_evsel *tracking_evsel)
static int cs_etm_get_ro(struct perf_pmu *pmu, int cpu, const char *path)
int(* read_finish)(struct auxtrace_record *itr, int idx)
u64(* reference)(struct auxtrace_record *itr)
static struct perf_session * session
static int cs_etm_find_snapshot(struct auxtrace_record *itr __maybe_unused, int idx, struct auxtrace_mmap *mm, unsigned char *data __maybe_unused, u64 *head, u64 *old)
static void cs_etm_get_metadata(int cpu, u32 *offset, struct auxtrace_record *itr, struct auxtrace_info_event *info)
#define evlist__for_each_entry(evlist, evsel)
static bool cpu_map__empty(const struct cpu_map *map)
struct perf_pmu * cs_etm_pmu
void(* free)(struct auxtrace_record *itr)
static size_t cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused, struct perf_evlist *evlist __maybe_unused)
int(* recording_options)(struct auxtrace_record *itr, struct perf_evlist *evlist, struct record_opts *opts)
static int str(yyscan_t scanner, int token)
int cs_etm_set_drv_config(struct perf_evsel_config_term *term)
void perf_evlist__to_front(struct perf_evlist *evlist, struct perf_evsel *move_evsel)
static const char * metadata_etmv3_ro[CS_ETM_PRIV_MAX]
static int cs_etm_read_finish(struct auxtrace_record *itr, int idx)
bool cpu_map__has(struct cpu_map *cpus, int cpu)
static int __printf(2, 3)
int(* parse_snapshot_options)(struct auxtrace_record *itr, struct record_opts *opts, const char *str)
int perf_event_paranoid(void)
static u64 cs_etmv4_get_config(struct auxtrace_record *itr)
int(* find_snapshot)(struct auxtrace_record *itr, int idx, struct auxtrace_mmap *mm, unsigned char *data, u64 *head, u64 *old)
bool auxtrace_snapshot_mode
struct perf_pmu * perf_pmu__find(const char *name)
#define CS_ETMV3_PRIV_SIZE
#define CS_ETM_HEADER_SIZE
static int cs_etm_info_fill(struct auxtrace_record *itr, struct perf_session *session, struct auxtrace_info_event *info, size_t priv_size)
static FILE * cs_device__open_file(const char *name)
int perf_evsel__enable(struct perf_evsel *evsel)
static int cs_etm_snapshot_finish(struct auxtrace_record *itr)
static int cs_etm_parse_snapshot_options(struct auxtrace_record *itr, struct record_opts *opts, const char *str)
static struct perf_evsel * perf_evlist__last(struct perf_evlist *evlist)
struct cpu_map * cpu_map__new(const char *cpu_list)
unsigned int auxtrace_mmap_pages
int(* info_fill)(struct auxtrace_record *itr, struct perf_session *session, struct auxtrace_info_event *auxtrace_info, size_t priv_size)
struct auxtrace_record * cs_etm_record_init(int *err)
static int cs_etm_recording_options(struct auxtrace_record *itr, struct perf_evlist *evlist, struct record_opts *opts)
#define pr_debug3(fmt,...)
struct perf_event_attr attr
static u64 cs_etm_reference(struct auxtrace_record *itr __maybe_unused)
int perf_evlist__enable_event_idx(struct perf_evlist *evlist, struct perf_evsel *evsel, int idx)
void static void * zalloc(size_t size)