1*94d3b452SApple OSS Distributions /*
2*94d3b452SApple OSS Distributions * Copyright (c) 2020 Apple Computer, Inc. All rights reserved.
3*94d3b452SApple OSS Distributions *
4*94d3b452SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*94d3b452SApple OSS Distributions *
6*94d3b452SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*94d3b452SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*94d3b452SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*94d3b452SApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*94d3b452SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*94d3b452SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*94d3b452SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*94d3b452SApple OSS Distributions * terms of an Apple operating system software license agreement.
14*94d3b452SApple OSS Distributions *
15*94d3b452SApple OSS Distributions * Please obtain a copy of the License at
16*94d3b452SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*94d3b452SApple OSS Distributions *
18*94d3b452SApple OSS Distributions * The Original Code and all software distributed under the License are
19*94d3b452SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*94d3b452SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*94d3b452SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*94d3b452SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*94d3b452SApple OSS Distributions * Please see the License for the specific language governing rights and
24*94d3b452SApple OSS Distributions * limitations under the License.
25*94d3b452SApple OSS Distributions *
26*94d3b452SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*94d3b452SApple OSS Distributions */
28*94d3b452SApple OSS Distributions
29*94d3b452SApple OSS Distributions #include <darwintest.h>
30*94d3b452SApple OSS Distributions #include <machine/cpu_capabilities.h>
31*94d3b452SApple OSS Distributions #include <sys/sysctl.h>
32*94d3b452SApple OSS Distributions
33*94d3b452SApple OSS Distributions #include "exc_helpers.h"
34*94d3b452SApple OSS Distributions
35*94d3b452SApple OSS Distributions T_GLOBAL_META(
36*94d3b452SApple OSS Distributions T_META_NAMESPACE("xnu.arm"),
37*94d3b452SApple OSS Distributions T_META_RADAR_COMPONENT_NAME("xnu"),
38*94d3b452SApple OSS Distributions T_META_RADAR_COMPONENT_VERSION("arm"),
39*94d3b452SApple OSS Distributions T_META_OWNER("sdooher"),
40*94d3b452SApple OSS Distributions T_META_RUN_CONCURRENTLY(true),
41*94d3b452SApple OSS Distributions T_META_TAG("SoCSpecific")
42*94d3b452SApple OSS Distributions );
43*94d3b452SApple OSS Distributions
44*94d3b452SApple OSS Distributions static volatile bool cap_usable;
45*94d3b452SApple OSS Distributions
46*94d3b452SApple OSS Distributions static size_t
bad_instruction_handler(mach_port_t task __unused,mach_port_t thread __unused,exception_type_t type __unused,mach_exception_data_t codes __unused)47*94d3b452SApple OSS Distributions bad_instruction_handler(mach_port_t task __unused, mach_port_t thread __unused,
48*94d3b452SApple OSS Distributions exception_type_t type __unused, mach_exception_data_t codes __unused)
49*94d3b452SApple OSS Distributions {
50*94d3b452SApple OSS Distributions cap_usable = false;
51*94d3b452SApple OSS Distributions return 4;
52*94d3b452SApple OSS Distributions }
53*94d3b452SApple OSS Distributions
54*94d3b452SApple OSS Distributions static void
try_fp16(void)55*94d3b452SApple OSS Distributions try_fp16(void)
56*94d3b452SApple OSS Distributions {
57*94d3b452SApple OSS Distributions asm volatile (
58*94d3b452SApple OSS Distributions "fmov h0, #0" "\n"
59*94d3b452SApple OSS Distributions :
60*94d3b452SApple OSS Distributions :
61*94d3b452SApple OSS Distributions : "v0"
62*94d3b452SApple OSS Distributions );
63*94d3b452SApple OSS Distributions }
64*94d3b452SApple OSS Distributions
65*94d3b452SApple OSS Distributions static void
try_atomics(void)66*94d3b452SApple OSS Distributions try_atomics(void)
67*94d3b452SApple OSS Distributions {
68*94d3b452SApple OSS Distributions uint64_t dword;
69*94d3b452SApple OSS Distributions asm volatile (
70*94d3b452SApple OSS Distributions "swp xzr, xzr, [%[dword]]"
71*94d3b452SApple OSS Distributions :
72*94d3b452SApple OSS Distributions : [dword]"r"(&dword)
73*94d3b452SApple OSS Distributions );
74*94d3b452SApple OSS Distributions }
75*94d3b452SApple OSS Distributions
76*94d3b452SApple OSS Distributions static void
try_crc32(void)77*94d3b452SApple OSS Distributions try_crc32(void)
78*94d3b452SApple OSS Distributions {
79*94d3b452SApple OSS Distributions asm volatile ( "crc32b wzr, wzr, wzr");
80*94d3b452SApple OSS Distributions }
81*94d3b452SApple OSS Distributions
82*94d3b452SApple OSS Distributions static void
try_fhm(void)83*94d3b452SApple OSS Distributions try_fhm(void)
84*94d3b452SApple OSS Distributions {
85*94d3b452SApple OSS Distributions asm volatile (
86*94d3b452SApple OSS Distributions "fmov d0, #0" "\n"
87*94d3b452SApple OSS Distributions "fmlal v0.2s, v0.2h, v0.2h" "\n"
88*94d3b452SApple OSS Distributions :
89*94d3b452SApple OSS Distributions :
90*94d3b452SApple OSS Distributions : "v0"
91*94d3b452SApple OSS Distributions );
92*94d3b452SApple OSS Distributions }
93*94d3b452SApple OSS Distributions
94*94d3b452SApple OSS Distributions static void
try_sha512(void)95*94d3b452SApple OSS Distributions try_sha512(void)
96*94d3b452SApple OSS Distributions {
97*94d3b452SApple OSS Distributions asm volatile (
98*94d3b452SApple OSS Distributions "fmov d0, #0" "\n"
99*94d3b452SApple OSS Distributions "fmov d1, #0" "\n"
100*94d3b452SApple OSS Distributions "sha512h q0, q0, v0.2d" "\n"
101*94d3b452SApple OSS Distributions :
102*94d3b452SApple OSS Distributions :
103*94d3b452SApple OSS Distributions : "v0"
104*94d3b452SApple OSS Distributions );
105*94d3b452SApple OSS Distributions }
106*94d3b452SApple OSS Distributions
107*94d3b452SApple OSS Distributions static void
try_sha3(void)108*94d3b452SApple OSS Distributions try_sha3(void)
109*94d3b452SApple OSS Distributions {
110*94d3b452SApple OSS Distributions asm volatile (
111*94d3b452SApple OSS Distributions "fmov d0, #0" "\n"
112*94d3b452SApple OSS Distributions "fmov d1, #0" "\n"
113*94d3b452SApple OSS Distributions "eor3 v0.16b, v0.16b, v0.16b, v0.16b" "\n"
114*94d3b452SApple OSS Distributions :
115*94d3b452SApple OSS Distributions :
116*94d3b452SApple OSS Distributions : "v0"
117*94d3b452SApple OSS Distributions );
118*94d3b452SApple OSS Distributions }
119*94d3b452SApple OSS Distributions
120*94d3b452SApple OSS Distributions static void
try_sha1(void)121*94d3b452SApple OSS Distributions try_sha1(void)
122*94d3b452SApple OSS Distributions {
123*94d3b452SApple OSS Distributions asm volatile (
124*94d3b452SApple OSS Distributions "fmov s0, #0" "\n"
125*94d3b452SApple OSS Distributions "sha1h s0, s0" "\n"
126*94d3b452SApple OSS Distributions :
127*94d3b452SApple OSS Distributions :
128*94d3b452SApple OSS Distributions : "v0"
129*94d3b452SApple OSS Distributions );
130*94d3b452SApple OSS Distributions }
131*94d3b452SApple OSS Distributions
132*94d3b452SApple OSS Distributions static void
try_pmull(void)133*94d3b452SApple OSS Distributions try_pmull(void)
134*94d3b452SApple OSS Distributions {
135*94d3b452SApple OSS Distributions asm volatile (
136*94d3b452SApple OSS Distributions "fmov d0, #0" "\n"
137*94d3b452SApple OSS Distributions "pmull v0.1q, v0.1d, v0.1d" "\n"
138*94d3b452SApple OSS Distributions :
139*94d3b452SApple OSS Distributions :
140*94d3b452SApple OSS Distributions : "v0"
141*94d3b452SApple OSS Distributions );
142*94d3b452SApple OSS Distributions }
143*94d3b452SApple OSS Distributions
144*94d3b452SApple OSS Distributions static void
try_aes(void)145*94d3b452SApple OSS Distributions try_aes(void)
146*94d3b452SApple OSS Distributions {
147*94d3b452SApple OSS Distributions asm volatile (
148*94d3b452SApple OSS Distributions "fmov d0, #0" "\n"
149*94d3b452SApple OSS Distributions "fmov d1, #0" "\n"
150*94d3b452SApple OSS Distributions "aesd v0.16B, v0.16B" "\n"
151*94d3b452SApple OSS Distributions :
152*94d3b452SApple OSS Distributions :
153*94d3b452SApple OSS Distributions : "v0"
154*94d3b452SApple OSS Distributions );
155*94d3b452SApple OSS Distributions }
156*94d3b452SApple OSS Distributions
157*94d3b452SApple OSS Distributions
158*94d3b452SApple OSS Distributions static void
try_sha256(void)159*94d3b452SApple OSS Distributions try_sha256(void)
160*94d3b452SApple OSS Distributions {
161*94d3b452SApple OSS Distributions asm volatile (
162*94d3b452SApple OSS Distributions "fmov d0, #0" "\n"
163*94d3b452SApple OSS Distributions "fmov d1, #0" "\n"
164*94d3b452SApple OSS Distributions "sha256h q0, q0, v0.4s" "\n"
165*94d3b452SApple OSS Distributions :
166*94d3b452SApple OSS Distributions :
167*94d3b452SApple OSS Distributions : "v0"
168*94d3b452SApple OSS Distributions );
169*94d3b452SApple OSS Distributions }
170*94d3b452SApple OSS Distributions
171*94d3b452SApple OSS Distributions
172*94d3b452SApple OSS Distributions static void
try_compnum(void)173*94d3b452SApple OSS Distributions try_compnum(void)
174*94d3b452SApple OSS Distributions {
175*94d3b452SApple OSS Distributions asm volatile (
176*94d3b452SApple OSS Distributions "fmov d0, #0" "\n"
177*94d3b452SApple OSS Distributions "fcadd v0.2s, v0.2s, v0.2s, #90" "\n"
178*94d3b452SApple OSS Distributions :
179*94d3b452SApple OSS Distributions :
180*94d3b452SApple OSS Distributions : "v0"
181*94d3b452SApple OSS Distributions );
182*94d3b452SApple OSS Distributions }
183*94d3b452SApple OSS Distributions
184*94d3b452SApple OSS Distributions
185*94d3b452SApple OSS Distributions static void
try_flagm(void)186*94d3b452SApple OSS Distributions try_flagm(void)
187*94d3b452SApple OSS Distributions {
188*94d3b452SApple OSS Distributions asm volatile (
189*94d3b452SApple OSS Distributions "cfinv" "\n"
190*94d3b452SApple OSS Distributions "cfinv" "\n"
191*94d3b452SApple OSS Distributions );
192*94d3b452SApple OSS Distributions }
193*94d3b452SApple OSS Distributions
194*94d3b452SApple OSS Distributions static void
try_flagm2(void)195*94d3b452SApple OSS Distributions try_flagm2(void)
196*94d3b452SApple OSS Distributions {
197*94d3b452SApple OSS Distributions asm volatile (
198*94d3b452SApple OSS Distributions "axflag" "\n"
199*94d3b452SApple OSS Distributions "xaflag" "\n"
200*94d3b452SApple OSS Distributions );
201*94d3b452SApple OSS Distributions }
202*94d3b452SApple OSS Distributions
203*94d3b452SApple OSS Distributions static void
try_dotprod(void)204*94d3b452SApple OSS Distributions try_dotprod(void)
205*94d3b452SApple OSS Distributions {
206*94d3b452SApple OSS Distributions asm volatile (
207*94d3b452SApple OSS Distributions "udot v0.4S,v1.16B,v2.16B"
208*94d3b452SApple OSS Distributions :
209*94d3b452SApple OSS Distributions :
210*94d3b452SApple OSS Distributions : "v0"
211*94d3b452SApple OSS Distributions );
212*94d3b452SApple OSS Distributions }
213*94d3b452SApple OSS Distributions
214*94d3b452SApple OSS Distributions static void
try_rdm(void)215*94d3b452SApple OSS Distributions try_rdm(void)
216*94d3b452SApple OSS Distributions {
217*94d3b452SApple OSS Distributions asm volatile (
218*94d3b452SApple OSS Distributions "sqrdmlah s0, s1, s2"
219*94d3b452SApple OSS Distributions :
220*94d3b452SApple OSS Distributions :
221*94d3b452SApple OSS Distributions : "s0"
222*94d3b452SApple OSS Distributions );
223*94d3b452SApple OSS Distributions }
224*94d3b452SApple OSS Distributions
225*94d3b452SApple OSS Distributions static void
try_sb(void)226*94d3b452SApple OSS Distributions try_sb(void)
227*94d3b452SApple OSS Distributions {
228*94d3b452SApple OSS Distributions asm volatile (
229*94d3b452SApple OSS Distributions "sb"
230*94d3b452SApple OSS Distributions );
231*94d3b452SApple OSS Distributions }
232*94d3b452SApple OSS Distributions
233*94d3b452SApple OSS Distributions static void
try_frintts(void)234*94d3b452SApple OSS Distributions try_frintts(void)
235*94d3b452SApple OSS Distributions {
236*94d3b452SApple OSS Distributions asm volatile (
237*94d3b452SApple OSS Distributions "frint32x s0, s0"
238*94d3b452SApple OSS Distributions :
239*94d3b452SApple OSS Distributions :
240*94d3b452SApple OSS Distributions : "s0"
241*94d3b452SApple OSS Distributions );
242*94d3b452SApple OSS Distributions }
243*94d3b452SApple OSS Distributions
244*94d3b452SApple OSS Distributions static void
try_jscvt(void)245*94d3b452SApple OSS Distributions try_jscvt(void)
246*94d3b452SApple OSS Distributions {
247*94d3b452SApple OSS Distributions asm volatile (
248*94d3b452SApple OSS Distributions "fmov d0, #0" "\n"
249*94d3b452SApple OSS Distributions "fjcvtzs w1, d0" "\n"
250*94d3b452SApple OSS Distributions :
251*94d3b452SApple OSS Distributions :
252*94d3b452SApple OSS Distributions : "w1", "d0"
253*94d3b452SApple OSS Distributions );
254*94d3b452SApple OSS Distributions }
255*94d3b452SApple OSS Distributions
256*94d3b452SApple OSS Distributions static void
try_pauth(void)257*94d3b452SApple OSS Distributions try_pauth(void)
258*94d3b452SApple OSS Distributions {
259*94d3b452SApple OSS Distributions asm volatile (
260*94d3b452SApple OSS Distributions "pacga x0, x0, x0"
261*94d3b452SApple OSS Distributions :
262*94d3b452SApple OSS Distributions :
263*94d3b452SApple OSS Distributions : "x0"
264*94d3b452SApple OSS Distributions );
265*94d3b452SApple OSS Distributions }
266*94d3b452SApple OSS Distributions
267*94d3b452SApple OSS Distributions static void
try_dpb(void)268*94d3b452SApple OSS Distributions try_dpb(void)
269*94d3b452SApple OSS Distributions {
270*94d3b452SApple OSS Distributions int x;
271*94d3b452SApple OSS Distributions asm volatile (
272*94d3b452SApple OSS Distributions "dc cvap, %0"
273*94d3b452SApple OSS Distributions :
274*94d3b452SApple OSS Distributions : "r" (&x)
275*94d3b452SApple OSS Distributions );
276*94d3b452SApple OSS Distributions }
277*94d3b452SApple OSS Distributions
278*94d3b452SApple OSS Distributions static void
try_dpb2(void)279*94d3b452SApple OSS Distributions try_dpb2(void)
280*94d3b452SApple OSS Distributions {
281*94d3b452SApple OSS Distributions int x;
282*94d3b452SApple OSS Distributions asm volatile (
283*94d3b452SApple OSS Distributions "dc cvadp, %0"
284*94d3b452SApple OSS Distributions :
285*94d3b452SApple OSS Distributions : "r" (&x)
286*94d3b452SApple OSS Distributions );
287*94d3b452SApple OSS Distributions }
288*94d3b452SApple OSS Distributions
289*94d3b452SApple OSS Distributions static void
try_lrcpc(void)290*94d3b452SApple OSS Distributions try_lrcpc(void)
291*94d3b452SApple OSS Distributions {
292*94d3b452SApple OSS Distributions int x;
293*94d3b452SApple OSS Distributions asm volatile (
294*94d3b452SApple OSS Distributions "ldaprb w0, [%0]"
295*94d3b452SApple OSS Distributions :
296*94d3b452SApple OSS Distributions : "r" (&x)
297*94d3b452SApple OSS Distributions : "w0"
298*94d3b452SApple OSS Distributions );
299*94d3b452SApple OSS Distributions }
300*94d3b452SApple OSS Distributions
301*94d3b452SApple OSS Distributions static void
try_lrcpc2(void)302*94d3b452SApple OSS Distributions try_lrcpc2(void)
303*94d3b452SApple OSS Distributions {
304*94d3b452SApple OSS Distributions int x;
305*94d3b452SApple OSS Distributions asm volatile (
306*94d3b452SApple OSS Distributions "ldapurb w0, [%0]"
307*94d3b452SApple OSS Distributions :
308*94d3b452SApple OSS Distributions : "r" (&x)
309*94d3b452SApple OSS Distributions : "w0"
310*94d3b452SApple OSS Distributions );
311*94d3b452SApple OSS Distributions }
312*94d3b452SApple OSS Distributions
313*94d3b452SApple OSS Distributions
314*94d3b452SApple OSS Distributions static void
try_specres(void)315*94d3b452SApple OSS Distributions try_specres(void)
316*94d3b452SApple OSS Distributions {
317*94d3b452SApple OSS Distributions int x;
318*94d3b452SApple OSS Distributions asm volatile (
319*94d3b452SApple OSS Distributions "cfp rctx, %0"
320*94d3b452SApple OSS Distributions :
321*94d3b452SApple OSS Distributions : "r" (&x)
322*94d3b452SApple OSS Distributions );
323*94d3b452SApple OSS Distributions }
324*94d3b452SApple OSS Distributions
325*94d3b452SApple OSS Distributions static void
try_bf16(void)326*94d3b452SApple OSS Distributions try_bf16(void)
327*94d3b452SApple OSS Distributions {
328*94d3b452SApple OSS Distributions asm volatile (
329*94d3b452SApple OSS Distributions "bfdot v0.4S,v1.8H,v2.8H"
330*94d3b452SApple OSS Distributions :
331*94d3b452SApple OSS Distributions :
332*94d3b452SApple OSS Distributions : "v0"
333*94d3b452SApple OSS Distributions );
334*94d3b452SApple OSS Distributions }
335*94d3b452SApple OSS Distributions
336*94d3b452SApple OSS Distributions static void
try_i8mm(void)337*94d3b452SApple OSS Distributions try_i8mm(void)
338*94d3b452SApple OSS Distributions {
339*94d3b452SApple OSS Distributions asm volatile (
340*94d3b452SApple OSS Distributions "sudot v0.4S,v1.16B,v2.4B[0]"
341*94d3b452SApple OSS Distributions :
342*94d3b452SApple OSS Distributions :
343*94d3b452SApple OSS Distributions : "v0"
344*94d3b452SApple OSS Distributions );
345*94d3b452SApple OSS Distributions }
346*94d3b452SApple OSS Distributions
347*94d3b452SApple OSS Distributions static void
try_ecv(void)348*94d3b452SApple OSS Distributions try_ecv(void)
349*94d3b452SApple OSS Distributions {
350*94d3b452SApple OSS Distributions /*
351*94d3b452SApple OSS Distributions * These registers are present only when FEAT_ECV is implemented.
352*94d3b452SApple OSS Distributions * Otherwise, direct accesses to CNTPCTSS_EL0 or CNTVCTSS_EL0 are UNDEFINED.
353*94d3b452SApple OSS Distributions */
354*94d3b452SApple OSS Distributions (void)__builtin_arm_rsr64("CNTPCTSS_EL0");
355*94d3b452SApple OSS Distributions (void)__builtin_arm_rsr64("CNTVCTSS_EL0");
356*94d3b452SApple OSS Distributions }
357*94d3b452SApple OSS Distributions
358*94d3b452SApple OSS Distributions
359*94d3b452SApple OSS Distributions
360*94d3b452SApple OSS Distributions static void
try_fpexcp(void)361*94d3b452SApple OSS Distributions try_fpexcp(void)
362*94d3b452SApple OSS Distributions {
363*94d3b452SApple OSS Distributions /* FP Exceptions are supported if all exceptions bit can be set. */
364*94d3b452SApple OSS Distributions const uint64_t flags = (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) | (1 << 15);
365*94d3b452SApple OSS Distributions
366*94d3b452SApple OSS Distributions uint64_t old_fpcr = __builtin_arm_rsr64("FPCR");
367*94d3b452SApple OSS Distributions __builtin_arm_wsr64("FPCR", old_fpcr | flags);
368*94d3b452SApple OSS Distributions uint64_t new_fpcr = __builtin_arm_rsr64("FPCR");
369*94d3b452SApple OSS Distributions __builtin_arm_wsr64("FPCR", old_fpcr);
370*94d3b452SApple OSS Distributions
371*94d3b452SApple OSS Distributions if ((new_fpcr & flags) != flags) {
372*94d3b452SApple OSS Distributions cap_usable = false;
373*94d3b452SApple OSS Distributions }
374*94d3b452SApple OSS Distributions }
375*94d3b452SApple OSS Distributions
376*94d3b452SApple OSS Distributions static void
try_dit(void)377*94d3b452SApple OSS Distributions try_dit(void)
378*94d3b452SApple OSS Distributions {
379*94d3b452SApple OSS Distributions asm volatile (
380*94d3b452SApple OSS Distributions "msr DIT, x0"
381*94d3b452SApple OSS Distributions :
382*94d3b452SApple OSS Distributions :
383*94d3b452SApple OSS Distributions : "x0"
384*94d3b452SApple OSS Distributions );
385*94d3b452SApple OSS Distributions }
386*94d3b452SApple OSS Distributions
387*94d3b452SApple OSS Distributions static mach_port_t exc_port;
388*94d3b452SApple OSS Distributions
389*94d3b452SApple OSS Distributions static void
test_cpu_capability(const char * cap_name,uint64_t cap_flag,bool has_commpage_entry,const char * cap_sysctl,void (* try_cpu_capability)(void))390*94d3b452SApple OSS Distributions test_cpu_capability(const char *cap_name, uint64_t cap_flag, bool has_commpage_entry, const char *cap_sysctl, void (*try_cpu_capability)(void))
391*94d3b452SApple OSS Distributions {
392*94d3b452SApple OSS Distributions uint64_t caps = _get_cpu_capabilities();
393*94d3b452SApple OSS Distributions bool has_cap_flag = (caps & cap_flag);
394*94d3b452SApple OSS Distributions
395*94d3b452SApple OSS Distributions int sysctl_val;
396*94d3b452SApple OSS Distributions bool has_sysctl_flag = 0;
397*94d3b452SApple OSS Distributions if (cap_sysctl != NULL) {
398*94d3b452SApple OSS Distributions size_t sysctl_size = sizeof(sysctl_val);
399*94d3b452SApple OSS Distributions int err = sysctlbyname(cap_sysctl, &sysctl_val, &sysctl_size, NULL, 0);
400*94d3b452SApple OSS Distributions has_sysctl_flag = (err == 0 && sysctl_val > 0);
401*94d3b452SApple OSS Distributions }
402*94d3b452SApple OSS Distributions
403*94d3b452SApple OSS Distributions bool has_capability = has_commpage_entry ? has_cap_flag : has_sysctl_flag;
404*94d3b452SApple OSS Distributions
405*94d3b452SApple OSS Distributions if (!has_commpage_entry && cap_sysctl == NULL) {
406*94d3b452SApple OSS Distributions T_FAIL("Tested capability must have either sysctl or commpage flag");
407*94d3b452SApple OSS Distributions return;
408*94d3b452SApple OSS Distributions }
409*94d3b452SApple OSS Distributions
410*94d3b452SApple OSS Distributions if (has_commpage_entry && cap_sysctl != NULL) {
411*94d3b452SApple OSS Distributions T_EXPECT_EQ(has_cap_flag, has_sysctl_flag, "%s commpage flag matches sysctl flag", cap_name);
412*94d3b452SApple OSS Distributions }
413*94d3b452SApple OSS Distributions
414*94d3b452SApple OSS Distributions if (try_cpu_capability != NULL) {
415*94d3b452SApple OSS Distributions cap_usable = true;
416*94d3b452SApple OSS Distributions try_cpu_capability();
417*94d3b452SApple OSS Distributions T_EXPECT_EQ(has_capability, cap_usable, "%s capability matches actual usability", cap_name);
418*94d3b452SApple OSS Distributions }
419*94d3b452SApple OSS Distributions }
420*94d3b452SApple OSS Distributions
421*94d3b452SApple OSS Distributions T_DECL(cpu_capabilities, "Verify ARM CPU capabilities") {
422*94d3b452SApple OSS Distributions exc_port = create_exception_port(EXC_MASK_BAD_INSTRUCTION);
423*94d3b452SApple OSS Distributions repeat_exception_handler(exc_port, bad_instruction_handler);
424*94d3b452SApple OSS Distributions
425*94d3b452SApple OSS Distributions test_cpu_capability("FP16 (deprecated sysctl)", kHasFeatFP16, true, "hw.optional.neon_fp16", NULL);
426*94d3b452SApple OSS Distributions test_cpu_capability("FP16", kHasFeatFP16, true, "hw.optional.arm.FEAT_FP16", try_fp16);
427*94d3b452SApple OSS Distributions test_cpu_capability("LSE (deprecated sysctl)", kHasFeatLSE, true, "hw.optional.armv8_1_atomics", NULL);
428*94d3b452SApple OSS Distributions test_cpu_capability("LSE", kHasFeatLSE, true, "hw.optional.arm.FEAT_LSE", try_atomics);
429*94d3b452SApple OSS Distributions test_cpu_capability("CRC32", kHasARMv8Crc32, true, "hw.optional.armv8_crc32", try_crc32);
430*94d3b452SApple OSS Distributions test_cpu_capability("FHM (deprecated sysctl)", kHasFeatFHM, true, "hw.optional.armv8_2_fhm", NULL);
431*94d3b452SApple OSS Distributions test_cpu_capability("FHM", kHasFeatFHM, true, "hw.optional.arm.FEAT_FHM", try_fhm);
432*94d3b452SApple OSS Distributions test_cpu_capability("SHA512", kHasFeatSHA512, true, "hw.optional.armv8_2_sha512", try_sha512);
433*94d3b452SApple OSS Distributions test_cpu_capability("SHA3", kHasFeatSHA3, true, "hw.optional.armv8_2_sha3", try_sha3);
434*94d3b452SApple OSS Distributions test_cpu_capability("AES", kHasFeatAES, true, "hw.optional.arm.FEAT_AES", try_aes);
435*94d3b452SApple OSS Distributions test_cpu_capability("SHA1", kHasFeatSHA1, true, "hw.optional.arm.FEAT_SHA1", try_sha1);
436*94d3b452SApple OSS Distributions test_cpu_capability("SHA256", kHasFeatSHA256, true, "hw.optional.arm.FEAT_SHA256", try_sha256);
437*94d3b452SApple OSS Distributions test_cpu_capability("PMULL", kHasFeatPMULL, true, "hw.optional.arm.FEAT_PMULL", try_pmull);
438*94d3b452SApple OSS Distributions test_cpu_capability("FCMA (deprecated sysctl)", kHasFeatFCMA, true, "hw.optional.armv8_3_compnum", NULL);
439*94d3b452SApple OSS Distributions test_cpu_capability("FCMA", kHasFeatFCMA, true, "hw.optional.arm.FEAT_FCMA", try_compnum);
440*94d3b452SApple OSS Distributions test_cpu_capability("FlagM", kHasFEATFlagM, true, "hw.optional.arm.FEAT_FlagM", try_flagm);
441*94d3b452SApple OSS Distributions test_cpu_capability("FlagM2", kHasFEATFlagM2, true, "hw.optional.arm.FEAT_FlagM2", try_flagm2);
442*94d3b452SApple OSS Distributions test_cpu_capability("DotProd", kHasFeatDotProd, true, "hw.optional.arm.FEAT_DotProd", try_dotprod);
443*94d3b452SApple OSS Distributions test_cpu_capability("RDM", kHasFeatRDM, true, "hw.optional.arm.FEAT_RDM", try_rdm);
444*94d3b452SApple OSS Distributions test_cpu_capability("SB", kHasFeatSB, true, "hw.optional.arm.FEAT_SB", try_sb);
445*94d3b452SApple OSS Distributions test_cpu_capability("FRINTTS", kHasFeatFRINTTS, true, "hw.optional.arm.FEAT_FRINTTS", try_frintts);
446*94d3b452SApple OSS Distributions test_cpu_capability("JSCVT", kHasFeatJSCVT, true, "hw.optional.arm.FEAT_JSCVT", try_jscvt);
447*94d3b452SApple OSS Distributions test_cpu_capability("PAuth", kHasFeatPAuth, true, "hw.optional.arm.FEAT_PAuth", try_pauth);
448*94d3b452SApple OSS Distributions test_cpu_capability("DBP", kHasFeatDPB, true, "hw.optional.arm.FEAT_DPB", try_dpb);
449*94d3b452SApple OSS Distributions test_cpu_capability("DBP2", kHasFeatDPB2, true, "hw.optional.arm.FEAT_DPB2", try_dpb2);
450*94d3b452SApple OSS Distributions test_cpu_capability("SPECRES", kHasFeatSPECRES, true, "hw.optional.arm.FEAT_SPECRES", try_specres);
451*94d3b452SApple OSS Distributions test_cpu_capability("LRCPC", kHasFeatLRCPC, true, "hw.optional.arm.FEAT_LRCPC", try_lrcpc);
452*94d3b452SApple OSS Distributions test_cpu_capability("LRCPC2", kHasFeatLRCPC2, true, "hw.optional.arm.FEAT_LRCPC2", try_lrcpc2);
453*94d3b452SApple OSS Distributions test_cpu_capability("DIT", kHasFeatDIT, true, "hw.optional.arm.FEAT_DIT", try_dit);
454*94d3b452SApple OSS Distributions test_cpu_capability("FP16", kHasFP_SyncExceptions, true, "hw.optional.arm.FP_SyncExceptions", try_fpexcp);
455*94d3b452SApple OSS Distributions
456*94d3b452SApple OSS Distributions // The following features do not have a commpage entry
457*94d3b452SApple OSS Distributions test_cpu_capability("BF16", 0, false, "hw.optional.arm.FEAT_BF16", try_bf16);
458*94d3b452SApple OSS Distributions test_cpu_capability("I8MM", 0, false, "hw.optional.arm.FEAT_I8MM", try_i8mm);
459*94d3b452SApple OSS Distributions test_cpu_capability("ECV", 0, false, "hw.optional.arm.FEAT_ECV", try_ecv);
460*94d3b452SApple OSS Distributions
461*94d3b452SApple OSS Distributions // The following features do not add instructions or registers to test for the presence of
462*94d3b452SApple OSS Distributions test_cpu_capability("LSE2", kHasFeatLSE2, true, "hw.optional.arm.FEAT_LSE2", NULL);
463*94d3b452SApple OSS Distributions test_cpu_capability("CSV2", kHasFeatCSV2, true, "hw.optional.arm.FEAT_CSV2", NULL);
464*94d3b452SApple OSS Distributions test_cpu_capability("CSV3", kHasFeatCSV3, true, "hw.optional.arm.FEAT_CSV3", NULL);
465*94d3b452SApple OSS Distributions }
466