Merge tag 'drm-next-2022-06-03-1' of git://anongit.freedesktop.org/drm/drm
[linux-2.6-microblaze.git] / drivers / perf / riscv_pmu_sbi.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * RISC-V performance counter support.
4  *
5  * Copyright (C) 2021 Western Digital Corporation or its affiliates.
6  *
7  * This code is based on ARM perf event code which is in turn based on
8  * sparc64 and x86 code.
9  */
10
11 #define pr_fmt(fmt) "riscv-pmu-sbi: " fmt
12
13 #include <linux/mod_devicetable.h>
14 #include <linux/perf/riscv_pmu.h>
15 #include <linux/platform_device.h>
16 #include <linux/irq.h>
17 #include <linux/irqdomain.h>
18 #include <linux/of_irq.h>
19 #include <linux/of.h>
20
21 #include <asm/sbi.h>
22 #include <asm/hwcap.h>
23
24 union sbi_pmu_ctr_info {
25         unsigned long value;
26         struct {
27                 unsigned long csr:12;
28                 unsigned long width:6;
29 #if __riscv_xlen == 32
30                 unsigned long reserved:13;
31 #else
32                 unsigned long reserved:45;
33 #endif
34                 unsigned long type:1;
35         };
36 };
37
38 /*
39  * RISC-V doesn't have hetergenous harts yet. This need to be part of
40  * per_cpu in case of harts with different pmu counters
41  */
42 static union sbi_pmu_ctr_info *pmu_ctr_list;
43 static unsigned int riscv_pmu_irq;
44
45 struct sbi_pmu_event_data {
46         union {
47                 union {
48                         struct hw_gen_event {
49                                 uint32_t event_code:16;
50                                 uint32_t event_type:4;
51                                 uint32_t reserved:12;
52                         } hw_gen_event;
53                         struct hw_cache_event {
54                                 uint32_t result_id:1;
55                                 uint32_t op_id:2;
56                                 uint32_t cache_id:13;
57                                 uint32_t event_type:4;
58                                 uint32_t reserved:12;
59                         } hw_cache_event;
60                 };
61                 uint32_t event_idx;
62         };
63 };
64
65 static const struct sbi_pmu_event_data pmu_hw_event_map[] = {
66         [PERF_COUNT_HW_CPU_CYCLES]              = {.hw_gen_event = {
67                                                         SBI_PMU_HW_CPU_CYCLES,
68                                                         SBI_PMU_EVENT_TYPE_HW, 0}},
69         [PERF_COUNT_HW_INSTRUCTIONS]            = {.hw_gen_event = {
70                                                         SBI_PMU_HW_INSTRUCTIONS,
71                                                         SBI_PMU_EVENT_TYPE_HW, 0}},
72         [PERF_COUNT_HW_CACHE_REFERENCES]        = {.hw_gen_event = {
73                                                         SBI_PMU_HW_CACHE_REFERENCES,
74                                                         SBI_PMU_EVENT_TYPE_HW, 0}},
75         [PERF_COUNT_HW_CACHE_MISSES]            = {.hw_gen_event = {
76                                                         SBI_PMU_HW_CACHE_MISSES,
77                                                         SBI_PMU_EVENT_TYPE_HW, 0}},
78         [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = {.hw_gen_event = {
79                                                         SBI_PMU_HW_BRANCH_INSTRUCTIONS,
80                                                         SBI_PMU_EVENT_TYPE_HW, 0}},
81         [PERF_COUNT_HW_BRANCH_MISSES]           = {.hw_gen_event = {
82                                                         SBI_PMU_HW_BRANCH_MISSES,
83                                                         SBI_PMU_EVENT_TYPE_HW, 0}},
84         [PERF_COUNT_HW_BUS_CYCLES]              = {.hw_gen_event = {
85                                                         SBI_PMU_HW_BUS_CYCLES,
86                                                         SBI_PMU_EVENT_TYPE_HW, 0}},
87         [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = {.hw_gen_event = {
88                                                         SBI_PMU_HW_STALLED_CYCLES_FRONTEND,
89                                                         SBI_PMU_EVENT_TYPE_HW, 0}},
90         [PERF_COUNT_HW_STALLED_CYCLES_BACKEND]  = {.hw_gen_event = {
91                                                         SBI_PMU_HW_STALLED_CYCLES_BACKEND,
92                                                         SBI_PMU_EVENT_TYPE_HW, 0}},
93         [PERF_COUNT_HW_REF_CPU_CYCLES]          = {.hw_gen_event = {
94                                                         SBI_PMU_HW_REF_CPU_CYCLES,
95                                                         SBI_PMU_EVENT_TYPE_HW, 0}},
96 };
97
98 #define C(x) PERF_COUNT_HW_CACHE_##x
99 static const struct sbi_pmu_event_data pmu_cache_event_map[PERF_COUNT_HW_CACHE_MAX]
100 [PERF_COUNT_HW_CACHE_OP_MAX]
101 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
102         [C(L1D)] = {
103                 [C(OP_READ)] = {
104                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
105                                         C(OP_READ), C(L1D), SBI_PMU_EVENT_TYPE_CACHE, 0}},
106                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
107                                         C(OP_READ), C(L1D), SBI_PMU_EVENT_TYPE_CACHE, 0}},
108                 },
109                 [C(OP_WRITE)] = {
110                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
111                                         C(OP_WRITE), C(L1D), SBI_PMU_EVENT_TYPE_CACHE, 0}},
112                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
113                                         C(OP_WRITE), C(L1D), SBI_PMU_EVENT_TYPE_CACHE, 0}},
114                 },
115                 [C(OP_PREFETCH)] = {
116                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
117                                         C(OP_PREFETCH), C(L1D), SBI_PMU_EVENT_TYPE_CACHE, 0}},
118                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
119                                         C(OP_PREFETCH), C(L1D), SBI_PMU_EVENT_TYPE_CACHE, 0}},
120                 },
121         },
122         [C(L1I)] = {
123                 [C(OP_READ)] = {
124                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
125                                         C(OP_READ), C(L1I), SBI_PMU_EVENT_TYPE_CACHE, 0}},
126                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS), C(OP_READ),
127                                         C(L1I), SBI_PMU_EVENT_TYPE_CACHE, 0}},
128                 },
129                 [C(OP_WRITE)] = {
130                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
131                                         C(OP_WRITE), C(L1I), SBI_PMU_EVENT_TYPE_CACHE, 0}},
132                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
133                                         C(OP_WRITE), C(L1I), SBI_PMU_EVENT_TYPE_CACHE, 0}},
134                 },
135                 [C(OP_PREFETCH)] = {
136                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
137                                         C(OP_PREFETCH), C(L1I), SBI_PMU_EVENT_TYPE_CACHE, 0}},
138                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
139                                         C(OP_PREFETCH), C(L1I), SBI_PMU_EVENT_TYPE_CACHE, 0}},
140                 },
141         },
142         [C(LL)] = {
143                 [C(OP_READ)] = {
144                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
145                                         C(OP_READ), C(LL), SBI_PMU_EVENT_TYPE_CACHE, 0}},
146                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
147                                         C(OP_READ), C(LL), SBI_PMU_EVENT_TYPE_CACHE, 0}},
148                 },
149                 [C(OP_WRITE)] = {
150                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
151                                         C(OP_WRITE), C(LL), SBI_PMU_EVENT_TYPE_CACHE, 0}},
152                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
153                                         C(OP_WRITE), C(LL), SBI_PMU_EVENT_TYPE_CACHE, 0}},
154                 },
155                 [C(OP_PREFETCH)] = {
156                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
157                                         C(OP_PREFETCH), C(LL), SBI_PMU_EVENT_TYPE_CACHE, 0}},
158                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
159                                         C(OP_PREFETCH), C(LL), SBI_PMU_EVENT_TYPE_CACHE, 0}},
160                 },
161         },
162         [C(DTLB)] = {
163                 [C(OP_READ)] = {
164                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
165                                         C(OP_READ), C(DTLB), SBI_PMU_EVENT_TYPE_CACHE, 0}},
166                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
167                                         C(OP_READ), C(DTLB), SBI_PMU_EVENT_TYPE_CACHE, 0}},
168                 },
169                 [C(OP_WRITE)] = {
170                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
171                                         C(OP_WRITE), C(DTLB), SBI_PMU_EVENT_TYPE_CACHE, 0}},
172                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
173                                         C(OP_WRITE), C(DTLB), SBI_PMU_EVENT_TYPE_CACHE, 0}},
174                 },
175                 [C(OP_PREFETCH)] = {
176                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
177                                         C(OP_PREFETCH), C(DTLB), SBI_PMU_EVENT_TYPE_CACHE, 0}},
178                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
179                                         C(OP_PREFETCH), C(DTLB), SBI_PMU_EVENT_TYPE_CACHE, 0}},
180                 },
181         },
182         [C(ITLB)] = {
183                 [C(OP_READ)] = {
184                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
185                                         C(OP_READ), C(ITLB), SBI_PMU_EVENT_TYPE_CACHE, 0}},
186                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
187                                         C(OP_READ), C(ITLB), SBI_PMU_EVENT_TYPE_CACHE, 0}},
188                 },
189                 [C(OP_WRITE)] = {
190                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
191                                         C(OP_WRITE), C(ITLB), SBI_PMU_EVENT_TYPE_CACHE, 0}},
192                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
193                                         C(OP_WRITE), C(ITLB), SBI_PMU_EVENT_TYPE_CACHE, 0}},
194                 },
195                 [C(OP_PREFETCH)] = {
196                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
197                                         C(OP_PREFETCH), C(ITLB), SBI_PMU_EVENT_TYPE_CACHE, 0}},
198                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
199                                         C(OP_PREFETCH), C(ITLB), SBI_PMU_EVENT_TYPE_CACHE, 0}},
200                 },
201         },
202         [C(BPU)] = {
203                 [C(OP_READ)] = {
204                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
205                                         C(OP_READ), C(BPU), SBI_PMU_EVENT_TYPE_CACHE, 0}},
206                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
207                                         C(OP_READ), C(BPU), SBI_PMU_EVENT_TYPE_CACHE, 0}},
208                 },
209                 [C(OP_WRITE)] = {
210                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
211                                         C(OP_WRITE), C(BPU), SBI_PMU_EVENT_TYPE_CACHE, 0}},
212                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
213                                         C(OP_WRITE), C(BPU), SBI_PMU_EVENT_TYPE_CACHE, 0}},
214                 },
215                 [C(OP_PREFETCH)] = {
216                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
217                                         C(OP_PREFETCH), C(BPU), SBI_PMU_EVENT_TYPE_CACHE, 0}},
218                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
219                                         C(OP_PREFETCH), C(BPU), SBI_PMU_EVENT_TYPE_CACHE, 0}},
220                 },
221         },
222         [C(NODE)] = {
223                 [C(OP_READ)] = {
224                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
225                                         C(OP_READ), C(NODE), SBI_PMU_EVENT_TYPE_CACHE, 0}},
226                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
227                                         C(OP_READ), C(NODE), SBI_PMU_EVENT_TYPE_CACHE, 0}},
228                 },
229                 [C(OP_WRITE)] = {
230                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
231                                         C(OP_WRITE), C(NODE), SBI_PMU_EVENT_TYPE_CACHE, 0}},
232                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
233                                         C(OP_WRITE), C(NODE), SBI_PMU_EVENT_TYPE_CACHE, 0}},
234                 },
235                 [C(OP_PREFETCH)] = {
236                         [C(RESULT_ACCESS)] = {.hw_cache_event = {C(RESULT_ACCESS),
237                                         C(OP_PREFETCH), C(NODE), SBI_PMU_EVENT_TYPE_CACHE, 0}},
238                         [C(RESULT_MISS)] = {.hw_cache_event = {C(RESULT_MISS),
239                                         C(OP_PREFETCH), C(NODE), SBI_PMU_EVENT_TYPE_CACHE, 0}},
240                 },
241         },
242 };
243
244 static int pmu_sbi_ctr_get_width(int idx)
245 {
246         return pmu_ctr_list[idx].width;
247 }
248
249 static bool pmu_sbi_ctr_is_fw(int cidx)
250 {
251         union sbi_pmu_ctr_info *info;
252
253         info = &pmu_ctr_list[cidx];
254         if (!info)
255                 return false;
256
257         return (info->type == SBI_PMU_CTR_TYPE_FW) ? true : false;
258 }
259
260 static int pmu_sbi_ctr_get_idx(struct perf_event *event)
261 {
262         struct hw_perf_event *hwc = &event->hw;
263         struct riscv_pmu *rvpmu = to_riscv_pmu(event->pmu);
264         struct cpu_hw_events *cpuc = this_cpu_ptr(rvpmu->hw_events);
265         struct sbiret ret;
266         int idx;
267         uint64_t cbase = 0;
268         uint64_t cmask = GENMASK_ULL(rvpmu->num_counters - 1, 0);
269         unsigned long cflags = 0;
270
271         if (event->attr.exclude_kernel)
272                 cflags |= SBI_PMU_CFG_FLAG_SET_SINH;
273         if (event->attr.exclude_user)
274                 cflags |= SBI_PMU_CFG_FLAG_SET_UINH;
275
276         /* retrieve the available counter index */
277         ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase, cmask,
278                         cflags, hwc->event_base, hwc->config, 0);
279         if (ret.error) {
280                 pr_debug("Not able to find a counter for event %lx config %llx\n",
281                         hwc->event_base, hwc->config);
282                 return sbi_err_map_linux_errno(ret.error);
283         }
284
285         idx = ret.value;
286         if (idx >= rvpmu->num_counters || !pmu_ctr_list[idx].value)
287                 return -ENOENT;
288
289         /* Additional sanity check for the counter id */
290         if (pmu_sbi_ctr_is_fw(idx)) {
291                 if (!test_and_set_bit(idx, cpuc->used_fw_ctrs))
292                         return idx;
293         } else {
294                 if (!test_and_set_bit(idx, cpuc->used_hw_ctrs))
295                         return idx;
296         }
297
298         return -ENOENT;
299 }
300
301 static void pmu_sbi_ctr_clear_idx(struct perf_event *event)
302 {
303
304         struct hw_perf_event *hwc = &event->hw;
305         struct riscv_pmu *rvpmu = to_riscv_pmu(event->pmu);
306         struct cpu_hw_events *cpuc = this_cpu_ptr(rvpmu->hw_events);
307         int idx = hwc->idx;
308
309         if (pmu_sbi_ctr_is_fw(idx))
310                 clear_bit(idx, cpuc->used_fw_ctrs);
311         else
312                 clear_bit(idx, cpuc->used_hw_ctrs);
313 }
314
315 static int pmu_event_find_cache(u64 config)
316 {
317         unsigned int cache_type, cache_op, cache_result, ret;
318
319         cache_type = (config >>  0) & 0xff;
320         if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
321                 return -EINVAL;
322
323         cache_op = (config >>  8) & 0xff;
324         if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
325                 return -EINVAL;
326
327         cache_result = (config >> 16) & 0xff;
328         if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
329                 return -EINVAL;
330
331         ret = pmu_cache_event_map[cache_type][cache_op][cache_result].event_idx;
332
333         return ret;
334 }
335
336 static bool pmu_sbi_is_fw_event(struct perf_event *event)
337 {
338         u32 type = event->attr.type;
339         u64 config = event->attr.config;
340
341         if ((type == PERF_TYPE_RAW) && ((config >> 63) == 1))
342                 return true;
343         else
344                 return false;
345 }
346
347 static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
348 {
349         u32 type = event->attr.type;
350         u64 config = event->attr.config;
351         int bSoftware;
352         u64 raw_config_val;
353         int ret;
354
355         switch (type) {
356         case PERF_TYPE_HARDWARE:
357                 if (config >= PERF_COUNT_HW_MAX)
358                         return -EINVAL;
359                 ret = pmu_hw_event_map[event->attr.config].event_idx;
360                 break;
361         case PERF_TYPE_HW_CACHE:
362                 ret = pmu_event_find_cache(config);
363                 break;
364         case PERF_TYPE_RAW:
365                 /*
366                  * As per SBI specification, the upper 16 bits must be unused for
367                  * a raw event. Use the MSB (63b) to distinguish between hardware
368                  * raw event and firmware events.
369                  */
370                 bSoftware = config >> 63;
371                 raw_config_val = config & RISCV_PMU_RAW_EVENT_MASK;
372                 if (bSoftware) {
373                         if (raw_config_val < SBI_PMU_FW_MAX)
374                                 ret = (raw_config_val & 0xFFFF) |
375                                       (SBI_PMU_EVENT_TYPE_FW << 16);
376                         else
377                                 return -EINVAL;
378                 } else {
379                         ret = RISCV_PMU_RAW_EVENT_IDX;
380                         *econfig = raw_config_val;
381                 }
382                 break;
383         default:
384                 ret = -EINVAL;
385                 break;
386         }
387
388         return ret;
389 }
390
391 static u64 pmu_sbi_ctr_read(struct perf_event *event)
392 {
393         struct hw_perf_event *hwc = &event->hw;
394         int idx = hwc->idx;
395         struct sbiret ret;
396         union sbi_pmu_ctr_info info;
397         u64 val = 0;
398
399         if (pmu_sbi_is_fw_event(event)) {
400                 ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_FW_READ,
401                                 hwc->idx, 0, 0, 0, 0, 0);
402                 if (!ret.error)
403                         val = ret.value;
404         } else {
405                 info = pmu_ctr_list[idx];
406                 val = riscv_pmu_ctr_read_csr(info.csr);
407                 if (IS_ENABLED(CONFIG_32BIT))
408                         val = ((u64)riscv_pmu_ctr_read_csr(info.csr + 0x80)) << 31 | val;
409         }
410
411         return val;
412 }
413
414 static void pmu_sbi_ctr_start(struct perf_event *event, u64 ival)
415 {
416         struct sbiret ret;
417         struct hw_perf_event *hwc = &event->hw;
418         unsigned long flag = SBI_PMU_START_FLAG_SET_INIT_VALUE;
419
420         ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, hwc->idx,
421                         1, flag, ival, ival >> 32, 0);
422         if (ret.error && (ret.error != SBI_ERR_ALREADY_STARTED))
423                 pr_err("Starting counter idx %d failed with error %d\n",
424                         hwc->idx, sbi_err_map_linux_errno(ret.error));
425 }
426
427 static void pmu_sbi_ctr_stop(struct perf_event *event, unsigned long flag)
428 {
429         struct sbiret ret;
430         struct hw_perf_event *hwc = &event->hw;
431
432         ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP, hwc->idx, 1, flag, 0, 0, 0);
433         if (ret.error && (ret.error != SBI_ERR_ALREADY_STOPPED) &&
434                 flag != SBI_PMU_STOP_FLAG_RESET)
435                 pr_err("Stopping counter idx %d failed with error %d\n",
436                         hwc->idx, sbi_err_map_linux_errno(ret.error));
437 }
438
439 static int pmu_sbi_find_num_ctrs(void)
440 {
441         struct sbiret ret;
442
443         ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_NUM_COUNTERS, 0, 0, 0, 0, 0, 0);
444         if (!ret.error)
445                 return ret.value;
446         else
447                 return sbi_err_map_linux_errno(ret.error);
448 }
449
450 static int pmu_sbi_get_ctrinfo(int nctr)
451 {
452         struct sbiret ret;
453         int i, num_hw_ctr = 0, num_fw_ctr = 0;
454         union sbi_pmu_ctr_info cinfo;
455
456         pmu_ctr_list = kcalloc(nctr, sizeof(*pmu_ctr_list), GFP_KERNEL);
457         if (!pmu_ctr_list)
458                 return -ENOMEM;
459
460         for (i = 0; i <= nctr; i++) {
461                 ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_GET_INFO, i, 0, 0, 0, 0, 0);
462                 if (ret.error)
463                         /* The logical counter ids are not expected to be contiguous */
464                         continue;
465                 cinfo.value = ret.value;
466                 if (cinfo.type == SBI_PMU_CTR_TYPE_FW)
467                         num_fw_ctr++;
468                 else
469                         num_hw_ctr++;
470                 pmu_ctr_list[i].value = cinfo.value;
471         }
472
473         pr_info("%d firmware and %d hardware counters\n", num_fw_ctr, num_hw_ctr);
474
475         return 0;
476 }
477
478 static inline void pmu_sbi_stop_all(struct riscv_pmu *pmu)
479 {
480         /*
481          * No need to check the error because we are disabling all the counters
482          * which may include counters that are not enabled yet.
483          */
484         sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP,
485                   0, GENMASK_ULL(pmu->num_counters - 1, 0), 0, 0, 0, 0);
486 }
487
488 static inline void pmu_sbi_stop_hw_ctrs(struct riscv_pmu *pmu)
489 {
490         struct cpu_hw_events *cpu_hw_evt = this_cpu_ptr(pmu->hw_events);
491
492         /* No need to check the error here as we can't do anything about the error */
493         sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP, 0,
494                   cpu_hw_evt->used_hw_ctrs[0], 0, 0, 0, 0);
495 }
496
497 /*
498  * This function starts all the used counters in two step approach.
499  * Any counter that did not overflow can be start in a single step
500  * while the overflowed counters need to be started with updated initialization
501  * value.
502  */
503 static inline void pmu_sbi_start_overflow_mask(struct riscv_pmu *pmu,
504                                                unsigned long ctr_ovf_mask)
505 {
506         int idx = 0;
507         struct cpu_hw_events *cpu_hw_evt = this_cpu_ptr(pmu->hw_events);
508         struct perf_event *event;
509         unsigned long flag = SBI_PMU_START_FLAG_SET_INIT_VALUE;
510         unsigned long ctr_start_mask = 0;
511         uint64_t max_period;
512         struct hw_perf_event *hwc;
513         u64 init_val = 0;
514
515         ctr_start_mask = cpu_hw_evt->used_hw_ctrs[0] & ~ctr_ovf_mask;
516
517         /* Start all the counters that did not overflow in a single shot */
518         sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, 0, ctr_start_mask,
519                   0, 0, 0, 0);
520
521         /* Reinitialize and start all the counter that overflowed */
522         while (ctr_ovf_mask) {
523                 if (ctr_ovf_mask & 0x01) {
524                         event = cpu_hw_evt->events[idx];
525                         hwc = &event->hw;
526                         max_period = riscv_pmu_ctr_get_width_mask(event);
527                         init_val = local64_read(&hwc->prev_count) & max_period;
528                         sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, idx, 1,
529                                   flag, init_val, 0, 0);
530                 }
531                 ctr_ovf_mask = ctr_ovf_mask >> 1;
532                 idx++;
533         }
534 }
535
536 static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
537 {
538         struct perf_sample_data data;
539         struct pt_regs *regs;
540         struct hw_perf_event *hw_evt;
541         union sbi_pmu_ctr_info *info;
542         int lidx, hidx, fidx;
543         struct riscv_pmu *pmu;
544         struct perf_event *event;
545         unsigned long overflow;
546         unsigned long overflowed_ctrs = 0;
547         struct cpu_hw_events *cpu_hw_evt = dev;
548
549         if (WARN_ON_ONCE(!cpu_hw_evt))
550                 return IRQ_NONE;
551
552         /* Firmware counter don't support overflow yet */
553         fidx = find_first_bit(cpu_hw_evt->used_hw_ctrs, RISCV_MAX_COUNTERS);
554         event = cpu_hw_evt->events[fidx];
555         if (!event) {
556                 csr_clear(CSR_SIP, SIP_LCOFIP);
557                 return IRQ_NONE;
558         }
559
560         pmu = to_riscv_pmu(event->pmu);
561         pmu_sbi_stop_hw_ctrs(pmu);
562
563         /* Overflow status register should only be read after counter are stopped */
564         overflow = csr_read(CSR_SSCOUNTOVF);
565
566         /*
567          * Overflow interrupt pending bit should only be cleared after stopping
568          * all the counters to avoid any race condition.
569          */
570         csr_clear(CSR_SIP, SIP_LCOFIP);
571
572         /* No overflow bit is set */
573         if (!overflow)
574                 return IRQ_NONE;
575
576         regs = get_irq_regs();
577
578         for_each_set_bit(lidx, cpu_hw_evt->used_hw_ctrs, RISCV_MAX_COUNTERS) {
579                 struct perf_event *event = cpu_hw_evt->events[lidx];
580
581                 /* Skip if invalid event or user did not request a sampling */
582                 if (!event || !is_sampling_event(event))
583                         continue;
584
585                 info = &pmu_ctr_list[lidx];
586                 /* Do a sanity check */
587                 if (!info || info->type != SBI_PMU_CTR_TYPE_HW)
588                         continue;
589
590                 /* compute hardware counter index */
591                 hidx = info->csr - CSR_CYCLE;
592                 /* check if the corresponding bit is set in sscountovf */
593                 if (!(overflow & (1 << hidx)))
594                         continue;
595
596                 /*
597                  * Keep a track of overflowed counters so that they can be started
598                  * with updated initial value.
599                  */
600                 overflowed_ctrs |= 1 << lidx;
601                 hw_evt = &event->hw;
602                 riscv_pmu_event_update(event);
603                 perf_sample_data_init(&data, 0, hw_evt->last_period);
604                 if (riscv_pmu_event_set_period(event)) {
605                         /*
606                          * Unlike other ISAs, RISC-V don't have to disable interrupts
607                          * to avoid throttling here. As per the specification, the
608                          * interrupt remains disabled until the OF bit is set.
609                          * Interrupts are enabled again only during the start.
610                          * TODO: We will need to stop the guest counters once
611                          * virtualization support is added.
612                          */
613                         perf_event_overflow(event, &data, regs);
614                 }
615         }
616         pmu_sbi_start_overflow_mask(pmu, overflowed_ctrs);
617
618         return IRQ_HANDLED;
619 }
620
621 static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node)
622 {
623         struct riscv_pmu *pmu = hlist_entry_safe(node, struct riscv_pmu, node);
624         struct cpu_hw_events *cpu_hw_evt = this_cpu_ptr(pmu->hw_events);
625
626         /* Enable the access for TIME csr only from the user mode now */
627         csr_write(CSR_SCOUNTEREN, 0x2);
628
629         /* Stop all the counters so that they can be enabled from perf */
630         pmu_sbi_stop_all(pmu);
631
632         if (riscv_isa_extension_available(NULL, SSCOFPMF)) {
633                 cpu_hw_evt->irq = riscv_pmu_irq;
634                 csr_clear(CSR_IP, BIT(RV_IRQ_PMU));
635                 csr_set(CSR_IE, BIT(RV_IRQ_PMU));
636                 enable_percpu_irq(riscv_pmu_irq, IRQ_TYPE_NONE);
637         }
638
639         return 0;
640 }
641
642 static int pmu_sbi_dying_cpu(unsigned int cpu, struct hlist_node *node)
643 {
644         if (riscv_isa_extension_available(NULL, SSCOFPMF)) {
645                 disable_percpu_irq(riscv_pmu_irq);
646                 csr_clear(CSR_IE, BIT(RV_IRQ_PMU));
647         }
648
649         /* Disable all counters access for user mode now */
650         csr_write(CSR_SCOUNTEREN, 0x0);
651
652         return 0;
653 }
654
655 static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pdev)
656 {
657         int ret;
658         struct cpu_hw_events __percpu *hw_events = pmu->hw_events;
659         struct device_node *cpu, *child;
660         struct irq_domain *domain = NULL;
661
662         if (!riscv_isa_extension_available(NULL, SSCOFPMF))
663                 return -EOPNOTSUPP;
664
665         for_each_of_cpu_node(cpu) {
666                 child = of_get_compatible_child(cpu, "riscv,cpu-intc");
667                 if (!child) {
668                         pr_err("Failed to find INTC node\n");
669                         return -ENODEV;
670                 }
671                 domain = irq_find_host(child);
672                 of_node_put(child);
673                 if (domain)
674                         break;
675         }
676         if (!domain) {
677                 pr_err("Failed to find INTC IRQ root domain\n");
678                 return -ENODEV;
679         }
680
681         riscv_pmu_irq = irq_create_mapping(domain, RV_IRQ_PMU);
682         if (!riscv_pmu_irq) {
683                 pr_err("Failed to map PMU interrupt for node\n");
684                 return -ENODEV;
685         }
686
687         ret = request_percpu_irq(riscv_pmu_irq, pmu_sbi_ovf_handler, "riscv-pmu", hw_events);
688         if (ret) {
689                 pr_err("registering percpu irq failed [%d]\n", ret);
690                 return ret;
691         }
692
693         return 0;
694 }
695
696 static int pmu_sbi_device_probe(struct platform_device *pdev)
697 {
698         struct riscv_pmu *pmu = NULL;
699         int num_counters;
700         int ret = -ENODEV;
701
702         pr_info("SBI PMU extension is available\n");
703         pmu = riscv_pmu_alloc();
704         if (!pmu)
705                 return -ENOMEM;
706
707         num_counters = pmu_sbi_find_num_ctrs();
708         if (num_counters < 0) {
709                 pr_err("SBI PMU extension doesn't provide any counters\n");
710                 goto out_free;
711         }
712
713         /* cache all the information about counters now */
714         if (pmu_sbi_get_ctrinfo(num_counters))
715                 goto out_free;
716
717         ret = pmu_sbi_setup_irqs(pmu, pdev);
718         if (ret < 0) {
719                 pr_info("Perf sampling/filtering is not supported as sscof extension is not available\n");
720                 pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
721                 pmu->pmu.capabilities |= PERF_PMU_CAP_NO_EXCLUDE;
722         }
723         pmu->num_counters = num_counters;
724         pmu->ctr_start = pmu_sbi_ctr_start;
725         pmu->ctr_stop = pmu_sbi_ctr_stop;
726         pmu->event_map = pmu_sbi_event_map;
727         pmu->ctr_get_idx = pmu_sbi_ctr_get_idx;
728         pmu->ctr_get_width = pmu_sbi_ctr_get_width;
729         pmu->ctr_clear_idx = pmu_sbi_ctr_clear_idx;
730         pmu->ctr_read = pmu_sbi_ctr_read;
731
732         ret = cpuhp_state_add_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node);
733         if (ret)
734                 return ret;
735
736         ret = perf_pmu_register(&pmu->pmu, "cpu", PERF_TYPE_RAW);
737         if (ret) {
738                 cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node);
739                 return ret;
740         }
741
742         return 0;
743
744 out_free:
745         kfree(pmu);
746         return ret;
747 }
748
749 static struct platform_driver pmu_sbi_driver = {
750         .probe          = pmu_sbi_device_probe,
751         .driver         = {
752                 .name   = RISCV_PMU_PDEV_NAME,
753         },
754 };
755
756 static int __init pmu_sbi_devinit(void)
757 {
758         int ret;
759         struct platform_device *pdev;
760
761         if (sbi_spec_version < sbi_mk_version(0, 3) ||
762             sbi_probe_extension(SBI_EXT_PMU) <= 0) {
763                 return 0;
764         }
765
766         ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_RISCV_STARTING,
767                                       "perf/riscv/pmu:starting",
768                                       pmu_sbi_starting_cpu, pmu_sbi_dying_cpu);
769         if (ret) {
770                 pr_err("CPU hotplug notifier could not be registered: %d\n",
771                        ret);
772                 return ret;
773         }
774
775         ret = platform_driver_register(&pmu_sbi_driver);
776         if (ret)
777                 return ret;
778
779         pdev = platform_device_register_simple(RISCV_PMU_PDEV_NAME, -1, NULL, 0);
780         if (IS_ERR(pdev)) {
781                 platform_driver_unregister(&pmu_sbi_driver);
782                 return PTR_ERR(pdev);
783         }
784
785         /* Notify legacy implementation that SBI pmu is available*/
786         riscv_pmu_legacy_skip_init();
787
788         return ret;
789 }
790 device_initcall(pmu_sbi_devinit)