4 #if !defined(__APPLE__) && defined(VGA_arm64)
8 #if defined(VGO_freebsd)
12 unsigned long getauxval(unsigned long type
);
14 unsigned long getauxval(unsigned long type
)
16 extern char** environ
;
17 char** envp
= environ
;
19 while(*envp
++ != NULL
)
21 for (auxp
= (Elf_Auxinfo
*)envp
; auxp
->a_type
!= AT_NULL
; auxp
++)
23 if (type
== auxp
->a_type
)
25 return (unsigned long)auxp
->a_un
.a_val
;
32 // This file determines arm64 features a processor supports.
33 // Arm processors do not have a x86-like cpuinfo instruction. Instead the
34 // getauxval() syscall is used with capabilities parameters: getauxval(AT_HWCAP)
35 // and getauxval(AT_HWCAP2).
38 // - 0 if the machine has the asked-for feature.
39 // - 1 if the machine doesn't have the asked-for feature.
40 // - 2 if the asked-for feature isn't recognised (this will always be the case
41 // for any feature if run on a non-arm64 machine).
42 // - 3 if there was a usage error (it also prints an error message).
43 #define FEATURE_PRESENT 0
44 #define FEATURE_NOT_PRESENT 1
45 #define UNRECOGNISED_FEATURE 2
52 #if defined(VGA_arm64)
54 // The processor's capabilities/features are returned by getauxval() as an
55 // unsigned long with each bit representing a capability/feature.
57 #define HWCAP_FP (1 << 0)
60 #define HWCAP_ASIMD (1 << 1)
63 #define HWCAP_EVTSTRM (1 << 2)
66 #define HWCAP_AES (1 << 3)
69 #define HWCAP_PMULL (1 << 4)
74 #define HWCAP_SHA1 (1 << 5)
77 #define HWCAP_SHA2 (1 << 6)
80 #define HWCAP_CRC32 (1 << 7)
83 #define HWCAP_ATOMICS (1 << 8)
86 #define HWCAP_FPHP (1 << 9)
89 #define HWCAP_ASIMDHP (1 << 10)
92 #define HWCAP_CPUID (1 << 11)
94 #ifndef HWCAP_ASIMDRDM
95 #define HWCAP_ASIMDRDM (1 << 12)
98 #define HWCAP_JSCVT (1 << 13)
101 #define HWCAP_FCMA (1 << 14)
104 #define HWCAP_LRCPC (1 << 15)
107 #define HWCAP_DCPOP (1 << 16)
110 #define HWCAP_SHA3 (1 << 17)
113 #define HWCAP_SM3 (1 << 18)
116 #define HWCAP_SM4 (1 << 19)
118 #ifndef HWCAP_ASIMDDP
119 #define HWCAP_ASIMDDP (1 << 20)
122 #define HWCAP_SHA512 (1 << 21)
125 #define HWCAP_SVE (1 << 22)
127 #ifndef HWCAP_ASIMDFHM
128 #define HWCAP_ASIMDFHM (1 << 23)
131 #define HWCAP_DIT (1 << 24)
134 #define HWCAP_USCAT (1 << 25)
137 #define HWCAP_ILRCPC (1 << 26)
140 #define HWCAP_FLAGM (1 << 27)
143 #define HWCAP_SSBS (1 << 28)
146 #define HWCAP_SB (1 << 29)
149 #define HWCAP_PACA (1 << 30)
152 #define HWCAP_PACG (1UL << 31)
155 #ifndef HWCAP2_DCPODP
156 #define HWCAP2_DCPODP (1 << 0)
159 #define HWCAP2_SVE2 (1 << 1)
161 #ifndef HWCAP2_SVEAES
162 #define HWCAP2_SVEAES (1 << 2)
164 #ifndef HWCAP2_SVEPMULL
165 #define HWCAP2_SVEPMULL (1 << 3)
167 #ifndef HWCAP2_SVEBITPERM
168 #define HWCAP2_SVEBITPERM (1 << 4)
170 #ifndef HWCAP2_SVESHA3
171 #define HWCAP2_SVESHA3 (1 << 5)
173 #ifndef HWCAP2_SVESM4
174 #define HWCAP2_SVESM4 (1 << 6)
176 #ifndef HWCAP2_FLAGM2
177 #define HWCAP2_FLAGM2 (1 << 7)
180 #define HWCAP2_FRINT (1 << 8)
183 unsigned long hwcaps
[] = {
184 HWCAP_FP
, HWCAP_ASIMD
, HWCAP_EVTSTRM
, HWCAP_AES
, HWCAP_PMULL
,
185 HWCAP_SHA1
, HWCAP_SHA2
, HWCAP_CRC32
, HWCAP_ATOMICS
, HWCAP_FPHP
,
186 HWCAP_ASIMDHP
,HWCAP_CPUID
, HWCAP_ASIMDRDM
,HWCAP_JSCVT
, HWCAP_FCMA
,
187 HWCAP_LRCPC
, HWCAP_DCPOP
, HWCAP_SHA3
, HWCAP_SM3
, HWCAP_SM4
,
188 HWCAP_ASIMDDP
,HWCAP_SHA512
, HWCAP_SVE
, HWCAP_ASIMDFHM
,HWCAP_DIT
,
189 HWCAP_USCAT
, HWCAP_ILRCPC
, HWCAP_FLAGM
, HWCAP_SSBS
, HWCAP_SB
,
190 HWCAP_PACA
, HWCAP_PACG
, 0ul};
192 unsigned long hwcaps2
[] = {
193 HWCAP2_DCPODP
, HWCAP2_SVE2
, HWCAP2_SVEAES
, HWCAP2_SVEPMULL
,
194 HWCAP2_SVEBITPERM
, HWCAP2_SVESHA3
, HWCAP2_SVESM4
, HWCAP2_FLAGM2
,
200 unsigned long cap_bit
;
203 capability capabilities
[] = {
204 {"fp", HWCAP_FP
}, {"asimd", HWCAP_ASIMD
},
205 {"evtstrm", HWCAP_EVTSTRM
}, {"aes", HWCAP_AES
},
206 {"pmull", HWCAP_PMULL
}, {"sha1", HWCAP_SHA1
},
207 {"sha2", HWCAP_SHA2
}, {"crc32", HWCAP_CRC32
},
208 {"atomics", HWCAP_ATOMICS
}, {"fphp", HWCAP_FPHP
},
209 {"asimdhp", HWCAP_ASIMDHP
}, {"cpuid", HWCAP_CPUID
},
210 {"asimdrdm", HWCAP_ASIMDRDM
}, {"jscvt", HWCAP_JSCVT
},
211 {"fcma", HWCAP_FCMA
}, {"lrcpc", HWCAP_LRCPC
},
212 {"dcpop", HWCAP_DCPOP
}, {"sha3", HWCAP_SHA3
},
213 {"sm3", HWCAP_SM3
}, {"sm4", HWCAP_SM4
},
214 {"asimddp", HWCAP_ASIMDDP
}, {"sha512", HWCAP_SHA512
},
215 {"sve", HWCAP_SVE
}, {"asimdfhm", HWCAP_ASIMDFHM
},
216 {"dit", HWCAP_DIT
}, {"uscat", HWCAP_USCAT
},
217 {"ilrcpc", HWCAP_ILRCPC
}, {"flagm", HWCAP_FLAGM
},
218 {"ssbs", HWCAP_SSBS
}, {"sb", HWCAP_SB
},
219 {"paca", HWCAP_PACA
}, {"pacg", HWCAP_PACG
},
223 capability capabilities2
[] = {
224 {"dcpodp", HWCAP2_DCPODP
}, {"sve2", HWCAP2_SVE2
},
225 {"sveaes", HWCAP2_SVEAES
}, {"svepmull", HWCAP2_SVEPMULL
},
226 {"svebitperm", HWCAP2_SVEBITPERM
}, {"svesha3", HWCAP2_SVESHA3
},
227 {"svesm4", HWCAP2_SVESM4
}, {"flagm2", HWCAP2_FLAGM2
},
228 {"frint", HWCAP2_FRINT
}, {"", 0ul}
234 unsigned long hwcap2
;
237 #define CAPABILITIES_SEARCH_LOOP(hwcversion) \
238 for (int i = 0; capabilities ## hwcversion[i].cap_bit; ++i) \
239 if (strcmp(name, capabilities ## hwcversion[i].name) == 0) { \
240 caps->hwcap ## hwcversion = capabilities ## hwcversion[i].cap_bit; \
244 static Bool get_feature_from_string(const char *name, hwc *caps)
246 caps
->hwcap
= caps
->hwcap2
= 0;
247 CAPABILITIES_SEARCH_LOOP()
248 CAPABILITIES_SEARCH_LOOP(2)
252 static int go(const char* feature_name
)
255 unsigned long hwcap
= getauxval(AT_HWCAP
);
256 unsigned long hwcap2
= getauxval(AT_HWCAP2
);
258 if (!get_feature_from_string(feature_name
, &hw
))
259 return UNRECOGNISED_FEATURE
;
261 if ((hw
.hwcap
& hwcap
) || (hw
.hwcap2
& hwcap2
))
262 return FEATURE_PRESENT
;
264 return FEATURE_NOT_PRESENT
;
269 static Bool
go(const char* feature_name
)
271 // Feature not recognised (non-arm64 machine!)
272 return UNRECOGNISED_FEATURE
;
275 #endif // defined(VGA_arm64)
278 //---------------------------------------------------------------------------
280 //---------------------------------------------------------------------------
281 int main(int argc
, char **argv
)
284 fprintf(stderr
, "usage: arm64_features <feature>\n");