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