]>
git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - tools/perf/arch/arm/util/auxtrace.c
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
112 u64
compat_auxtrace_mmap__read_head(struct auxtrace_mmap
*mm
)
114 struct perf_event_mmap_page
*pc
= mm
->userpg
;
117 __asm__
__volatile__(
118 " ldrd %0, %H0, [%1]"
120 : "r" (&pc
->aux_head
), "Qo" (pc
->aux_head
)
126 int compat_auxtrace_mmap__write_tail(struct auxtrace_mmap
*mm
, u64 tail
)
128 struct perf_event_mmap_page
*pc
= mm
->userpg
;
130 /* Ensure all reads are done before we write the tail out */
133 __asm__
__volatile__(
134 " strd %2, %H2, [%1]"
135 : "=Qo" (pc
->aux_tail
)
136 : "r" (&pc
->aux_tail
), "r" (tail
)