riscv: cpufeature: extend riscv_cpufeature_patch_func to all ISA extensions
riscv_cpufeature_patch_func() currently only scans a limited set of cpufeatures, explicitly defined with macros. Extend it to probe for all ISA extensions. Signed-off-by: Jisheng Zhang <jszhang@kernel.org> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Reviewed-by: Conor Dooley <conor.dooley@microchip.com> Link: https://lore.kernel.org/r/20230128172856.3814-5-jszhang@kernel.org Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
parent
d8a3d8a752
commit
4bf8860760
2 changed files with 11 additions and 62 deletions
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <asm/alternative.h>
|
#include <asm/alternative.h>
|
||||||
#include <asm/csr.h>
|
#include <asm/csr.h>
|
||||||
|
#include <asm/hwcap.h>
|
||||||
#include <asm/vendorid_list.h>
|
#include <asm/vendorid_list.h>
|
||||||
|
|
||||||
#ifdef CONFIG_ERRATA_SIFIVE
|
#ifdef CONFIG_ERRATA_SIFIVE
|
||||||
|
@ -22,10 +23,6 @@
|
||||||
#define ERRATA_THEAD_NUMBER 3
|
#define ERRATA_THEAD_NUMBER 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CPUFEATURE_SVPBMT 0
|
|
||||||
#define CPUFEATURE_ZICBOM 1
|
|
||||||
#define CPUFEATURE_NUMBER 2
|
|
||||||
|
|
||||||
#ifdef __ASSEMBLY__
|
#ifdef __ASSEMBLY__
|
||||||
|
|
||||||
#define ALT_INSN_FAULT(x) \
|
#define ALT_INSN_FAULT(x) \
|
||||||
|
@ -55,7 +52,7 @@ asm(ALTERNATIVE("sfence.vma %0", "sfence.vma", SIFIVE_VENDOR_ID, \
|
||||||
#define ALT_SVPBMT(_val, prot) \
|
#define ALT_SVPBMT(_val, prot) \
|
||||||
asm(ALTERNATIVE_2("li %0, 0\t\nnop", \
|
asm(ALTERNATIVE_2("li %0, 0\t\nnop", \
|
||||||
"li %0, %1\t\nslli %0,%0,%3", 0, \
|
"li %0, %1\t\nslli %0,%0,%3", 0, \
|
||||||
CPUFEATURE_SVPBMT, CONFIG_RISCV_ISA_SVPBMT, \
|
RISCV_ISA_EXT_SVPBMT, CONFIG_RISCV_ISA_SVPBMT, \
|
||||||
"li %0, %2\t\nslli %0,%0,%4", THEAD_VENDOR_ID, \
|
"li %0, %2\t\nslli %0,%0,%4", THEAD_VENDOR_ID, \
|
||||||
ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT) \
|
ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT) \
|
||||||
: "=r"(_val) \
|
: "=r"(_val) \
|
||||||
|
@ -129,7 +126,7 @@ asm volatile(ALTERNATIVE_2( \
|
||||||
"add a0, a0, %0\n\t" \
|
"add a0, a0, %0\n\t" \
|
||||||
"2:\n\t" \
|
"2:\n\t" \
|
||||||
"bltu a0, %2, 3b\n\t" \
|
"bltu a0, %2, 3b\n\t" \
|
||||||
"nop", 0, CPUFEATURE_ZICBOM, CONFIG_RISCV_ISA_ZICBOM, \
|
"nop", 0, RISCV_ISA_EXT_ZICBOM, CONFIG_RISCV_ISA_ZICBOM, \
|
||||||
"mv a0, %1\n\t" \
|
"mv a0, %1\n\t" \
|
||||||
"j 2f\n\t" \
|
"j 2f\n\t" \
|
||||||
"3:\n\t" \
|
"3:\n\t" \
|
||||||
|
|
|
@ -276,59 +276,11 @@ void __init riscv_fill_hwcap(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_RISCV_ALTERNATIVE
|
#ifdef CONFIG_RISCV_ALTERNATIVE
|
||||||
static bool __init_or_module cpufeature_probe_svpbmt(unsigned int stage)
|
|
||||||
{
|
|
||||||
if (!IS_ENABLED(CONFIG_RISCV_ISA_SVPBMT))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return riscv_isa_extension_available(NULL, SVPBMT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool __init_or_module cpufeature_probe_zicbom(unsigned int stage)
|
|
||||||
{
|
|
||||||
if (!IS_ENABLED(CONFIG_RISCV_ISA_ZICBOM))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!riscv_isa_extension_available(NULL, ZICBOM))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Probe presence of individual extensions.
|
|
||||||
*
|
|
||||||
* This code may also be executed before kernel relocation, so we cannot use
|
|
||||||
* addresses generated by the address-of operator as they won't be valid in
|
|
||||||
* this context.
|
|
||||||
* Tests, unless otherwise required, are to be added in alphabetical order.
|
|
||||||
*/
|
|
||||||
static u32 __init_or_module cpufeature_probe(unsigned int stage)
|
|
||||||
{
|
|
||||||
u32 cpu_req_feature = 0;
|
|
||||||
|
|
||||||
if (cpufeature_probe_svpbmt(stage))
|
|
||||||
cpu_req_feature |= BIT(CPUFEATURE_SVPBMT);
|
|
||||||
|
|
||||||
if (cpufeature_probe_zicbom(stage))
|
|
||||||
cpu_req_feature |= BIT(CPUFEATURE_ZICBOM);
|
|
||||||
|
|
||||||
return cpu_req_feature;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin,
|
void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin,
|
||||||
struct alt_entry *end,
|
struct alt_entry *end,
|
||||||
unsigned int stage)
|
unsigned int stage)
|
||||||
{
|
{
|
||||||
u32 cpu_req_feature = cpufeature_probe(stage);
|
|
||||||
struct alt_entry *alt;
|
struct alt_entry *alt;
|
||||||
u32 tmp;
|
|
||||||
|
|
||||||
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
|
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
|
||||||
return;
|
return;
|
||||||
|
@ -336,18 +288,18 @@ void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin,
|
||||||
for (alt = begin; alt < end; alt++) {
|
for (alt = begin; alt < end; alt++) {
|
||||||
if (alt->vendor_id != 0)
|
if (alt->vendor_id != 0)
|
||||||
continue;
|
continue;
|
||||||
if (alt->errata_id >= CPUFEATURE_NUMBER) {
|
if (alt->errata_id >= RISCV_ISA_EXT_MAX) {
|
||||||
WARN(1, "This feature id:%d is not in kernel cpufeature list",
|
WARN(1, "This extension id:%d is not in ISA extension list",
|
||||||
alt->errata_id);
|
alt->errata_id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = (1U << alt->errata_id);
|
if (!__riscv_isa_extension_available(NULL, alt->errata_id))
|
||||||
if (cpu_req_feature & tmp) {
|
continue;
|
||||||
|
|
||||||
patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len);
|
patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len);
|
||||||
riscv_alternative_fix_offsets(alt->old_ptr, alt->alt_len,
|
riscv_alternative_fix_offsets(alt->old_ptr, alt->alt_len,
|
||||||
alt->old_ptr - alt->alt_ptr);
|
alt->old_ptr - alt->alt_ptr);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue