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>
This commit is contained in:
parent
40a4d0dfbc
commit
02d52fbd94
|
@ -34,7 +34,25 @@ extern unsigned long elf_hwcap;
|
|||
#define RISCV_ISA_EXT_s ('s' - 'a')
|
||||
#define RISCV_ISA_EXT_u ('u' - 'a')
|
||||
|
||||
/*
|
||||
* Increse this to higher value as kernel support more ISA extensions.
|
||||
*/
|
||||
#define RISCV_ISA_EXT_MAX 64
|
||||
#define RISCV_ISA_EXT_NAME_LEN_MAX 32
|
||||
|
||||
/* The base ID for multi-letter ISA extensions */
|
||||
#define RISCV_ISA_EXT_BASE 26
|
||||
|
||||
/*
|
||||
* This enum represent the logical ID for each multi-letter RISC-V ISA extension.
|
||||
* The logical ID should start from RISCV_ISA_EXT_BASE and must not exceed
|
||||
* RISCV_ISA_EXT_MAX. 0-25 range is reserved for single letter
|
||||
* extensions while all the multi-letter extensions should define the next
|
||||
* available logical extension id.
|
||||
*/
|
||||
enum riscv_isa_ext_id {
|
||||
RISCV_ISA_EXT_ID_MAX = RISCV_ISA_EXT_MAX,
|
||||
};
|
||||
|
||||
unsigned long riscv_isa_extension_base(const unsigned long *isa_bitmap);
|
||||
|
||||
|
|
|
@ -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++)
|
||||
|
|
Loading…
Reference in New Issue