diff options
author | Atish Patra <atishp@rivosinc.com> | 2022-03-14 21:38:43 +0100 |
---|---|---|
committer | Palmer Dabbelt <palmer@rivosinc.com> | 2022-03-17 20:18:00 +0100 |
commit | 02d52fbd940af7d7fe0a523e99938113b2addd35 (patch) | |
tree | b31a40200efc8cc7468c87d119cca05e389a6661 /arch/riscv/kernel/cpufeature.c | |
parent | RISC-V: Extract multi-letter extension names from "riscv, isa" (diff) | |
download | linux-02d52fbd940af7d7fe0a523e99938113b2addd35.tar.xz linux-02d52fbd940af7d7fe0a523e99938113b2addd35.zip |
RISC-V: Implement multi-letter ISA extension probing framework
Multi-letter extensions can be probed using exising
riscv_isa_extension_available API now. It doesn't support versioning
right now as there is no use case for it.
Individual extension specific implementation will be added during
each extension support.
Tested-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Diffstat (limited to 'arch/riscv/kernel/cpufeature.c')
-rw-r--r-- | arch/riscv/kernel/cpufeature.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index b0df7eff47f7..3455fdfd680e 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -83,7 +83,7 @@ void __init riscv_fill_hwcap(void) for_each_of_cpu_node(node) { unsigned long this_hwcap = 0; - unsigned long this_isa = 0; + DECLARE_BITMAP(this_isa, RISCV_ISA_EXT_MAX); if (riscv_of_processor_hartid(node) < 0) continue; @@ -100,6 +100,7 @@ void __init riscv_fill_hwcap(void) if (!strncmp(isa, "rv64", 4)) isa += 4; #endif + bitmap_zero(this_isa, RISCV_ISA_EXT_MAX); for (; *isa; ++isa) { const char *ext = isa++; const char *ext_end = isa; @@ -172,12 +173,20 @@ void __init riscv_fill_hwcap(void) if (*isa != '_') --isa; +#define SET_ISA_EXT_MAP(name, bit) \ + do { \ + if ((ext_end - ext == sizeof(name) - 1) && \ + !memcmp(ext, name, sizeof(name) - 1)) \ + set_bit(bit, this_isa); \ + } while (false) \ + if (unlikely(ext_err)) continue; if (!ext_long) { this_hwcap |= isa2hwcap[(unsigned char)(*ext)]; - this_isa |= (1UL << (*ext - 'a')); + set_bit(*ext - 'a', this_isa); } +#undef SET_ISA_EXT_MAP } /* @@ -190,10 +199,11 @@ void __init riscv_fill_hwcap(void) else elf_hwcap = this_hwcap; - if (riscv_isa[0]) - riscv_isa[0] &= this_isa; + if (bitmap_weight(riscv_isa, RISCV_ISA_EXT_MAX)) + bitmap_and(riscv_isa, riscv_isa, this_isa, RISCV_ISA_EXT_MAX); else - riscv_isa[0] = this_isa; + bitmap_copy(riscv_isa, this_isa, RISCV_ISA_EXT_MAX); + } /* We don't support systems with F but without D, so mask those out @@ -207,7 +217,7 @@ void __init riscv_fill_hwcap(void) for (i = 0, j = 0; i < NUM_ALPHA_EXTS; i++) if (riscv_isa[0] & BIT_MASK(i)) print_str[j++] = (char)('a' + i); - pr_info("riscv: ISA extensions %s\n", print_str); + pr_info("riscv: base ISA extensions %s\n", print_str); memset(print_str, 0, sizeof(print_str)); for (i = 0, j = 0; i < NUM_ALPHA_EXTS; i++) |