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