auxtrace.c (0cce284537fb42d9c28b9b31038ffc9b464555f5) auxtrace.c (ffd3d18c20b8df281a18940ee80a99b28114d4b7)
1/*
2 * Copyright(C) 2015 Linaro Limited. All rights reserved.
3 * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *

--- 8 unchanged lines hidden (view full) ---

17
18#include <stdbool.h>
19#include <linux/coresight-pmu.h>
20
21#include "../../util/auxtrace.h"
22#include "../../util/evlist.h"
23#include "../../util/pmu.h"
24#include "cs-etm.h"
1/*
2 * Copyright(C) 2015 Linaro Limited. All rights reserved.
3 * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *

--- 8 unchanged lines hidden (view full) ---

17
18#include <stdbool.h>
19#include <linux/coresight-pmu.h>
20
21#include "../../util/auxtrace.h"
22#include "../../util/evlist.h"
23#include "../../util/pmu.h"
24#include "cs-etm.h"
25#include "arm-spe.h"
25
26
27static struct perf_pmu **find_all_arm_spe_pmus(int *nr_spes, int *err)
28{
29 struct perf_pmu **arm_spe_pmus = NULL;
30 int ret, i, nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
31 /* arm_spe_xxxxxxxxx\0 */
32 char arm_spe_pmu_name[sizeof(ARM_SPE_PMU_NAME) + 10];
33
34 arm_spe_pmus = zalloc(sizeof(struct perf_pmu *) * nr_cpus);
35 if (!arm_spe_pmus) {
36 pr_err("spes alloc failed\n");
37 *err = -ENOMEM;
38 return NULL;
39 }
40
41 for (i = 0; i < nr_cpus; i++) {
42 ret = sprintf(arm_spe_pmu_name, "%s%d", ARM_SPE_PMU_NAME, i);
43 if (ret < 0) {
44 pr_err("sprintf failed\n");
45 *err = -ENOMEM;
46 return NULL;
47 }
48
49 arm_spe_pmus[*nr_spes] = perf_pmu__find(arm_spe_pmu_name);
50 if (arm_spe_pmus[*nr_spes]) {
51 pr_debug2("%s %d: arm_spe_pmu %d type %d name %s\n",
52 __func__, __LINE__, *nr_spes,
53 arm_spe_pmus[*nr_spes]->type,
54 arm_spe_pmus[*nr_spes]->name);
55 (*nr_spes)++;
56 }
57 }
58
59 return arm_spe_pmus;
60}
61
26struct auxtrace_record
27*auxtrace_record__init(struct perf_evlist *evlist, int *err)
28{
29 struct perf_pmu *cs_etm_pmu;
30 struct perf_evsel *evsel;
31 bool found_etm = false;
62struct auxtrace_record
63*auxtrace_record__init(struct perf_evlist *evlist, int *err)
64{
65 struct perf_pmu *cs_etm_pmu;
66 struct perf_evsel *evsel;
67 bool found_etm = false;
68 bool found_spe = false;
69 static struct perf_pmu **arm_spe_pmus = NULL;
70 static int nr_spes = 0;
71 int i;
32
72
73 if (!evlist)
74 return NULL;
75
33 cs_etm_pmu = perf_pmu__find(CORESIGHT_ETM_PMU_NAME);
34
76 cs_etm_pmu = perf_pmu__find(CORESIGHT_ETM_PMU_NAME);
77
35 if (evlist) {
36 evlist__for_each_entry(evlist, evsel) {
37 if (cs_etm_pmu &&
38 evsel->attr.type == cs_etm_pmu->type)
39 found_etm = true;
78 if (!arm_spe_pmus)
79 arm_spe_pmus = find_all_arm_spe_pmus(&nr_spes, err);
80
81 evlist__for_each_entry(evlist, evsel) {
82 if (cs_etm_pmu &&
83 evsel->attr.type == cs_etm_pmu->type)
84 found_etm = true;
85
86 if (!nr_spes)
87 continue;
88
89 for (i = 0; i < nr_spes; i++) {
90 if (evsel->attr.type == arm_spe_pmus[i]->type) {
91 found_spe = true;
92 break;
93 }
40 }
41 }
42
94 }
95 }
96
97 if (found_etm && found_spe) {
98 pr_err("Concurrent ARM Coresight ETM and SPE operation not currently supported\n");
99 *err = -EOPNOTSUPP;
100 return NULL;
101 }
102
43 if (found_etm)
44 return cs_etm_record_init(err);
45
103 if (found_etm)
104 return cs_etm_record_init(err);
105
106#if defined(__aarch64__)
107 if (found_spe)
108 return arm_spe_recording_init(err, arm_spe_pmus[i]);
109#endif
110
46 /*
111 /*
47 * Clear 'err' even if we haven't found a cs_etm event - that way perf
112 * Clear 'err' even if we haven't found an event - that way perf
48 * record can still be used even if tracers aren't present. The NULL
49 * return value will take care of telling the infrastructure HW tracing
50 * isn't available.
51 */
52 *err = 0;
53 return NULL;
54}
113 * record can still be used even if tracers aren't present. The NULL
114 * return value will take care of telling the infrastructure HW tracing
115 * isn't available.
116 */
117 *err = 0;
118 return NULL;
119}