2 * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code.
4 * ARMv7 support: Jean Pihet <jpihet@mvista.com>
5 * 2010 (c) MontaVista Software, LLC.
7 * Copied from ARMv6 code, with the low level code inspired
8 * by the ARMv7 Oprofile code.
10 * Cortex-A8 has up to 4 configurable performance counters and
11 * a single cycle counter.
12 * Cortex-A9 has up to 31 configurable performance counters and
13 * a single cycle counter.
15 * All counters can be enabled/disabled and IRQ masked separately. The cycle
16 * counter and all 4 performance counters together can be reset separately.
23 #include "../vfp/vfpinstr.h"
26 * Common ARMv7 event types
28 * Note: An implementation may not be able to count all of these events
29 * but the encodings are considered to be `reserved' in the case that
30 * they are not available.
32 enum armv7_perf_types
{
33 ARMV7_PERFCTR_PMNC_SW_INCR
= 0x00,
34 ARMV7_PERFCTR_L1_ICACHE_REFILL
= 0x01,
35 ARMV7_PERFCTR_ITLB_REFILL
= 0x02,
36 ARMV7_PERFCTR_L1_DCACHE_REFILL
= 0x03,
37 ARMV7_PERFCTR_L1_DCACHE_ACCESS
= 0x04,
38 ARMV7_PERFCTR_DTLB_REFILL
= 0x05,
39 ARMV7_PERFCTR_MEM_READ
= 0x06,
40 ARMV7_PERFCTR_MEM_WRITE
= 0x07,
41 ARMV7_PERFCTR_INSTR_EXECUTED
= 0x08,
42 ARMV7_PERFCTR_EXC_TAKEN
= 0x09,
43 ARMV7_PERFCTR_EXC_EXECUTED
= 0x0A,
44 ARMV7_PERFCTR_CID_WRITE
= 0x0B,
47 * ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
49 * - all (taken) branch instructions,
50 * - instructions that explicitly write the PC,
51 * - exception generating instructions.
53 ARMV7_PERFCTR_PC_WRITE
= 0x0C,
54 ARMV7_PERFCTR_PC_IMM_BRANCH
= 0x0D,
55 ARMV7_PERFCTR_PC_PROC_RETURN
= 0x0E,
56 ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS
= 0x0F,
57 ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
= 0x10,
58 ARMV7_PERFCTR_CLOCK_CYCLES
= 0x11,
59 ARMV7_PERFCTR_PC_BRANCH_PRED
= 0x12,
61 /* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
62 ARMV7_PERFCTR_MEM_ACCESS
= 0x13,
63 ARMV7_PERFCTR_L1_ICACHE_ACCESS
= 0x14,
64 ARMV7_PERFCTR_L1_DCACHE_WB
= 0x15,
65 ARMV7_PERFCTR_L2_CACHE_ACCESS
= 0x16,
66 ARMV7_PERFCTR_L2_CACHE_REFILL
= 0x17,
67 ARMV7_PERFCTR_L2_CACHE_WB
= 0x18,
68 ARMV7_PERFCTR_BUS_ACCESS
= 0x19,
69 ARMV7_PERFCTR_MEM_ERROR
= 0x1A,
70 ARMV7_PERFCTR_INSTR_SPEC
= 0x1B,
71 ARMV7_PERFCTR_TTBR_WRITE
= 0x1C,
72 ARMV7_PERFCTR_BUS_CYCLES
= 0x1D,
74 ARMV7_PERFCTR_CPU_CYCLES
= 0xFF
77 /* ARMv7 Cortex-A8 specific event types */
78 enum armv7_a8_perf_types
{
79 ARMV7_A8_PERFCTR_L2_CACHE_ACCESS
= 0x43,
80 ARMV7_A8_PERFCTR_L2_CACHE_REFILL
= 0x44,
81 ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS
= 0x50,
82 ARMV7_A8_PERFCTR_STALL_ISIDE
= 0x56,
85 /* ARMv7 Cortex-A9 specific event types */
86 enum armv7_a9_perf_types
{
87 ARMV7_A9_PERFCTR_INSTR_CORE_RENAME
= 0x68,
88 ARMV7_A9_PERFCTR_STALL_ICACHE
= 0x60,
89 ARMV7_A9_PERFCTR_STALL_DISPATCH
= 0x66,
92 /* ARMv7 Cortex-A5 specific event types */
93 enum armv7_a5_perf_types
{
94 ARMV7_A5_PERFCTR_PREFETCH_LINEFILL
= 0xc2,
95 ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP
= 0xc3,
98 /* ARMv7 Cortex-A15 specific event types */
99 enum armv7_a15_perf_types
{
100 ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ
= 0x40,
101 ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE
= 0x41,
102 ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ
= 0x42,
103 ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE
= 0x43,
105 ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ
= 0x4C,
106 ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE
= 0x4D,
108 ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ
= 0x50,
109 ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE
= 0x51,
110 ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ
= 0x52,
111 ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE
= 0x53,
113 ARMV7_A15_PERFCTR_PC_WRITE_SPEC
= 0x76,
116 /* ARMv7 Cortex-A12 specific event types */
117 enum armv7_a12_perf_types
{
118 ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ
= 0x40,
119 ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE
= 0x41,
121 ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ
= 0x50,
122 ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE
= 0x51,
124 ARMV7_A12_PERFCTR_PC_WRITE_SPEC
= 0x76,
126 ARMV7_A12_PERFCTR_PF_TLB_REFILL
= 0xe7,
129 /* ARMv7 Krait specific event types */
130 enum krait_perf_types
{
131 KRAIT_PMRESR0_GROUP0
= 0xcc,
132 KRAIT_PMRESR1_GROUP0
= 0xd0,
133 KRAIT_PMRESR2_GROUP0
= 0xd4,
134 KRAIT_VPMRESR0_GROUP0
= 0xd8,
136 KRAIT_PERFCTR_L1_ICACHE_ACCESS
= 0x10011,
137 KRAIT_PERFCTR_L1_ICACHE_MISS
= 0x10010,
139 KRAIT_PERFCTR_L1_ITLB_ACCESS
= 0x12222,
140 KRAIT_PERFCTR_L1_DTLB_ACCESS
= 0x12210,
144 * Cortex-A8 HW events mapping
146 * The hardware events that we support. We do support cache operations but
147 * we have harvard caches and no way to combine instruction and data
148 * accesses/misses in hardware.
150 static const unsigned armv7_a8_perf_map
[PERF_COUNT_HW_MAX
] = {
151 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
152 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_PERFCTR_INSTR_EXECUTED
,
153 [PERF_COUNT_HW_CACHE_REFERENCES
] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
154 [PERF_COUNT_HW_CACHE_MISSES
] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
155 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = ARMV7_PERFCTR_PC_WRITE
,
156 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
157 [PERF_COUNT_HW_BUS_CYCLES
] = HW_OP_UNSUPPORTED
,
158 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
] = ARMV7_A8_PERFCTR_STALL_ISIDE
,
159 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND
] = HW_OP_UNSUPPORTED
,
162 static const unsigned armv7_a8_perf_cache_map
[PERF_COUNT_HW_CACHE_MAX
]
163 [PERF_COUNT_HW_CACHE_OP_MAX
]
164 [PERF_COUNT_HW_CACHE_RESULT_MAX
] = {
167 * The performance counters don't differentiate between read
168 * and write accesses/misses so this isn't strictly correct,
169 * but it's the best we can do. Writes and reads get
173 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
174 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
177 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
178 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
181 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
182 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
187 [C(RESULT_ACCESS
)] = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS
,
188 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_ICACHE_REFILL
,
191 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
192 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
195 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
196 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
201 [C(RESULT_ACCESS
)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS
,
202 [C(RESULT_MISS
)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL
,
205 [C(RESULT_ACCESS
)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS
,
206 [C(RESULT_MISS
)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL
,
209 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
210 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
215 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
216 [C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
219 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
220 [C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
223 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
224 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
229 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
230 [C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
233 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
234 [C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
237 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
238 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
243 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
244 [C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
247 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
248 [C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
251 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
252 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
257 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
258 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
261 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
262 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
265 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
266 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
272 * Cortex-A9 HW events mapping
274 static const unsigned armv7_a9_perf_map
[PERF_COUNT_HW_MAX
] = {
275 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
276 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_A9_PERFCTR_INSTR_CORE_RENAME
,
277 [PERF_COUNT_HW_CACHE_REFERENCES
] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
278 [PERF_COUNT_HW_CACHE_MISSES
] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
279 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = ARMV7_PERFCTR_PC_WRITE
,
280 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
281 [PERF_COUNT_HW_BUS_CYCLES
] = HW_OP_UNSUPPORTED
,
282 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
] = ARMV7_A9_PERFCTR_STALL_ICACHE
,
283 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND
] = ARMV7_A9_PERFCTR_STALL_DISPATCH
,
286 static const unsigned armv7_a9_perf_cache_map
[PERF_COUNT_HW_CACHE_MAX
]
287 [PERF_COUNT_HW_CACHE_OP_MAX
]
288 [PERF_COUNT_HW_CACHE_RESULT_MAX
] = {
291 * The performance counters don't differentiate between read
292 * and write accesses/misses so this isn't strictly correct,
293 * but it's the best we can do. Writes and reads get
297 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
298 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
301 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
302 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
305 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
306 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
311 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
312 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_ICACHE_REFILL
,
315 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
316 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
319 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
320 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
325 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
326 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
329 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
330 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
333 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
334 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
339 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
340 [C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
343 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
344 [C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
347 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
348 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
353 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
354 [C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
357 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
358 [C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
361 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
362 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
367 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
368 [C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
371 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
372 [C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
375 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
376 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
381 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
382 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
385 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
386 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
389 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
390 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
396 * Cortex-A5 HW events mapping
398 static const unsigned armv7_a5_perf_map
[PERF_COUNT_HW_MAX
] = {
399 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
400 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_PERFCTR_INSTR_EXECUTED
,
401 [PERF_COUNT_HW_CACHE_REFERENCES
] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
402 [PERF_COUNT_HW_CACHE_MISSES
] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
403 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = ARMV7_PERFCTR_PC_WRITE
,
404 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
405 [PERF_COUNT_HW_BUS_CYCLES
] = HW_OP_UNSUPPORTED
,
406 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
] = HW_OP_UNSUPPORTED
,
407 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND
] = HW_OP_UNSUPPORTED
,
410 static const unsigned armv7_a5_perf_cache_map
[PERF_COUNT_HW_CACHE_MAX
]
411 [PERF_COUNT_HW_CACHE_OP_MAX
]
412 [PERF_COUNT_HW_CACHE_RESULT_MAX
] = {
415 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
416 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
419 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
420 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
423 [C(RESULT_ACCESS
)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL
,
424 [C(RESULT_MISS
)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP
,
429 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS
,
430 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_ICACHE_REFILL
,
433 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
434 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
437 * The prefetch counters don't differentiate between the I
438 * side and the D side.
441 [C(RESULT_ACCESS
)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL
,
442 [C(RESULT_MISS
)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP
,
447 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
448 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
451 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
452 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
455 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
456 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
461 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
462 [C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
465 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
466 [C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
469 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
470 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
475 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
476 [C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
479 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
480 [C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
483 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
484 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
489 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
490 [C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
493 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
494 [C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
497 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
498 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
503 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
504 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
507 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
508 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
511 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
512 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
518 * Cortex-A15 HW events mapping
520 static const unsigned armv7_a15_perf_map
[PERF_COUNT_HW_MAX
] = {
521 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
522 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_PERFCTR_INSTR_EXECUTED
,
523 [PERF_COUNT_HW_CACHE_REFERENCES
] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
524 [PERF_COUNT_HW_CACHE_MISSES
] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
525 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = ARMV7_A15_PERFCTR_PC_WRITE_SPEC
,
526 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
527 [PERF_COUNT_HW_BUS_CYCLES
] = ARMV7_PERFCTR_BUS_CYCLES
,
528 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
] = HW_OP_UNSUPPORTED
,
529 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND
] = HW_OP_UNSUPPORTED
,
532 static const unsigned armv7_a15_perf_cache_map
[PERF_COUNT_HW_CACHE_MAX
]
533 [PERF_COUNT_HW_CACHE_OP_MAX
]
534 [PERF_COUNT_HW_CACHE_RESULT_MAX
] = {
537 [C(RESULT_ACCESS
)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ
,
538 [C(RESULT_MISS
)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ
,
541 [C(RESULT_ACCESS
)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE
,
542 [C(RESULT_MISS
)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE
,
545 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
546 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
551 * Not all performance counters differentiate between read
552 * and write accesses/misses so we're not always strictly
553 * correct, but it's the best we can do. Writes and reads get
554 * combined in these cases.
557 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS
,
558 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_ICACHE_REFILL
,
561 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
562 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
565 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
566 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
571 [C(RESULT_ACCESS
)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ
,
572 [C(RESULT_MISS
)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ
,
575 [C(RESULT_ACCESS
)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE
,
576 [C(RESULT_MISS
)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE
,
579 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
580 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
585 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
586 [C(RESULT_MISS
)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ
,
589 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
590 [C(RESULT_MISS
)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE
,
593 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
594 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
599 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
600 [C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
603 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
604 [C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
607 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
608 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
613 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
614 [C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
617 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
618 [C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
621 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
622 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
627 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
628 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
631 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
632 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
635 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
636 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
642 * Cortex-A7 HW events mapping
644 static const unsigned armv7_a7_perf_map
[PERF_COUNT_HW_MAX
] = {
645 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
646 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_PERFCTR_INSTR_EXECUTED
,
647 [PERF_COUNT_HW_CACHE_REFERENCES
] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
648 [PERF_COUNT_HW_CACHE_MISSES
] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
649 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = ARMV7_PERFCTR_PC_WRITE
,
650 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
651 [PERF_COUNT_HW_BUS_CYCLES
] = ARMV7_PERFCTR_BUS_CYCLES
,
652 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
] = HW_OP_UNSUPPORTED
,
653 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND
] = HW_OP_UNSUPPORTED
,
656 static const unsigned armv7_a7_perf_cache_map
[PERF_COUNT_HW_CACHE_MAX
]
657 [PERF_COUNT_HW_CACHE_OP_MAX
]
658 [PERF_COUNT_HW_CACHE_RESULT_MAX
] = {
661 * The performance counters don't differentiate between read
662 * and write accesses/misses so this isn't strictly correct,
663 * but it's the best we can do. Writes and reads get
667 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
668 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
671 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
672 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
675 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
676 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
681 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS
,
682 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_ICACHE_REFILL
,
685 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
686 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
689 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
690 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
695 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L2_CACHE_ACCESS
,
696 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L2_CACHE_REFILL
,
699 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L2_CACHE_ACCESS
,
700 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L2_CACHE_REFILL
,
703 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
704 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
709 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
710 [C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
713 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
714 [C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
717 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
718 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
723 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
724 [C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
727 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
728 [C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
731 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
732 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
737 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
738 [C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
741 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
742 [C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
745 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
746 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
751 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
752 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
755 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
756 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
759 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
760 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
766 * Cortex-A12 HW events mapping
768 static const unsigned armv7_a12_perf_map
[PERF_COUNT_HW_MAX
] = {
769 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
770 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_PERFCTR_INSTR_EXECUTED
,
771 [PERF_COUNT_HW_CACHE_REFERENCES
] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
772 [PERF_COUNT_HW_CACHE_MISSES
] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
773 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = ARMV7_A12_PERFCTR_PC_WRITE_SPEC
,
774 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
775 [PERF_COUNT_HW_BUS_CYCLES
] = ARMV7_PERFCTR_BUS_CYCLES
,
776 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
] = HW_OP_UNSUPPORTED
,
777 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND
] = HW_OP_UNSUPPORTED
,
780 static const unsigned armv7_a12_perf_cache_map
[PERF_COUNT_HW_CACHE_MAX
]
781 [PERF_COUNT_HW_CACHE_OP_MAX
]
782 [PERF_COUNT_HW_CACHE_RESULT_MAX
] = {
785 [C(RESULT_ACCESS
)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ
,
786 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
789 [C(RESULT_ACCESS
)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE
,
790 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
793 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
794 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
799 * Not all performance counters differentiate between read
800 * and write accesses/misses so we're not always strictly
801 * correct, but it's the best we can do. Writes and reads get
802 * combined in these cases.
805 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS
,
806 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_ICACHE_REFILL
,
809 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
810 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
813 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
814 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
819 [C(RESULT_ACCESS
)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ
,
820 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L2_CACHE_REFILL
,
823 [C(RESULT_ACCESS
)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE
,
824 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L2_CACHE_REFILL
,
827 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
828 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
833 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
834 [C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
837 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
838 [C(RESULT_MISS
)] = ARMV7_PERFCTR_DTLB_REFILL
,
841 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
842 [C(RESULT_MISS
)] = ARMV7_A12_PERFCTR_PF_TLB_REFILL
,
847 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
848 [C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
851 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
852 [C(RESULT_MISS
)] = ARMV7_PERFCTR_ITLB_REFILL
,
855 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
856 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
861 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
862 [C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
865 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
866 [C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
869 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
870 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
875 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
876 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
879 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
880 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
883 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
884 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
890 * Krait HW events mapping
892 static const unsigned krait_perf_map
[PERF_COUNT_HW_MAX
] = {
893 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
894 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_PERFCTR_INSTR_EXECUTED
,
895 [PERF_COUNT_HW_CACHE_REFERENCES
] = HW_OP_UNSUPPORTED
,
896 [PERF_COUNT_HW_CACHE_MISSES
] = HW_OP_UNSUPPORTED
,
897 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = ARMV7_PERFCTR_PC_WRITE
,
898 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
899 [PERF_COUNT_HW_BUS_CYCLES
] = ARMV7_PERFCTR_CLOCK_CYCLES
,
902 static const unsigned krait_perf_map_no_branch
[PERF_COUNT_HW_MAX
] = {
903 [PERF_COUNT_HW_CPU_CYCLES
] = ARMV7_PERFCTR_CPU_CYCLES
,
904 [PERF_COUNT_HW_INSTRUCTIONS
] = ARMV7_PERFCTR_INSTR_EXECUTED
,
905 [PERF_COUNT_HW_CACHE_REFERENCES
] = HW_OP_UNSUPPORTED
,
906 [PERF_COUNT_HW_CACHE_MISSES
] = HW_OP_UNSUPPORTED
,
907 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = HW_OP_UNSUPPORTED
,
908 [PERF_COUNT_HW_BRANCH_MISSES
] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
909 [PERF_COUNT_HW_BUS_CYCLES
] = ARMV7_PERFCTR_CLOCK_CYCLES
,
912 static const unsigned krait_perf_cache_map
[PERF_COUNT_HW_CACHE_MAX
]
913 [PERF_COUNT_HW_CACHE_OP_MAX
]
914 [PERF_COUNT_HW_CACHE_RESULT_MAX
] = {
917 * The performance counters don't differentiate between read
918 * and write accesses/misses so this isn't strictly correct,
919 * but it's the best we can do. Writes and reads get
923 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
924 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
927 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS
,
928 [C(RESULT_MISS
)] = ARMV7_PERFCTR_L1_DCACHE_REFILL
,
931 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
932 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
937 [C(RESULT_ACCESS
)] = KRAIT_PERFCTR_L1_ICACHE_ACCESS
,
938 [C(RESULT_MISS
)] = KRAIT_PERFCTR_L1_ICACHE_MISS
,
941 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
942 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
945 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
946 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
951 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
952 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
955 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
956 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
959 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
960 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
965 [C(RESULT_ACCESS
)] = KRAIT_PERFCTR_L1_DTLB_ACCESS
,
966 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
969 [C(RESULT_ACCESS
)] = KRAIT_PERFCTR_L1_DTLB_ACCESS
,
970 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
973 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
974 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
979 [C(RESULT_ACCESS
)] = KRAIT_PERFCTR_L1_ITLB_ACCESS
,
980 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
983 [C(RESULT_ACCESS
)] = KRAIT_PERFCTR_L1_ITLB_ACCESS
,
984 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
987 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
988 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
993 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
994 [C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
997 [C(RESULT_ACCESS
)] = ARMV7_PERFCTR_PC_BRANCH_PRED
,
998 [C(RESULT_MISS
)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
,
1000 [C(OP_PREFETCH
)] = {
1001 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
1002 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
1007 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
1008 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
1011 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
1012 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
1014 [C(OP_PREFETCH
)] = {
1015 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
1016 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
1022 * Perf Events' indices
1024 #define ARMV7_IDX_CYCLE_COUNTER 0
1025 #define ARMV7_IDX_COUNTER0 1
1026 #define ARMV7_IDX_COUNTER_LAST(cpu_pmu) \
1027 (ARMV7_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1)
1029 #define ARMV7_MAX_COUNTERS 32
1030 #define ARMV7_COUNTER_MASK (ARMV7_MAX_COUNTERS - 1)
1033 * ARMv7 low level PMNC access
1037 * Perf Event to low level counters mapping
1039 #define ARMV7_IDX_TO_COUNTER(x) \
1040 (((x) - ARMV7_IDX_COUNTER0) & ARMV7_COUNTER_MASK)
1043 * Per-CPU PMNC: config reg
1045 #define ARMV7_PMNC_E (1 << 0) /* Enable all counters */
1046 #define ARMV7_PMNC_P (1 << 1) /* Reset all counters */
1047 #define ARMV7_PMNC_C (1 << 2) /* Cycle counter reset */
1048 #define ARMV7_PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
1049 #define ARMV7_PMNC_X (1 << 4) /* Export to ETM */
1050 #define ARMV7_PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
1051 #define ARMV7_PMNC_N_SHIFT 11 /* Number of counters supported */
1052 #define ARMV7_PMNC_N_MASK 0x1f
1053 #define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */
1056 * FLAG: counters overflow flag status reg
1058 #define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */
1059 #define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK
1062 * PMXEVTYPER: Event selection reg
1064 #define ARMV7_EVTYPE_MASK 0xc80000ff /* Mask for writable bits */
1065 #define ARMV7_EVTYPE_EVENT 0xff /* Mask for EVENT bits */
1068 * Event filters for PMUv2
1070 #define ARMV7_EXCLUDE_PL1 (1 << 31)
1071 #define ARMV7_EXCLUDE_USER (1 << 30)
1072 #define ARMV7_INCLUDE_HYP (1 << 27)
1074 static inline u32
armv7_pmnc_read(void)
1077 asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val
));
1081 static inline void armv7_pmnc_write(u32 val
)
1083 val
&= ARMV7_PMNC_MASK
;
1085 asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val
));
1088 static inline int armv7_pmnc_has_overflowed(u32 pmnc
)
1090 return pmnc
& ARMV7_OVERFLOWED_MASK
;
1093 static inline int armv7_pmnc_counter_valid(struct arm_pmu
*cpu_pmu
, int idx
)
1095 return idx
>= ARMV7_IDX_CYCLE_COUNTER
&&
1096 idx
<= ARMV7_IDX_COUNTER_LAST(cpu_pmu
);
1099 static inline int armv7_pmnc_counter_has_overflowed(u32 pmnc
, int idx
)
1101 return pmnc
& BIT(ARMV7_IDX_TO_COUNTER(idx
));
1104 static inline int armv7_pmnc_select_counter(int idx
)
1106 u32 counter
= ARMV7_IDX_TO_COUNTER(idx
);
1107 asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (counter
));
1113 static inline u32
armv7pmu_read_counter(struct perf_event
*event
)
1115 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
1116 struct hw_perf_event
*hwc
= &event
->hw
;
1120 if (!armv7_pmnc_counter_valid(cpu_pmu
, idx
))
1121 pr_err("CPU%u reading wrong counter %d\n",
1122 smp_processor_id(), idx
);
1123 else if (idx
== ARMV7_IDX_CYCLE_COUNTER
)
1124 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value
));
1125 else if (armv7_pmnc_select_counter(idx
) == idx
)
1126 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (value
));
1131 static inline void armv7pmu_write_counter(struct perf_event
*event
, u32 value
)
1133 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
1134 struct hw_perf_event
*hwc
= &event
->hw
;
1137 if (!armv7_pmnc_counter_valid(cpu_pmu
, idx
))
1138 pr_err("CPU%u writing wrong counter %d\n",
1139 smp_processor_id(), idx
);
1140 else if (idx
== ARMV7_IDX_CYCLE_COUNTER
)
1141 asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value
));
1142 else if (armv7_pmnc_select_counter(idx
) == idx
)
1143 asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (value
));
1146 static inline void armv7_pmnc_write_evtsel(int idx
, u32 val
)
1148 if (armv7_pmnc_select_counter(idx
) == idx
) {
1149 val
&= ARMV7_EVTYPE_MASK
;
1150 asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val
));
1154 static inline int armv7_pmnc_enable_counter(int idx
)
1156 u32 counter
= ARMV7_IDX_TO_COUNTER(idx
);
1157 asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(counter
)));
1161 static inline int armv7_pmnc_disable_counter(int idx
)
1163 u32 counter
= ARMV7_IDX_TO_COUNTER(idx
);
1164 asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(counter
)));
1168 static inline int armv7_pmnc_enable_intens(int idx
)
1170 u32 counter
= ARMV7_IDX_TO_COUNTER(idx
);
1171 asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(counter
)));
1175 static inline int armv7_pmnc_disable_intens(int idx
)
1177 u32 counter
= ARMV7_IDX_TO_COUNTER(idx
);
1178 asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(counter
)));
1180 /* Clear the overflow flag in case an interrupt is pending. */
1181 asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (BIT(counter
)));
1187 static inline u32
armv7_pmnc_getreset_flags(void)
1192 asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val
));
1194 /* Write to clear flags */
1195 val
&= ARMV7_FLAG_MASK
;
1196 asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val
));
1202 static void armv7_pmnc_dump_regs(struct arm_pmu
*cpu_pmu
)
1207 printk(KERN_INFO
"PMNC registers dump:\n");
1209 asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val
));
1210 printk(KERN_INFO
"PMNC =0x%08x\n", val
);
1212 asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val
));
1213 printk(KERN_INFO
"CNTENS=0x%08x\n", val
);
1215 asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val
));
1216 printk(KERN_INFO
"INTENS=0x%08x\n", val
);
1218 asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val
));
1219 printk(KERN_INFO
"FLAGS =0x%08x\n", val
);
1221 asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val
));
1222 printk(KERN_INFO
"SELECT=0x%08x\n", val
);
1224 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val
));
1225 printk(KERN_INFO
"CCNT =0x%08x\n", val
);
1227 for (cnt
= ARMV7_IDX_COUNTER0
;
1228 cnt
<= ARMV7_IDX_COUNTER_LAST(cpu_pmu
); cnt
++) {
1229 armv7_pmnc_select_counter(cnt
);
1230 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val
));
1231 printk(KERN_INFO
"CNT[%d] count =0x%08x\n",
1232 ARMV7_IDX_TO_COUNTER(cnt
), val
);
1233 asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val
));
1234 printk(KERN_INFO
"CNT[%d] evtsel=0x%08x\n",
1235 ARMV7_IDX_TO_COUNTER(cnt
), val
);
1240 static void armv7pmu_enable_event(struct perf_event
*event
)
1242 unsigned long flags
;
1243 struct hw_perf_event
*hwc
= &event
->hw
;
1244 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
1245 struct pmu_hw_events
*events
= cpu_pmu
->get_hw_events();
1248 if (!armv7_pmnc_counter_valid(cpu_pmu
, idx
)) {
1249 pr_err("CPU%u enabling wrong PMNC counter IRQ enable %d\n",
1250 smp_processor_id(), idx
);
1255 * Enable counter and interrupt, and set the counter to count
1256 * the event that we're interested in.
1258 raw_spin_lock_irqsave(&events
->pmu_lock
, flags
);
1263 armv7_pmnc_disable_counter(idx
);
1266 * Set event (if destined for PMNx counters)
1267 * We only need to set the event for the cycle counter if we
1268 * have the ability to perform event filtering.
1270 if (cpu_pmu
->set_event_filter
|| idx
!= ARMV7_IDX_CYCLE_COUNTER
)
1271 armv7_pmnc_write_evtsel(idx
, hwc
->config_base
);
1274 * Enable interrupt for this counter
1276 armv7_pmnc_enable_intens(idx
);
1281 armv7_pmnc_enable_counter(idx
);
1283 raw_spin_unlock_irqrestore(&events
->pmu_lock
, flags
);
1286 static void armv7pmu_disable_event(struct perf_event
*event
)
1288 unsigned long flags
;
1289 struct hw_perf_event
*hwc
= &event
->hw
;
1290 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
1291 struct pmu_hw_events
*events
= cpu_pmu
->get_hw_events();
1294 if (!armv7_pmnc_counter_valid(cpu_pmu
, idx
)) {
1295 pr_err("CPU%u disabling wrong PMNC counter IRQ enable %d\n",
1296 smp_processor_id(), idx
);
1301 * Disable counter and interrupt
1303 raw_spin_lock_irqsave(&events
->pmu_lock
, flags
);
1308 armv7_pmnc_disable_counter(idx
);
1311 * Disable interrupt for this counter
1313 armv7_pmnc_disable_intens(idx
);
1315 raw_spin_unlock_irqrestore(&events
->pmu_lock
, flags
);
1318 static irqreturn_t
armv7pmu_handle_irq(int irq_num
, void *dev
)
1321 struct perf_sample_data data
;
1322 struct arm_pmu
*cpu_pmu
= (struct arm_pmu
*)dev
;
1323 struct pmu_hw_events
*cpuc
= cpu_pmu
->get_hw_events();
1324 struct pt_regs
*regs
;
1328 * Get and reset the IRQ flags
1330 pmnc
= armv7_pmnc_getreset_flags();
1333 * Did an overflow occur?
1335 if (!armv7_pmnc_has_overflowed(pmnc
))
1339 * Handle the counter(s) overflow(s)
1341 regs
= get_irq_regs();
1343 for (idx
= 0; idx
< cpu_pmu
->num_events
; ++idx
) {
1344 struct perf_event
*event
= cpuc
->events
[idx
];
1345 struct hw_perf_event
*hwc
;
1347 /* Ignore if we don't have an event. */
1352 * We have a single interrupt for all counters. Check that
1353 * each counter has overflowed before we process it.
1355 if (!armv7_pmnc_counter_has_overflowed(pmnc
, idx
))
1359 armpmu_event_update(event
);
1360 perf_sample_data_init(&data
, 0, hwc
->last_period
);
1361 if (!armpmu_event_set_period(event
))
1364 if (perf_event_overflow(event
, &data
, regs
))
1365 cpu_pmu
->disable(event
);
1369 * Handle the pending perf events.
1371 * Note: this call *must* be run with interrupts disabled. For
1372 * platforms that can have the PMU interrupts raised as an NMI, this
1380 static void armv7pmu_start(struct arm_pmu
*cpu_pmu
)
1382 unsigned long flags
;
1383 struct pmu_hw_events
*events
= cpu_pmu
->get_hw_events();
1385 raw_spin_lock_irqsave(&events
->pmu_lock
, flags
);
1386 /* Enable all counters */
1387 armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E
);
1388 raw_spin_unlock_irqrestore(&events
->pmu_lock
, flags
);
1391 static void armv7pmu_stop(struct arm_pmu
*cpu_pmu
)
1393 unsigned long flags
;
1394 struct pmu_hw_events
*events
= cpu_pmu
->get_hw_events();
1396 raw_spin_lock_irqsave(&events
->pmu_lock
, flags
);
1397 /* Disable all counters */
1398 armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E
);
1399 raw_spin_unlock_irqrestore(&events
->pmu_lock
, flags
);
1402 static int armv7pmu_get_event_idx(struct pmu_hw_events
*cpuc
,
1403 struct perf_event
*event
)
1406 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
1407 struct hw_perf_event
*hwc
= &event
->hw
;
1408 unsigned long evtype
= hwc
->config_base
& ARMV7_EVTYPE_EVENT
;
1410 /* Always place a cycle counter into the cycle counter. */
1411 if (evtype
== ARMV7_PERFCTR_CPU_CYCLES
) {
1412 if (test_and_set_bit(ARMV7_IDX_CYCLE_COUNTER
, cpuc
->used_mask
))
1415 return ARMV7_IDX_CYCLE_COUNTER
;
1419 * For anything other than a cycle counter, try and use
1420 * the events counters
1422 for (idx
= ARMV7_IDX_COUNTER0
; idx
< cpu_pmu
->num_events
; ++idx
) {
1423 if (!test_and_set_bit(idx
, cpuc
->used_mask
))
1427 /* The counters are all in use. */
1432 * Add an event filter to a given event. This will only work for PMUv2 PMUs.
1434 static int armv7pmu_set_event_filter(struct hw_perf_event
*event
,
1435 struct perf_event_attr
*attr
)
1437 unsigned long config_base
= 0;
1439 if (attr
->exclude_idle
)
1441 if (attr
->exclude_user
)
1442 config_base
|= ARMV7_EXCLUDE_USER
;
1443 if (attr
->exclude_kernel
)
1444 config_base
|= ARMV7_EXCLUDE_PL1
;
1445 if (!attr
->exclude_hv
)
1446 config_base
|= ARMV7_INCLUDE_HYP
;
1449 * Install the filter into config_base as this is used to
1450 * construct the event type.
1452 event
->config_base
= config_base
;
1457 static void armv7pmu_reset(void *info
)
1459 struct arm_pmu
*cpu_pmu
= (struct arm_pmu
*)info
;
1460 u32 idx
, nb_cnt
= cpu_pmu
->num_events
;
1462 /* The counter and interrupt enable registers are unknown at reset. */
1463 for (idx
= ARMV7_IDX_CYCLE_COUNTER
; idx
< nb_cnt
; ++idx
) {
1464 armv7_pmnc_disable_counter(idx
);
1465 armv7_pmnc_disable_intens(idx
);
1468 /* Initialize & Reset PMNC: C and P bits */
1469 armv7_pmnc_write(ARMV7_PMNC_P
| ARMV7_PMNC_C
);
1472 static int armv7_a8_map_event(struct perf_event
*event
)
1474 return armpmu_map_event(event
, &armv7_a8_perf_map
,
1475 &armv7_a8_perf_cache_map
, 0xFF);
1478 static int armv7_a9_map_event(struct perf_event
*event
)
1480 return armpmu_map_event(event
, &armv7_a9_perf_map
,
1481 &armv7_a9_perf_cache_map
, 0xFF);
1484 static int armv7_a5_map_event(struct perf_event
*event
)
1486 return armpmu_map_event(event
, &armv7_a5_perf_map
,
1487 &armv7_a5_perf_cache_map
, 0xFF);
1490 static int armv7_a15_map_event(struct perf_event
*event
)
1492 return armpmu_map_event(event
, &armv7_a15_perf_map
,
1493 &armv7_a15_perf_cache_map
, 0xFF);
1496 static int armv7_a7_map_event(struct perf_event
*event
)
1498 return armpmu_map_event(event
, &armv7_a7_perf_map
,
1499 &armv7_a7_perf_cache_map
, 0xFF);
1502 static int armv7_a12_map_event(struct perf_event
*event
)
1504 return armpmu_map_event(event
, &armv7_a12_perf_map
,
1505 &armv7_a12_perf_cache_map
, 0xFF);
1508 static int krait_map_event(struct perf_event
*event
)
1510 return armpmu_map_event(event
, &krait_perf_map
,
1511 &krait_perf_cache_map
, 0xFFFFF);
1514 static int krait_map_event_no_branch(struct perf_event
*event
)
1516 return armpmu_map_event(event
, &krait_perf_map_no_branch
,
1517 &krait_perf_cache_map
, 0xFFFFF);
1520 static void armv7pmu_init(struct arm_pmu
*cpu_pmu
)
1522 cpu_pmu
->handle_irq
= armv7pmu_handle_irq
;
1523 cpu_pmu
->enable
= armv7pmu_enable_event
;
1524 cpu_pmu
->disable
= armv7pmu_disable_event
;
1525 cpu_pmu
->read_counter
= armv7pmu_read_counter
;
1526 cpu_pmu
->write_counter
= armv7pmu_write_counter
;
1527 cpu_pmu
->get_event_idx
= armv7pmu_get_event_idx
;
1528 cpu_pmu
->start
= armv7pmu_start
;
1529 cpu_pmu
->stop
= armv7pmu_stop
;
1530 cpu_pmu
->reset
= armv7pmu_reset
;
1531 cpu_pmu
->max_period
= (1LLU << 32) - 1;
1534 static u32
armv7_read_num_pmnc_events(void)
1538 /* Read the nb of CNTx counters supported from PMNC */
1539 nb_cnt
= (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT
) & ARMV7_PMNC_N_MASK
;
1541 /* Add the CPU cycles counter and return */
1545 static int armv7_a8_pmu_init(struct arm_pmu
*cpu_pmu
)
1547 armv7pmu_init(cpu_pmu
);
1548 cpu_pmu
->name
= "ARMv7 Cortex-A8";
1549 cpu_pmu
->map_event
= armv7_a8_map_event
;
1550 cpu_pmu
->num_events
= armv7_read_num_pmnc_events();
1554 static int armv7_a9_pmu_init(struct arm_pmu
*cpu_pmu
)
1556 armv7pmu_init(cpu_pmu
);
1557 cpu_pmu
->name
= "ARMv7 Cortex-A9";
1558 cpu_pmu
->map_event
= armv7_a9_map_event
;
1559 cpu_pmu
->num_events
= armv7_read_num_pmnc_events();
1563 static int armv7_a5_pmu_init(struct arm_pmu
*cpu_pmu
)
1565 armv7pmu_init(cpu_pmu
);
1566 cpu_pmu
->name
= "ARMv7 Cortex-A5";
1567 cpu_pmu
->map_event
= armv7_a5_map_event
;
1568 cpu_pmu
->num_events
= armv7_read_num_pmnc_events();
1572 static int armv7_a15_pmu_init(struct arm_pmu
*cpu_pmu
)
1574 armv7pmu_init(cpu_pmu
);
1575 cpu_pmu
->name
= "ARMv7 Cortex-A15";
1576 cpu_pmu
->map_event
= armv7_a15_map_event
;
1577 cpu_pmu
->num_events
= armv7_read_num_pmnc_events();
1578 cpu_pmu
->set_event_filter
= armv7pmu_set_event_filter
;
1582 static int armv7_a7_pmu_init(struct arm_pmu
*cpu_pmu
)
1584 armv7pmu_init(cpu_pmu
);
1585 cpu_pmu
->name
= "ARMv7 Cortex-A7";
1586 cpu_pmu
->map_event
= armv7_a7_map_event
;
1587 cpu_pmu
->num_events
= armv7_read_num_pmnc_events();
1588 cpu_pmu
->set_event_filter
= armv7pmu_set_event_filter
;
1592 static int armv7_a12_pmu_init(struct arm_pmu
*cpu_pmu
)
1594 armv7pmu_init(cpu_pmu
);
1595 cpu_pmu
->name
= "ARMv7 Cortex-A12";
1596 cpu_pmu
->map_event
= armv7_a12_map_event
;
1597 cpu_pmu
->num_events
= armv7_read_num_pmnc_events();
1598 cpu_pmu
->set_event_filter
= armv7pmu_set_event_filter
;
1602 static int armv7_a17_pmu_init(struct arm_pmu
*cpu_pmu
)
1604 armv7_a12_pmu_init(cpu_pmu
);
1605 cpu_pmu
->name
= "ARMv7 Cortex-A17";
1610 * Krait Performance Monitor Region Event Selection Register (PMRESRn)
1613 * +--------------------------------+
1614 * PMRESR0 | EN | CC | CC | CC | CC | N = 1, R = 0
1615 * +--------------------------------+
1616 * PMRESR1 | EN | CC | CC | CC | CC | N = 1, R = 1
1617 * +--------------------------------+
1618 * PMRESR2 | EN | CC | CC | CC | CC | N = 1, R = 2
1619 * +--------------------------------+
1620 * VPMRESR0 | EN | CC | CC | CC | CC | N = 2, R = ?
1621 * +--------------------------------+
1622 * EN | G=3 | G=2 | G=1 | G=0
1626 * hwc->config_base = 0xNRCCG
1628 * N = prefix, 1 for Krait CPU (PMRESRn), 2 for Venum VFP (VPMRESR)
1629 * R = region register
1630 * CC = class of events the group G is choosing from
1631 * G = group or particular event
1633 * Example: 0x12021 is a Krait CPU event in PMRESR2's group 1 with code 2
1635 * A region (R) corresponds to a piece of the CPU (execution unit, instruction
1636 * unit, etc.) while the event code (CC) corresponds to a particular class of
1637 * events (interrupts for example). An event code is broken down into
1638 * groups (G) that can be mapped into the PMU (irq, fiqs, and irq+fiqs for
1642 #define KRAIT_EVENT (1 << 16)
1643 #define VENUM_EVENT (2 << 16)
1644 #define KRAIT_EVENT_MASK (KRAIT_EVENT | VENUM_EVENT)
1645 #define PMRESRn_EN BIT(31)
1647 static u32
krait_read_pmresrn(int n
)
1653 asm volatile("mrc p15, 1, %0, c9, c15, 0" : "=r" (val
));
1656 asm volatile("mrc p15, 1, %0, c9, c15, 1" : "=r" (val
));
1659 asm volatile("mrc p15, 1, %0, c9, c15, 2" : "=r" (val
));
1662 BUG(); /* Should be validated in krait_pmu_get_event_idx() */
1668 static void krait_write_pmresrn(int n
, u32 val
)
1672 asm volatile("mcr p15, 1, %0, c9, c15, 0" : : "r" (val
));
1675 asm volatile("mcr p15, 1, %0, c9, c15, 1" : : "r" (val
));
1678 asm volatile("mcr p15, 1, %0, c9, c15, 2" : : "r" (val
));
1681 BUG(); /* Should be validated in krait_pmu_get_event_idx() */
1685 static u32
krait_read_vpmresr0(void)
1688 asm volatile("mrc p10, 7, %0, c11, c0, 0" : "=r" (val
));
1692 static void krait_write_vpmresr0(u32 val
)
1694 asm volatile("mcr p10, 7, %0, c11, c0, 0" : : "r" (val
));
1697 static void krait_pre_vpmresr0(u32
*venum_orig_val
, u32
*fp_orig_val
)
1702 BUG_ON(preemptible());
1703 /* CPACR Enable CP10 and CP11 access */
1704 *venum_orig_val
= get_copro_access();
1705 venum_new_val
= *venum_orig_val
| CPACC_SVC(10) | CPACC_SVC(11);
1706 set_copro_access(venum_new_val
);
1709 *fp_orig_val
= fmrx(FPEXC
);
1710 fp_new_val
= *fp_orig_val
| FPEXC_EN
;
1711 fmxr(FPEXC
, fp_new_val
);
1714 static void krait_post_vpmresr0(u32 venum_orig_val
, u32 fp_orig_val
)
1716 BUG_ON(preemptible());
1718 fmxr(FPEXC
, fp_orig_val
);
1721 set_copro_access(venum_orig_val
);
1724 static u32
krait_get_pmresrn_event(unsigned int region
)
1726 static const u32 pmresrn_table
[] = { KRAIT_PMRESR0_GROUP0
,
1727 KRAIT_PMRESR1_GROUP0
,
1728 KRAIT_PMRESR2_GROUP0
};
1729 return pmresrn_table
[region
];
1732 static void krait_evt_setup(int idx
, u32 config_base
)
1737 unsigned int region
;
1740 unsigned int group_shift
;
1743 venum_event
= !!(config_base
& VENUM_EVENT
);
1744 region
= (config_base
>> 12) & 0xf;
1745 code
= (config_base
>> 4) & 0xff;
1746 group
= (config_base
>> 0) & 0xf;
1748 group_shift
= group
* 8;
1749 mask
= 0xff << group_shift
;
1751 /* Configure evtsel for the region and group */
1753 val
= KRAIT_VPMRESR0_GROUP0
;
1755 val
= krait_get_pmresrn_event(region
);
1757 /* Mix in mode-exclusion bits */
1758 val
|= config_base
& (ARMV7_EXCLUDE_USER
| ARMV7_EXCLUDE_PL1
);
1759 armv7_pmnc_write_evtsel(idx
, val
);
1761 asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
1764 krait_pre_vpmresr0(&vval
, &fval
);
1765 val
= krait_read_vpmresr0();
1767 val
|= code
<< group_shift
;
1769 krait_write_vpmresr0(val
);
1770 krait_post_vpmresr0(vval
, fval
);
1772 val
= krait_read_pmresrn(region
);
1774 val
|= code
<< group_shift
;
1776 krait_write_pmresrn(region
, val
);
1780 static u32
krait_clear_pmresrn_group(u32 val
, int group
)
1785 group_shift
= group
* 8;
1786 mask
= 0xff << group_shift
;
1789 /* Don't clear enable bit if entire region isn't disabled */
1790 if (val
& ~PMRESRn_EN
)
1791 return val
|= PMRESRn_EN
;
1796 static void krait_clearpmu(u32 config_base
)
1800 unsigned int region
;
1804 venum_event
= !!(config_base
& VENUM_EVENT
);
1805 region
= (config_base
>> 12) & 0xf;
1806 group
= (config_base
>> 0) & 0xf;
1809 krait_pre_vpmresr0(&vval
, &fval
);
1810 val
= krait_read_vpmresr0();
1811 val
= krait_clear_pmresrn_group(val
, group
);
1812 krait_write_vpmresr0(val
);
1813 krait_post_vpmresr0(vval
, fval
);
1815 val
= krait_read_pmresrn(region
);
1816 val
= krait_clear_pmresrn_group(val
, group
);
1817 krait_write_pmresrn(region
, val
);
1821 static void krait_pmu_disable_event(struct perf_event
*event
)
1823 unsigned long flags
;
1824 struct hw_perf_event
*hwc
= &event
->hw
;
1826 struct pmu_hw_events
*events
= cpu_pmu
->get_hw_events();
1828 /* Disable counter and interrupt */
1829 raw_spin_lock_irqsave(&events
->pmu_lock
, flags
);
1831 /* Disable counter */
1832 armv7_pmnc_disable_counter(idx
);
1835 * Clear pmresr code (if destined for PMNx counters)
1837 if (hwc
->config_base
& KRAIT_EVENT_MASK
)
1838 krait_clearpmu(hwc
->config_base
);
1840 /* Disable interrupt for this counter */
1841 armv7_pmnc_disable_intens(idx
);
1843 raw_spin_unlock_irqrestore(&events
->pmu_lock
, flags
);
1846 static void krait_pmu_enable_event(struct perf_event
*event
)
1848 unsigned long flags
;
1849 struct hw_perf_event
*hwc
= &event
->hw
;
1851 struct pmu_hw_events
*events
= cpu_pmu
->get_hw_events();
1854 * Enable counter and interrupt, and set the counter to count
1855 * the event that we're interested in.
1857 raw_spin_lock_irqsave(&events
->pmu_lock
, flags
);
1859 /* Disable counter */
1860 armv7_pmnc_disable_counter(idx
);
1863 * Set event (if destined for PMNx counters)
1864 * We set the event for the cycle counter because we
1865 * have the ability to perform event filtering.
1867 if (hwc
->config_base
& KRAIT_EVENT_MASK
)
1868 krait_evt_setup(idx
, hwc
->config_base
);
1870 armv7_pmnc_write_evtsel(idx
, hwc
->config_base
);
1872 /* Enable interrupt for this counter */
1873 armv7_pmnc_enable_intens(idx
);
1875 /* Enable counter */
1876 armv7_pmnc_enable_counter(idx
);
1878 raw_spin_unlock_irqrestore(&events
->pmu_lock
, flags
);
1881 static void krait_pmu_reset(void *info
)
1885 armv7pmu_reset(info
);
1887 /* Clear all pmresrs */
1888 krait_write_pmresrn(0, 0);
1889 krait_write_pmresrn(1, 0);
1890 krait_write_pmresrn(2, 0);
1892 krait_pre_vpmresr0(&vval
, &fval
);
1893 krait_write_vpmresr0(0);
1894 krait_post_vpmresr0(vval
, fval
);
1897 static int krait_event_to_bit(struct perf_event
*event
, unsigned int region
,
1901 struct hw_perf_event
*hwc
= &event
->hw
;
1902 struct arm_pmu
*cpu_pmu
= to_arm_pmu(event
->pmu
);
1904 if (hwc
->config_base
& VENUM_EVENT
)
1905 bit
= KRAIT_VPMRESR0_GROUP0
;
1907 bit
= krait_get_pmresrn_event(region
);
1908 bit
-= krait_get_pmresrn_event(0);
1911 * Lower bits are reserved for use by the counters (see
1912 * armv7pmu_get_event_idx() for more info)
1914 bit
+= ARMV7_IDX_COUNTER_LAST(cpu_pmu
) + 1;
1920 * We check for column exclusion constraints here.
1921 * Two events cant use the same group within a pmresr register.
1923 static int krait_pmu_get_event_idx(struct pmu_hw_events
*cpuc
,
1924 struct perf_event
*event
)
1928 unsigned int prefix
;
1929 unsigned int region
;
1933 struct hw_perf_event
*hwc
= &event
->hw
;
1935 region
= (hwc
->config_base
>> 12) & 0xf;
1936 code
= (hwc
->config_base
>> 4) & 0xff;
1937 group
= (hwc
->config_base
>> 0) & 0xf;
1938 krait_event
= !!(hwc
->config_base
& KRAIT_EVENT_MASK
);
1941 /* Ignore invalid events */
1942 if (group
> 3 || region
> 2)
1944 prefix
= hwc
->config_base
& KRAIT_EVENT_MASK
;
1945 if (prefix
!= KRAIT_EVENT
&& prefix
!= VENUM_EVENT
)
1947 if (prefix
== VENUM_EVENT
&& (code
& 0xe0))
1950 bit
= krait_event_to_bit(event
, region
, group
);
1951 if (test_and_set_bit(bit
, cpuc
->used_mask
))
1955 idx
= armv7pmu_get_event_idx(cpuc
, event
);
1956 if (idx
< 0 && krait_event
)
1957 clear_bit(bit
, cpuc
->used_mask
);
1962 static void krait_pmu_clear_event_idx(struct pmu_hw_events
*cpuc
,
1963 struct perf_event
*event
)
1966 struct hw_perf_event
*hwc
= &event
->hw
;
1967 unsigned int region
;
1971 region
= (hwc
->config_base
>> 12) & 0xf;
1972 group
= (hwc
->config_base
>> 0) & 0xf;
1973 krait_event
= !!(hwc
->config_base
& KRAIT_EVENT_MASK
);
1976 bit
= krait_event_to_bit(event
, region
, group
);
1977 clear_bit(bit
, cpuc
->used_mask
);
1981 static int krait_pmu_init(struct arm_pmu
*cpu_pmu
)
1983 armv7pmu_init(cpu_pmu
);
1984 cpu_pmu
->name
= "ARMv7 Krait";
1985 /* Some early versions of Krait don't support PC write events */
1986 if (of_property_read_bool(cpu_pmu
->plat_device
->dev
.of_node
,
1987 "qcom,no-pc-write"))
1988 cpu_pmu
->map_event
= krait_map_event_no_branch
;
1990 cpu_pmu
->map_event
= krait_map_event
;
1991 cpu_pmu
->num_events
= armv7_read_num_pmnc_events();
1992 cpu_pmu
->set_event_filter
= armv7pmu_set_event_filter
;
1993 cpu_pmu
->reset
= krait_pmu_reset
;
1994 cpu_pmu
->enable
= krait_pmu_enable_event
;
1995 cpu_pmu
->disable
= krait_pmu_disable_event
;
1996 cpu_pmu
->get_event_idx
= krait_pmu_get_event_idx
;
1997 cpu_pmu
->clear_event_idx
= krait_pmu_clear_event_idx
;
2001 static inline int armv7_a8_pmu_init(struct arm_pmu
*cpu_pmu
)
2006 static inline int armv7_a9_pmu_init(struct arm_pmu
*cpu_pmu
)
2011 static inline int armv7_a5_pmu_init(struct arm_pmu
*cpu_pmu
)
2016 static inline int armv7_a15_pmu_init(struct arm_pmu
*cpu_pmu
)
2021 static inline int armv7_a7_pmu_init(struct arm_pmu
*cpu_pmu
)
2026 static inline int armv7_a12_pmu_init(struct arm_pmu
*cpu_pmu
)
2031 static inline int armv7_a17_pmu_init(struct arm_pmu
*cpu_pmu
)
2036 static inline int krait_pmu_init(struct arm_pmu
*cpu_pmu
)
2040 #endif /* CONFIG_CPU_V7 */