Skip to content

Commit bc969d6

Browse files
lyctwpalmer-dabbelt
authored andcommitted
perf: RISC-V: Introduce Andes PMU to support perf event sampling
Assign riscv_pmu_irq_num the value of (256 + 18) for the custome PMU and add SSCOUNTOVF and SIP alternatives to ALT_SBI_PMU_OVERFLOW() and ALT_SBI_PMU_OVF_CLEAR_PENDING() macros, respectively. To make use of Andes PMU extension, "xandespmu" needs to be appended to the riscv,isa-extensions for each cpu node in device-tree, and make sure CONFIG_ANDES_CUSTOM_PMU is enabled. Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com> Reviewed-by: Charles Ci-Jyun Wu <dminus@andestech.com> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com> Co-developed-by: Locus Wei-Han Chen <locus84@andestech.com> Signed-off-by: Locus Wei-Han Chen <locus84@andestech.com> Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> Link: https://lore.kernel.org/r/20240222083946.3977135-8-peterlin@andestech.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
1 parent ea0e017 commit bc969d6

File tree

5 files changed

+48
-12
lines changed

5 files changed

+48
-12
lines changed

arch/riscv/include/asm/errata_list.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,6 @@ asm volatile(ALTERNATIVE( \
112112
#define THEAD_C9XX_RV_IRQ_PMU 17
113113
#define THEAD_C9XX_CSR_SCOUNTEROF 0x5c5
114114

115-
#define ALT_SBI_PMU_OVERFLOW(__ovl) \
116-
asm volatile(ALTERNATIVE( \
117-
"csrr %0, " __stringify(CSR_SSCOUNTOVF), \
118-
"csrr %0, " __stringify(THEAD_C9XX_CSR_SCOUNTEROF), \
119-
THEAD_VENDOR_ID, ERRATA_THEAD_PMU, \
120-
CONFIG_ERRATA_THEAD_PMU) \
121-
: "=r" (__ovl) : \
122-
: "memory")
123-
124115
#endif /* __ASSEMBLY__ */
125116

126117
#endif

arch/riscv/include/asm/hwcap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
#define RISCV_ISA_EXT_ZFA 71
8181
#define RISCV_ISA_EXT_ZTSO 72
8282
#define RISCV_ISA_EXT_ZACAS 73
83+
#define RISCV_ISA_EXT_XANDESPMU 74
8384

8485
#define RISCV_ISA_EXT_MAX 128
8586
#define RISCV_ISA_EXT_INVALID U32_MAX

arch/riscv/kernel/cpufeature.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
307307
__RISCV_ISA_EXT_DATA(svinval, RISCV_ISA_EXT_SVINVAL),
308308
__RISCV_ISA_EXT_DATA(svnapot, RISCV_ISA_EXT_SVNAPOT),
309309
__RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT),
310+
__RISCV_ISA_EXT_DATA(xandespmu, RISCV_ISA_EXT_XANDESPMU),
310311
};
311312

312313
const size_t riscv_isa_ext_count = ARRAY_SIZE(riscv_isa_ext);

drivers/perf/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,20 @@ config RISCV_PMU_SBI
8686
full perf feature support i.e. counter overflow, privilege mode
8787
filtering, counter configuration.
8888

89+
config ANDES_CUSTOM_PMU
90+
bool "Andes custom PMU support"
91+
depends on ARCH_RENESAS && RISCV_ALTERNATIVE && RISCV_PMU_SBI
92+
default y
93+
help
94+
The Andes cores implement the PMU overflow extension very
95+
similar to the standard Sscofpmf and Smcntrpmf extension.
96+
97+
This will patch the overflow and pending CSRs and handle the
98+
non-standard behaviour via the regular SBI PMU driver and
99+
interface.
100+
101+
If you don't know what to do here, say "Y".
102+
89103
config ARM_PMU_ACPI
90104
depends on ARM_PMU && ACPI
91105
def_bool y

drivers/perf/riscv_pmu_sbi.c

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,33 @@
1919
#include <linux/of.h>
2020
#include <linux/cpu_pm.h>
2121
#include <linux/sched/clock.h>
22+
#include <linux/soc/andes/irq.h>
2223

2324
#include <asm/errata_list.h>
2425
#include <asm/sbi.h>
2526
#include <asm/cpufeature.h>
2627

28+
#define ALT_SBI_PMU_OVERFLOW(__ovl) \
29+
asm volatile(ALTERNATIVE_2( \
30+
"csrr %0, " __stringify(CSR_SSCOUNTOVF), \
31+
"csrr %0, " __stringify(THEAD_C9XX_CSR_SCOUNTEROF), \
32+
THEAD_VENDOR_ID, ERRATA_THEAD_PMU, \
33+
CONFIG_ERRATA_THEAD_PMU, \
34+
"csrr %0, " __stringify(ANDES_CSR_SCOUNTEROF), \
35+
0, RISCV_ISA_EXT_XANDESPMU, \
36+
CONFIG_ANDES_CUSTOM_PMU) \
37+
: "=r" (__ovl) : \
38+
: "memory")
39+
40+
#define ALT_SBI_PMU_OVF_CLEAR_PENDING(__irq_mask) \
41+
asm volatile(ALTERNATIVE( \
42+
"csrc " __stringify(CSR_IP) ", %0\n\t", \
43+
"csrc " __stringify(ANDES_CSR_SLIP) ", %0\n\t", \
44+
0, RISCV_ISA_EXT_XANDESPMU, \
45+
CONFIG_ANDES_CUSTOM_PMU) \
46+
: : "r"(__irq_mask) \
47+
: "memory")
48+
2749
#define SYSCTL_NO_USER_ACCESS 0
2850
#define SYSCTL_USER_ACCESS 1
2951
#define SYSCTL_LEGACY 2
@@ -61,6 +83,7 @@ static int sysctl_perf_user_access __read_mostly = SYSCTL_USER_ACCESS;
6183
static union sbi_pmu_ctr_info *pmu_ctr_list;
6284
static bool riscv_pmu_use_irq;
6385
static unsigned int riscv_pmu_irq_num;
86+
static unsigned int riscv_pmu_irq_mask;
6487
static unsigned int riscv_pmu_irq;
6588

6689
/* Cache the available counters in a bitmask */
@@ -694,7 +717,7 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
694717

695718
event = cpu_hw_evt->events[fidx];
696719
if (!event) {
697-
csr_clear(CSR_SIP, BIT(riscv_pmu_irq_num));
720+
ALT_SBI_PMU_OVF_CLEAR_PENDING(riscv_pmu_irq_mask);
698721
return IRQ_NONE;
699722
}
700723

@@ -708,7 +731,7 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
708731
* Overflow interrupt pending bit should only be cleared after stopping
709732
* all the counters to avoid any race condition.
710733
*/
711-
csr_clear(CSR_SIP, BIT(riscv_pmu_irq_num));
734+
ALT_SBI_PMU_OVF_CLEAR_PENDING(riscv_pmu_irq_mask);
712735

713736
/* No overflow bit is set */
714737
if (!overflow)
@@ -780,7 +803,7 @@ static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node)
780803

781804
if (riscv_pmu_use_irq) {
782805
cpu_hw_evt->irq = riscv_pmu_irq;
783-
csr_clear(CSR_IP, BIT(riscv_pmu_irq_num));
806+
ALT_SBI_PMU_OVF_CLEAR_PENDING(riscv_pmu_irq_mask);
784807
enable_percpu_irq(riscv_pmu_irq, IRQ_TYPE_NONE);
785808
}
786809

@@ -814,8 +837,14 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pde
814837
riscv_cached_mimpid(0) == 0) {
815838
riscv_pmu_irq_num = THEAD_C9XX_RV_IRQ_PMU;
816839
riscv_pmu_use_irq = true;
840+
} else if (riscv_isa_extension_available(NULL, XANDESPMU) &&
841+
IS_ENABLED(CONFIG_ANDES_CUSTOM_PMU)) {
842+
riscv_pmu_irq_num = ANDES_SLI_CAUSE_BASE + ANDES_RV_IRQ_PMOVI;
843+
riscv_pmu_use_irq = true;
817844
}
818845

846+
riscv_pmu_irq_mask = BIT(riscv_pmu_irq_num % BITS_PER_LONG);
847+
819848
if (!riscv_pmu_use_irq)
820849
return -EOPNOTSUPP;
821850

0 commit comments

Comments
 (0)