Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
perf_event_v6.c
Go to the documentation of this file.
1 /*
2  * ARMv6 Performance counter handling code.
3  *
4  * Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles
5  *
6  * ARMv6 has 2 configurable performance counters and a single cycle counter.
7  * They all share a single reset bit but can be written to zero so we can use
8  * that for a reset.
9  *
10  * The counters can't be individually enabled or disabled so when we remove
11  * one event and replace it with another we could get spurious counts from the
12  * wrong event. However, we can take advantage of the fact that the
13  * performance counters can export events to the event bus, and the event bus
14  * itself can be monitored. This requires that we *don't* export the events to
15  * the event bus. The procedure for disabling a configurable counter is:
16  * - change the counter to count the ETMEXTOUT[0] signal (0x20). This
17  * effectively stops the counter from counting.
18  * - disable the counter's interrupt generation (each counter has it's
19  * own interrupt enable bit).
20  * Once stopped, the counter value can be written as 0 to reset.
21  *
22  * To enable a counter:
23  * - enable the counter's interrupt generation.
24  * - set the new event type.
25  *
26  * Note: the dedicated cycle counter only counts cycles and can't be
27  * enabled/disabled independently of the others. When we want to disable the
28  * cycle counter, we have to just disable the interrupt reporting and start
29  * ignoring that counter. When re-enabling, we have to reset the value and
30  * enable the interrupt.
31  */
32 
33 #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
34 enum armv6_perf_types {
35  ARMV6_PERFCTR_ICACHE_MISS = 0x0,
36  ARMV6_PERFCTR_IBUF_STALL = 0x1,
37  ARMV6_PERFCTR_DDEP_STALL = 0x2,
38  ARMV6_PERFCTR_ITLB_MISS = 0x3,
39  ARMV6_PERFCTR_DTLB_MISS = 0x4,
40  ARMV6_PERFCTR_BR_EXEC = 0x5,
41  ARMV6_PERFCTR_BR_MISPREDICT = 0x6,
42  ARMV6_PERFCTR_INSTR_EXEC = 0x7,
43  ARMV6_PERFCTR_DCACHE_HIT = 0x9,
44  ARMV6_PERFCTR_DCACHE_ACCESS = 0xA,
45  ARMV6_PERFCTR_DCACHE_MISS = 0xB,
46  ARMV6_PERFCTR_DCACHE_WBACK = 0xC,
47  ARMV6_PERFCTR_SW_PC_CHANGE = 0xD,
48  ARMV6_PERFCTR_MAIN_TLB_MISS = 0xF,
49  ARMV6_PERFCTR_EXPL_D_ACCESS = 0x10,
50  ARMV6_PERFCTR_LSU_FULL_STALL = 0x11,
51  ARMV6_PERFCTR_WBUF_DRAINED = 0x12,
52  ARMV6_PERFCTR_CPU_CYCLES = 0xFF,
53  ARMV6_PERFCTR_NOP = 0x20,
54 };
55 
56 enum armv6_counters {
57  ARMV6_CYCLE_COUNTER = 0,
58  ARMV6_COUNTER0,
59  ARMV6_COUNTER1,
60 };
61 
62 /*
63  * The hardware events that we support. We do support cache operations but
64  * we have harvard caches and no way to combine instruction and data
65  * accesses/misses in hardware.
66  */
67 static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = {
68  [PERF_COUNT_HW_CPU_CYCLES] = ARMV6_PERFCTR_CPU_CYCLES,
69  [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6_PERFCTR_INSTR_EXEC,
72  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC,
73  [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6_PERFCTR_BR_MISPREDICT,
75  [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV6_PERFCTR_IBUF_STALL,
76  [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV6_PERFCTR_LSU_FULL_STALL,
77 };
78 
79 static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
82  [C(L1D)] = {
83  /*
84  * The performance counters don't differentiate between read
85  * and write accesses/misses so this isn't strictly correct,
86  * but it's the best we can do. Writes and reads get
87  * combined.
88  */
89  [C(OP_READ)] = {
90  [C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS,
91  [C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS,
92  },
93  [C(OP_WRITE)] = {
94  [C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS,
95  [C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS,
96  },
97  [C(OP_PREFETCH)] = {
98  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
99  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
100  },
101  },
102  [C(L1I)] = {
103  [C(OP_READ)] = {
104  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
105  [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS,
106  },
107  [C(OP_WRITE)] = {
108  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
109  [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS,
110  },
111  [C(OP_PREFETCH)] = {
112  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
113  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
114  },
115  },
116  [C(LL)] = {
117  [C(OP_READ)] = {
118  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
119  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
120  },
121  [C(OP_WRITE)] = {
122  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
123  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
124  },
125  [C(OP_PREFETCH)] = {
126  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
127  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
128  },
129  },
130  [C(DTLB)] = {
131  /*
132  * The ARM performance counters can count micro DTLB misses,
133  * micro ITLB misses and main TLB misses. There isn't an event
134  * for TLB misses, so use the micro misses here and if users
135  * want the main TLB misses they can use a raw counter.
136  */
137  [C(OP_READ)] = {
138  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
139  [C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS,
140  },
141  [C(OP_WRITE)] = {
142  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
143  [C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS,
144  },
145  [C(OP_PREFETCH)] = {
146  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
147  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
148  },
149  },
150  [C(ITLB)] = {
151  [C(OP_READ)] = {
152  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
153  [C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS,
154  },
155  [C(OP_WRITE)] = {
156  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
157  [C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS,
158  },
159  [C(OP_PREFETCH)] = {
160  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
161  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
162  },
163  },
164  [C(BPU)] = {
165  [C(OP_READ)] = {
166  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
167  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
168  },
169  [C(OP_WRITE)] = {
170  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
171  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
172  },
173  [C(OP_PREFETCH)] = {
174  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
175  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
176  },
177  },
178  [C(NODE)] = {
179  [C(OP_READ)] = {
180  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
181  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
182  },
183  [C(OP_WRITE)] = {
184  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
185  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
186  },
187  [C(OP_PREFETCH)] = {
188  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
189  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
190  },
191  },
192 };
193 
194 enum armv6mpcore_perf_types {
195  ARMV6MPCORE_PERFCTR_ICACHE_MISS = 0x0,
196  ARMV6MPCORE_PERFCTR_IBUF_STALL = 0x1,
197  ARMV6MPCORE_PERFCTR_DDEP_STALL = 0x2,
198  ARMV6MPCORE_PERFCTR_ITLB_MISS = 0x3,
199  ARMV6MPCORE_PERFCTR_DTLB_MISS = 0x4,
200  ARMV6MPCORE_PERFCTR_BR_EXEC = 0x5,
201  ARMV6MPCORE_PERFCTR_BR_NOTPREDICT = 0x6,
202  ARMV6MPCORE_PERFCTR_BR_MISPREDICT = 0x7,
203  ARMV6MPCORE_PERFCTR_INSTR_EXEC = 0x8,
204  ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS = 0xA,
205  ARMV6MPCORE_PERFCTR_DCACHE_RDMISS = 0xB,
206  ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS = 0xC,
207  ARMV6MPCORE_PERFCTR_DCACHE_WRMISS = 0xD,
208  ARMV6MPCORE_PERFCTR_DCACHE_EVICTION = 0xE,
209  ARMV6MPCORE_PERFCTR_SW_PC_CHANGE = 0xF,
210  ARMV6MPCORE_PERFCTR_MAIN_TLB_MISS = 0x10,
211  ARMV6MPCORE_PERFCTR_EXPL_MEM_ACCESS = 0x11,
212  ARMV6MPCORE_PERFCTR_LSU_FULL_STALL = 0x12,
213  ARMV6MPCORE_PERFCTR_WBUF_DRAINED = 0x13,
214  ARMV6MPCORE_PERFCTR_CPU_CYCLES = 0xFF,
215 };
216 
217 /*
218  * The hardware events that we support. We do support cache operations but
219  * we have harvard caches and no way to combine instruction and data
220  * accesses/misses in hardware.
221  */
222 static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX] = {
223  [PERF_COUNT_HW_CPU_CYCLES] = ARMV6MPCORE_PERFCTR_CPU_CYCLES,
224  [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_INSTR_EXEC,
227  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC,
228  [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6MPCORE_PERFCTR_BR_MISPREDICT,
230  [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV6MPCORE_PERFCTR_IBUF_STALL,
231  [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV6MPCORE_PERFCTR_LSU_FULL_STALL,
232 };
233 
234 static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
237  [C(L1D)] = {
238  [C(OP_READ)] = {
239  [C(RESULT_ACCESS)] =
240  ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS,
241  [C(RESULT_MISS)] =
242  ARMV6MPCORE_PERFCTR_DCACHE_RDMISS,
243  },
244  [C(OP_WRITE)] = {
245  [C(RESULT_ACCESS)] =
246  ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS,
247  [C(RESULT_MISS)] =
248  ARMV6MPCORE_PERFCTR_DCACHE_WRMISS,
249  },
250  [C(OP_PREFETCH)] = {
251  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
252  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
253  },
254  },
255  [C(L1I)] = {
256  [C(OP_READ)] = {
257  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
258  [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
259  },
260  [C(OP_WRITE)] = {
261  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
262  [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
263  },
264  [C(OP_PREFETCH)] = {
265  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
266  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
267  },
268  },
269  [C(LL)] = {
270  [C(OP_READ)] = {
271  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
272  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
273  },
274  [C(OP_WRITE)] = {
275  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
276  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
277  },
278  [C(OP_PREFETCH)] = {
279  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
280  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
281  },
282  },
283  [C(DTLB)] = {
284  /*
285  * The ARM performance counters can count micro DTLB misses,
286  * micro ITLB misses and main TLB misses. There isn't an event
287  * for TLB misses, so use the micro misses here and if users
288  * want the main TLB misses they can use a raw counter.
289  */
290  [C(OP_READ)] = {
291  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
292  [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS,
293  },
294  [C(OP_WRITE)] = {
295  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
296  [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS,
297  },
298  [C(OP_PREFETCH)] = {
299  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
300  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
301  },
302  },
303  [C(ITLB)] = {
304  [C(OP_READ)] = {
305  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
306  [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ITLB_MISS,
307  },
308  [C(OP_WRITE)] = {
309  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
310  [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ITLB_MISS,
311  },
312  [C(OP_PREFETCH)] = {
313  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
314  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
315  },
316  },
317  [C(BPU)] = {
318  [C(OP_READ)] = {
319  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
320  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
321  },
322  [C(OP_WRITE)] = {
323  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
324  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
325  },
326  [C(OP_PREFETCH)] = {
327  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
328  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
329  },
330  },
331  [C(NODE)] = {
332  [C(OP_READ)] = {
333  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
334  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
335  },
336  [C(OP_WRITE)] = {
337  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
338  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
339  },
340  [C(OP_PREFETCH)] = {
341  [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
342  [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
343  },
344  },
345 };
346 
347 static inline unsigned long
348 armv6_pmcr_read(void)
349 {
350  u32 val;
351  asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r"(val));
352  return val;
353 }
354 
355 static inline void
356 armv6_pmcr_write(unsigned long val)
357 {
358  asm volatile("mcr p15, 0, %0, c15, c12, 0" : : "r"(val));
359 }
360 
361 #define ARMV6_PMCR_ENABLE (1 << 0)
362 #define ARMV6_PMCR_CTR01_RESET (1 << 1)
363 #define ARMV6_PMCR_CCOUNT_RESET (1 << 2)
364 #define ARMV6_PMCR_CCOUNT_DIV (1 << 3)
365 #define ARMV6_PMCR_COUNT0_IEN (1 << 4)
366 #define ARMV6_PMCR_COUNT1_IEN (1 << 5)
367 #define ARMV6_PMCR_CCOUNT_IEN (1 << 6)
368 #define ARMV6_PMCR_COUNT0_OVERFLOW (1 << 8)
369 #define ARMV6_PMCR_COUNT1_OVERFLOW (1 << 9)
370 #define ARMV6_PMCR_CCOUNT_OVERFLOW (1 << 10)
371 #define ARMV6_PMCR_EVT_COUNT0_SHIFT 20
372 #define ARMV6_PMCR_EVT_COUNT0_MASK (0xFF << ARMV6_PMCR_EVT_COUNT0_SHIFT)
373 #define ARMV6_PMCR_EVT_COUNT1_SHIFT 12
374 #define ARMV6_PMCR_EVT_COUNT1_MASK (0xFF << ARMV6_PMCR_EVT_COUNT1_SHIFT)
375 
376 #define ARMV6_PMCR_OVERFLOWED_MASK \
377  (ARMV6_PMCR_COUNT0_OVERFLOW | ARMV6_PMCR_COUNT1_OVERFLOW | \
378  ARMV6_PMCR_CCOUNT_OVERFLOW)
379 
380 static inline int
381 armv6_pmcr_has_overflowed(unsigned long pmcr)
382 {
383  return pmcr & ARMV6_PMCR_OVERFLOWED_MASK;
384 }
385 
386 static inline int
387 armv6_pmcr_counter_has_overflowed(unsigned long pmcr,
388  enum armv6_counters counter)
389 {
390  int ret = 0;
391 
392  if (ARMV6_CYCLE_COUNTER == counter)
393  ret = pmcr & ARMV6_PMCR_CCOUNT_OVERFLOW;
394  else if (ARMV6_COUNTER0 == counter)
395  ret = pmcr & ARMV6_PMCR_COUNT0_OVERFLOW;
396  else if (ARMV6_COUNTER1 == counter)
397  ret = pmcr & ARMV6_PMCR_COUNT1_OVERFLOW;
398  else
399  WARN_ONCE(1, "invalid counter number (%d)\n", counter);
400 
401  return ret;
402 }
403 
404 static inline u32
405 armv6pmu_read_counter(int counter)
406 {
407  unsigned long value = 0;
408 
409  if (ARMV6_CYCLE_COUNTER == counter)
410  asm volatile("mrc p15, 0, %0, c15, c12, 1" : "=r"(value));
411  else if (ARMV6_COUNTER0 == counter)
412  asm volatile("mrc p15, 0, %0, c15, c12, 2" : "=r"(value));
413  else if (ARMV6_COUNTER1 == counter)
414  asm volatile("mrc p15, 0, %0, c15, c12, 3" : "=r"(value));
415  else
416  WARN_ONCE(1, "invalid counter number (%d)\n", counter);
417 
418  return value;
419 }
420 
421 static inline void
422 armv6pmu_write_counter(int counter,
423  u32 value)
424 {
425  if (ARMV6_CYCLE_COUNTER == counter)
426  asm volatile("mcr p15, 0, %0, c15, c12, 1" : : "r"(value));
427  else if (ARMV6_COUNTER0 == counter)
428  asm volatile("mcr p15, 0, %0, c15, c12, 2" : : "r"(value));
429  else if (ARMV6_COUNTER1 == counter)
430  asm volatile("mcr p15, 0, %0, c15, c12, 3" : : "r"(value));
431  else
432  WARN_ONCE(1, "invalid counter number (%d)\n", counter);
433 }
434 
435 static void
436 armv6pmu_enable_event(struct hw_perf_event *hwc,
437  int idx)
438 {
439  unsigned long val, mask, evt, flags;
440  struct pmu_hw_events *events = cpu_pmu->get_hw_events();
441 
442  if (ARMV6_CYCLE_COUNTER == idx) {
443  mask = 0;
444  evt = ARMV6_PMCR_CCOUNT_IEN;
445  } else if (ARMV6_COUNTER0 == idx) {
446  mask = ARMV6_PMCR_EVT_COUNT0_MASK;
447  evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT0_SHIFT) |
448  ARMV6_PMCR_COUNT0_IEN;
449  } else if (ARMV6_COUNTER1 == idx) {
450  mask = ARMV6_PMCR_EVT_COUNT1_MASK;
451  evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT1_SHIFT) |
452  ARMV6_PMCR_COUNT1_IEN;
453  } else {
454  WARN_ONCE(1, "invalid counter number (%d)\n", idx);
455  return;
456  }
457 
458  /*
459  * Mask out the current event and set the counter to count the event
460  * that we're interested in.
461  */
462  raw_spin_lock_irqsave(&events->pmu_lock, flags);
463  val = armv6_pmcr_read();
464  val &= ~mask;
465  val |= evt;
466  armv6_pmcr_write(val);
467  raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
468 }
469 
470 static irqreturn_t
471 armv6pmu_handle_irq(int irq_num,
472  void *dev)
473 {
474  unsigned long pmcr = armv6_pmcr_read();
475  struct perf_sample_data data;
476  struct pmu_hw_events *cpuc;
477  struct pt_regs *regs;
478  int idx;
479 
480  if (!armv6_pmcr_has_overflowed(pmcr))
481  return IRQ_NONE;
482 
483  regs = get_irq_regs();
484 
485  /*
486  * The interrupts are cleared by writing the overflow flags back to
487  * the control register. All of the other bits don't have any effect
488  * if they are rewritten, so write the whole value back.
489  */
490  armv6_pmcr_write(pmcr);
491 
492  cpuc = &__get_cpu_var(cpu_hw_events);
493  for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
494  struct perf_event *event = cpuc->events[idx];
495  struct hw_perf_event *hwc;
496 
497  /* Ignore if we don't have an event. */
498  if (!event)
499  continue;
500 
501  /*
502  * We have a single interrupt for all counters. Check that
503  * each counter has overflowed before we process it.
504  */
505  if (!armv6_pmcr_counter_has_overflowed(pmcr, idx))
506  continue;
507 
508  hwc = &event->hw;
509  armpmu_event_update(event, hwc, idx);
510  perf_sample_data_init(&data, 0, hwc->last_period);
511  if (!armpmu_event_set_period(event, hwc, idx))
512  continue;
513 
514  if (perf_event_overflow(event, &data, regs))
515  cpu_pmu->disable(hwc, idx);
516  }
517 
518  /*
519  * Handle the pending perf events.
520  *
521  * Note: this call *must* be run with interrupts disabled. For
522  * platforms that can have the PMU interrupts raised as an NMI, this
523  * will not work.
524  */
525  irq_work_run();
526 
527  return IRQ_HANDLED;
528 }
529 
530 static void
531 armv6pmu_start(void)
532 {
533  unsigned long flags, val;
534  struct pmu_hw_events *events = cpu_pmu->get_hw_events();
535 
536  raw_spin_lock_irqsave(&events->pmu_lock, flags);
537  val = armv6_pmcr_read();
538  val |= ARMV6_PMCR_ENABLE;
539  armv6_pmcr_write(val);
540  raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
541 }
542 
543 static void
544 armv6pmu_stop(void)
545 {
546  unsigned long flags, val;
547  struct pmu_hw_events *events = cpu_pmu->get_hw_events();
548 
549  raw_spin_lock_irqsave(&events->pmu_lock, flags);
550  val = armv6_pmcr_read();
551  val &= ~ARMV6_PMCR_ENABLE;
552  armv6_pmcr_write(val);
553  raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
554 }
555 
556 static int
557 armv6pmu_get_event_idx(struct pmu_hw_events *cpuc,
558  struct hw_perf_event *event)
559 {
560  /* Always place a cycle counter into the cycle counter. */
561  if (ARMV6_PERFCTR_CPU_CYCLES == event->config_base) {
562  if (test_and_set_bit(ARMV6_CYCLE_COUNTER, cpuc->used_mask))
563  return -EAGAIN;
564 
565  return ARMV6_CYCLE_COUNTER;
566  } else {
567  /*
568  * For anything other than a cycle counter, try and use
569  * counter0 and counter1.
570  */
571  if (!test_and_set_bit(ARMV6_COUNTER1, cpuc->used_mask))
572  return ARMV6_COUNTER1;
573 
574  if (!test_and_set_bit(ARMV6_COUNTER0, cpuc->used_mask))
575  return ARMV6_COUNTER0;
576 
577  /* The counters are all in use. */
578  return -EAGAIN;
579  }
580 }
581 
582 static void
583 armv6pmu_disable_event(struct hw_perf_event *hwc,
584  int idx)
585 {
586  unsigned long val, mask, evt, flags;
587  struct pmu_hw_events *events = cpu_pmu->get_hw_events();
588 
589  if (ARMV6_CYCLE_COUNTER == idx) {
590  mask = ARMV6_PMCR_CCOUNT_IEN;
591  evt = 0;
592  } else if (ARMV6_COUNTER0 == idx) {
593  mask = ARMV6_PMCR_COUNT0_IEN | ARMV6_PMCR_EVT_COUNT0_MASK;
594  evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT0_SHIFT;
595  } else if (ARMV6_COUNTER1 == idx) {
596  mask = ARMV6_PMCR_COUNT1_IEN | ARMV6_PMCR_EVT_COUNT1_MASK;
597  evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT1_SHIFT;
598  } else {
599  WARN_ONCE(1, "invalid counter number (%d)\n", idx);
600  return;
601  }
602 
603  /*
604  * Mask out the current event and set the counter to count the number
605  * of ETM bus signal assertion cycles. The external reporting should
606  * be disabled and so this should never increment.
607  */
608  raw_spin_lock_irqsave(&events->pmu_lock, flags);
609  val = armv6_pmcr_read();
610  val &= ~mask;
611  val |= evt;
612  armv6_pmcr_write(val);
613  raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
614 }
615 
616 static void
617 armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,
618  int idx)
619 {
620  unsigned long val, mask, flags, evt = 0;
621  struct pmu_hw_events *events = cpu_pmu->get_hw_events();
622 
623  if (ARMV6_CYCLE_COUNTER == idx) {
624  mask = ARMV6_PMCR_CCOUNT_IEN;
625  } else if (ARMV6_COUNTER0 == idx) {
626  mask = ARMV6_PMCR_COUNT0_IEN;
627  } else if (ARMV6_COUNTER1 == idx) {
628  mask = ARMV6_PMCR_COUNT1_IEN;
629  } else {
630  WARN_ONCE(1, "invalid counter number (%d)\n", idx);
631  return;
632  }
633 
634  /*
635  * Unlike UP ARMv6, we don't have a way of stopping the counters. We
636  * simply disable the interrupt reporting.
637  */
638  raw_spin_lock_irqsave(&events->pmu_lock, flags);
639  val = armv6_pmcr_read();
640  val &= ~mask;
641  val |= evt;
642  armv6_pmcr_write(val);
643  raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
644 }
645 
646 static int armv6_map_event(struct perf_event *event)
647 {
648  return armpmu_map_event(event, &armv6_perf_map,
649  &armv6_perf_cache_map, 0xFF);
650 }
651 
652 static struct arm_pmu armv6pmu = {
653  .name = "v6",
654  .handle_irq = armv6pmu_handle_irq,
655  .enable = armv6pmu_enable_event,
656  .disable = armv6pmu_disable_event,
657  .read_counter = armv6pmu_read_counter,
658  .write_counter = armv6pmu_write_counter,
659  .get_event_idx = armv6pmu_get_event_idx,
660  .start = armv6pmu_start,
661  .stop = armv6pmu_stop,
662  .map_event = armv6_map_event,
663  .num_events = 3,
664  .max_period = (1LLU << 32) - 1,
665 };
666 
667 static struct arm_pmu *__devinit armv6pmu_init(void)
668 {
669  return &armv6pmu;
670 }
671 
672 /*
673  * ARMv6mpcore is almost identical to single core ARMv6 with the exception
674  * that some of the events have different enumerations and that there is no
675  * *hack* to stop the programmable counters. To stop the counters we simply
676  * disable the interrupt reporting and update the event. When unthrottling we
677  * reset the period and enable the interrupt reporting.
678  */
679 
680 static int armv6mpcore_map_event(struct perf_event *event)
681 {
682  return armpmu_map_event(event, &armv6mpcore_perf_map,
683  &armv6mpcore_perf_cache_map, 0xFF);
684 }
685 
686 static struct arm_pmu armv6mpcore_pmu = {
687  .name = "v6mpcore",
688  .handle_irq = armv6pmu_handle_irq,
689  .enable = armv6pmu_enable_event,
690  .disable = armv6mpcore_pmu_disable_event,
691  .read_counter = armv6pmu_read_counter,
692  .write_counter = armv6pmu_write_counter,
693  .get_event_idx = armv6pmu_get_event_idx,
694  .start = armv6pmu_start,
695  .stop = armv6pmu_stop,
696  .map_event = armv6mpcore_map_event,
697  .num_events = 3,
698  .max_period = (1LLU << 32) - 1,
699 };
700 
701 static struct arm_pmu *__devinit armv6mpcore_pmu_init(void)
702 {
703  return &armv6mpcore_pmu;
704 }
705 #else
706 static struct arm_pmu *__devinit armv6pmu_init(void)
707 {
708  return NULL;
709 }
710 
711 static struct arm_pmu *__devinit armv6mpcore_pmu_init(void)
712 {
713  return NULL;
714 }
715 #endif /* CONFIG_CPU_V6 || CONFIG_CPU_V6K */