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} |