1 // SPDX-License-Identifier: GPL-2.0+
3 // Linux performance counter support for ARC CPUs.
4 // This code is inspired by the perf support of various other architectures.
6 // Copyright (C) 2013-2018 Synopsys, Inc. (www.synopsys.com)
8 #include <linux/errno.h>
9 #include <linux/interrupt.h>
10 #include <linux/module.h>
12 #include <linux/perf_event.h>
13 #include <linux/platform_device.h>
14 #include <asm/arcregs.h>
15 #include <asm/stacktrace.h>
17 /* HW holds 8 symbols + one for null terminator */
18 #define ARCPMU_EVENT_NAME_LEN 9
21 * Some ARC pct quirks:
23 * PERF_COUNT_HW_STALLED_CYCLES_BACKEND
24 * PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
25 * The ARC 700 can either measure stalls per pipeline stage, or all stalls
26 * combined; for now we assign all stalls to STALLED_CYCLES_BACKEND
27 * and all pipeline flushes (e.g. caused by mispredicts, etc.) to
28 * STALLED_CYCLES_FRONTEND.
30 * We could start multiple performance counters and combine everything
31 * afterwards, but that makes it complicated.
33 * Note that I$ cache misses aren't counted by either of the two!
37 * ARC PCT has hardware conditions with fixed "names" but variable "indexes"
38 * (based on a specific RTL build)
39 * Below is the static map between perf generic/arc specific event_id and
40 * h/w condition names.
41 * At the time of probe, we loop thru each index and find its name to
42 * complete the mapping of perf event_id to h/w index as latter is needed
43 * to program the counter really
45 static const char * const arc_pmu_ev_hw_map
[] = {
47 [PERF_COUNT_HW_CPU_CYCLES
] = "crun",
48 [PERF_COUNT_HW_REF_CPU_CYCLES
] = "crun",
49 [PERF_COUNT_HW_BUS_CYCLES
] = "crun",
51 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
] = "bflush",
52 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND
] = "bstall",
54 /* counts condition */
55 [PERF_COUNT_HW_INSTRUCTIONS
] = "iall",
56 /* All jump instructions that are taken */
57 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS
] = "ijmptak",
58 #ifdef CONFIG_ISA_ARCV2
59 [PERF_COUNT_HW_BRANCH_MISSES
] = "bpmp",
61 [PERF_COUNT_ARC_BPOK
] = "bpok", /* NP-NT, PT-T, PNT-NT */
62 [PERF_COUNT_HW_BRANCH_MISSES
] = "bpfail", /* NP-T, PT-NT, PNT-T */
64 [PERF_COUNT_ARC_LDC
] = "imemrdc", /* Instr: mem read cached */
65 [PERF_COUNT_ARC_STC
] = "imemwrc", /* Instr: mem write cached */
67 [PERF_COUNT_ARC_DCLM
] = "dclm", /* D-cache Load Miss */
68 [PERF_COUNT_ARC_DCSM
] = "dcsm", /* D-cache Store Miss */
69 [PERF_COUNT_ARC_ICM
] = "icm", /* I-cache Miss */
70 [PERF_COUNT_ARC_EDTLB
] = "edtlb", /* D-TLB Miss */
71 [PERF_COUNT_ARC_EITLB
] = "eitlb", /* I-TLB Miss */
73 [PERF_COUNT_HW_CACHE_REFERENCES
] = "imemrdc", /* Instr: mem read cached */
74 [PERF_COUNT_HW_CACHE_MISSES
] = "dclm", /* D-cache Load Miss */
77 #define C(_x) PERF_COUNT_HW_CACHE_##_x
78 #define CACHE_OP_UNSUPPORTED 0xffff
80 static const unsigned int arc_pmu_cache_map
[C(MAX
)][C(OP_MAX
)][C(RESULT_MAX
)] = {
83 [C(RESULT_ACCESS
)] = PERF_COUNT_ARC_LDC
,
84 [C(RESULT_MISS
)] = PERF_COUNT_ARC_DCLM
,
87 [C(RESULT_ACCESS
)] = PERF_COUNT_ARC_STC
,
88 [C(RESULT_MISS
)] = PERF_COUNT_ARC_DCSM
,
91 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
92 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
97 [C(RESULT_ACCESS
)] = PERF_COUNT_HW_INSTRUCTIONS
,
98 [C(RESULT_MISS
)] = PERF_COUNT_ARC_ICM
,
101 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
102 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
105 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
106 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
111 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
112 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
115 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
116 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
119 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
120 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
125 [C(RESULT_ACCESS
)] = PERF_COUNT_ARC_LDC
,
126 [C(RESULT_MISS
)] = PERF_COUNT_ARC_EDTLB
,
128 /* DTLB LD/ST Miss not segregated by h/w*/
130 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
131 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
134 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
135 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
140 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
141 [C(RESULT_MISS
)] = PERF_COUNT_ARC_EITLB
,
144 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
145 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
148 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
149 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
154 [C(RESULT_ACCESS
)] = PERF_COUNT_HW_BRANCH_INSTRUCTIONS
,
155 [C(RESULT_MISS
)] = PERF_COUNT_HW_BRANCH_MISSES
,
158 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
159 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
162 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
163 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
168 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
169 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
172 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
173 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
176 [C(RESULT_ACCESS
)] = CACHE_OP_UNSUPPORTED
,
177 [C(RESULT_MISS
)] = CACHE_OP_UNSUPPORTED
,
182 enum arc_pmu_attr_groups
{
183 ARCPMU_ATTR_GR_EVENTS
,
184 ARCPMU_ATTR_GR_FORMATS
,
188 struct arc_pmu_raw_event_entry
{
189 char name
[ARCPMU_EVENT_NAME_LEN
];
198 int ev_hw_idx
[PERF_COUNT_ARC_HW_MAX
];
200 struct arc_pmu_raw_event_entry
*raw_entry
;
201 struct attribute
**attrs
;
202 struct perf_pmu_events_attr
*attr
;
203 const struct attribute_group
*attr_groups
[ARCPMU_NR_ATTR_GR
+ 1];
208 * A 1 bit for an index indicates that the counter is being used for
209 * an event. A 0 means that the counter can be used.
211 unsigned long used_mask
[BITS_TO_LONGS(ARC_PERF_MAX_COUNTERS
)];
214 * The events that are active on the PMU for the given index.
216 struct perf_event
*act_counter
[ARC_PERF_MAX_COUNTERS
];
219 struct arc_callchain_trace
{
224 static int callchain_trace(unsigned int addr
, void *data
)
226 struct arc_callchain_trace
*ctrl
= data
;
227 struct perf_callchain_entry_ctx
*entry
= ctrl
->perf_stuff
;
229 perf_callchain_store(entry
, addr
);
231 if (ctrl
->depth
++ < 3)
237 void perf_callchain_kernel(struct perf_callchain_entry_ctx
*entry
,
238 struct pt_regs
*regs
)
240 struct arc_callchain_trace ctrl
= {
245 arc_unwind_core(NULL
, regs
, callchain_trace
, &ctrl
);
248 void perf_callchain_user(struct perf_callchain_entry_ctx
*entry
,
249 struct pt_regs
*regs
)
252 * User stack can't be unwound trivially with kernel dwarf unwinder
253 * So for now just record the user PC
255 perf_callchain_store(entry
, instruction_pointer(regs
));
258 static struct arc_pmu
*arc_pmu
;
259 static DEFINE_PER_CPU(struct arc_pmu_cpu
, arc_pmu_cpu
);
261 /* read counter #idx; note that counter# != event# on ARC! */
262 static u64
arc_pmu_read_counter(int idx
)
268 * ARC supports making 'snapshots' of the counters, so we don't
269 * need to care about counters wrapping to 0 underneath our feet
271 write_aux_reg(ARC_REG_PCT_INDEX
, idx
);
272 tmp
= read_aux_reg(ARC_REG_PCT_CONTROL
);
273 write_aux_reg(ARC_REG_PCT_CONTROL
, tmp
| ARC_REG_PCT_CONTROL_SN
);
274 result
= (u64
) (read_aux_reg(ARC_REG_PCT_SNAPH
)) << 32;
275 result
|= read_aux_reg(ARC_REG_PCT_SNAPL
);
280 static void arc_perf_event_update(struct perf_event
*event
,
281 struct hw_perf_event
*hwc
, int idx
)
283 u64 prev_raw_count
= local64_read(&hwc
->prev_count
);
284 u64 new_raw_count
= arc_pmu_read_counter(idx
);
285 s64 delta
= new_raw_count
- prev_raw_count
;
288 * We aren't afraid of hwc->prev_count changing beneath our feet
289 * because there's no way for us to re-enter this function anytime.
291 local64_set(&hwc
->prev_count
, new_raw_count
);
292 local64_add(delta
, &event
->count
);
293 local64_sub(delta
, &hwc
->period_left
);
296 static void arc_pmu_read(struct perf_event
*event
)
298 arc_perf_event_update(event
, &event
->hw
, event
->hw
.idx
);
301 static int arc_pmu_cache_event(u64 config
)
303 unsigned int cache_type
, cache_op
, cache_result
;
306 cache_type
= (config
>> 0) & 0xff;
307 cache_op
= (config
>> 8) & 0xff;
308 cache_result
= (config
>> 16) & 0xff;
309 if (cache_type
>= PERF_COUNT_HW_CACHE_MAX
)
311 if (cache_op
>= PERF_COUNT_HW_CACHE_OP_MAX
)
313 if (cache_result
>= PERF_COUNT_HW_CACHE_RESULT_MAX
)
316 ret
= arc_pmu_cache_map
[cache_type
][cache_op
][cache_result
];
318 if (ret
== CACHE_OP_UNSUPPORTED
)
321 pr_debug("init cache event: type/op/result %d/%d/%d with h/w %d \'%s\'\n",
322 cache_type
, cache_op
, cache_result
, ret
,
323 arc_pmu_ev_hw_map
[ret
]);
328 /* initializes hw_perf_event structure if event is supported */
329 static int arc_pmu_event_init(struct perf_event
*event
)
331 struct hw_perf_event
*hwc
= &event
->hw
;
334 if (!is_sampling_event(event
)) {
335 hwc
->sample_period
= arc_pmu
->max_period
;
336 hwc
->last_period
= hwc
->sample_period
;
337 local64_set(&hwc
->period_left
, hwc
->sample_period
);
342 if (is_isa_arcv2()) {
343 /* "exclude user" means "count only kernel" */
344 if (event
->attr
.exclude_user
)
345 hwc
->config
|= ARC_REG_PCT_CONFIG_KERN
;
347 /* "exclude kernel" means "count only user" */
348 if (event
->attr
.exclude_kernel
)
349 hwc
->config
|= ARC_REG_PCT_CONFIG_USER
;
352 switch (event
->attr
.type
) {
353 case PERF_TYPE_HARDWARE
:
354 if (event
->attr
.config
>= PERF_COUNT_HW_MAX
)
356 if (arc_pmu
->ev_hw_idx
[event
->attr
.config
] < 0)
358 hwc
->config
|= arc_pmu
->ev_hw_idx
[event
->attr
.config
];
359 pr_debug("init event %d with h/w %08x \'%s\'\n",
360 (int)event
->attr
.config
, (int)hwc
->config
,
361 arc_pmu_ev_hw_map
[event
->attr
.config
]);
364 case PERF_TYPE_HW_CACHE
:
365 ret
= arc_pmu_cache_event(event
->attr
.config
);
368 hwc
->config
|= arc_pmu
->ev_hw_idx
[ret
];
369 pr_debug("init cache event with h/w %08x \'%s\'\n",
370 (int)hwc
->config
, arc_pmu_ev_hw_map
[ret
]);
374 if (event
->attr
.config
>= arc_pmu
->n_events
)
377 hwc
->config
|= event
->attr
.config
;
378 pr_debug("init raw event with idx %lld \'%s\'\n",
380 arc_pmu
->raw_entry
[event
->attr
.config
].name
);
389 /* starts all counters */
390 static void arc_pmu_enable(struct pmu
*pmu
)
393 tmp
= read_aux_reg(ARC_REG_PCT_CONTROL
);
394 write_aux_reg(ARC_REG_PCT_CONTROL
, (tmp
& 0xffff0000) | 0x1);
397 /* stops all counters */
398 static void arc_pmu_disable(struct pmu
*pmu
)
401 tmp
= read_aux_reg(ARC_REG_PCT_CONTROL
);
402 write_aux_reg(ARC_REG_PCT_CONTROL
, (tmp
& 0xffff0000) | 0x0);
405 static int arc_pmu_event_set_period(struct perf_event
*event
)
407 struct hw_perf_event
*hwc
= &event
->hw
;
408 s64 left
= local64_read(&hwc
->period_left
);
409 s64 period
= hwc
->sample_period
;
414 if (unlikely(left
<= -period
)) {
415 /* left underflowed by more than period. */
417 local64_set(&hwc
->period_left
, left
);
418 hwc
->last_period
= period
;
420 } else if (unlikely(left
<= 0)) {
421 /* left underflowed by less than period. */
423 local64_set(&hwc
->period_left
, left
);
424 hwc
->last_period
= period
;
428 if (left
> arc_pmu
->max_period
)
429 left
= arc_pmu
->max_period
;
431 value
= arc_pmu
->max_period
- left
;
432 local64_set(&hwc
->prev_count
, value
);
435 write_aux_reg(ARC_REG_PCT_INDEX
, idx
);
438 write_aux_reg(ARC_REG_PCT_COUNTL
, lower_32_bits(value
));
439 write_aux_reg(ARC_REG_PCT_COUNTH
, upper_32_bits(value
));
441 perf_event_update_userpage(event
);
447 * Assigns hardware counter to hardware condition.
448 * Note that there is no separate start/stop mechanism;
449 * stopping is achieved by assigning the 'never' condition
451 static void arc_pmu_start(struct perf_event
*event
, int flags
)
453 struct hw_perf_event
*hwc
= &event
->hw
;
456 if (WARN_ON_ONCE(idx
== -1))
459 if (flags
& PERF_EF_RELOAD
)
460 WARN_ON_ONCE(!(hwc
->state
& PERF_HES_UPTODATE
));
464 arc_pmu_event_set_period(event
);
466 /* Enable interrupt for this counter */
467 if (is_sampling_event(event
))
468 write_aux_reg(ARC_REG_PCT_INT_CTRL
,
469 read_aux_reg(ARC_REG_PCT_INT_CTRL
) | BIT(idx
));
471 /* enable ARC pmu here */
472 write_aux_reg(ARC_REG_PCT_INDEX
, idx
); /* counter # */
473 write_aux_reg(ARC_REG_PCT_CONFIG
, hwc
->config
); /* condition */
476 static void arc_pmu_stop(struct perf_event
*event
, int flags
)
478 struct hw_perf_event
*hwc
= &event
->hw
;
481 /* Disable interrupt for this counter */
482 if (is_sampling_event(event
)) {
484 * Reset interrupt flag by writing of 1. This is required
485 * to make sure pending interrupt was not left.
487 write_aux_reg(ARC_REG_PCT_INT_ACT
, BIT(idx
));
488 write_aux_reg(ARC_REG_PCT_INT_CTRL
,
489 read_aux_reg(ARC_REG_PCT_INT_CTRL
) & ~BIT(idx
));
492 if (!(event
->hw
.state
& PERF_HES_STOPPED
)) {
493 /* stop hw counter here */
494 write_aux_reg(ARC_REG_PCT_INDEX
, idx
);
496 /* condition code #0 is always "never" */
497 write_aux_reg(ARC_REG_PCT_CONFIG
, 0);
499 event
->hw
.state
|= PERF_HES_STOPPED
;
502 if ((flags
& PERF_EF_UPDATE
) &&
503 !(event
->hw
.state
& PERF_HES_UPTODATE
)) {
504 arc_perf_event_update(event
, &event
->hw
, idx
);
505 event
->hw
.state
|= PERF_HES_UPTODATE
;
509 static void arc_pmu_del(struct perf_event
*event
, int flags
)
511 struct arc_pmu_cpu
*pmu_cpu
= this_cpu_ptr(&arc_pmu_cpu
);
513 arc_pmu_stop(event
, PERF_EF_UPDATE
);
514 __clear_bit(event
->hw
.idx
, pmu_cpu
->used_mask
);
516 pmu_cpu
->act_counter
[event
->hw
.idx
] = 0;
518 perf_event_update_userpage(event
);
521 /* allocate hardware counter and optionally start counting */
522 static int arc_pmu_add(struct perf_event
*event
, int flags
)
524 struct arc_pmu_cpu
*pmu_cpu
= this_cpu_ptr(&arc_pmu_cpu
);
525 struct hw_perf_event
*hwc
= &event
->hw
;
528 idx
= ffz(pmu_cpu
->used_mask
[0]);
529 if (idx
== arc_pmu
->n_counters
)
532 __set_bit(idx
, pmu_cpu
->used_mask
);
535 write_aux_reg(ARC_REG_PCT_INDEX
, idx
);
537 pmu_cpu
->act_counter
[idx
] = event
;
539 if (is_sampling_event(event
)) {
540 /* Mimic full counter overflow as other arches do */
541 write_aux_reg(ARC_REG_PCT_INT_CNTL
,
542 lower_32_bits(arc_pmu
->max_period
));
543 write_aux_reg(ARC_REG_PCT_INT_CNTH
,
544 upper_32_bits(arc_pmu
->max_period
));
547 write_aux_reg(ARC_REG_PCT_CONFIG
, 0);
548 write_aux_reg(ARC_REG_PCT_COUNTL
, 0);
549 write_aux_reg(ARC_REG_PCT_COUNTH
, 0);
550 local64_set(&hwc
->prev_count
, 0);
552 hwc
->state
= PERF_HES_UPTODATE
| PERF_HES_STOPPED
;
553 if (flags
& PERF_EF_START
)
554 arc_pmu_start(event
, PERF_EF_RELOAD
);
556 perf_event_update_userpage(event
);
561 #ifdef CONFIG_ISA_ARCV2
562 static irqreturn_t
arc_pmu_intr(int irq
, void *dev
)
564 struct perf_sample_data data
;
565 struct arc_pmu_cpu
*pmu_cpu
= this_cpu_ptr(&arc_pmu_cpu
);
566 struct pt_regs
*regs
;
567 unsigned int active_ints
;
570 arc_pmu_disable(&arc_pmu
->pmu
);
572 active_ints
= read_aux_reg(ARC_REG_PCT_INT_ACT
);
576 regs
= get_irq_regs();
579 struct perf_event
*event
;
580 struct hw_perf_event
*hwc
;
582 idx
= __ffs(active_ints
);
584 /* Reset interrupt flag by writing of 1 */
585 write_aux_reg(ARC_REG_PCT_INT_ACT
, BIT(idx
));
588 * On reset of "interrupt active" bit corresponding
589 * "interrupt enable" bit gets automatically reset as well.
590 * Now we need to re-enable interrupt for the counter.
592 write_aux_reg(ARC_REG_PCT_INT_CTRL
,
593 read_aux_reg(ARC_REG_PCT_INT_CTRL
) | BIT(idx
));
595 event
= pmu_cpu
->act_counter
[idx
];
598 WARN_ON_ONCE(hwc
->idx
!= idx
);
600 arc_perf_event_update(event
, &event
->hw
, event
->hw
.idx
);
601 perf_sample_data_init(&data
, 0, hwc
->last_period
);
602 if (arc_pmu_event_set_period(event
)) {
603 if (perf_event_overflow(event
, &data
, regs
))
604 arc_pmu_stop(event
, 0);
607 active_ints
&= ~BIT(idx
);
608 } while (active_ints
);
611 arc_pmu_enable(&arc_pmu
->pmu
);
617 static irqreturn_t
arc_pmu_intr(int irq
, void *dev
)
622 #endif /* CONFIG_ISA_ARCV2 */
624 static void arc_cpu_pmu_irq_init(void *data
)
626 int irq
= *(int *)data
;
628 enable_percpu_irq(irq
, IRQ_TYPE_NONE
);
630 /* Clear all pending interrupt flags */
631 write_aux_reg(ARC_REG_PCT_INT_ACT
, 0xffffffff);
634 /* Event field occupies the bottom 15 bits of our config field */
635 PMU_FORMAT_ATTR(event
, "config:0-14");
636 static struct attribute
*arc_pmu_format_attrs
[] = {
637 &format_attr_event
.attr
,
641 static struct attribute_group arc_pmu_format_attr_gr
= {
643 .attrs
= arc_pmu_format_attrs
,
646 static ssize_t
arc_pmu_events_sysfs_show(struct device
*dev
,
647 struct device_attribute
*attr
,
650 struct perf_pmu_events_attr
*pmu_attr
;
652 pmu_attr
= container_of(attr
, struct perf_pmu_events_attr
, attr
);
653 return sprintf(page
, "event=0x%04llx\n", pmu_attr
->id
);
657 * We don't add attrs here as we don't have pre-defined list of perf events.
658 * We will generate and add attrs dynamically in probe() after we read HW
661 static struct attribute_group arc_pmu_events_attr_gr
= {
665 static void arc_pmu_add_raw_event_attr(int j
, char *str
)
667 memmove(arc_pmu
->raw_entry
[j
].name
, str
, ARCPMU_EVENT_NAME_LEN
- 1);
668 arc_pmu
->attr
[j
].attr
.attr
.name
= arc_pmu
->raw_entry
[j
].name
;
669 arc_pmu
->attr
[j
].attr
.attr
.mode
= VERIFY_OCTAL_PERMISSIONS(0444);
670 arc_pmu
->attr
[j
].attr
.show
= arc_pmu_events_sysfs_show
;
671 arc_pmu
->attr
[j
].id
= j
;
672 arc_pmu
->attrs
[j
] = &(arc_pmu
->attr
[j
].attr
.attr
);
675 static int arc_pmu_raw_alloc(struct device
*dev
)
677 arc_pmu
->attr
= devm_kmalloc_array(dev
, arc_pmu
->n_events
+ 1,
678 sizeof(*arc_pmu
->attr
), GFP_KERNEL
| __GFP_ZERO
);
682 arc_pmu
->attrs
= devm_kmalloc_array(dev
, arc_pmu
->n_events
+ 1,
683 sizeof(*arc_pmu
->attrs
), GFP_KERNEL
| __GFP_ZERO
);
687 arc_pmu
->raw_entry
= devm_kmalloc_array(dev
, arc_pmu
->n_events
,
688 sizeof(*arc_pmu
->raw_entry
), GFP_KERNEL
| __GFP_ZERO
);
689 if (!arc_pmu
->raw_entry
)
695 static inline bool event_in_hw_event_map(int i
, char *name
)
697 if (!arc_pmu_ev_hw_map
[i
])
700 if (!strlen(arc_pmu_ev_hw_map
[i
]))
703 if (strcmp(arc_pmu_ev_hw_map
[i
], name
))
709 static void arc_pmu_map_hw_event(int j
, char *str
)
713 /* See if HW condition has been mapped to a perf event_id */
714 for (i
= 0; i
< ARRAY_SIZE(arc_pmu_ev_hw_map
); i
++) {
715 if (event_in_hw_event_map(i
, str
)) {
716 pr_debug("mapping perf event %2d to h/w event \'%8s\' (idx %d)\n",
718 arc_pmu
->ev_hw_idx
[i
] = j
;
723 static int arc_pmu_device_probe(struct platform_device
*pdev
)
725 struct arc_reg_pct_build pct_bcr
;
726 struct arc_reg_cc_build cc_bcr
;
727 int i
, has_interrupts
, irq
= -1;
728 int counter_size
; /* in bits */
735 char str
[ARCPMU_EVENT_NAME_LEN
];
739 READ_BCR(ARC_REG_PCT_BUILD
, pct_bcr
);
741 pr_err("This core does not have performance counters!\n");
744 BUILD_BUG_ON(ARC_PERF_MAX_COUNTERS
> 32);
745 if (WARN_ON(pct_bcr
.c
> ARC_PERF_MAX_COUNTERS
))
748 READ_BCR(ARC_REG_CC_BUILD
, cc_bcr
);
749 if (WARN(!cc_bcr
.v
, "Counters exist but No countable conditions?"))
752 arc_pmu
= devm_kzalloc(&pdev
->dev
, sizeof(struct arc_pmu
), GFP_KERNEL
);
756 arc_pmu
->n_events
= cc_bcr
.c
;
758 if (arc_pmu_raw_alloc(&pdev
->dev
))
761 has_interrupts
= is_isa_arcv2() ? pct_bcr
.i
: 0;
763 arc_pmu
->n_counters
= pct_bcr
.c
;
764 counter_size
= 32 + (pct_bcr
.s
<< 4);
766 arc_pmu
->max_period
= (1ULL << counter_size
) / 2 - 1ULL;
768 pr_info("ARC perf\t: %d counters (%d bits), %d conditions%s\n",
769 arc_pmu
->n_counters
, counter_size
, cc_bcr
.c
,
770 has_interrupts
? ", [overflow IRQ support]" : "");
772 cc_name
.str
[ARCPMU_EVENT_NAME_LEN
- 1] = 0;
773 for (i
= 0; i
< PERF_COUNT_ARC_HW_MAX
; i
++)
774 arc_pmu
->ev_hw_idx
[i
] = -1;
776 /* loop thru all available h/w condition indexes */
777 for (i
= 0; i
< cc_bcr
.c
; i
++) {
778 write_aux_reg(ARC_REG_CC_INDEX
, i
);
779 cc_name
.indiv
.word0
= le32_to_cpu(read_aux_reg(ARC_REG_CC_NAME0
));
780 cc_name
.indiv
.word1
= le32_to_cpu(read_aux_reg(ARC_REG_CC_NAME1
));
782 arc_pmu_map_hw_event(i
, cc_name
.str
);
783 arc_pmu_add_raw_event_attr(i
, cc_name
.str
);
786 arc_pmu_events_attr_gr
.attrs
= arc_pmu
->attrs
;
787 arc_pmu
->attr_groups
[ARCPMU_ATTR_GR_EVENTS
] = &arc_pmu_events_attr_gr
;
788 arc_pmu
->attr_groups
[ARCPMU_ATTR_GR_FORMATS
] = &arc_pmu_format_attr_gr
;
790 arc_pmu
->pmu
= (struct pmu
) {
791 .pmu_enable
= arc_pmu_enable
,
792 .pmu_disable
= arc_pmu_disable
,
793 .event_init
= arc_pmu_event_init
,
796 .start
= arc_pmu_start
,
797 .stop
= arc_pmu_stop
,
798 .read
= arc_pmu_read
,
799 .attr_groups
= arc_pmu
->attr_groups
,
802 if (has_interrupts
) {
803 irq
= platform_get_irq(pdev
, 0);
809 /* intc map function ensures irq_set_percpu_devid() called */
810 ret
= request_percpu_irq(irq
, arc_pmu_intr
, "ARC perf counters",
811 this_cpu_ptr(&arc_pmu_cpu
));
814 on_each_cpu(arc_cpu_pmu_irq_init
, &irq
, 1);
822 arc_pmu
->pmu
.capabilities
|= PERF_PMU_CAP_NO_INTERRUPT
;
825 * perf parser doesn't really like '-' symbol in events name, so let's
826 * use '_' in arc pct name as it goes to kernel PMU event prefix.
828 return perf_pmu_register(&arc_pmu
->pmu
, "arc_pct", PERF_TYPE_RAW
);
831 static const struct of_device_id arc_pmu_match
[] = {
832 { .compatible
= "snps,arc700-pct" },
833 { .compatible
= "snps,archs-pct" },
836 MODULE_DEVICE_TABLE(of
, arc_pmu_match
);
838 static struct platform_driver arc_pmu_driver
= {
841 .of_match_table
= of_match_ptr(arc_pmu_match
),
843 .probe
= arc_pmu_device_probe
,
846 module_platform_driver(arc_pmu_driver
);
848 MODULE_LICENSE("GPL");
849 MODULE_AUTHOR("Mischa Jonker <mjonker@synopsys.com>");
850 MODULE_DESCRIPTION("ARC PMU driver");