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 */
10long riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pair_count,
11		   size_t cpu_count, unsigned long *cpus, unsigned int flags);
12
13int 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