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