xref: /qemu/tests/tcg/aarch64/sve-ioctls.c (revision 2b6d6371)
1*2b6d6371SAlex Bennée /*
2*2b6d6371SAlex Bennée  * SVE ioctls tests
3*2b6d6371SAlex Bennée  *
4*2b6d6371SAlex Bennée  * Test the SVE width setting ioctls work and provide a base for
5*2b6d6371SAlex Bennée  * testing the gdbstub.
6*2b6d6371SAlex Bennée  *
7*2b6d6371SAlex Bennée  * Copyright (c) 2019 Linaro Ltd
8*2b6d6371SAlex Bennée  *
9*2b6d6371SAlex Bennée  * SPDX-License-Identifier: GPL-2.0-or-later
10*2b6d6371SAlex Bennée  */
11*2b6d6371SAlex Bennée #include <sys/prctl.h>
12*2b6d6371SAlex Bennée #include <asm/hwcap.h>
13*2b6d6371SAlex Bennée #include <stdio.h>
14*2b6d6371SAlex Bennée #include <sys/auxv.h>
15*2b6d6371SAlex Bennée #include <stdint.h>
16*2b6d6371SAlex Bennée #include <stdlib.h>
17*2b6d6371SAlex Bennée 
18*2b6d6371SAlex Bennée #ifndef HWCAP_CPUID
19*2b6d6371SAlex Bennée #define HWCAP_CPUID (1 << 11)
20*2b6d6371SAlex Bennée #endif
21*2b6d6371SAlex Bennée 
22*2b6d6371SAlex Bennée #define SVE_MAX_QUADS  (2048 / 128)
23*2b6d6371SAlex Bennée #define BYTES_PER_QUAD (128 / 8)
24*2b6d6371SAlex Bennée 
25*2b6d6371SAlex Bennée #define get_cpu_reg(id) ({                                      \
26*2b6d6371SAlex Bennée             unsigned long __val;                                \
27*2b6d6371SAlex Bennée             asm("mrs %0, "#id : "=r" (__val));                  \
28*2b6d6371SAlex Bennée             __val;                                              \
29*2b6d6371SAlex Bennée         })
30*2b6d6371SAlex Bennée 
do_sve_ioctl_test(void)31*2b6d6371SAlex Bennée static int do_sve_ioctl_test(void)
32*2b6d6371SAlex Bennée {
33*2b6d6371SAlex Bennée     int i, res, init_vq;
34*2b6d6371SAlex Bennée 
35*2b6d6371SAlex Bennée     res = prctl(PR_SVE_GET_VL, 0, 0, 0, 0);
36*2b6d6371SAlex Bennée     if (res < 0) {
37*2b6d6371SAlex Bennée         printf("FAILED to PR_SVE_GET_VL (%d)", res);
38*2b6d6371SAlex Bennée         return -1;
39*2b6d6371SAlex Bennée     }
40*2b6d6371SAlex Bennée     init_vq = res & PR_SVE_VL_LEN_MASK;
41*2b6d6371SAlex Bennée 
42*2b6d6371SAlex Bennée     for (i = init_vq; i > 15; i /= 2) {
43*2b6d6371SAlex Bennée         printf("Checking PR_SVE_SET_VL=%d\n", i);
44*2b6d6371SAlex Bennée         res = prctl(PR_SVE_SET_VL, i, 0, 0, 0, 0);
45*2b6d6371SAlex Bennée         if (res < 0) {
46*2b6d6371SAlex Bennée             printf("FAILED to PR_SVE_SET_VL (%d)", res);
47*2b6d6371SAlex Bennée             return -1;
48*2b6d6371SAlex Bennée         }
49*2b6d6371SAlex Bennée         asm("index z0.b, #0, #1\n"
50*2b6d6371SAlex Bennée             ".global __sve_ld_done\n"
51*2b6d6371SAlex Bennée             "__sve_ld_done:\n"
52*2b6d6371SAlex Bennée             "mov z0.b, #0\n"
53*2b6d6371SAlex Bennée             : /* no outputs kept */
54*2b6d6371SAlex Bennée             : /* no inputs */
55*2b6d6371SAlex Bennée             : "memory", "z0");
56*2b6d6371SAlex Bennée     }
57*2b6d6371SAlex Bennée     printf("PASS\n");
58*2b6d6371SAlex Bennée     return 0;
59*2b6d6371SAlex Bennée }
60*2b6d6371SAlex Bennée 
main(int argc,char ** argv)61*2b6d6371SAlex Bennée int main(int argc, char **argv)
62*2b6d6371SAlex Bennée {
63*2b6d6371SAlex Bennée     /* we also need to probe for the ioctl support */
64*2b6d6371SAlex Bennée     if (getauxval(AT_HWCAP) & HWCAP_SVE) {
65*2b6d6371SAlex Bennée         return do_sve_ioctl_test();
66*2b6d6371SAlex Bennée     } else {
67*2b6d6371SAlex Bennée         printf("SKIP: no HWCAP_SVE on this system\n");
68*2b6d6371SAlex Bennée         return 0;
69*2b6d6371SAlex Bennée     }
70*2b6d6371SAlex Bennée }
71