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 
21 static 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 
366 static 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 
392 static 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 
408 int main(int argc, char **argv)
409 {
410 	return test_harness(test_vphn, "test-vphn");
411 }
412