1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <stddef.h>
3 #include <asm/hwprobe.h>
4 
5 /*
6  * Rather than relying on having a new enough libc to define this, just do it
7  * ourselves.  This way we don't need to be coupled to a new-enough libc to
8  * contain the call.
9  */
10 long riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pair_count,
11 		   size_t cpu_count, unsigned long *cpus, unsigned int flags);
12 
13 int main(int argc, char **argv)
14 {
15 	struct riscv_hwprobe pairs[8];
16 	unsigned long cpus;
17 	long out;
18 
19 	/* Fake the CPU_SET ops. */
20 	cpus = -1;
21 
22 	/*
23 	 * Just run a basic test: pass enough pairs to get up to the base
24 	 * behavior, and then check to make sure it's sane.
25 	 */
26 	for (long i = 0; i < 8; i++)
27 		pairs[i].key = i;
28 	out = riscv_hwprobe(pairs, 8, 1, &cpus, 0);
29 	if (out != 0)
30 		return -1;
31 	for (long i = 0; i < 4; ++i) {
32 		/* Fail if the kernel claims not to recognize a base key. */
33 		if ((i < 4) && (pairs[i].key != i))
34 			return -2;
35 
36 		if (pairs[i].key != RISCV_HWPROBE_KEY_BASE_BEHAVIOR)
37 			continue;
38 
39 		if (pairs[i].value & RISCV_HWPROBE_BASE_BEHAVIOR_IMA)
40 			continue;
41 
42 		return -3;
43 	}
44 
45 	/*
46 	 * This should also work with a NULL CPU set, but should not work
47 	 * with an improperly supplied CPU set.
48 	 */
49 	out = riscv_hwprobe(pairs, 8, 0, 0, 0);
50 	if (out != 0)
51 		return -4;
52 
53 	out = riscv_hwprobe(pairs, 8, 0, &cpus, 0);
54 	if (out == 0)
55 		return -5;
56 
57 	out = riscv_hwprobe(pairs, 8, 1, 0, 0);
58 	if (out == 0)
59 		return -6;
60 
61 	/*
62 	 * Check that keys work by providing one that we know exists, and
63 	 * checking to make sure the resultig pair is what we asked for.
64 	 */
65 	pairs[0].key = RISCV_HWPROBE_KEY_BASE_BEHAVIOR;
66 	out = riscv_hwprobe(pairs, 1, 1, &cpus, 0);
67 	if (out != 0)
68 		return -7;
69 	if (pairs[0].key != RISCV_HWPROBE_KEY_BASE_BEHAVIOR)
70 		return -8;
71 
72 	/*
73 	 * Check that an unknown key gets overwritten with -1,
74 	 * but doesn't block elements after it.
75 	 */
76 	pairs[0].key = 0x5555;
77 	pairs[1].key = 1;
78 	pairs[1].value = 0xAAAA;
79 	out = riscv_hwprobe(pairs, 2, 0, 0, 0);
80 	if (out != 0)
81 		return -9;
82 
83 	if (pairs[0].key != -1)
84 		return -10;
85 
86 	if ((pairs[1].key != 1) || (pairs[1].value == 0xAAAA))
87 		return -11;
88 
89 	return 0;
90 }
91