1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright(C) 2015 Linaro Limited. All rights reserved.
4 * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
8 #include <linux/coresight-pmu.h>
9 #include <linux/zalloc.h>
11 #include "../../util/auxtrace.h"
12 #include "../../util/debug.h"
13 #include "../../util/evlist.h"
14 #include "../../util/pmu.h"
18 static struct perf_pmu
**find_all_arm_spe_pmus(int *nr_spes
, int *err
)
20 struct perf_pmu
**arm_spe_pmus
= NULL
;
21 int ret
, i
, nr_cpus
= sysconf(_SC_NPROCESSORS_CONF
);
22 /* arm_spe_xxxxxxxxx\0 */
23 char arm_spe_pmu_name
[sizeof(ARM_SPE_PMU_NAME
) + 10];
25 arm_spe_pmus
= zalloc(sizeof(struct perf_pmu
*) * nr_cpus
);
27 pr_err("spes alloc failed\n");
32 for (i
= 0; i
< nr_cpus
; i
++) {
33 ret
= sprintf(arm_spe_pmu_name
, "%s%d", ARM_SPE_PMU_NAME
, i
);
35 pr_err("sprintf failed\n");
40 arm_spe_pmus
[*nr_spes
] = perf_pmu__find(arm_spe_pmu_name
);
41 if (arm_spe_pmus
[*nr_spes
]) {
42 pr_debug2("%s %d: arm_spe_pmu %d type %d name %s\n",
43 __func__
, __LINE__
, *nr_spes
,
44 arm_spe_pmus
[*nr_spes
]->type
,
45 arm_spe_pmus
[*nr_spes
]->name
);
53 struct auxtrace_record
54 *auxtrace_record__init(struct evlist
*evlist
, int *err
)
56 struct perf_pmu
*cs_etm_pmu
;
58 bool found_etm
= false;
59 struct perf_pmu
*found_spe
= NULL
;
60 struct perf_pmu
**arm_spe_pmus
= NULL
;
67 cs_etm_pmu
= perf_pmu__find(CORESIGHT_ETM_PMU_NAME
);
68 arm_spe_pmus
= find_all_arm_spe_pmus(&nr_spes
, err
);
70 evlist__for_each_entry(evlist
, evsel
) {
72 evsel
->core
.attr
.type
== cs_etm_pmu
->type
)
75 if (!nr_spes
|| found_spe
)
78 for (i
= 0; i
< nr_spes
; i
++) {
79 if (evsel
->core
.attr
.type
== arm_spe_pmus
[i
]->type
) {
80 found_spe
= arm_spe_pmus
[i
];
87 if (found_etm
&& found_spe
) {
88 pr_err("Concurrent ARM Coresight ETM and SPE operation not currently supported\n");
94 return cs_etm_record_init(err
);
96 #if defined(__aarch64__)
98 return arm_spe_recording_init(err
, found_spe
);
102 * Clear 'err' even if we haven't found an event - that way perf
103 * record can still be used even if tracers aren't present. The NULL
104 * return value will take care of telling the infrastructure HW tracing