1*700637cbSDimitry Andric //=== cpu_model/riscv.c - Update RISC-V Feature Bits Structure -*- C -*-======//
2*700637cbSDimitry Andric //
3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*700637cbSDimitry Andric //
7*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
8*700637cbSDimitry Andric
9*700637cbSDimitry Andric #include "cpu_model.h"
10*700637cbSDimitry Andric
11*700637cbSDimitry Andric #define RISCV_FEATURE_BITS_LENGTH 2
12*700637cbSDimitry Andric struct {
13*700637cbSDimitry Andric unsigned length;
14*700637cbSDimitry Andric unsigned long long features[RISCV_FEATURE_BITS_LENGTH];
15*700637cbSDimitry Andric } __riscv_feature_bits __attribute__((visibility("hidden"), nocommon));
16*700637cbSDimitry Andric
17*700637cbSDimitry Andric struct {
18*700637cbSDimitry Andric unsigned mvendorid;
19*700637cbSDimitry Andric unsigned long long marchid;
20*700637cbSDimitry Andric unsigned long long mimpid;
21*700637cbSDimitry Andric } __riscv_cpu_model __attribute__((visibility("hidden"), nocommon));
22*700637cbSDimitry Andric
23*700637cbSDimitry Andric // NOTE: Should sync-up with RISCVFeatures.td
24*700637cbSDimitry Andric // TODO: Maybe generate a header from tablegen then include it.
25*700637cbSDimitry Andric #define A_GROUPID 0
26*700637cbSDimitry Andric #define A_BITMASK (1ULL << 0)
27*700637cbSDimitry Andric #define B_GROUPID 0
28*700637cbSDimitry Andric #define B_BITMASK (1ULL << 1)
29*700637cbSDimitry Andric #define C_GROUPID 0
30*700637cbSDimitry Andric #define C_BITMASK (1ULL << 2)
31*700637cbSDimitry Andric #define D_GROUPID 0
32*700637cbSDimitry Andric #define D_BITMASK (1ULL << 3)
33*700637cbSDimitry Andric #define E_GROUPID 0
34*700637cbSDimitry Andric #define E_BITMASK (1ULL << 4)
35*700637cbSDimitry Andric #define F_GROUPID 0
36*700637cbSDimitry Andric #define F_BITMASK (1ULL << 5)
37*700637cbSDimitry Andric #define H_GROUPID 0
38*700637cbSDimitry Andric #define H_BITMASK (1ULL << 7)
39*700637cbSDimitry Andric #define I_GROUPID 0
40*700637cbSDimitry Andric #define I_BITMASK (1ULL << 8)
41*700637cbSDimitry Andric #define M_GROUPID 0
42*700637cbSDimitry Andric #define M_BITMASK (1ULL << 12)
43*700637cbSDimitry Andric #define Q_GROUPID 0
44*700637cbSDimitry Andric #define Q_BITMASK (1ULL << 16)
45*700637cbSDimitry Andric #define V_GROUPID 0
46*700637cbSDimitry Andric #define V_BITMASK (1ULL << 21)
47*700637cbSDimitry Andric #define ZACAS_GROUPID 0
48*700637cbSDimitry Andric #define ZACAS_BITMASK (1ULL << 26)
49*700637cbSDimitry Andric #define ZBA_GROUPID 0
50*700637cbSDimitry Andric #define ZBA_BITMASK (1ULL << 27)
51*700637cbSDimitry Andric #define ZBB_GROUPID 0
52*700637cbSDimitry Andric #define ZBB_BITMASK (1ULL << 28)
53*700637cbSDimitry Andric #define ZBC_GROUPID 0
54*700637cbSDimitry Andric #define ZBC_BITMASK (1ULL << 29)
55*700637cbSDimitry Andric #define ZBKB_GROUPID 0
56*700637cbSDimitry Andric #define ZBKB_BITMASK (1ULL << 30)
57*700637cbSDimitry Andric #define ZBKC_GROUPID 0
58*700637cbSDimitry Andric #define ZBKC_BITMASK (1ULL << 31)
59*700637cbSDimitry Andric #define ZBKX_GROUPID 0
60*700637cbSDimitry Andric #define ZBKX_BITMASK (1ULL << 32)
61*700637cbSDimitry Andric #define ZBS_GROUPID 0
62*700637cbSDimitry Andric #define ZBS_BITMASK (1ULL << 33)
63*700637cbSDimitry Andric #define ZFA_GROUPID 0
64*700637cbSDimitry Andric #define ZFA_BITMASK (1ULL << 34)
65*700637cbSDimitry Andric #define ZFH_GROUPID 0
66*700637cbSDimitry Andric #define ZFH_BITMASK (1ULL << 35)
67*700637cbSDimitry Andric #define ZFHMIN_GROUPID 0
68*700637cbSDimitry Andric #define ZFHMIN_BITMASK (1ULL << 36)
69*700637cbSDimitry Andric #define ZICBOZ_GROUPID 0
70*700637cbSDimitry Andric #define ZICBOZ_BITMASK (1ULL << 37)
71*700637cbSDimitry Andric #define ZICOND_GROUPID 0
72*700637cbSDimitry Andric #define ZICOND_BITMASK (1ULL << 38)
73*700637cbSDimitry Andric #define ZIHINTNTL_GROUPID 0
74*700637cbSDimitry Andric #define ZIHINTNTL_BITMASK (1ULL << 39)
75*700637cbSDimitry Andric #define ZIHINTPAUSE_GROUPID 0
76*700637cbSDimitry Andric #define ZIHINTPAUSE_BITMASK (1ULL << 40)
77*700637cbSDimitry Andric #define ZKND_GROUPID 0
78*700637cbSDimitry Andric #define ZKND_BITMASK (1ULL << 41)
79*700637cbSDimitry Andric #define ZKNE_GROUPID 0
80*700637cbSDimitry Andric #define ZKNE_BITMASK (1ULL << 42)
81*700637cbSDimitry Andric #define ZKNH_GROUPID 0
82*700637cbSDimitry Andric #define ZKNH_BITMASK (1ULL << 43)
83*700637cbSDimitry Andric #define ZKSED_GROUPID 0
84*700637cbSDimitry Andric #define ZKSED_BITMASK (1ULL << 44)
85*700637cbSDimitry Andric #define ZKSH_GROUPID 0
86*700637cbSDimitry Andric #define ZKSH_BITMASK (1ULL << 45)
87*700637cbSDimitry Andric #define ZKT_GROUPID 0
88*700637cbSDimitry Andric #define ZKT_BITMASK (1ULL << 46)
89*700637cbSDimitry Andric #define ZTSO_GROUPID 0
90*700637cbSDimitry Andric #define ZTSO_BITMASK (1ULL << 47)
91*700637cbSDimitry Andric #define ZVBB_GROUPID 0
92*700637cbSDimitry Andric #define ZVBB_BITMASK (1ULL << 48)
93*700637cbSDimitry Andric #define ZVBC_GROUPID 0
94*700637cbSDimitry Andric #define ZVBC_BITMASK (1ULL << 49)
95*700637cbSDimitry Andric #define ZVFH_GROUPID 0
96*700637cbSDimitry Andric #define ZVFH_BITMASK (1ULL << 50)
97*700637cbSDimitry Andric #define ZVFHMIN_GROUPID 0
98*700637cbSDimitry Andric #define ZVFHMIN_BITMASK (1ULL << 51)
99*700637cbSDimitry Andric #define ZVKB_GROUPID 0
100*700637cbSDimitry Andric #define ZVKB_BITMASK (1ULL << 52)
101*700637cbSDimitry Andric #define ZVKG_GROUPID 0
102*700637cbSDimitry Andric #define ZVKG_BITMASK (1ULL << 53)
103*700637cbSDimitry Andric #define ZVKNED_GROUPID 0
104*700637cbSDimitry Andric #define ZVKNED_BITMASK (1ULL << 54)
105*700637cbSDimitry Andric #define ZVKNHA_GROUPID 0
106*700637cbSDimitry Andric #define ZVKNHA_BITMASK (1ULL << 55)
107*700637cbSDimitry Andric #define ZVKNHB_GROUPID 0
108*700637cbSDimitry Andric #define ZVKNHB_BITMASK (1ULL << 56)
109*700637cbSDimitry Andric #define ZVKSED_GROUPID 0
110*700637cbSDimitry Andric #define ZVKSED_BITMASK (1ULL << 57)
111*700637cbSDimitry Andric #define ZVKSH_GROUPID 0
112*700637cbSDimitry Andric #define ZVKSH_BITMASK (1ULL << 58)
113*700637cbSDimitry Andric #define ZVKT_GROUPID 0
114*700637cbSDimitry Andric #define ZVKT_BITMASK (1ULL << 59)
115*700637cbSDimitry Andric #define ZVE32X_GROUPID 0
116*700637cbSDimitry Andric #define ZVE32X_BITMASK (1ULL << 60)
117*700637cbSDimitry Andric #define ZVE32F_GROUPID 0
118*700637cbSDimitry Andric #define ZVE32F_BITMASK (1ULL << 61)
119*700637cbSDimitry Andric #define ZVE64X_GROUPID 0
120*700637cbSDimitry Andric #define ZVE64X_BITMASK (1ULL << 62)
121*700637cbSDimitry Andric #define ZVE64F_GROUPID 0
122*700637cbSDimitry Andric #define ZVE64F_BITMASK (1ULL << 63)
123*700637cbSDimitry Andric #define ZVE64D_GROUPID 1
124*700637cbSDimitry Andric #define ZVE64D_BITMASK (1ULL << 0)
125*700637cbSDimitry Andric #define ZIMOP_GROUPID 1
126*700637cbSDimitry Andric #define ZIMOP_BITMASK (1ULL << 1)
127*700637cbSDimitry Andric #define ZCA_GROUPID 1
128*700637cbSDimitry Andric #define ZCA_BITMASK (1ULL << 2)
129*700637cbSDimitry Andric #define ZCB_GROUPID 1
130*700637cbSDimitry Andric #define ZCB_BITMASK (1ULL << 3)
131*700637cbSDimitry Andric #define ZCD_GROUPID 1
132*700637cbSDimitry Andric #define ZCD_BITMASK (1ULL << 4)
133*700637cbSDimitry Andric #define ZCF_GROUPID 1
134*700637cbSDimitry Andric #define ZCF_BITMASK (1ULL << 5)
135*700637cbSDimitry Andric #define ZCMOP_GROUPID 1
136*700637cbSDimitry Andric #define ZCMOP_BITMASK (1ULL << 6)
137*700637cbSDimitry Andric #define ZAWRS_GROUPID 1
138*700637cbSDimitry Andric #define ZAWRS_BITMASK (1ULL << 7)
139*700637cbSDimitry Andric #define ZILSD_GROUPID 1
140*700637cbSDimitry Andric #define ZILSD_BITMASK (1ULL << 8)
141*700637cbSDimitry Andric #define ZCLSD_GROUPID 1
142*700637cbSDimitry Andric #define ZCLSD_BITMASK (1ULL << 9)
143*700637cbSDimitry Andric #define ZCMP_GROUPID 1
144*700637cbSDimitry Andric #define ZCMP_BITMASK (1ULL << 10)
145*700637cbSDimitry Andric
146*700637cbSDimitry Andric #if defined(__linux__)
147*700637cbSDimitry Andric
148*700637cbSDimitry Andric // The RISC-V hwprobe interface is documented here:
149*700637cbSDimitry Andric // <https://docs.kernel.org/arch/riscv/hwprobe.html>.
150*700637cbSDimitry Andric
syscall_impl_5_args(long number,long arg1,long arg2,long arg3,long arg4,long arg5)151*700637cbSDimitry Andric static long syscall_impl_5_args(long number, long arg1, long arg2, long arg3,
152*700637cbSDimitry Andric long arg4, long arg5) {
153*700637cbSDimitry Andric register long a7 __asm__("a7") = number;
154*700637cbSDimitry Andric register long a0 __asm__("a0") = arg1;
155*700637cbSDimitry Andric register long a1 __asm__("a1") = arg2;
156*700637cbSDimitry Andric register long a2 __asm__("a2") = arg3;
157*700637cbSDimitry Andric register long a3 __asm__("a3") = arg4;
158*700637cbSDimitry Andric register long a4 __asm__("a4") = arg5;
159*700637cbSDimitry Andric __asm__ __volatile__("ecall\n\t"
160*700637cbSDimitry Andric : "=r"(a0)
161*700637cbSDimitry Andric : "r"(a7), "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4)
162*700637cbSDimitry Andric : "memory");
163*700637cbSDimitry Andric return a0;
164*700637cbSDimitry Andric }
165*700637cbSDimitry Andric
166*700637cbSDimitry Andric #define RISCV_HWPROBE_KEY_MVENDORID 0
167*700637cbSDimitry Andric #define RISCV_HWPROBE_KEY_MARCHID 1
168*700637cbSDimitry Andric #define RISCV_HWPROBE_KEY_MIMPID 2
169*700637cbSDimitry Andric #define RISCV_HWPROBE_KEY_BASE_BEHAVIOR 3
170*700637cbSDimitry Andric #define RISCV_HWPROBE_BASE_BEHAVIOR_IMA (1ULL << 0)
171*700637cbSDimitry Andric #define RISCV_HWPROBE_KEY_IMA_EXT_0 4
172*700637cbSDimitry Andric #define RISCV_HWPROBE_IMA_FD (1ULL << 0)
173*700637cbSDimitry Andric #define RISCV_HWPROBE_IMA_C (1ULL << 1)
174*700637cbSDimitry Andric #define RISCV_HWPROBE_IMA_V (1ULL << 2)
175*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZBA (1ULL << 3)
176*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZBB (1ULL << 4)
177*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZBS (1ULL << 5)
178*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZICBOZ (1ULL << 6)
179*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZBC (1ULL << 7)
180*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZBKB (1ULL << 8)
181*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZBKC (1ULL << 9)
182*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZBKX (1ULL << 10)
183*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZKND (1ULL << 11)
184*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZKNE (1ULL << 12)
185*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZKNH (1ULL << 13)
186*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZKSED (1ULL << 14)
187*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZKSH (1ULL << 15)
188*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZKT (1ULL << 16)
189*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVBB (1ULL << 17)
190*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVBC (1ULL << 18)
191*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVKB (1ULL << 19)
192*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVKG (1ULL << 20)
193*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVKNED (1ULL << 21)
194*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVKNHA (1ULL << 22)
195*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVKNHB (1ULL << 23)
196*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVKSED (1ULL << 24)
197*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVKSH (1ULL << 25)
198*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVKT (1ULL << 26)
199*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZFH (1ULL << 27)
200*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZFHMIN (1ULL << 28)
201*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZIHINTNTL (1ULL << 29)
202*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVFH (1ULL << 30)
203*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVFHMIN (1ULL << 31)
204*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZFA (1ULL << 32)
205*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZTSO (1ULL << 33)
206*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34)
207*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZICOND (1ULL << 35)
208*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZIHINTPAUSE (1ULL << 36)
209*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVE32X (1ULL << 37)
210*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVE32F (1ULL << 38)
211*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVE64X (1ULL << 39)
212*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVE64F (1ULL << 40)
213*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZVE64D (1ULL << 41)
214*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZIMOP (1ULL << 42)
215*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZCA (1ULL << 43)
216*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZCB (1ULL << 44)
217*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZCD (1ULL << 45)
218*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZCF (1ULL << 46)
219*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZCMOP (1ULL << 47)
220*700637cbSDimitry Andric #define RISCV_HWPROBE_EXT_ZAWRS (1ULL << 48)
221*700637cbSDimitry Andric #define RISCV_HWPROBE_KEY_CPUPERF_0 5
222*700637cbSDimitry Andric #define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
223*700637cbSDimitry Andric #define RISCV_HWPROBE_MISALIGNED_EMULATED (1ULL << 0)
224*700637cbSDimitry Andric #define RISCV_HWPROBE_MISALIGNED_SLOW (2 << 0)
225*700637cbSDimitry Andric #define RISCV_HWPROBE_MISALIGNED_FAST (3 << 0)
226*700637cbSDimitry Andric #define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
227*700637cbSDimitry Andric #define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
228*700637cbSDimitry Andric #define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6
229*700637cbSDimitry Andric /* Increase RISCV_HWPROBE_MAX_KEY when adding items. */
230*700637cbSDimitry Andric
231*700637cbSDimitry Andric struct riscv_hwprobe {
232*700637cbSDimitry Andric long long key;
233*700637cbSDimitry Andric unsigned long long value;
234*700637cbSDimitry Andric };
235*700637cbSDimitry Andric
236*700637cbSDimitry Andric #define __NR_riscv_hwprobe 258
initHwProbe(struct riscv_hwprobe * Hwprobes,int len)237*700637cbSDimitry Andric static long initHwProbe(struct riscv_hwprobe *Hwprobes, int len) {
238*700637cbSDimitry Andric return syscall_impl_5_args(__NR_riscv_hwprobe, (long)Hwprobes, len, 0, 0, 0);
239*700637cbSDimitry Andric }
240*700637cbSDimitry Andric
241*700637cbSDimitry Andric #define SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(EXTNAME) \
242*700637cbSDimitry Andric SET_SINGLE_IMAEXT_RISCV_FEATURE(RISCV_HWPROBE_EXT_##EXTNAME, EXTNAME)
243*700637cbSDimitry Andric
244*700637cbSDimitry Andric #define SET_SINGLE_IMAEXT_RISCV_FEATURE(HWPROBE_BITMASK, EXT) \
245*700637cbSDimitry Andric SET_SINGLE_RISCV_FEATURE(IMAEXT0Value &HWPROBE_BITMASK, EXT)
246*700637cbSDimitry Andric
247*700637cbSDimitry Andric #define SET_SINGLE_RISCV_FEATURE(COND, EXT) \
248*700637cbSDimitry Andric if (COND) { \
249*700637cbSDimitry Andric SET_RISCV_FEATURE(EXT); \
250*700637cbSDimitry Andric }
251*700637cbSDimitry Andric
252*700637cbSDimitry Andric #define SET_RISCV_FEATURE(EXT) features[EXT##_GROUPID] |= EXT##_BITMASK
253*700637cbSDimitry Andric
initRISCVFeature(struct riscv_hwprobe Hwprobes[])254*700637cbSDimitry Andric static void initRISCVFeature(struct riscv_hwprobe Hwprobes[]) {
255*700637cbSDimitry Andric
256*700637cbSDimitry Andric // Note: If a hwprobe key is unknown to the kernel, its key field
257*700637cbSDimitry Andric // will be cleared to -1, and its value set to 0.
258*700637cbSDimitry Andric // This unsets all extension bitmask bits.
259*700637cbSDimitry Andric
260*700637cbSDimitry Andric // Init VendorID, ArchID, ImplID
261*700637cbSDimitry Andric __riscv_cpu_model.mvendorid = Hwprobes[2].value;
262*700637cbSDimitry Andric __riscv_cpu_model.marchid = Hwprobes[3].value;
263*700637cbSDimitry Andric __riscv_cpu_model.mimpid = Hwprobes[4].value;
264*700637cbSDimitry Andric
265*700637cbSDimitry Andric // Init standard extension
266*700637cbSDimitry Andric // TODO: Maybe Extension implied generate from tablegen?
267*700637cbSDimitry Andric
268*700637cbSDimitry Andric unsigned long long features[RISCV_FEATURE_BITS_LENGTH];
269*700637cbSDimitry Andric int i;
270*700637cbSDimitry Andric
271*700637cbSDimitry Andric for (i = 0; i < RISCV_FEATURE_BITS_LENGTH; i++)
272*700637cbSDimitry Andric features[i] = 0;
273*700637cbSDimitry Andric
274*700637cbSDimitry Andric // Check RISCV_HWPROBE_KEY_BASE_BEHAVIOR
275*700637cbSDimitry Andric unsigned long long BaseValue = Hwprobes[0].value;
276*700637cbSDimitry Andric if (BaseValue & RISCV_HWPROBE_BASE_BEHAVIOR_IMA) {
277*700637cbSDimitry Andric SET_RISCV_FEATURE(I);
278*700637cbSDimitry Andric SET_RISCV_FEATURE(M);
279*700637cbSDimitry Andric SET_RISCV_FEATURE(A);
280*700637cbSDimitry Andric }
281*700637cbSDimitry Andric
282*700637cbSDimitry Andric // Check RISCV_HWPROBE_KEY_IMA_EXT_0
283*700637cbSDimitry Andric unsigned long long IMAEXT0Value = Hwprobes[1].value;
284*700637cbSDimitry Andric if (IMAEXT0Value & RISCV_HWPROBE_IMA_FD) {
285*700637cbSDimitry Andric SET_RISCV_FEATURE(F);
286*700637cbSDimitry Andric SET_RISCV_FEATURE(D);
287*700637cbSDimitry Andric }
288*700637cbSDimitry Andric
289*700637cbSDimitry Andric SET_SINGLE_IMAEXT_RISCV_FEATURE(RISCV_HWPROBE_IMA_C, C);
290*700637cbSDimitry Andric SET_SINGLE_IMAEXT_RISCV_FEATURE(RISCV_HWPROBE_IMA_V, V);
291*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBA);
292*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBB);
293*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBS);
294*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZICBOZ);
295*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBC);
296*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBKB);
297*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBKC);
298*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBKX);
299*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKND);
300*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKNE);
301*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKNH);
302*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKSED);
303*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKSH);
304*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKT);
305*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVBB);
306*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVBC);
307*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKB);
308*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKG);
309*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKNED);
310*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKNHA);
311*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKNHB);
312*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKSED);
313*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKSH);
314*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKT);
315*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZFH);
316*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZFHMIN);
317*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZIHINTNTL);
318*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZIHINTPAUSE);
319*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVFH);
320*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVFHMIN);
321*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZFA);
322*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZTSO);
323*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZACAS);
324*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZICOND);
325*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE32X);
326*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE32F);
327*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64X);
328*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64F);
329*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64D);
330*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZIMOP);
331*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCA);
332*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCB);
333*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCD);
334*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCF);
335*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCMOP);
336*700637cbSDimitry Andric SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZAWRS);
337*700637cbSDimitry Andric
338*700637cbSDimitry Andric for (i = 0; i < RISCV_FEATURE_BITS_LENGTH; i++)
339*700637cbSDimitry Andric __riscv_feature_bits.features[i] = features[i];
340*700637cbSDimitry Andric }
341*700637cbSDimitry Andric
342*700637cbSDimitry Andric #endif // defined(__linux__)
343*700637cbSDimitry Andric
344*700637cbSDimitry Andric static int FeaturesBitCached = 0;
345*700637cbSDimitry Andric
346*700637cbSDimitry Andric void __init_riscv_feature_bits(void *);
347*700637cbSDimitry Andric static void __init_riscv_feature_bits_ctor(void) CONSTRUCTOR_ATTRIBUTE;
348*700637cbSDimitry Andric
349*700637cbSDimitry Andric // A constructor function that sets __riscv_feature_bits
350*700637cbSDimitry Andric // to the right values. This needs to run only once. This constructor is given
351*700637cbSDimitry Andric // the highest priority and it should run before constructors without the
352*700637cbSDimitry Andric // priority set. However, it still runs after ifunc initializers and needs to
353*700637cbSDimitry Andric // be called explicitly there.
354*700637cbSDimitry Andric
__init_riscv_feature_bits_ctor(void)355*700637cbSDimitry Andric static void CONSTRUCTOR_ATTRIBUTE __init_riscv_feature_bits_ctor(void) {
356*700637cbSDimitry Andric __init_riscv_feature_bits(0);
357*700637cbSDimitry Andric }
358*700637cbSDimitry Andric
359*700637cbSDimitry Andric // PlatformArgs allows the platform to provide pre-computed data and access it
360*700637cbSDimitry Andric // without extra effort. For example, Linux could pass the vDSO object to avoid
361*700637cbSDimitry Andric // an extra system call.
__init_riscv_feature_bits(void * PlatformArgs)362*700637cbSDimitry Andric void __init_riscv_feature_bits(void *PlatformArgs) {
363*700637cbSDimitry Andric
364*700637cbSDimitry Andric if (FeaturesBitCached)
365*700637cbSDimitry Andric return;
366*700637cbSDimitry Andric
367*700637cbSDimitry Andric __riscv_feature_bits.length = RISCV_FEATURE_BITS_LENGTH;
368*700637cbSDimitry Andric
369*700637cbSDimitry Andric #if defined(__linux__)
370*700637cbSDimitry Andric struct riscv_hwprobe Hwprobes[] = {
371*700637cbSDimitry Andric {RISCV_HWPROBE_KEY_BASE_BEHAVIOR, 0}, {RISCV_HWPROBE_KEY_IMA_EXT_0, 0},
372*700637cbSDimitry Andric {RISCV_HWPROBE_KEY_MVENDORID, 0}, {RISCV_HWPROBE_KEY_MARCHID, 0},
373*700637cbSDimitry Andric {RISCV_HWPROBE_KEY_MIMPID, 0},
374*700637cbSDimitry Andric };
375*700637cbSDimitry Andric if (initHwProbe(Hwprobes, sizeof(Hwprobes) / sizeof(Hwprobes[0])))
376*700637cbSDimitry Andric return;
377*700637cbSDimitry Andric
378*700637cbSDimitry Andric initRISCVFeature(Hwprobes);
379*700637cbSDimitry Andric #endif // defined(__linux__)
380*700637cbSDimitry Andric
381*700637cbSDimitry Andric FeaturesBitCached = 1;
382*700637cbSDimitry Andric }
383