diff mbox series

[v2,3/4] riscv: Introduce vendor variants of extension helpers

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

Checks

Context Check Description
conchuod/vmtest-fixes-PR success PR summary
conchuod/patch-3-test-1 success .github/scripts/patches/tests/build_rv32_defconfig.sh
conchuod/patch-3-test-2 success .github/scripts/patches/tests/build_rv64_clang_allmodconfig.sh
conchuod/patch-3-test-3 success .github/scripts/patches/tests/build_rv64_gcc_allmodconfig.sh
conchuod/patch-3-test-4 success .github/scripts/patches/tests/build_rv64_nommu_k210_defconfig.sh
conchuod/patch-3-test-5 success .github/scripts/patches/tests/build_rv64_nommu_virt_defconfig.sh
conchuod/patch-3-test-6 warning .github/scripts/patches/tests/checkpatch.sh
conchuod/patch-3-test-7 success .github/scripts/patches/tests/dtb_warn_rv64.sh
conchuod/patch-3-test-8 success .github/scripts/patches/tests/header_inline.sh
conchuod/patch-3-test-9 success .github/scripts/patches/tests/kdoc.sh
conchuod/patch-3-test-10 success .github/scripts/patches/tests/module_param.sh
conchuod/patch-3-test-11 success .github/scripts/patches/tests/verify_fixes.sh
conchuod/patch-3-test-12 success .github/scripts/patches/tests/verify_signedoff.sh

Commit Message

Charlie Jenkins June 10, 2024, 4:34 a.m. UTC
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>
---
 arch/riscv/include/asm/vendor_extensions.h | 83 ++++++++++++++++++++++++++++++
 drivers/perf/riscv_pmu_sbi.c               |  3 +-
 2 files changed, 85 insertions(+), 1 deletion(-)

Comments

Andy Chiu June 21, 2024, 8:37 a.m. UTC | #1
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 mbox series

Patch

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;