xref: /linux/arch/riscv/kernel/vendor_extensions.c (revision 119b1e61a769aa98e68599f44721661a4d8c55f3)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright 2024 Rivos, Inc
4  */
5 
6 #include <asm/vendorid_list.h>
7 #include <asm/vendor_extensions.h>
8 #include <asm/vendor_extensions/andes.h>
9 #include <asm/vendor_extensions/sifive.h>
10 #include <asm/vendor_extensions/thead.h>
11 
12 #include <linux/array_size.h>
13 #include <linux/types.h>
14 
15 struct riscv_isa_vendor_ext_data_list *riscv_isa_vendor_ext_list[] = {
16 #ifdef CONFIG_RISCV_ISA_VENDOR_EXT_ANDES
17 	&riscv_isa_vendor_ext_list_andes,
18 #endif
19 #ifdef CONFIG_RISCV_ISA_VENDOR_EXT_SIFIVE
20 	&riscv_isa_vendor_ext_list_sifive,
21 #endif
22 #ifdef CONFIG_RISCV_ISA_VENDOR_EXT_THEAD
23 	&riscv_isa_vendor_ext_list_thead,
24 #endif
25 };
26 
27 const size_t riscv_isa_vendor_ext_list_size = ARRAY_SIZE(riscv_isa_vendor_ext_list);
28 
29 /**
30  * __riscv_isa_vendor_extension_available() - Check whether given vendor
31  * extension is available or not.
32  *
33  * @cpu: check if extension is available on this cpu
34  * @vendor: vendor that the extension is a member of
35  * @bit: bit position of the desired extension
36  * Return: true or false
37  *
38  * NOTE: When cpu is -1, will check if extension is available on all cpus
39  */
__riscv_isa_vendor_extension_available(int cpu,unsigned long vendor,unsigned int bit)40 bool __riscv_isa_vendor_extension_available(int cpu, unsigned long vendor, unsigned int bit)
41 {
42 	struct riscv_isavendorinfo *bmap;
43 	struct riscv_isavendorinfo *cpu_bmap;
44 
45 	switch (vendor) {
46 	#ifdef CONFIG_RISCV_ISA_VENDOR_EXT_ANDES
47 	case ANDES_VENDOR_ID:
48 		bmap = &riscv_isa_vendor_ext_list_andes.all_harts_isa_bitmap;
49 		cpu_bmap = riscv_isa_vendor_ext_list_andes.per_hart_isa_bitmap;
50 		break;
51 	#endif
52 	#ifdef CONFIG_RISCV_ISA_VENDOR_EXT_SIFIVE
53 	case SIFIVE_VENDOR_ID:
54 		bmap = &riscv_isa_vendor_ext_list_sifive.all_harts_isa_bitmap;
55 		cpu_bmap = riscv_isa_vendor_ext_list_sifive.per_hart_isa_bitmap;
56 		break;
57 	#endif
58 	#ifdef CONFIG_RISCV_ISA_VENDOR_EXT_THEAD
59 	case THEAD_VENDOR_ID:
60 		bmap = &riscv_isa_vendor_ext_list_thead.all_harts_isa_bitmap;
61 		cpu_bmap = riscv_isa_vendor_ext_list_thead.per_hart_isa_bitmap;
62 		break;
63 	#endif
64 	default:
65 		return false;
66 	}
67 
68 	if (cpu != -1)
69 		bmap = &cpu_bmap[cpu];
70 
71 	if (bit >= RISCV_ISA_VENDOR_EXT_MAX)
72 		return false;
73 
74 	return test_bit(bit, bmap->isa);
75 }
76 EXPORT_SYMBOL_GPL(__riscv_isa_vendor_extension_available);
77