1// SPDX-License-Identifier: GPL-2.0
2#include <stdio.h>
3#include <byteswap.h>
4#include "utils.h"
5#include "subunit.h"
6
7#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
8#define cpu_to_be32(x)		bswap_32(x)
9#define be32_to_cpu(x)		bswap_32(x)
10#define be16_to_cpup(x)		bswap_16(*x)
11#define cpu_to_be64(x)		bswap_64(x)
12#else
13#define cpu_to_be32(x)		(x)
14#define be32_to_cpu(x)		(x)
15#define be16_to_cpup(x)		(*x)
16#define cpu_to_be64(x)		(x)
17#endif
18
19#include "vphn.c"
20
21static struct test {
22	char *descr;
23	long input[VPHN_REGISTER_COUNT];
24	u32 expected[VPHN_ASSOC_BUFSIZE];
25} all_tests[] = {
26	{
27		"vphn: no data",
28		{
29			0xffffffffffffffff,
30			0xffffffffffffffff,
31			0xffffffffffffffff,
32			0xffffffffffffffff,
33			0xffffffffffffffff,
34			0xffffffffffffffff,
35		},
36		{
37			0x00000000
38		}
39	},
40	{
41		"vphn: 1 x 16-bit value",
42		{
43			0x8001ffffffffffff,
44			0xffffffffffffffff,
45			0xffffffffffffffff,
46			0xffffffffffffffff,
47			0xffffffffffffffff,
48			0xffffffffffffffff,
49		},
50		{
51			0x00000001,
52			0x00000001
53		}
54	},
55	{
56		"vphn: 2 x 16-bit values",
57		{
58			0x80018002ffffffff,
59			0xffffffffffffffff,
60			0xffffffffffffffff,
61			0xffffffffffffffff,
62			0xffffffffffffffff,
63			0xffffffffffffffff,
64		},
65		{
66			0x00000002,
67			0x00000001,
68			0x00000002
69		}
70	},
71	{
72		"vphn: 3 x 16-bit values",
73		{
74			0x800180028003ffff,
75			0xffffffffffffffff,
76			0xffffffffffffffff,
77			0xffffffffffffffff,
78			0xffffffffffffffff,
79			0xffffffffffffffff,
80		},
81		{
82			0x00000003,
83			0x00000001,
84			0x00000002,
85			0x00000003
86		}
87	},
88	{
89		"vphn: 4 x 16-bit values",
90		{
91			0x8001800280038004,
92			0xffffffffffffffff,
93			0xffffffffffffffff,
94			0xffffffffffffffff,
95			0xffffffffffffffff,
96			0xffffffffffffffff,
97		},
98		{
99			0x00000004,
100			0x00000001,
101			0x00000002,
102			0x00000003,
103			0x00000004
104		}
105	},
106	{
107		/* Parsing the next 16-bit value out of the next 64-bit input
108		 * value.
109		 */
110		"vphn: 5 x 16-bit values",
111		{
112			0x8001800280038004,
113			0x8005ffffffffffff,
114			0xffffffffffffffff,
115			0xffffffffffffffff,
116			0xffffffffffffffff,
117			0xffffffffffffffff,
118		},
119		{
120			0x00000005,
121			0x00000001,
122			0x00000002,
123			0x00000003,
124			0x00000004,
125			0x00000005
126		}
127	},
128	{
129		/* Parse at most 6 x 64-bit input values */
130		"vphn: 24 x 16-bit values",
131		{
132			0x8001800280038004,
133			0x8005800680078008,
134			0x8009800a800b800c,
135			0x800d800e800f8010,
136			0x8011801280138014,
137			0x8015801680178018
138		},
139		{
140			0x00000018,
141			0x00000001,
142			0x00000002,
143			0x00000003,
144			0x00000004,
145			0x00000005,
146			0x00000006,
147			0x00000007,
148			0x00000008,
149			0x00000009,
150			0x0000000a,
151			0x0000000b,
152			0x0000000c,
153			0x0000000d,
154			0x0000000e,
155			0x0000000f,
156			0x00000010,
157			0x00000011,
158			0x00000012,
159			0x00000013,
160			0x00000014,
161			0x00000015,
162			0x00000016,
163			0x00000017,
164			0x00000018
165		}
166	},
167	{
168		"vphn: 1 x 32-bit value",
169		{
170			0x00000001ffffffff,
171			0xffffffffffffffff,
172			0xffffffffffffffff,
173			0xffffffffffffffff,
174			0xffffffffffffffff,
175			0xffffffffffffffff
176		},
177		{
178			0x00000001,
179			0x00000001
180		}
181	},
182	{
183		"vphn: 2 x 32-bit values",
184		{
185			0x0000000100000002,
186			0xffffffffffffffff,
187			0xffffffffffffffff,
188			0xffffffffffffffff,
189			0xffffffffffffffff,
190			0xffffffffffffffff
191		},
192		{
193			0x00000002,
194			0x00000001,
195			0x00000002
196		}
197	},
198	{
199		/* Parsing the next 32-bit value out of the next 64-bit input
200		 * value.
201		 */
202		"vphn: 3 x 32-bit values",
203		{
204			0x0000000100000002,
205			0x00000003ffffffff,
206			0xffffffffffffffff,
207			0xffffffffffffffff,
208			0xffffffffffffffff,
209			0xffffffffffffffff
210		},
211		{
212			0x00000003,
213			0x00000001,
214			0x00000002,
215			0x00000003
216		}
217	},
218	{
219		/* Parse at most 6 x 64-bit input values */
220		"vphn: 12 x 32-bit values",
221		{
222			0x0000000100000002,
223			0x0000000300000004,
224			0x0000000500000006,
225			0x0000000700000008,
226			0x000000090000000a,
227			0x0000000b0000000c
228		},
229		{
230			0x0000000c,
231			0x00000001,
232			0x00000002,
233			0x00000003,
234			0x00000004,
235			0x00000005,
236			0x00000006,
237			0x00000007,
238			0x00000008,
239			0x00000009,
240			0x0000000a,
241			0x0000000b,
242			0x0000000c
243		}
244	},
245	{
246		"vphn: 16-bit value followed by 32-bit value",
247		{
248			0x800100000002ffff,
249			0xffffffffffffffff,
250			0xffffffffffffffff,
251			0xffffffffffffffff,
252			0xffffffffffffffff,
253			0xffffffffffffffff
254		},
255		{
256			0x00000002,
257			0x00000001,
258			0x00000002
259		}
260	},
261	{
262		"vphn: 32-bit value followed by 16-bit value",
263		{
264			0x000000018002ffff,
265			0xffffffffffffffff,
266			0xffffffffffffffff,
267			0xffffffffffffffff,
268			0xffffffffffffffff,
269			0xffffffffffffffff
270		},
271		{
272			0x00000002,
273			0x00000001,
274			0x00000002
275		}
276	},
277	{
278		/* Parse a 32-bit value split accross two consecutives 64-bit
279		 * input values.
280		 */
281		"vphn: 16-bit value followed by 2 x 32-bit values",
282		{
283			0x8001000000020000,
284			0x0003ffffffffffff,
285			0xffffffffffffffff,
286			0xffffffffffffffff,
287			0xffffffffffffffff,
288			0xffffffffffffffff
289		},
290		{
291			0x00000003,
292			0x00000001,
293			0x00000002,
294			0x00000003,
295			0x00000004,
296			0x00000005
297		}
298	},
299	{
300		/* The lower bits in 0x0001ffff don't get mixed up with the
301		 * 0xffff terminator.
302		 */
303		"vphn: 32-bit value has all ones in 16 lower bits",
304		{
305			0x0001ffff80028003,
306			0xffffffffffffffff,
307			0xffffffffffffffff,
308			0xffffffffffffffff,
309			0xffffffffffffffff,
310			0xffffffffffffffff
311		},
312		{
313			0x00000003,
314			0x0001ffff,
315			0x00000002,
316			0x00000003
317		}
318	},
319	{
320		/* The following input doesn't follow the specification.
321		 */
322		"vphn: last 32-bit value is truncated",
323		{
324			0x0000000100000002,
325			0x0000000300000004,
326			0x0000000500000006,
327			0x0000000700000008,
328			0x000000090000000a,
329			0x0000000b800c2bad
330		},
331		{
332			0x0000000c,
333			0x00000001,
334			0x00000002,
335			0x00000003,
336			0x00000004,
337			0x00000005,
338			0x00000006,
339			0x00000007,
340			0x00000008,
341			0x00000009,
342			0x0000000a,
343			0x0000000b,
344			0x0000000c
345		}
346	},
347	{
348		"vphn: garbage after terminator",
349		{
350			0xffff2bad2bad2bad,
351			0x2bad2bad2bad2bad,
352			0x2bad2bad2bad2bad,
353			0x2bad2bad2bad2bad,
354			0x2bad2bad2bad2bad,
355			0x2bad2bad2bad2bad
356		},
357		{
358			0x00000000
359		}
360	},
361	{
362		NULL
363	}
364};
365
366static int test_one(struct test *test)
367{
368	__be32 output[VPHN_ASSOC_BUFSIZE] = { 0 };
369	int i, len;
370
371	vphn_unpack_associativity(test->input, output);
372
373	len = be32_to_cpu(output[0]);
374	if (len != test->expected[0]) {
375		printf("expected %d elements, got %d\n", test->expected[0],
376		       len);
377		return 1;
378	}
379
380	for (i = 1; i < len; i++) {
381		u32 val = be32_to_cpu(output[i]);
382		if (val != test->expected[i]) {
383			printf("element #%d is 0x%x, should be 0x%x\n", i, val,
384			       test->expected[i]);
385			return 1;
386		}
387	}
388
389	return 0;
390}
391
392static int test_vphn(void)
393{
394	static struct test *test;
395
396	for (test = all_tests; test->descr; test++) {
397		int ret;
398
399		ret = test_one(test);
400		test_finish(test->descr, ret);
401		if (ret)
402			return ret;
403	}
404
405	return 0;
406}
407
408int main(int argc, char **argv)
409{
410	return test_harness(test_vphn, "test-vphn");
411}
412