riscv: Introduce vendor variants of extension helpers
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> Link: https://lore.kernel.org/r/20240719-support_vendor_extensions-v3-3-0af7587bbec0@rivosinc.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
parent
9448d9accd
commit
0f24254111
@ -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 */
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user