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