xref: /linux/tools/testing/selftests/riscv/vector/v_helpers.c (revision cee73b1e840c154f64ace682cb477c1ae2e29cc4)
1 // SPDX-License-Identifier: GPL-2.0-only
2 
3 #include "../hwprobe/hwprobe.h"
4 #include <asm/vendor/thead.h>
5 #include <stdbool.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <sys/wait.h>
10 
11 bool is_xtheadvector_supported(void)
12 {
13 	struct riscv_hwprobe pair;
14 
15 	pair.key = RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0;
16 	riscv_hwprobe(&pair, 1, 0, NULL, 0);
17 	return pair.value & RISCV_HWPROBE_VENDOR_EXT_XTHEADVECTOR;
18 }
19 
20 bool is_vector_supported(void)
21 {
22 	struct riscv_hwprobe pair;
23 
24 	pair.key = RISCV_HWPROBE_KEY_IMA_EXT_0;
25 	riscv_hwprobe(&pair, 1, 0, NULL, 0);
26 	return pair.value & RISCV_HWPROBE_EXT_ZVE32X;
27 }
28 
29 unsigned long get_vr_len(void)
30 {
31 	unsigned long vlenb;
32 
33 	if (is_vector_supported()) {
34 		asm volatile("csrr %[vlenb], vlenb" : [vlenb] "=r"(vlenb));
35 		return vlenb;
36 	}
37 
38 	if (is_xtheadvector_supported()) {
39 		asm volatile (
40 			// 0 | zimm[10:0] | rs1 | 1 1 1 | rd | 1010111 | vsetvli
41 			// vsetvli	t4, x0, e8, m1, d1
42 			".4byte		0b00000000000000000111111011010111\n\t"
43 			"mv		%[vlenb], t4\n\t"
44 			: [vlenb] "=r"(vlenb) : : "memory", "t4");
45 		return vlenb;
46 	}
47 
48 	printf("WARNING: vector not supported\n");
49 	return 0;
50 }
51 
52 int launch_test(char *next_program, int test_inherit, int xtheadvector)
53 {
54 	char *exec_argv[4], *exec_envp[1];
55 	int rc, pid, status;
56 
57 	pid = fork();
58 	if (pid < 0) {
59 		printf("fork failed %d", pid);
60 		return -1;
61 	}
62 
63 	if (!pid) {
64 		exec_argv[0] = next_program;
65 		exec_argv[1] = test_inherit != 0 ? "x" : NULL;
66 		exec_argv[2] = xtheadvector != 0 ? "x" : NULL;
67 		exec_argv[3] = NULL;
68 		exec_envp[0] = NULL;
69 		/* launch the program again to check inherit */
70 		rc = execve(next_program, exec_argv, exec_envp);
71 		if (rc) {
72 			perror("execve");
73 			printf("child execve failed %d\n", rc);
74 			exit(-1);
75 		}
76 	}
77 
78 	rc = waitpid(-1, &status, 0);
79 	if (rc < 0) {
80 		printf("waitpid failed\n");
81 		return -3;
82 	}
83 
84 	if ((WIFEXITED(status) && WEXITSTATUS(status) == -1) ||
85 	    WIFSIGNALED(status)) {
86 		printf("child exited abnormally\n");
87 		return -4;
88 	}
89 
90 	return WEXITSTATUS(status);
91 }
92