Message ID | 20240609-support_vendor_extensions-v2-3-9a43f1fdcbb9@rivosinc.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | riscv: Separate vendor extensions from standard extensions | expand |
On Mon, Jun 10, 2024 at 12:34 PM Charlie Jenkins <charlie@rivosinc.com> wrote: > > Vendor extensions are maintained in per-vendor structs (separate from > standard extensions which live in riscv_isa). Create vendor variants for > the existing extension helpers to interface with the riscv_isa_vendor > bitmaps. > > Signed-off-by: Charlie Jenkins <charlie@rivosinc.com> > Reviewed-by: Conor Dooley <conor.dooley@microchip.com> Reviewed-by: Andy Chiu <andy.chiu@sifive.com> > --- > arch/riscv/include/asm/vendor_extensions.h | 83 ++++++++++++++++++++++++++++++ > drivers/perf/riscv_pmu_sbi.c | 3 +- > 2 files changed, 85 insertions(+), 1 deletion(-) > > diff --git a/arch/riscv/include/asm/vendor_extensions.h b/arch/riscv/include/asm/vendor_extensions.h > index 5fca550fc1f6..04d72b02ae6b 100644 > --- a/arch/riscv/include/asm/vendor_extensions.h > +++ b/arch/riscv/include/asm/vendor_extensions.h > @@ -42,8 +42,91 @@ extern const size_t riscv_isa_vendor_ext_list_size; > #define VENDOR_EXT_ALL_CPUS -1 > > bool __riscv_isa_vendor_extension_available(int cpu, unsigned long vendor, unsigned int bit); > +#define riscv_cpu_isa_vendor_extension_available(cpu, vendor, ext) \ > + __riscv_isa_vendor_extension_available(cpu, vendor, RISCV_ISA_VENDOR_EXT_##ext) > #define riscv_isa_vendor_extension_available(vendor, ext) \ > __riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor, \ > RISCV_ISA_VENDOR_EXT_##ext) > > +static __always_inline bool __riscv_has_extension_likely(const unsigned long vendor, > + const unsigned long ext) > +{ > + asm goto(ALTERNATIVE("j %l[l_no]", "nop", %[vendor], %[ext], 1) > + : > + : [vendor] "i" (vendor), [ext] "i" (ext) > + : > + : l_no); > + > + return true; > +l_no: > + return false; > +} > + > +static __always_inline bool __riscv_has_extension_unlikely(const unsigned long vendor, > + const unsigned long ext) > +{ > + asm goto(ALTERNATIVE("nop", "j %l[l_yes]", %[vendor], %[ext], 1) > + : > + : [vendor] "i" (vendor), [ext] "i" (ext) > + : > + : l_yes); > + > + return false; > +l_yes: > + return true; > +} > + > +static __always_inline bool riscv_has_vendor_extension_likely(const unsigned long vendor, > + const unsigned long ext) > +{ > + if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT)) > + return false; > + > + if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) > + return __riscv_has_extension_likely(vendor, > + ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE); > + > + return __riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor, ext); > +} > + > +static __always_inline bool riscv_has_vendor_extension_unlikely(const unsigned long vendor, > + const unsigned long ext) > +{ > + if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT)) > + return false; > + > + if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) > + return __riscv_has_extension_unlikely(vendor, > + ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE); > + > + return __riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor, ext); > +} > + > +static __always_inline bool riscv_cpu_has_vendor_extension_likely(const unsigned long vendor, > + int cpu, const unsigned long ext) > +{ > + if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT)) > + return false; > + > + if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) && > + __riscv_has_extension_likely(vendor, ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE)) > + return true; > + > + return __riscv_isa_vendor_extension_available(cpu, vendor, ext); > +} > + > +static __always_inline bool riscv_cpu_has_vendor_extension_unlikely(const unsigned long vendor, > + int cpu, > + const unsigned long ext) > +{ > + if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT)) > + return false; > + > + if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) && > + __riscv_has_extension_unlikely(vendor, ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE)) > + return true; > + > + return __riscv_isa_vendor_extension_available(cpu, vendor, ext); > +} > + > #endif /* _ASM_VENDOR_EXTENSIONS_H */ > diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c > index 02719e0c6368..e1f0edfb7dcc 100644 > --- a/drivers/perf/riscv_pmu_sbi.c > +++ b/drivers/perf/riscv_pmu_sbi.c > @@ -1064,7 +1064,8 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pde > riscv_cached_mimpid(0) == 0) { > riscv_pmu_irq_num = THEAD_C9XX_RV_IRQ_PMU; > riscv_pmu_use_irq = true; > - } else if (riscv_isa_vendor_extension_available(ANDES_VENDOR_ID, XANDESPMU) && > + } else if (riscv_has_vendor_extension_unlikely(ANDES_VENDOR_ID, > + RISCV_ISA_VENDOR_EXT_XANDESPMU) && > IS_ENABLED(CONFIG_ANDES_CUSTOM_PMU)) { > riscv_pmu_irq_num = ANDES_SLI_CAUSE_BASE + ANDES_RV_IRQ_PMOVI; > riscv_pmu_use_irq = true; > > -- > 2.44.0 >
diff --git a/arch/riscv/include/asm/vendor_extensions.h b/arch/riscv/include/asm/vendor_extensions.h index 5fca550fc1f6..04d72b02ae6b 100644 --- a/arch/riscv/include/asm/vendor_extensions.h +++ b/arch/riscv/include/asm/vendor_extensions.h @@ -42,8 +42,91 @@ extern const size_t riscv_isa_vendor_ext_list_size; #define VENDOR_EXT_ALL_CPUS -1 bool __riscv_isa_vendor_extension_available(int cpu, unsigned long vendor, unsigned int bit); +#define riscv_cpu_isa_vendor_extension_available(cpu, vendor, ext) \ + __riscv_isa_vendor_extension_available(cpu, vendor, RISCV_ISA_VENDOR_EXT_##ext) #define riscv_isa_vendor_extension_available(vendor, ext) \ __riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor, \ RISCV_ISA_VENDOR_EXT_##ext) +static __always_inline bool __riscv_has_extension_likely(const unsigned long vendor, + const unsigned long ext) +{ + asm goto(ALTERNATIVE("j %l[l_no]", "nop", %[vendor], %[ext], 1) + : + : [vendor] "i" (vendor), [ext] "i" (ext) + : + : l_no); + + return true; +l_no: + return false; +} + +static __always_inline bool __riscv_has_extension_unlikely(const unsigned long vendor, + const unsigned long ext) +{ + asm goto(ALTERNATIVE("nop", "j %l[l_yes]", %[vendor], %[ext], 1) + : + : [vendor] "i" (vendor), [ext] "i" (ext) + : + : l_yes); + + return false; +l_yes: + return true; +} + +static __always_inline bool riscv_has_vendor_extension_likely(const unsigned long vendor, + const unsigned long ext) +{ + if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT)) + return false; + + if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) + return __riscv_has_extension_likely(vendor, + ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE); + + return __riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor, ext); +} + +static __always_inline bool riscv_has_vendor_extension_unlikely(const unsigned long vendor, + const unsigned long ext) +{ + if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT)) + return false; + + if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) + return __riscv_has_extension_unlikely(vendor, + ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE); + + return __riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor, ext); +} + +static __always_inline bool riscv_cpu_has_vendor_extension_likely(const unsigned long vendor, + int cpu, const unsigned long ext) +{ + if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT)) + return false; + + if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) && + __riscv_has_extension_likely(vendor, ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE)) + return true; + + return __riscv_isa_vendor_extension_available(cpu, vendor, ext); +} + +static __always_inline bool riscv_cpu_has_vendor_extension_unlikely(const unsigned long vendor, + int cpu, + const unsigned long ext) +{ + if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT)) + return false; + + if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) && + __riscv_has_extension_unlikely(vendor, ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE)) + return true; + + return __riscv_isa_vendor_extension_available(cpu, vendor, ext); +} + #endif /* _ASM_VENDOR_EXTENSIONS_H */ diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 02719e0c6368..e1f0edfb7dcc 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -1064,7 +1064,8 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pde riscv_cached_mimpid(0) == 0) { riscv_pmu_irq_num = THEAD_C9XX_RV_IRQ_PMU; riscv_pmu_use_irq = true; - } else if (riscv_isa_vendor_extension_available(ANDES_VENDOR_ID, XANDESPMU) && + } else if (riscv_has_vendor_extension_unlikely(ANDES_VENDOR_ID, + RISCV_ISA_VENDOR_EXT_XANDESPMU) && IS_ENABLED(CONFIG_ANDES_CUSTOM_PMU)) { riscv_pmu_irq_num = ANDES_SLI_CAUSE_BASE + ANDES_RV_IRQ_PMOVI; riscv_pmu_use_irq = true;