2 * Performance event support - Freescale Embedded Performance Monitor
4 * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
5 * Copyright 2010 Freescale Semiconductor, Inc.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 #include <linux/perf_event.h>
15 #include <linux/percpu.h>
16 #include <linux/hardirq.h>
17 #include <asm/reg_fsl_emb.h>
19 #include <asm/machdep.h>
20 #include <asm/firmware.h>
21 #include <asm/ptrace.h>
23 struct cpu_hw_events
{
27 struct perf_event
*event
[MAX_HWEVENTS
];
29 static DEFINE_PER_CPU(struct cpu_hw_events
, cpu_hw_events
);
31 static struct fsl_emb_pmu
*ppmu
;
33 /* Number of perf_events counting hardware events */
34 static atomic_t num_events
;
35 /* Used to avoid races in calling reserve/release_pmc_hardware */
36 static DEFINE_MUTEX(pmc_reserve_mutex
);
39 * If interrupts were soft-disabled when a PMU interrupt occurs, treat
42 static inline int perf_intr_is_nmi(struct pt_regs
*regs
)
51 static void perf_event_interrupt(struct pt_regs
*regs
);
54 * Read one performance monitor counter (PMC).
56 static unsigned long read_pmc(int idx
)
62 val
= mfpmr(PMRN_PMC0
);
65 val
= mfpmr(PMRN_PMC1
);
68 val
= mfpmr(PMRN_PMC2
);
71 val
= mfpmr(PMRN_PMC3
);
74 val
= mfpmr(PMRN_PMC4
);
77 val
= mfpmr(PMRN_PMC5
);
80 printk(KERN_ERR
"oops trying to read PMC%d\n", idx
);
89 static void write_pmc(int idx
, unsigned long val
)
93 mtpmr(PMRN_PMC0
, val
);
96 mtpmr(PMRN_PMC1
, val
);
99 mtpmr(PMRN_PMC2
, val
);
102 mtpmr(PMRN_PMC3
, val
);
105 mtpmr(PMRN_PMC4
, val
);
108 mtpmr(PMRN_PMC5
, val
);
111 printk(KERN_ERR
"oops trying to write PMC%d\n", idx
);
118 * Write one local control A register
120 static void write_pmlca(int idx
, unsigned long val
)
124 mtpmr(PMRN_PMLCA0
, val
);
127 mtpmr(PMRN_PMLCA1
, val
);
130 mtpmr(PMRN_PMLCA2
, val
);
133 mtpmr(PMRN_PMLCA3
, val
);
136 mtpmr(PMRN_PMLCA4
, val
);
139 mtpmr(PMRN_PMLCA5
, val
);
142 printk(KERN_ERR
"oops trying to write PMLCA%d\n", idx
);
149 * Write one local control B register
151 static void write_pmlcb(int idx
, unsigned long val
)
155 mtpmr(PMRN_PMLCB0
, val
);
158 mtpmr(PMRN_PMLCB1
, val
);
161 mtpmr(PMRN_PMLCB2
, val
);
164 mtpmr(PMRN_PMLCB3
, val
);
167 mtpmr(PMRN_PMLCB4
, val
);
170 mtpmr(PMRN_PMLCB5
, val
);
173 printk(KERN_ERR
"oops trying to write PMLCB%d\n", idx
);
179 static void fsl_emb_pmu_read(struct perf_event
*event
)
181 s64 val
, delta
, prev
;
183 if (event
->hw
.state
& PERF_HES_STOPPED
)
187 * Performance monitor interrupts come even when interrupts
188 * are soft-disabled, as long as interrupts are hard-enabled.
189 * Therefore we treat them like NMIs.
192 prev
= local64_read(&event
->hw
.prev_count
);
194 val
= read_pmc(event
->hw
.idx
);
195 } while (local64_cmpxchg(&event
->hw
.prev_count
, prev
, val
) != prev
);
197 /* The counters are only 32 bits wide */
198 delta
= (val
- prev
) & 0xfffffffful
;
199 local64_add(delta
, &event
->count
);
200 local64_sub(delta
, &event
->hw
.period_left
);
204 * Disable all events to prevent PMU interrupts and to allow
205 * events to be added or removed.
207 static void fsl_emb_pmu_disable(struct pmu
*pmu
)
209 struct cpu_hw_events
*cpuhw
;
212 local_irq_save(flags
);
213 cpuhw
= this_cpu_ptr(&cpu_hw_events
);
215 if (!cpuhw
->disabled
) {
219 * Check if we ever enabled the PMU on this cpu.
221 if (!cpuhw
->pmcs_enabled
) {
223 cpuhw
->pmcs_enabled
= 1;
226 if (atomic_read(&num_events
)) {
228 * Set the 'freeze all counters' bit, and disable
229 * interrupts. The barrier is to make sure the
230 * mtpmr has been executed and the PMU has frozen
231 * the events before we return.
234 mtpmr(PMRN_PMGC0
, PMGC0_FAC
);
238 local_irq_restore(flags
);
242 * Re-enable all events if disable == 0.
243 * If we were previously disabled and events were added, then
244 * put the new config on the PMU.
246 static void fsl_emb_pmu_enable(struct pmu
*pmu
)
248 struct cpu_hw_events
*cpuhw
;
251 local_irq_save(flags
);
252 cpuhw
= this_cpu_ptr(&cpu_hw_events
);
253 if (!cpuhw
->disabled
)
257 ppc_set_pmu_inuse(cpuhw
->n_events
!= 0);
259 if (cpuhw
->n_events
> 0) {
260 mtpmr(PMRN_PMGC0
, PMGC0_PMIE
| PMGC0_FCECE
);
265 local_irq_restore(flags
);
268 static int collect_events(struct perf_event
*group
, int max_count
,
269 struct perf_event
*ctrs
[])
272 struct perf_event
*event
;
274 if (!is_software_event(group
)) {
280 list_for_each_entry(event
, &group
->sibling_list
, group_entry
) {
281 if (!is_software_event(event
) &&
282 event
->state
!= PERF_EVENT_STATE_OFF
) {
292 /* context locked on entry */
293 static int fsl_emb_pmu_add(struct perf_event
*event
, int flags
)
295 struct cpu_hw_events
*cpuhw
;
297 int num_counters
= ppmu
->n_counter
;
301 perf_pmu_disable(event
->pmu
);
302 cpuhw
= &get_cpu_var(cpu_hw_events
);
304 if (event
->hw
.config
& FSL_EMB_EVENT_RESTRICTED
)
305 num_counters
= ppmu
->n_restricted
;
308 * Allocate counters from top-down, so that restricted-capable
309 * counters are kept free as long as possible.
311 for (i
= num_counters
- 1; i
>= 0; i
--) {
322 cpuhw
->event
[i
] = event
;
326 if (event
->hw
.sample_period
) {
327 s64 left
= local64_read(&event
->hw
.period_left
);
328 if (left
< 0x80000000L
)
329 val
= 0x80000000L
- left
;
331 local64_set(&event
->hw
.prev_count
, val
);
333 if (unlikely(!(flags
& PERF_EF_START
))) {
334 event
->hw
.state
= PERF_HES_STOPPED
| PERF_HES_UPTODATE
;
337 event
->hw
.state
&= ~(PERF_HES_STOPPED
| PERF_HES_UPTODATE
);
341 perf_event_update_userpage(event
);
343 write_pmlcb(i
, event
->hw
.config
>> 32);
344 write_pmlca(i
, event
->hw
.config_base
);
348 put_cpu_var(cpu_hw_events
);
349 perf_pmu_enable(event
->pmu
);
353 /* context locked on entry */
354 static void fsl_emb_pmu_del(struct perf_event
*event
, int flags
)
356 struct cpu_hw_events
*cpuhw
;
357 int i
= event
->hw
.idx
;
359 perf_pmu_disable(event
->pmu
);
363 fsl_emb_pmu_read(event
);
365 cpuhw
= &get_cpu_var(cpu_hw_events
);
367 WARN_ON(event
!= cpuhw
->event
[event
->hw
.idx
]);
373 cpuhw
->event
[i
] = NULL
;
377 * TODO: if at least one restricted event exists, and we
378 * just freed up a non-restricted-capable counter, and
379 * there is a restricted-capable counter occupied by
380 * a non-restricted event, migrate that event to the
387 perf_pmu_enable(event
->pmu
);
388 put_cpu_var(cpu_hw_events
);
391 static void fsl_emb_pmu_start(struct perf_event
*event
, int ef_flags
)
397 if (event
->hw
.idx
< 0 || !event
->hw
.sample_period
)
400 if (!(event
->hw
.state
& PERF_HES_STOPPED
))
403 if (ef_flags
& PERF_EF_RELOAD
)
404 WARN_ON_ONCE(!(event
->hw
.state
& PERF_HES_UPTODATE
));
406 local_irq_save(flags
);
407 perf_pmu_disable(event
->pmu
);
410 left
= local64_read(&event
->hw
.period_left
);
412 if (left
< 0x80000000L
)
413 val
= 0x80000000L
- left
;
414 write_pmc(event
->hw
.idx
, val
);
416 perf_event_update_userpage(event
);
417 perf_pmu_enable(event
->pmu
);
418 local_irq_restore(flags
);
421 static void fsl_emb_pmu_stop(struct perf_event
*event
, int ef_flags
)
425 if (event
->hw
.idx
< 0 || !event
->hw
.sample_period
)
428 if (event
->hw
.state
& PERF_HES_STOPPED
)
431 local_irq_save(flags
);
432 perf_pmu_disable(event
->pmu
);
434 fsl_emb_pmu_read(event
);
435 event
->hw
.state
|= PERF_HES_STOPPED
| PERF_HES_UPTODATE
;
436 write_pmc(event
->hw
.idx
, 0);
438 perf_event_update_userpage(event
);
439 perf_pmu_enable(event
->pmu
);
440 local_irq_restore(flags
);
444 * Release the PMU if this is the last perf_event.
446 static void hw_perf_event_destroy(struct perf_event
*event
)
448 if (!atomic_add_unless(&num_events
, -1, 1)) {
449 mutex_lock(&pmc_reserve_mutex
);
450 if (atomic_dec_return(&num_events
) == 0)
451 release_pmc_hardware();
452 mutex_unlock(&pmc_reserve_mutex
);
457 * Translate a generic cache event_id config to a raw event_id code.
459 static int hw_perf_cache_event(u64 config
, u64
*eventp
)
461 unsigned long type
, op
, result
;
464 if (!ppmu
->cache_events
)
468 type
= config
& 0xff;
469 op
= (config
>> 8) & 0xff;
470 result
= (config
>> 16) & 0xff;
472 if (type
>= PERF_COUNT_HW_CACHE_MAX
||
473 op
>= PERF_COUNT_HW_CACHE_OP_MAX
||
474 result
>= PERF_COUNT_HW_CACHE_RESULT_MAX
)
477 ev
= (*ppmu
->cache_events
)[type
][op
][result
];
486 static int fsl_emb_pmu_event_init(struct perf_event
*event
)
489 struct perf_event
*events
[MAX_HWEVENTS
];
495 if (ppmu
->n_counter
> MAX_HWEVENTS
) {
496 WARN(1, "No. of perf counters (%d) is higher than max array size(%d)\n",
497 ppmu
->n_counter
, MAX_HWEVENTS
);
498 ppmu
->n_counter
= MAX_HWEVENTS
;
501 switch (event
->attr
.type
) {
502 case PERF_TYPE_HARDWARE
:
503 ev
= event
->attr
.config
;
504 if (ev
>= ppmu
->n_generic
|| ppmu
->generic_events
[ev
] == 0)
506 ev
= ppmu
->generic_events
[ev
];
509 case PERF_TYPE_HW_CACHE
:
510 err
= hw_perf_cache_event(event
->attr
.config
, &ev
);
516 ev
= event
->attr
.config
;
523 event
->hw
.config
= ppmu
->xlate_event(ev
);
524 if (!(event
->hw
.config
& FSL_EMB_EVENT_VALID
))
528 * If this is in a group, check if it can go on with all the
529 * other hardware events in the group. We assume the event
530 * hasn't been linked into its leader's sibling list at this point.
533 if (event
->group_leader
!= event
) {
534 n
= collect_events(event
->group_leader
,
535 ppmu
->n_counter
- 1, events
);
540 if (event
->hw
.config
& FSL_EMB_EVENT_RESTRICTED
) {
542 for (i
= 0; i
< n
; i
++) {
543 if (events
[i
]->hw
.config
& FSL_EMB_EVENT_RESTRICTED
)
547 if (num_restricted
>= ppmu
->n_restricted
)
553 event
->hw
.config_base
= PMLCA_CE
| PMLCA_FCM1
|
554 (u32
)((ev
<< 16) & PMLCA_EVENT_MASK
);
556 if (event
->attr
.exclude_user
)
557 event
->hw
.config_base
|= PMLCA_FCU
;
558 if (event
->attr
.exclude_kernel
)
559 event
->hw
.config_base
|= PMLCA_FCS
;
560 if (event
->attr
.exclude_idle
)
563 event
->hw
.last_period
= event
->hw
.sample_period
;
564 local64_set(&event
->hw
.period_left
, event
->hw
.last_period
);
567 * See if we need to reserve the PMU.
568 * If no events are currently in use, then we have to take a
569 * mutex to ensure that we don't race with another task doing
570 * reserve_pmc_hardware or release_pmc_hardware.
573 if (!atomic_inc_not_zero(&num_events
)) {
574 mutex_lock(&pmc_reserve_mutex
);
575 if (atomic_read(&num_events
) == 0 &&
576 reserve_pmc_hardware(perf_event_interrupt
))
579 atomic_inc(&num_events
);
580 mutex_unlock(&pmc_reserve_mutex
);
582 mtpmr(PMRN_PMGC0
, PMGC0_FAC
);
585 event
->destroy
= hw_perf_event_destroy
;
590 static struct pmu fsl_emb_pmu
= {
591 .pmu_enable
= fsl_emb_pmu_enable
,
592 .pmu_disable
= fsl_emb_pmu_disable
,
593 .event_init
= fsl_emb_pmu_event_init
,
594 .add
= fsl_emb_pmu_add
,
595 .del
= fsl_emb_pmu_del
,
596 .start
= fsl_emb_pmu_start
,
597 .stop
= fsl_emb_pmu_stop
,
598 .read
= fsl_emb_pmu_read
,
602 * A counter has overflowed; update its count and record
603 * things if requested. Note that interrupts are hard-disabled
604 * here so there is no possibility of being interrupted.
606 static void record_and_restart(struct perf_event
*event
, unsigned long val
,
607 struct pt_regs
*regs
)
609 u64 period
= event
->hw
.sample_period
;
610 s64 prev
, delta
, left
;
613 if (event
->hw
.state
& PERF_HES_STOPPED
) {
614 write_pmc(event
->hw
.idx
, 0);
618 /* we don't have to worry about interrupts here */
619 prev
= local64_read(&event
->hw
.prev_count
);
620 delta
= (val
- prev
) & 0xfffffffful
;
621 local64_add(delta
, &event
->count
);
624 * See if the total period for this event has expired,
625 * and update for the next period.
628 left
= local64_read(&event
->hw
.period_left
) - delta
;
635 event
->hw
.last_period
= event
->hw
.sample_period
;
637 if (left
< 0x80000000LL
)
638 val
= 0x80000000LL
- left
;
641 write_pmc(event
->hw
.idx
, val
);
642 local64_set(&event
->hw
.prev_count
, val
);
643 local64_set(&event
->hw
.period_left
, left
);
644 perf_event_update_userpage(event
);
647 * Finally record data if requested.
650 struct perf_sample_data data
;
652 perf_sample_data_init(&data
, 0, event
->hw
.last_period
);
654 if (perf_event_overflow(event
, &data
, regs
))
655 fsl_emb_pmu_stop(event
, 0);
659 static void perf_event_interrupt(struct pt_regs
*regs
)
662 struct cpu_hw_events
*cpuhw
= this_cpu_ptr(&cpu_hw_events
);
663 struct perf_event
*event
;
668 nmi
= perf_intr_is_nmi(regs
);
674 for (i
= 0; i
< ppmu
->n_counter
; ++i
) {
675 event
= cpuhw
->event
[i
];
680 /* event has overflowed */
682 record_and_restart(event
, val
, regs
);
685 * Disabled counter is negative,
686 * reset it just in case.
693 /* PMM will keep counters frozen until we return from the interrupt. */
694 mtmsr(mfmsr() | MSR_PMM
);
695 mtpmr(PMRN_PMGC0
, PMGC0_PMIE
| PMGC0_FCECE
);
704 void hw_perf_event_setup(int cpu
)
706 struct cpu_hw_events
*cpuhw
= &per_cpu(cpu_hw_events
, cpu
);
708 memset(cpuhw
, 0, sizeof(*cpuhw
));
711 int register_fsl_emb_pmu(struct fsl_emb_pmu
*pmu
)
714 return -EBUSY
; /* something's already registered */
717 pr_info("%s performance monitor hardware support registered\n",
720 perf_pmu_register(&fsl_emb_pmu
, "cpu", PERF_TYPE_RAW
);