[PATCH v2 3/4] riscv: Introduce vendor variants of extension helpers
Andy Chiu
andy.chiu at sifive.com
Fri Jun 21 01:37:26 PDT 2024
On Mon, Jun 10, 2024 at 12:34 PM Charlie Jenkins <charlie at 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 at rivosinc.com>
> Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
Reviewed-by: Andy Chiu <andy.chiu at 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
>
More information about the linux-riscv
mailing list