* [PATCH v6 0/2] riscv_pmu_sbi: add support for PMU variant on T-Head C9xx cores
@ 2022-10-11 23:18 ` Heiko Stuebner
0 siblings, 0 replies; 10+ messages in thread
From: Heiko Stuebner @ 2022-10-11 23:18 UTC (permalink / raw)
To: atishp, anup, will, mark.rutland, paul.walmsley, palmer, aou
Cc: linux-riscv, linux-kernel, Conor.Dooley, samuel, Heiko Stuebner
The PMU on T-Head C9xx cores is quite similar to the SSCOFPMF extension
but not completely identical, so this series
changes in v6:
- follow Anup's suggestion and hook into the (pending) cpuinfo patch [2]
instead of modifying the core sbi_get_* functions
changes in v5:
- add received Reviews
- fix sbi caching wrt. negative values (Drew)
- add comment about specific c9xx arch- and imp-ids (Conor)
changes in v4:
- add new patch to cache sbi mvendor, march and mimp-ids (Atish)
- errata dependencies in one line (Conor)
- make driver detection conditional on CONFIG_ERRATA_THEAD_PMU too (Atish)
changes in v3:
- improve commit message (Atish, Conor)
- IS_ENABLED and BIT() in errata probe (Conor)
The change depends on my cpufeature/t-head errata probe cleanup series [1].
changes in v2:
- use alternatives for the CSR access
- make the irq num selection a bit nicer
There is of course a matching opensbi-part whose most recent implementation
can be found on [0].
[0] https://patchwork.ozlabs.org/project/opensbi/cover/20221004164227.1381825-1-heiko@sntech.de
[1] https://lore.kernel.org/all/20220905111027.2463297-1-heiko@sntech.de/
[2] https://lore.kernel.org/r/20220727043829.151794-1-apatel@ventanamicro.com
Heiko Stuebner (2):
RISC-V: Cache SBI vendor values
drivers/perf: riscv_pmu_sbi: add support for PMU variant on T-Head
C9xx cores
arch/riscv/Kconfig.erratas | 13 +++++++++++
arch/riscv/errata/thead/errata.c | 19 ++++++++++++++++
arch/riscv/include/asm/errata_list.h | 16 ++++++++++++-
arch/riscv/include/asm/sbi.h | 5 ++++
arch/riscv/kernel/cpu.c | 30 +++++++++++++++++++++---
drivers/perf/riscv_pmu_sbi.c | 34 ++++++++++++++++++++--------
6 files changed, 103 insertions(+), 14 deletions(-)
--
2.35.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH v6 0/2] riscv_pmu_sbi: add support for PMU variant on T-Head C9xx cores @ 2022-10-11 23:18 ` Heiko Stuebner 0 siblings, 0 replies; 10+ messages in thread From: Heiko Stuebner @ 2022-10-11 23:18 UTC (permalink / raw) To: atishp, anup, will, mark.rutland, paul.walmsley, palmer, aou Cc: linux-riscv, linux-kernel, Conor.Dooley, samuel, Heiko Stuebner The PMU on T-Head C9xx cores is quite similar to the SSCOFPMF extension but not completely identical, so this series changes in v6: - follow Anup's suggestion and hook into the (pending) cpuinfo patch [2] instead of modifying the core sbi_get_* functions changes in v5: - add received Reviews - fix sbi caching wrt. negative values (Drew) - add comment about specific c9xx arch- and imp-ids (Conor) changes in v4: - add new patch to cache sbi mvendor, march and mimp-ids (Atish) - errata dependencies in one line (Conor) - make driver detection conditional on CONFIG_ERRATA_THEAD_PMU too (Atish) changes in v3: - improve commit message (Atish, Conor) - IS_ENABLED and BIT() in errata probe (Conor) The change depends on my cpufeature/t-head errata probe cleanup series [1]. changes in v2: - use alternatives for the CSR access - make the irq num selection a bit nicer There is of course a matching opensbi-part whose most recent implementation can be found on [0]. [0] https://patchwork.ozlabs.org/project/opensbi/cover/20221004164227.1381825-1-heiko@sntech.de [1] https://lore.kernel.org/all/20220905111027.2463297-1-heiko@sntech.de/ [2] https://lore.kernel.org/r/20220727043829.151794-1-apatel@ventanamicro.com Heiko Stuebner (2): RISC-V: Cache SBI vendor values drivers/perf: riscv_pmu_sbi: add support for PMU variant on T-Head C9xx cores arch/riscv/Kconfig.erratas | 13 +++++++++++ arch/riscv/errata/thead/errata.c | 19 ++++++++++++++++ arch/riscv/include/asm/errata_list.h | 16 ++++++++++++- arch/riscv/include/asm/sbi.h | 5 ++++ arch/riscv/kernel/cpu.c | 30 +++++++++++++++++++++--- drivers/perf/riscv_pmu_sbi.c | 34 ++++++++++++++++++++-------- 6 files changed, 103 insertions(+), 14 deletions(-) -- 2.35.1 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v6 1/2] RISC-V: Cache SBI vendor values 2022-10-11 23:18 ` Heiko Stuebner @ 2022-10-11 23:18 ` Heiko Stuebner -1 siblings, 0 replies; 10+ messages in thread From: Heiko Stuebner @ 2022-10-11 23:18 UTC (permalink / raw) To: atishp, anup, will, mark.rutland, paul.walmsley, palmer, aou Cc: linux-riscv, linux-kernel, Conor.Dooley, samuel, Heiko Stuebner, Anup Patel sbi_get_mvendorid(), sbi_get_marchid() and sbi_get_mimpid() might get called multiple times, though the values of these CSRs should not change during the runtime of a specific machine. Though the values can be different depending on which hart of the system they get called. So hook into the newly introduced cpuinfo struct to allow retrieving these cached values via new functions. Also use arch_initcall for the cpuinfo setup instead, as that now clearly is "architecture specific initialization" and also makes these information available slightly earlier. [caching vendor ids] Suggested-by: Atish Patra <atishp@atishpatra.org> [using cpuinfo struct as cache] Suggested-by: Anup Patel <apatel@ventanamicro.com> Signed-off-by: Heiko Stuebner <heiko@sntech.de> --- arch/riscv/include/asm/sbi.h | 5 +++++ arch/riscv/kernel/cpu.c | 30 +++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 2a0ef738695e..4ca7fbacff42 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -327,4 +327,9 @@ int sbi_err_map_linux_errno(int err); static inline int sbi_remote_fence_i(const struct cpumask *cpu_mask) { return -1; } static inline void sbi_init(void) {} #endif /* CONFIG_RISCV_SBI */ + +unsigned long riscv_cached_mvendorid(unsigned int cpu_id); +unsigned long riscv_cached_marchid(unsigned int cpu_id); +unsigned long riscv_cached_mimpid(unsigned int cpu_id); + #endif /* _ASM_RISCV_SBI_H */ diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c index 250220e2cceb..2c40763e1cc8 100644 --- a/arch/riscv/kernel/cpu.c +++ b/arch/riscv/kernel/cpu.c @@ -70,8 +70,6 @@ int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid) return -1; } -#ifdef CONFIG_PROC_FS - struct riscv_cpuinfo { unsigned long mvendorid; unsigned long marchid; @@ -79,6 +77,30 @@ struct riscv_cpuinfo { }; static DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo); +unsigned long riscv_cached_mvendorid(unsigned int cpu_id) +{ + struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id); + + return ci->mvendorid; +} +EXPORT_SYMBOL(riscv_cached_mvendorid); + +unsigned long riscv_cached_marchid(unsigned int cpu_id) +{ + struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id); + + return ci->marchid; +} +EXPORT_SYMBOL(riscv_cached_marchid); + +unsigned long riscv_cached_mimpid(unsigned int cpu_id) +{ + struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id); + + return ci->mimpid; +} +EXPORT_SYMBOL(riscv_cached_mimpid); + static int riscv_cpuinfo_starting(unsigned int cpu) { struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo); @@ -113,7 +135,9 @@ static int __init riscv_cpuinfo_init(void) return 0; } -device_initcall(riscv_cpuinfo_init); +arch_initcall(riscv_cpuinfo_init); + +#ifdef CONFIG_PROC_FS #define __RISCV_ISA_EXT_DATA(UPROP, EXTID) \ { \ -- 2.35.1 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v6 1/2] RISC-V: Cache SBI vendor values @ 2022-10-11 23:18 ` Heiko Stuebner 0 siblings, 0 replies; 10+ messages in thread From: Heiko Stuebner @ 2022-10-11 23:18 UTC (permalink / raw) To: atishp, anup, will, mark.rutland, paul.walmsley, palmer, aou Cc: linux-riscv, linux-kernel, Conor.Dooley, samuel, Heiko Stuebner, Anup Patel sbi_get_mvendorid(), sbi_get_marchid() and sbi_get_mimpid() might get called multiple times, though the values of these CSRs should not change during the runtime of a specific machine. Though the values can be different depending on which hart of the system they get called. So hook into the newly introduced cpuinfo struct to allow retrieving these cached values via new functions. Also use arch_initcall for the cpuinfo setup instead, as that now clearly is "architecture specific initialization" and also makes these information available slightly earlier. [caching vendor ids] Suggested-by: Atish Patra <atishp@atishpatra.org> [using cpuinfo struct as cache] Suggested-by: Anup Patel <apatel@ventanamicro.com> Signed-off-by: Heiko Stuebner <heiko@sntech.de> --- arch/riscv/include/asm/sbi.h | 5 +++++ arch/riscv/kernel/cpu.c | 30 +++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 2a0ef738695e..4ca7fbacff42 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -327,4 +327,9 @@ int sbi_err_map_linux_errno(int err); static inline int sbi_remote_fence_i(const struct cpumask *cpu_mask) { return -1; } static inline void sbi_init(void) {} #endif /* CONFIG_RISCV_SBI */ + +unsigned long riscv_cached_mvendorid(unsigned int cpu_id); +unsigned long riscv_cached_marchid(unsigned int cpu_id); +unsigned long riscv_cached_mimpid(unsigned int cpu_id); + #endif /* _ASM_RISCV_SBI_H */ diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c index 250220e2cceb..2c40763e1cc8 100644 --- a/arch/riscv/kernel/cpu.c +++ b/arch/riscv/kernel/cpu.c @@ -70,8 +70,6 @@ int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid) return -1; } -#ifdef CONFIG_PROC_FS - struct riscv_cpuinfo { unsigned long mvendorid; unsigned long marchid; @@ -79,6 +77,30 @@ struct riscv_cpuinfo { }; static DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo); +unsigned long riscv_cached_mvendorid(unsigned int cpu_id) +{ + struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id); + + return ci->mvendorid; +} +EXPORT_SYMBOL(riscv_cached_mvendorid); + +unsigned long riscv_cached_marchid(unsigned int cpu_id) +{ + struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id); + + return ci->marchid; +} +EXPORT_SYMBOL(riscv_cached_marchid); + +unsigned long riscv_cached_mimpid(unsigned int cpu_id) +{ + struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id); + + return ci->mimpid; +} +EXPORT_SYMBOL(riscv_cached_mimpid); + static int riscv_cpuinfo_starting(unsigned int cpu) { struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo); @@ -113,7 +135,9 @@ static int __init riscv_cpuinfo_init(void) return 0; } -device_initcall(riscv_cpuinfo_init); +arch_initcall(riscv_cpuinfo_init); + +#ifdef CONFIG_PROC_FS #define __RISCV_ISA_EXT_DATA(UPROP, EXTID) \ { \ -- 2.35.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v6 2/2] drivers/perf: riscv_pmu_sbi: add support for PMU variant on T-Head C9xx cores 2022-10-11 23:18 ` Heiko Stuebner @ 2022-10-11 23:18 ` Heiko Stuebner -1 siblings, 0 replies; 10+ messages in thread From: Heiko Stuebner @ 2022-10-11 23:18 UTC (permalink / raw) To: atishp, anup, will, mark.rutland, paul.walmsley, palmer, aou Cc: linux-riscv, linux-kernel, Conor.Dooley, samuel, Heiko Stuebner, Andrew Jones, Conor Dooley With the T-HEAD C9XX cores being designed before or during the ratification to the SSCOFPMF extension, it implements functionality very similar but not equal to it. It implements overflow handling and also some privilege-mode filtering. While SSCOFPMF supports this for all modes, the C9XX only implements the filtering for M-mode and S-mode but not user-mode. So add some adaptions to allow the C9XX to still handle its PMU through the regular SBI PMU interface instead of defining new interfaces or drivers. To work properly, this requires a matching change in SBI, though the actual interface between kernel and SBI does not change. The main differences are a the overflow CSR and irq number. As the reading of the overflow-csr is in the hot-path during irq handling, use an errata and alternatives to not introduce new conditionals there. Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Reviewed-by: Conor Dooley <conor.dooley@microchip.com> Signed-off-by: Heiko Stuebner <heiko@sntech.de> --- arch/riscv/Kconfig.erratas | 13 +++++++++++ arch/riscv/errata/thead/errata.c | 19 ++++++++++++++++ arch/riscv/include/asm/errata_list.h | 16 ++++++++++++- drivers/perf/riscv_pmu_sbi.c | 34 ++++++++++++++++++++-------- 4 files changed, 71 insertions(+), 11 deletions(-) diff --git a/arch/riscv/Kconfig.erratas b/arch/riscv/Kconfig.erratas index f3623df23b5f..69621ae6d647 100644 --- a/arch/riscv/Kconfig.erratas +++ b/arch/riscv/Kconfig.erratas @@ -66,4 +66,17 @@ config ERRATA_THEAD_CMO If you don't know what to do here, say "Y". +config ERRATA_THEAD_PMU + bool "Apply T-Head PMU errata" + depends on ERRATA_THEAD && RISCV_PMU_SBI + default y + help + The T-Head C9xx cores implement a PMU overflow extension very + similar to the core SSCOFPMF extension. + + This will apply the overflow errata to handle the non-standard + behaviour via the regular SBI PMU driver and interface. + + If you don't know what to do here, say "Y". + endmenu # "CPU errata selection" diff --git a/arch/riscv/errata/thead/errata.c b/arch/riscv/errata/thead/errata.c index 21546937db39..fac5742d1c1e 100644 --- a/arch/riscv/errata/thead/errata.c +++ b/arch/riscv/errata/thead/errata.c @@ -47,6 +47,22 @@ static bool errata_probe_cmo(unsigned int stage, return true; } +static bool errata_probe_pmu(unsigned int stage, + unsigned long arch_id, unsigned long impid) +{ + if (!IS_ENABLED(CONFIG_ERRATA_THEAD_PMU)) + return false; + + /* target-c9xx cores report arch_id and impid as 0 */ + if (arch_id != 0 || impid != 0) + return false; + + if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) + return false; + + return true; +} + static u32 thead_errata_probe(unsigned int stage, unsigned long archid, unsigned long impid) { @@ -58,6 +74,9 @@ static u32 thead_errata_probe(unsigned int stage, if (errata_probe_cmo(stage, archid, impid)) cpu_req_errata |= BIT(ERRATA_THEAD_CMO); + if (errata_probe_pmu(stage, archid, impid)) + cpu_req_errata |= BIT(ERRATA_THEAD_PMU); + return cpu_req_errata; } diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h index 19a771085781..4180312d2a70 100644 --- a/arch/riscv/include/asm/errata_list.h +++ b/arch/riscv/include/asm/errata_list.h @@ -6,6 +6,7 @@ #define ASM_ERRATA_LIST_H #include <asm/alternative.h> +#include <asm/csr.h> #include <asm/vendorid_list.h> #ifdef CONFIG_ERRATA_SIFIVE @@ -17,7 +18,8 @@ #ifdef CONFIG_ERRATA_THEAD #define ERRATA_THEAD_PBMT 0 #define ERRATA_THEAD_CMO 1 -#define ERRATA_THEAD_NUMBER 2 +#define ERRATA_THEAD_PMU 2 +#define ERRATA_THEAD_NUMBER 3 #endif #define CPUFEATURE_SVPBMT 0 @@ -142,6 +144,18 @@ asm volatile(ALTERNATIVE_2( \ "r"((unsigned long)(_start) + (_size)) \ : "a0") +#define THEAD_C9XX_RV_IRQ_PMU 17 +#define THEAD_C9XX_CSR_SCOUNTEROF 0x5c5 + +#define ALT_SBI_PMU_OVERFLOW(__ovl) \ +asm volatile(ALTERNATIVE( \ + "csrr %0, " __stringify(CSR_SSCOUNTOVF), \ + "csrr %0, " __stringify(THEAD_C9XX_CSR_SCOUNTEROF), \ + THEAD_VENDOR_ID, ERRATA_THEAD_PMU, \ + CONFIG_ERRATA_THEAD_PMU) \ + : "=r" (__ovl) : \ + : "memory") + #endif /* __ASSEMBLY__ */ #endif diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 8de4ca2fef21..a77fef6dc35f 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -19,6 +19,7 @@ #include <linux/of.h> #include <linux/cpu_pm.h> +#include <asm/errata_list.h> #include <asm/sbi.h> #include <asm/hwcap.h> @@ -46,6 +47,8 @@ static const struct attribute_group *riscv_pmu_attr_groups[] = { * per_cpu in case of harts with different pmu counters */ static union sbi_pmu_ctr_info *pmu_ctr_list; +static bool riscv_pmu_use_irq; +static unsigned int riscv_pmu_irq_num; static unsigned int riscv_pmu_irq; struct sbi_pmu_event_data { @@ -575,7 +578,7 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev) fidx = find_first_bit(cpu_hw_evt->used_hw_ctrs, RISCV_MAX_COUNTERS); event = cpu_hw_evt->events[fidx]; if (!event) { - csr_clear(CSR_SIP, SIP_LCOFIP); + csr_clear(CSR_SIP, BIT(riscv_pmu_irq_num)); return IRQ_NONE; } @@ -583,13 +586,13 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev) pmu_sbi_stop_hw_ctrs(pmu); /* Overflow status register should only be read after counter are stopped */ - overflow = csr_read(CSR_SSCOUNTOVF); + ALT_SBI_PMU_OVERFLOW(overflow); /* * Overflow interrupt pending bit should only be cleared after stopping * all the counters to avoid any race condition. */ - csr_clear(CSR_SIP, SIP_LCOFIP); + csr_clear(CSR_SIP, BIT(riscv_pmu_irq_num)); /* No overflow bit is set */ if (!overflow) @@ -651,10 +654,10 @@ static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node) /* Stop all the counters so that they can be enabled from perf */ pmu_sbi_stop_all(pmu); - if (riscv_isa_extension_available(NULL, SSCOFPMF)) { + if (riscv_pmu_use_irq) { cpu_hw_evt->irq = riscv_pmu_irq; - csr_clear(CSR_IP, BIT(RV_IRQ_PMU)); - csr_set(CSR_IE, BIT(RV_IRQ_PMU)); + csr_clear(CSR_IP, BIT(riscv_pmu_irq_num)); + csr_set(CSR_IE, BIT(riscv_pmu_irq_num)); enable_percpu_irq(riscv_pmu_irq, IRQ_TYPE_NONE); } @@ -663,9 +666,9 @@ static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node) static int pmu_sbi_dying_cpu(unsigned int cpu, struct hlist_node *node) { - if (riscv_isa_extension_available(NULL, SSCOFPMF)) { + if (riscv_pmu_use_irq) { disable_percpu_irq(riscv_pmu_irq); - csr_clear(CSR_IE, BIT(RV_IRQ_PMU)); + csr_clear(CSR_IE, BIT(riscv_pmu_irq_num)); } /* Disable all counters access for user mode now */ @@ -681,7 +684,18 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pde struct device_node *cpu, *child; struct irq_domain *domain = NULL; - if (!riscv_isa_extension_available(NULL, SSCOFPMF)) + if (riscv_isa_extension_available(NULL, SSCOFPMF)) { + riscv_pmu_irq_num = RV_IRQ_PMU; + riscv_pmu_use_irq = true; + } else if (IS_ENABLED(CONFIG_ERRATA_THEAD_PMU) && + riscv_cached_mvendorid(0) == THEAD_VENDOR_ID && + riscv_cached_marchid(0) == 0 && + riscv_cached_mimpid(0) == 0) { + riscv_pmu_irq_num = THEAD_C9XX_RV_IRQ_PMU; + riscv_pmu_use_irq = true; + } + + if (!riscv_pmu_use_irq) return -EOPNOTSUPP; for_each_of_cpu_node(cpu) { @@ -703,7 +717,7 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pde return -ENODEV; } - riscv_pmu_irq = irq_create_mapping(domain, RV_IRQ_PMU); + riscv_pmu_irq = irq_create_mapping(domain, riscv_pmu_irq_num); if (!riscv_pmu_irq) { pr_err("Failed to map PMU interrupt for node\n"); return -ENODEV; -- 2.35.1 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v6 2/2] drivers/perf: riscv_pmu_sbi: add support for PMU variant on T-Head C9xx cores @ 2022-10-11 23:18 ` Heiko Stuebner 0 siblings, 0 replies; 10+ messages in thread From: Heiko Stuebner @ 2022-10-11 23:18 UTC (permalink / raw) To: atishp, anup, will, mark.rutland, paul.walmsley, palmer, aou Cc: linux-riscv, linux-kernel, Conor.Dooley, samuel, Heiko Stuebner, Andrew Jones, Conor Dooley With the T-HEAD C9XX cores being designed before or during the ratification to the SSCOFPMF extension, it implements functionality very similar but not equal to it. It implements overflow handling and also some privilege-mode filtering. While SSCOFPMF supports this for all modes, the C9XX only implements the filtering for M-mode and S-mode but not user-mode. So add some adaptions to allow the C9XX to still handle its PMU through the regular SBI PMU interface instead of defining new interfaces or drivers. To work properly, this requires a matching change in SBI, though the actual interface between kernel and SBI does not change. The main differences are a the overflow CSR and irq number. As the reading of the overflow-csr is in the hot-path during irq handling, use an errata and alternatives to not introduce new conditionals there. Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Reviewed-by: Conor Dooley <conor.dooley@microchip.com> Signed-off-by: Heiko Stuebner <heiko@sntech.de> --- arch/riscv/Kconfig.erratas | 13 +++++++++++ arch/riscv/errata/thead/errata.c | 19 ++++++++++++++++ arch/riscv/include/asm/errata_list.h | 16 ++++++++++++- drivers/perf/riscv_pmu_sbi.c | 34 ++++++++++++++++++++-------- 4 files changed, 71 insertions(+), 11 deletions(-) diff --git a/arch/riscv/Kconfig.erratas b/arch/riscv/Kconfig.erratas index f3623df23b5f..69621ae6d647 100644 --- a/arch/riscv/Kconfig.erratas +++ b/arch/riscv/Kconfig.erratas @@ -66,4 +66,17 @@ config ERRATA_THEAD_CMO If you don't know what to do here, say "Y". +config ERRATA_THEAD_PMU + bool "Apply T-Head PMU errata" + depends on ERRATA_THEAD && RISCV_PMU_SBI + default y + help + The T-Head C9xx cores implement a PMU overflow extension very + similar to the core SSCOFPMF extension. + + This will apply the overflow errata to handle the non-standard + behaviour via the regular SBI PMU driver and interface. + + If you don't know what to do here, say "Y". + endmenu # "CPU errata selection" diff --git a/arch/riscv/errata/thead/errata.c b/arch/riscv/errata/thead/errata.c index 21546937db39..fac5742d1c1e 100644 --- a/arch/riscv/errata/thead/errata.c +++ b/arch/riscv/errata/thead/errata.c @@ -47,6 +47,22 @@ static bool errata_probe_cmo(unsigned int stage, return true; } +static bool errata_probe_pmu(unsigned int stage, + unsigned long arch_id, unsigned long impid) +{ + if (!IS_ENABLED(CONFIG_ERRATA_THEAD_PMU)) + return false; + + /* target-c9xx cores report arch_id and impid as 0 */ + if (arch_id != 0 || impid != 0) + return false; + + if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) + return false; + + return true; +} + static u32 thead_errata_probe(unsigned int stage, unsigned long archid, unsigned long impid) { @@ -58,6 +74,9 @@ static u32 thead_errata_probe(unsigned int stage, if (errata_probe_cmo(stage, archid, impid)) cpu_req_errata |= BIT(ERRATA_THEAD_CMO); + if (errata_probe_pmu(stage, archid, impid)) + cpu_req_errata |= BIT(ERRATA_THEAD_PMU); + return cpu_req_errata; } diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h index 19a771085781..4180312d2a70 100644 --- a/arch/riscv/include/asm/errata_list.h +++ b/arch/riscv/include/asm/errata_list.h @@ -6,6 +6,7 @@ #define ASM_ERRATA_LIST_H #include <asm/alternative.h> +#include <asm/csr.h> #include <asm/vendorid_list.h> #ifdef CONFIG_ERRATA_SIFIVE @@ -17,7 +18,8 @@ #ifdef CONFIG_ERRATA_THEAD #define ERRATA_THEAD_PBMT 0 #define ERRATA_THEAD_CMO 1 -#define ERRATA_THEAD_NUMBER 2 +#define ERRATA_THEAD_PMU 2 +#define ERRATA_THEAD_NUMBER 3 #endif #define CPUFEATURE_SVPBMT 0 @@ -142,6 +144,18 @@ asm volatile(ALTERNATIVE_2( \ "r"((unsigned long)(_start) + (_size)) \ : "a0") +#define THEAD_C9XX_RV_IRQ_PMU 17 +#define THEAD_C9XX_CSR_SCOUNTEROF 0x5c5 + +#define ALT_SBI_PMU_OVERFLOW(__ovl) \ +asm volatile(ALTERNATIVE( \ + "csrr %0, " __stringify(CSR_SSCOUNTOVF), \ + "csrr %0, " __stringify(THEAD_C9XX_CSR_SCOUNTEROF), \ + THEAD_VENDOR_ID, ERRATA_THEAD_PMU, \ + CONFIG_ERRATA_THEAD_PMU) \ + : "=r" (__ovl) : \ + : "memory") + #endif /* __ASSEMBLY__ */ #endif diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 8de4ca2fef21..a77fef6dc35f 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -19,6 +19,7 @@ #include <linux/of.h> #include <linux/cpu_pm.h> +#include <asm/errata_list.h> #include <asm/sbi.h> #include <asm/hwcap.h> @@ -46,6 +47,8 @@ static const struct attribute_group *riscv_pmu_attr_groups[] = { * per_cpu in case of harts with different pmu counters */ static union sbi_pmu_ctr_info *pmu_ctr_list; +static bool riscv_pmu_use_irq; +static unsigned int riscv_pmu_irq_num; static unsigned int riscv_pmu_irq; struct sbi_pmu_event_data { @@ -575,7 +578,7 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev) fidx = find_first_bit(cpu_hw_evt->used_hw_ctrs, RISCV_MAX_COUNTERS); event = cpu_hw_evt->events[fidx]; if (!event) { - csr_clear(CSR_SIP, SIP_LCOFIP); + csr_clear(CSR_SIP, BIT(riscv_pmu_irq_num)); return IRQ_NONE; } @@ -583,13 +586,13 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev) pmu_sbi_stop_hw_ctrs(pmu); /* Overflow status register should only be read after counter are stopped */ - overflow = csr_read(CSR_SSCOUNTOVF); + ALT_SBI_PMU_OVERFLOW(overflow); /* * Overflow interrupt pending bit should only be cleared after stopping * all the counters to avoid any race condition. */ - csr_clear(CSR_SIP, SIP_LCOFIP); + csr_clear(CSR_SIP, BIT(riscv_pmu_irq_num)); /* No overflow bit is set */ if (!overflow) @@ -651,10 +654,10 @@ static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node) /* Stop all the counters so that they can be enabled from perf */ pmu_sbi_stop_all(pmu); - if (riscv_isa_extension_available(NULL, SSCOFPMF)) { + if (riscv_pmu_use_irq) { cpu_hw_evt->irq = riscv_pmu_irq; - csr_clear(CSR_IP, BIT(RV_IRQ_PMU)); - csr_set(CSR_IE, BIT(RV_IRQ_PMU)); + csr_clear(CSR_IP, BIT(riscv_pmu_irq_num)); + csr_set(CSR_IE, BIT(riscv_pmu_irq_num)); enable_percpu_irq(riscv_pmu_irq, IRQ_TYPE_NONE); } @@ -663,9 +666,9 @@ static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node) static int pmu_sbi_dying_cpu(unsigned int cpu, struct hlist_node *node) { - if (riscv_isa_extension_available(NULL, SSCOFPMF)) { + if (riscv_pmu_use_irq) { disable_percpu_irq(riscv_pmu_irq); - csr_clear(CSR_IE, BIT(RV_IRQ_PMU)); + csr_clear(CSR_IE, BIT(riscv_pmu_irq_num)); } /* Disable all counters access for user mode now */ @@ -681,7 +684,18 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pde struct device_node *cpu, *child; struct irq_domain *domain = NULL; - if (!riscv_isa_extension_available(NULL, SSCOFPMF)) + if (riscv_isa_extension_available(NULL, SSCOFPMF)) { + riscv_pmu_irq_num = RV_IRQ_PMU; + riscv_pmu_use_irq = true; + } else if (IS_ENABLED(CONFIG_ERRATA_THEAD_PMU) && + riscv_cached_mvendorid(0) == THEAD_VENDOR_ID && + riscv_cached_marchid(0) == 0 && + riscv_cached_mimpid(0) == 0) { + riscv_pmu_irq_num = THEAD_C9XX_RV_IRQ_PMU; + riscv_pmu_use_irq = true; + } + + if (!riscv_pmu_use_irq) return -EOPNOTSUPP; for_each_of_cpu_node(cpu) { @@ -703,7 +717,7 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pde return -ENODEV; } - riscv_pmu_irq = irq_create_mapping(domain, RV_IRQ_PMU); + riscv_pmu_irq = irq_create_mapping(domain, riscv_pmu_irq_num); if (!riscv_pmu_irq) { pr_err("Failed to map PMU interrupt for node\n"); return -ENODEV; -- 2.35.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v6 0/2] riscv_pmu_sbi: add support for PMU variant on T-Head C9xx cores 2022-10-11 23:18 ` Heiko Stuebner @ 2022-10-27 5:02 ` Palmer Dabbelt -1 siblings, 0 replies; 10+ messages in thread From: Palmer Dabbelt @ 2022-10-27 5:02 UTC (permalink / raw) To: heiko Cc: atishp, anup, Will Deacon, mark.rutland, Paul Walmsley, aou, linux-riscv, linux-kernel, Conor.Dooley, samuel, heiko On Tue, 11 Oct 2022 16:18:39 PDT (-0700), heiko@sntech.de wrote: > The PMU on T-Head C9xx cores is quite similar to the SSCOFPMF extension > but not completely identical, so this series The rest of that sentance got dropped, so I put in The PMU on T-Head C9xx cores is quite similar to the SSCOFPMF extension but not completely identical, so this series adds a T-Head PMU errata that handlen the differences. but LMK if you had a better version, it's still early so I don't mind swapping it around. b4 also got kind of confused here so I had to merge suff manually. > changes in v6: > - follow Anup's suggestion and hook into the (pending) cpuinfo patch [2] > instead of modifying the core sbi_get_* functions > > changes in v5: > - add received Reviews > - fix sbi caching wrt. negative values (Drew) > - add comment about specific c9xx arch- and imp-ids (Conor) > > changes in v4: > - add new patch to cache sbi mvendor, march and mimp-ids (Atish) > - errata dependencies in one line (Conor) > - make driver detection conditional on CONFIG_ERRATA_THEAD_PMU too (Atish) > > changes in v3: > - improve commit message (Atish, Conor) > - IS_ENABLED and BIT() in errata probe (Conor) > > The change depends on my cpufeature/t-head errata probe cleanup series [1]. > > > changes in v2: > - use alternatives for the CSR access > - make the irq num selection a bit nicer > > There is of course a matching opensbi-part whose most recent implementation > can be found on [0]. > > > [0] https://patchwork.ozlabs.org/project/opensbi/cover/20221004164227.1381825-1-heiko@sntech.de > [1] https://lore.kernel.org/all/20220905111027.2463297-1-heiko@sntech.de/ > [2] https://lore.kernel.org/r/20220727043829.151794-1-apatel@ventanamicro.com > > Heiko Stuebner (2): > RISC-V: Cache SBI vendor values > drivers/perf: riscv_pmu_sbi: add support for PMU variant on T-Head > C9xx cores > > arch/riscv/Kconfig.erratas | 13 +++++++++++ > arch/riscv/errata/thead/errata.c | 19 ++++++++++++++++ > arch/riscv/include/asm/errata_list.h | 16 ++++++++++++- > arch/riscv/include/asm/sbi.h | 5 ++++ > arch/riscv/kernel/cpu.c | 30 +++++++++++++++++++++--- > drivers/perf/riscv_pmu_sbi.c | 34 ++++++++++++++++++++-------- > 6 files changed, 103 insertions(+), 14 deletions(-) _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v6 0/2] riscv_pmu_sbi: add support for PMU variant on T-Head C9xx cores @ 2022-10-27 5:02 ` Palmer Dabbelt 0 siblings, 0 replies; 10+ messages in thread From: Palmer Dabbelt @ 2022-10-27 5:02 UTC (permalink / raw) To: heiko Cc: atishp, anup, Will Deacon, mark.rutland, Paul Walmsley, aou, linux-riscv, linux-kernel, Conor.Dooley, samuel, heiko On Tue, 11 Oct 2022 16:18:39 PDT (-0700), heiko@sntech.de wrote: > The PMU on T-Head C9xx cores is quite similar to the SSCOFPMF extension > but not completely identical, so this series The rest of that sentance got dropped, so I put in The PMU on T-Head C9xx cores is quite similar to the SSCOFPMF extension but not completely identical, so this series adds a T-Head PMU errata that handlen the differences. but LMK if you had a better version, it's still early so I don't mind swapping it around. b4 also got kind of confused here so I had to merge suff manually. > changes in v6: > - follow Anup's suggestion and hook into the (pending) cpuinfo patch [2] > instead of modifying the core sbi_get_* functions > > changes in v5: > - add received Reviews > - fix sbi caching wrt. negative values (Drew) > - add comment about specific c9xx arch- and imp-ids (Conor) > > changes in v4: > - add new patch to cache sbi mvendor, march and mimp-ids (Atish) > - errata dependencies in one line (Conor) > - make driver detection conditional on CONFIG_ERRATA_THEAD_PMU too (Atish) > > changes in v3: > - improve commit message (Atish, Conor) > - IS_ENABLED and BIT() in errata probe (Conor) > > The change depends on my cpufeature/t-head errata probe cleanup series [1]. > > > changes in v2: > - use alternatives for the CSR access > - make the irq num selection a bit nicer > > There is of course a matching opensbi-part whose most recent implementation > can be found on [0]. > > > [0] https://patchwork.ozlabs.org/project/opensbi/cover/20221004164227.1381825-1-heiko@sntech.de > [1] https://lore.kernel.org/all/20220905111027.2463297-1-heiko@sntech.de/ > [2] https://lore.kernel.org/r/20220727043829.151794-1-apatel@ventanamicro.com > > Heiko Stuebner (2): > RISC-V: Cache SBI vendor values > drivers/perf: riscv_pmu_sbi: add support for PMU variant on T-Head > C9xx cores > > arch/riscv/Kconfig.erratas | 13 +++++++++++ > arch/riscv/errata/thead/errata.c | 19 ++++++++++++++++ > arch/riscv/include/asm/errata_list.h | 16 ++++++++++++- > arch/riscv/include/asm/sbi.h | 5 ++++ > arch/riscv/kernel/cpu.c | 30 +++++++++++++++++++++--- > drivers/perf/riscv_pmu_sbi.c | 34 ++++++++++++++++++++-------- > 6 files changed, 103 insertions(+), 14 deletions(-) ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v6 0/2] riscv_pmu_sbi: add support for PMU variant on T-Head C9xx cores 2022-10-27 5:02 ` Palmer Dabbelt @ 2022-10-27 19:53 ` Heiko Stübner -1 siblings, 0 replies; 10+ messages in thread From: Heiko Stübner @ 2022-10-27 19:53 UTC (permalink / raw) To: Palmer Dabbelt Cc: atishp, anup, Will Deacon, mark.rutland, Paul Walmsley, aou, linux-riscv, linux-kernel, Conor.Dooley, samuel Am Donnerstag, 27. Oktober 2022, 07:02:59 CEST schrieb Palmer Dabbelt: > On Tue, 11 Oct 2022 16:18:39 PDT (-0700), heiko@sntech.de wrote: > > The PMU on T-Head C9xx cores is quite similar to the SSCOFPMF extension > > but not completely identical, so this series > > The rest of that sentance got dropped, so I put in > > The PMU on T-Head C9xx cores is quite similar to the SSCOFPMF extension > but not completely identical, so this series adds a T-Head PMU errata > that handlen the differences. > > but LMK if you had a better version, it's still early so I don't mind > swapping it around. sounds just fine and sorry for not finishing that sentence on my own. > b4 also got kind of confused here so I had to merge suff manually. do you still know what b4 complained about? My patch workflow is pretty basic (git format-patch + separate git send-email) so I guess it might be interesting what it was stumbling on. Thanks Heiko > > changes in v6: > > - follow Anup's suggestion and hook into the (pending) cpuinfo patch [2] > > instead of modifying the core sbi_get_* functions > > > > changes in v5: > > - add received Reviews > > - fix sbi caching wrt. negative values (Drew) > > - add comment about specific c9xx arch- and imp-ids (Conor) > > > > changes in v4: > > - add new patch to cache sbi mvendor, march and mimp-ids (Atish) > > - errata dependencies in one line (Conor) > > - make driver detection conditional on CONFIG_ERRATA_THEAD_PMU too (Atish) > > > > changes in v3: > > - improve commit message (Atish, Conor) > > - IS_ENABLED and BIT() in errata probe (Conor) > > > > The change depends on my cpufeature/t-head errata probe cleanup series [1]. > > > > > > changes in v2: > > - use alternatives for the CSR access > > - make the irq num selection a bit nicer > > > > There is of course a matching opensbi-part whose most recent implementation > > can be found on [0]. > > > > > > [0] https://patchwork.ozlabs.org/project/opensbi/cover/20221004164227.1381825-1-heiko@sntech.de > > [1] https://lore.kernel.org/all/20220905111027.2463297-1-heiko@sntech.de/ > > [2] https://lore.kernel.org/r/20220727043829.151794-1-apatel@ventanamicro.com > > > > Heiko Stuebner (2): > > RISC-V: Cache SBI vendor values > > drivers/perf: riscv_pmu_sbi: add support for PMU variant on T-Head > > C9xx cores > > > > arch/riscv/Kconfig.erratas | 13 +++++++++++ > > arch/riscv/errata/thead/errata.c | 19 ++++++++++++++++ > > arch/riscv/include/asm/errata_list.h | 16 ++++++++++++- > > arch/riscv/include/asm/sbi.h | 5 ++++ > > arch/riscv/kernel/cpu.c | 30 +++++++++++++++++++++--- > > drivers/perf/riscv_pmu_sbi.c | 34 ++++++++++++++++++++-------- > > 6 files changed, 103 insertions(+), 14 deletions(-) > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v6 0/2] riscv_pmu_sbi: add support for PMU variant on T-Head C9xx cores @ 2022-10-27 19:53 ` Heiko Stübner 0 siblings, 0 replies; 10+ messages in thread From: Heiko Stübner @ 2022-10-27 19:53 UTC (permalink / raw) To: Palmer Dabbelt Cc: atishp, anup, Will Deacon, mark.rutland, Paul Walmsley, aou, linux-riscv, linux-kernel, Conor.Dooley, samuel Am Donnerstag, 27. Oktober 2022, 07:02:59 CEST schrieb Palmer Dabbelt: > On Tue, 11 Oct 2022 16:18:39 PDT (-0700), heiko@sntech.de wrote: > > The PMU on T-Head C9xx cores is quite similar to the SSCOFPMF extension > > but not completely identical, so this series > > The rest of that sentance got dropped, so I put in > > The PMU on T-Head C9xx cores is quite similar to the SSCOFPMF extension > but not completely identical, so this series adds a T-Head PMU errata > that handlen the differences. > > but LMK if you had a better version, it's still early so I don't mind > swapping it around. sounds just fine and sorry for not finishing that sentence on my own. > b4 also got kind of confused here so I had to merge suff manually. do you still know what b4 complained about? My patch workflow is pretty basic (git format-patch + separate git send-email) so I guess it might be interesting what it was stumbling on. Thanks Heiko > > changes in v6: > > - follow Anup's suggestion and hook into the (pending) cpuinfo patch [2] > > instead of modifying the core sbi_get_* functions > > > > changes in v5: > > - add received Reviews > > - fix sbi caching wrt. negative values (Drew) > > - add comment about specific c9xx arch- and imp-ids (Conor) > > > > changes in v4: > > - add new patch to cache sbi mvendor, march and mimp-ids (Atish) > > - errata dependencies in one line (Conor) > > - make driver detection conditional on CONFIG_ERRATA_THEAD_PMU too (Atish) > > > > changes in v3: > > - improve commit message (Atish, Conor) > > - IS_ENABLED and BIT() in errata probe (Conor) > > > > The change depends on my cpufeature/t-head errata probe cleanup series [1]. > > > > > > changes in v2: > > - use alternatives for the CSR access > > - make the irq num selection a bit nicer > > > > There is of course a matching opensbi-part whose most recent implementation > > can be found on [0]. > > > > > > [0] https://patchwork.ozlabs.org/project/opensbi/cover/20221004164227.1381825-1-heiko@sntech.de > > [1] https://lore.kernel.org/all/20220905111027.2463297-1-heiko@sntech.de/ > > [2] https://lore.kernel.org/r/20220727043829.151794-1-apatel@ventanamicro.com > > > > Heiko Stuebner (2): > > RISC-V: Cache SBI vendor values > > drivers/perf: riscv_pmu_sbi: add support for PMU variant on T-Head > > C9xx cores > > > > arch/riscv/Kconfig.erratas | 13 +++++++++++ > > arch/riscv/errata/thead/errata.c | 19 ++++++++++++++++ > > arch/riscv/include/asm/errata_list.h | 16 ++++++++++++- > > arch/riscv/include/asm/sbi.h | 5 ++++ > > arch/riscv/kernel/cpu.c | 30 +++++++++++++++++++++--- > > drivers/perf/riscv_pmu_sbi.c | 34 ++++++++++++++++++++-------- > > 6 files changed, 103 insertions(+), 14 deletions(-) > ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2022-10-27 19:53 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-10-11 23:18 [PATCH v6 0/2] riscv_pmu_sbi: add support for PMU variant on T-Head C9xx cores Heiko Stuebner 2022-10-11 23:18 ` Heiko Stuebner 2022-10-11 23:18 ` [PATCH v6 1/2] RISC-V: Cache SBI vendor values Heiko Stuebner 2022-10-11 23:18 ` Heiko Stuebner 2022-10-11 23:18 ` [PATCH v6 2/2] drivers/perf: riscv_pmu_sbi: add support for PMU variant on T-Head C9xx cores Heiko Stuebner 2022-10-11 23:18 ` Heiko Stuebner 2022-10-27 5:02 ` [PATCH v6 0/2] " Palmer Dabbelt 2022-10-27 5:02 ` Palmer Dabbelt 2022-10-27 19:53 ` Heiko Stübner 2022-10-27 19:53 ` Heiko Stübner
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.