Skip to content

Commit 02d52fb

Browse files
atishp04palmer-dabbelt
authored andcommitted
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>
1 parent 40a4d0d commit 02d52fb

2 files changed

Lines changed: 34 additions & 6 deletions

File tree

arch/riscv/include/asm/hwcap.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,25 @@ extern unsigned long elf_hwcap;
3434
#define RISCV_ISA_EXT_s ('s' - 'a')
3535
#define RISCV_ISA_EXT_u ('u' - 'a')
3636

37+
/*
38+
* Increse this to higher value as kernel support more ISA extensions.
39+
*/
3740
#define RISCV_ISA_EXT_MAX 64
41+
#define RISCV_ISA_EXT_NAME_LEN_MAX 32
42+
43+
/* The base ID for multi-letter ISA extensions */
44+
#define RISCV_ISA_EXT_BASE 26
45+
46+
/*
47+
* This enum represent the logical ID for each multi-letter RISC-V ISA extension.
48+
* The logical ID should start from RISCV_ISA_EXT_BASE and must not exceed
49+
* RISCV_ISA_EXT_MAX. 0-25 range is reserved for single letter
50+
* extensions while all the multi-letter extensions should define the next
51+
* available logical extension id.
52+
*/
53+
enum riscv_isa_ext_id {
54+
RISCV_ISA_EXT_ID_MAX = RISCV_ISA_EXT_MAX,
55+
};
3856

3957
unsigned long riscv_isa_extension_base(const unsigned long *isa_bitmap);
4058

arch/riscv/kernel/cpufeature.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ void __init riscv_fill_hwcap(void)
8383

8484
for_each_of_cpu_node(node) {
8585
unsigned long this_hwcap = 0;
86-
unsigned long this_isa = 0;
86+
DECLARE_BITMAP(this_isa, RISCV_ISA_EXT_MAX);
8787

8888
if (riscv_of_processor_hartid(node) < 0)
8989
continue;
@@ -100,6 +100,7 @@ void __init riscv_fill_hwcap(void)
100100
if (!strncmp(isa, "rv64", 4))
101101
isa += 4;
102102
#endif
103+
bitmap_zero(this_isa, RISCV_ISA_EXT_MAX);
103104
for (; *isa; ++isa) {
104105
const char *ext = isa++;
105106
const char *ext_end = isa;
@@ -172,12 +173,20 @@ void __init riscv_fill_hwcap(void)
172173
if (*isa != '_')
173174
--isa;
174175

176+
#define SET_ISA_EXT_MAP(name, bit) \
177+
do { \
178+
if ((ext_end - ext == sizeof(name) - 1) && \
179+
!memcmp(ext, name, sizeof(name) - 1)) \
180+
set_bit(bit, this_isa); \
181+
} while (false) \
182+
175183
if (unlikely(ext_err))
176184
continue;
177185
if (!ext_long) {
178186
this_hwcap |= isa2hwcap[(unsigned char)(*ext)];
179-
this_isa |= (1UL << (*ext - 'a'));
187+
set_bit(*ext - 'a', this_isa);
180188
}
189+
#undef SET_ISA_EXT_MAP
181190
}
182191

183192
/*
@@ -190,10 +199,11 @@ void __init riscv_fill_hwcap(void)
190199
else
191200
elf_hwcap = this_hwcap;
192201

193-
if (riscv_isa[0])
194-
riscv_isa[0] &= this_isa;
202+
if (bitmap_weight(riscv_isa, RISCV_ISA_EXT_MAX))
203+
bitmap_and(riscv_isa, riscv_isa, this_isa, RISCV_ISA_EXT_MAX);
195204
else
196-
riscv_isa[0] = this_isa;
205+
bitmap_copy(riscv_isa, this_isa, RISCV_ISA_EXT_MAX);
206+
197207
}
198208

199209
/* We don't support systems with F but without D, so mask those out
@@ -207,7 +217,7 @@ void __init riscv_fill_hwcap(void)
207217
for (i = 0, j = 0; i < NUM_ALPHA_EXTS; i++)
208218
if (riscv_isa[0] & BIT_MASK(i))
209219
print_str[j++] = (char)('a' + i);
210-
pr_info("riscv: ISA extensions %s\n", print_str);
220+
pr_info("riscv: base ISA extensions %s\n", print_str);
211221

212222
memset(print_str, 0, sizeof(print_str));
213223
for (i = 0, j = 0; i < NUM_ALPHA_EXTS; i++)

0 commit comments

Comments
 (0)