162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#include <stdio.h>
362306a36Sopenharmony_ci#include <byteswap.h>
462306a36Sopenharmony_ci#include "utils.h"
562306a36Sopenharmony_ci#include "subunit.h"
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
862306a36Sopenharmony_ci#define cpu_to_be32(x)		bswap_32(x)
962306a36Sopenharmony_ci#define be32_to_cpu(x)		bswap_32(x)
1062306a36Sopenharmony_ci#define be16_to_cpup(x)		bswap_16(*x)
1162306a36Sopenharmony_ci#define cpu_to_be64(x)		bswap_64(x)
1262306a36Sopenharmony_ci#else
1362306a36Sopenharmony_ci#define cpu_to_be32(x)		(x)
1462306a36Sopenharmony_ci#define be32_to_cpu(x)		(x)
1562306a36Sopenharmony_ci#define be16_to_cpup(x)		(*x)
1662306a36Sopenharmony_ci#define cpu_to_be64(x)		(x)
1762306a36Sopenharmony_ci#endif
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#include "vphn.c"
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cistatic struct test {
2262306a36Sopenharmony_ci	char *descr;
2362306a36Sopenharmony_ci	long input[VPHN_REGISTER_COUNT];
2462306a36Sopenharmony_ci	u32 expected[VPHN_ASSOC_BUFSIZE];
2562306a36Sopenharmony_ci} all_tests[] = {
2662306a36Sopenharmony_ci	{
2762306a36Sopenharmony_ci		"vphn: no data",
2862306a36Sopenharmony_ci		{
2962306a36Sopenharmony_ci			0xffffffffffffffff,
3062306a36Sopenharmony_ci			0xffffffffffffffff,
3162306a36Sopenharmony_ci			0xffffffffffffffff,
3262306a36Sopenharmony_ci			0xffffffffffffffff,
3362306a36Sopenharmony_ci			0xffffffffffffffff,
3462306a36Sopenharmony_ci			0xffffffffffffffff,
3562306a36Sopenharmony_ci		},
3662306a36Sopenharmony_ci		{
3762306a36Sopenharmony_ci			0x00000000
3862306a36Sopenharmony_ci		}
3962306a36Sopenharmony_ci	},
4062306a36Sopenharmony_ci	{
4162306a36Sopenharmony_ci		"vphn: 1 x 16-bit value",
4262306a36Sopenharmony_ci		{
4362306a36Sopenharmony_ci			0x8001ffffffffffff,
4462306a36Sopenharmony_ci			0xffffffffffffffff,
4562306a36Sopenharmony_ci			0xffffffffffffffff,
4662306a36Sopenharmony_ci			0xffffffffffffffff,
4762306a36Sopenharmony_ci			0xffffffffffffffff,
4862306a36Sopenharmony_ci			0xffffffffffffffff,
4962306a36Sopenharmony_ci		},
5062306a36Sopenharmony_ci		{
5162306a36Sopenharmony_ci			0x00000001,
5262306a36Sopenharmony_ci			0x00000001
5362306a36Sopenharmony_ci		}
5462306a36Sopenharmony_ci	},
5562306a36Sopenharmony_ci	{
5662306a36Sopenharmony_ci		"vphn: 2 x 16-bit values",
5762306a36Sopenharmony_ci		{
5862306a36Sopenharmony_ci			0x80018002ffffffff,
5962306a36Sopenharmony_ci			0xffffffffffffffff,
6062306a36Sopenharmony_ci			0xffffffffffffffff,
6162306a36Sopenharmony_ci			0xffffffffffffffff,
6262306a36Sopenharmony_ci			0xffffffffffffffff,
6362306a36Sopenharmony_ci			0xffffffffffffffff,
6462306a36Sopenharmony_ci		},
6562306a36Sopenharmony_ci		{
6662306a36Sopenharmony_ci			0x00000002,
6762306a36Sopenharmony_ci			0x00000001,
6862306a36Sopenharmony_ci			0x00000002
6962306a36Sopenharmony_ci		}
7062306a36Sopenharmony_ci	},
7162306a36Sopenharmony_ci	{
7262306a36Sopenharmony_ci		"vphn: 3 x 16-bit values",
7362306a36Sopenharmony_ci		{
7462306a36Sopenharmony_ci			0x800180028003ffff,
7562306a36Sopenharmony_ci			0xffffffffffffffff,
7662306a36Sopenharmony_ci			0xffffffffffffffff,
7762306a36Sopenharmony_ci			0xffffffffffffffff,
7862306a36Sopenharmony_ci			0xffffffffffffffff,
7962306a36Sopenharmony_ci			0xffffffffffffffff,
8062306a36Sopenharmony_ci		},
8162306a36Sopenharmony_ci		{
8262306a36Sopenharmony_ci			0x00000003,
8362306a36Sopenharmony_ci			0x00000001,
8462306a36Sopenharmony_ci			0x00000002,
8562306a36Sopenharmony_ci			0x00000003
8662306a36Sopenharmony_ci		}
8762306a36Sopenharmony_ci	},
8862306a36Sopenharmony_ci	{
8962306a36Sopenharmony_ci		"vphn: 4 x 16-bit values",
9062306a36Sopenharmony_ci		{
9162306a36Sopenharmony_ci			0x8001800280038004,
9262306a36Sopenharmony_ci			0xffffffffffffffff,
9362306a36Sopenharmony_ci			0xffffffffffffffff,
9462306a36Sopenharmony_ci			0xffffffffffffffff,
9562306a36Sopenharmony_ci			0xffffffffffffffff,
9662306a36Sopenharmony_ci			0xffffffffffffffff,
9762306a36Sopenharmony_ci		},
9862306a36Sopenharmony_ci		{
9962306a36Sopenharmony_ci			0x00000004,
10062306a36Sopenharmony_ci			0x00000001,
10162306a36Sopenharmony_ci			0x00000002,
10262306a36Sopenharmony_ci			0x00000003,
10362306a36Sopenharmony_ci			0x00000004
10462306a36Sopenharmony_ci		}
10562306a36Sopenharmony_ci	},
10662306a36Sopenharmony_ci	{
10762306a36Sopenharmony_ci		/* Parsing the next 16-bit value out of the next 64-bit input
10862306a36Sopenharmony_ci		 * value.
10962306a36Sopenharmony_ci		 */
11062306a36Sopenharmony_ci		"vphn: 5 x 16-bit values",
11162306a36Sopenharmony_ci		{
11262306a36Sopenharmony_ci			0x8001800280038004,
11362306a36Sopenharmony_ci			0x8005ffffffffffff,
11462306a36Sopenharmony_ci			0xffffffffffffffff,
11562306a36Sopenharmony_ci			0xffffffffffffffff,
11662306a36Sopenharmony_ci			0xffffffffffffffff,
11762306a36Sopenharmony_ci			0xffffffffffffffff,
11862306a36Sopenharmony_ci		},
11962306a36Sopenharmony_ci		{
12062306a36Sopenharmony_ci			0x00000005,
12162306a36Sopenharmony_ci			0x00000001,
12262306a36Sopenharmony_ci			0x00000002,
12362306a36Sopenharmony_ci			0x00000003,
12462306a36Sopenharmony_ci			0x00000004,
12562306a36Sopenharmony_ci			0x00000005
12662306a36Sopenharmony_ci		}
12762306a36Sopenharmony_ci	},
12862306a36Sopenharmony_ci	{
12962306a36Sopenharmony_ci		/* Parse at most 6 x 64-bit input values */
13062306a36Sopenharmony_ci		"vphn: 24 x 16-bit values",
13162306a36Sopenharmony_ci		{
13262306a36Sopenharmony_ci			0x8001800280038004,
13362306a36Sopenharmony_ci			0x8005800680078008,
13462306a36Sopenharmony_ci			0x8009800a800b800c,
13562306a36Sopenharmony_ci			0x800d800e800f8010,
13662306a36Sopenharmony_ci			0x8011801280138014,
13762306a36Sopenharmony_ci			0x8015801680178018
13862306a36Sopenharmony_ci		},
13962306a36Sopenharmony_ci		{
14062306a36Sopenharmony_ci			0x00000018,
14162306a36Sopenharmony_ci			0x00000001,
14262306a36Sopenharmony_ci			0x00000002,
14362306a36Sopenharmony_ci			0x00000003,
14462306a36Sopenharmony_ci			0x00000004,
14562306a36Sopenharmony_ci			0x00000005,
14662306a36Sopenharmony_ci			0x00000006,
14762306a36Sopenharmony_ci			0x00000007,
14862306a36Sopenharmony_ci			0x00000008,
14962306a36Sopenharmony_ci			0x00000009,
15062306a36Sopenharmony_ci			0x0000000a,
15162306a36Sopenharmony_ci			0x0000000b,
15262306a36Sopenharmony_ci			0x0000000c,
15362306a36Sopenharmony_ci			0x0000000d,
15462306a36Sopenharmony_ci			0x0000000e,
15562306a36Sopenharmony_ci			0x0000000f,
15662306a36Sopenharmony_ci			0x00000010,
15762306a36Sopenharmony_ci			0x00000011,
15862306a36Sopenharmony_ci			0x00000012,
15962306a36Sopenharmony_ci			0x00000013,
16062306a36Sopenharmony_ci			0x00000014,
16162306a36Sopenharmony_ci			0x00000015,
16262306a36Sopenharmony_ci			0x00000016,
16362306a36Sopenharmony_ci			0x00000017,
16462306a36Sopenharmony_ci			0x00000018
16562306a36Sopenharmony_ci		}
16662306a36Sopenharmony_ci	},
16762306a36Sopenharmony_ci	{
16862306a36Sopenharmony_ci		"vphn: 1 x 32-bit value",
16962306a36Sopenharmony_ci		{
17062306a36Sopenharmony_ci			0x00000001ffffffff,
17162306a36Sopenharmony_ci			0xffffffffffffffff,
17262306a36Sopenharmony_ci			0xffffffffffffffff,
17362306a36Sopenharmony_ci			0xffffffffffffffff,
17462306a36Sopenharmony_ci			0xffffffffffffffff,
17562306a36Sopenharmony_ci			0xffffffffffffffff
17662306a36Sopenharmony_ci		},
17762306a36Sopenharmony_ci		{
17862306a36Sopenharmony_ci			0x00000001,
17962306a36Sopenharmony_ci			0x00000001
18062306a36Sopenharmony_ci		}
18162306a36Sopenharmony_ci	},
18262306a36Sopenharmony_ci	{
18362306a36Sopenharmony_ci		"vphn: 2 x 32-bit values",
18462306a36Sopenharmony_ci		{
18562306a36Sopenharmony_ci			0x0000000100000002,
18662306a36Sopenharmony_ci			0xffffffffffffffff,
18762306a36Sopenharmony_ci			0xffffffffffffffff,
18862306a36Sopenharmony_ci			0xffffffffffffffff,
18962306a36Sopenharmony_ci			0xffffffffffffffff,
19062306a36Sopenharmony_ci			0xffffffffffffffff
19162306a36Sopenharmony_ci		},
19262306a36Sopenharmony_ci		{
19362306a36Sopenharmony_ci			0x00000002,
19462306a36Sopenharmony_ci			0x00000001,
19562306a36Sopenharmony_ci			0x00000002
19662306a36Sopenharmony_ci		}
19762306a36Sopenharmony_ci	},
19862306a36Sopenharmony_ci	{
19962306a36Sopenharmony_ci		/* Parsing the next 32-bit value out of the next 64-bit input
20062306a36Sopenharmony_ci		 * value.
20162306a36Sopenharmony_ci		 */
20262306a36Sopenharmony_ci		"vphn: 3 x 32-bit values",
20362306a36Sopenharmony_ci		{
20462306a36Sopenharmony_ci			0x0000000100000002,
20562306a36Sopenharmony_ci			0x00000003ffffffff,
20662306a36Sopenharmony_ci			0xffffffffffffffff,
20762306a36Sopenharmony_ci			0xffffffffffffffff,
20862306a36Sopenharmony_ci			0xffffffffffffffff,
20962306a36Sopenharmony_ci			0xffffffffffffffff
21062306a36Sopenharmony_ci		},
21162306a36Sopenharmony_ci		{
21262306a36Sopenharmony_ci			0x00000003,
21362306a36Sopenharmony_ci			0x00000001,
21462306a36Sopenharmony_ci			0x00000002,
21562306a36Sopenharmony_ci			0x00000003
21662306a36Sopenharmony_ci		}
21762306a36Sopenharmony_ci	},
21862306a36Sopenharmony_ci	{
21962306a36Sopenharmony_ci		/* Parse at most 6 x 64-bit input values */
22062306a36Sopenharmony_ci		"vphn: 12 x 32-bit values",
22162306a36Sopenharmony_ci		{
22262306a36Sopenharmony_ci			0x0000000100000002,
22362306a36Sopenharmony_ci			0x0000000300000004,
22462306a36Sopenharmony_ci			0x0000000500000006,
22562306a36Sopenharmony_ci			0x0000000700000008,
22662306a36Sopenharmony_ci			0x000000090000000a,
22762306a36Sopenharmony_ci			0x0000000b0000000c
22862306a36Sopenharmony_ci		},
22962306a36Sopenharmony_ci		{
23062306a36Sopenharmony_ci			0x0000000c,
23162306a36Sopenharmony_ci			0x00000001,
23262306a36Sopenharmony_ci			0x00000002,
23362306a36Sopenharmony_ci			0x00000003,
23462306a36Sopenharmony_ci			0x00000004,
23562306a36Sopenharmony_ci			0x00000005,
23662306a36Sopenharmony_ci			0x00000006,
23762306a36Sopenharmony_ci			0x00000007,
23862306a36Sopenharmony_ci			0x00000008,
23962306a36Sopenharmony_ci			0x00000009,
24062306a36Sopenharmony_ci			0x0000000a,
24162306a36Sopenharmony_ci			0x0000000b,
24262306a36Sopenharmony_ci			0x0000000c
24362306a36Sopenharmony_ci		}
24462306a36Sopenharmony_ci	},
24562306a36Sopenharmony_ci	{
24662306a36Sopenharmony_ci		"vphn: 16-bit value followed by 32-bit value",
24762306a36Sopenharmony_ci		{
24862306a36Sopenharmony_ci			0x800100000002ffff,
24962306a36Sopenharmony_ci			0xffffffffffffffff,
25062306a36Sopenharmony_ci			0xffffffffffffffff,
25162306a36Sopenharmony_ci			0xffffffffffffffff,
25262306a36Sopenharmony_ci			0xffffffffffffffff,
25362306a36Sopenharmony_ci			0xffffffffffffffff
25462306a36Sopenharmony_ci		},
25562306a36Sopenharmony_ci		{
25662306a36Sopenharmony_ci			0x00000002,
25762306a36Sopenharmony_ci			0x00000001,
25862306a36Sopenharmony_ci			0x00000002
25962306a36Sopenharmony_ci		}
26062306a36Sopenharmony_ci	},
26162306a36Sopenharmony_ci	{
26262306a36Sopenharmony_ci		"vphn: 32-bit value followed by 16-bit value",
26362306a36Sopenharmony_ci		{
26462306a36Sopenharmony_ci			0x000000018002ffff,
26562306a36Sopenharmony_ci			0xffffffffffffffff,
26662306a36Sopenharmony_ci			0xffffffffffffffff,
26762306a36Sopenharmony_ci			0xffffffffffffffff,
26862306a36Sopenharmony_ci			0xffffffffffffffff,
26962306a36Sopenharmony_ci			0xffffffffffffffff
27062306a36Sopenharmony_ci		},
27162306a36Sopenharmony_ci		{
27262306a36Sopenharmony_ci			0x00000002,
27362306a36Sopenharmony_ci			0x00000001,
27462306a36Sopenharmony_ci			0x00000002
27562306a36Sopenharmony_ci		}
27662306a36Sopenharmony_ci	},
27762306a36Sopenharmony_ci	{
27862306a36Sopenharmony_ci		/* Parse a 32-bit value split accross two consecutives 64-bit
27962306a36Sopenharmony_ci		 * input values.
28062306a36Sopenharmony_ci		 */
28162306a36Sopenharmony_ci		"vphn: 16-bit value followed by 2 x 32-bit values",
28262306a36Sopenharmony_ci		{
28362306a36Sopenharmony_ci			0x8001000000020000,
28462306a36Sopenharmony_ci			0x0003ffffffffffff,
28562306a36Sopenharmony_ci			0xffffffffffffffff,
28662306a36Sopenharmony_ci			0xffffffffffffffff,
28762306a36Sopenharmony_ci			0xffffffffffffffff,
28862306a36Sopenharmony_ci			0xffffffffffffffff
28962306a36Sopenharmony_ci		},
29062306a36Sopenharmony_ci		{
29162306a36Sopenharmony_ci			0x00000003,
29262306a36Sopenharmony_ci			0x00000001,
29362306a36Sopenharmony_ci			0x00000002,
29462306a36Sopenharmony_ci			0x00000003,
29562306a36Sopenharmony_ci			0x00000004,
29662306a36Sopenharmony_ci			0x00000005
29762306a36Sopenharmony_ci		}
29862306a36Sopenharmony_ci	},
29962306a36Sopenharmony_ci	{
30062306a36Sopenharmony_ci		/* The lower bits in 0x0001ffff don't get mixed up with the
30162306a36Sopenharmony_ci		 * 0xffff terminator.
30262306a36Sopenharmony_ci		 */
30362306a36Sopenharmony_ci		"vphn: 32-bit value has all ones in 16 lower bits",
30462306a36Sopenharmony_ci		{
30562306a36Sopenharmony_ci			0x0001ffff80028003,
30662306a36Sopenharmony_ci			0xffffffffffffffff,
30762306a36Sopenharmony_ci			0xffffffffffffffff,
30862306a36Sopenharmony_ci			0xffffffffffffffff,
30962306a36Sopenharmony_ci			0xffffffffffffffff,
31062306a36Sopenharmony_ci			0xffffffffffffffff
31162306a36Sopenharmony_ci		},
31262306a36Sopenharmony_ci		{
31362306a36Sopenharmony_ci			0x00000003,
31462306a36Sopenharmony_ci			0x0001ffff,
31562306a36Sopenharmony_ci			0x00000002,
31662306a36Sopenharmony_ci			0x00000003
31762306a36Sopenharmony_ci		}
31862306a36Sopenharmony_ci	},
31962306a36Sopenharmony_ci	{
32062306a36Sopenharmony_ci		/* The following input doesn't follow the specification.
32162306a36Sopenharmony_ci		 */
32262306a36Sopenharmony_ci		"vphn: last 32-bit value is truncated",
32362306a36Sopenharmony_ci		{
32462306a36Sopenharmony_ci			0x0000000100000002,
32562306a36Sopenharmony_ci			0x0000000300000004,
32662306a36Sopenharmony_ci			0x0000000500000006,
32762306a36Sopenharmony_ci			0x0000000700000008,
32862306a36Sopenharmony_ci			0x000000090000000a,
32962306a36Sopenharmony_ci			0x0000000b800c2bad
33062306a36Sopenharmony_ci		},
33162306a36Sopenharmony_ci		{
33262306a36Sopenharmony_ci			0x0000000c,
33362306a36Sopenharmony_ci			0x00000001,
33462306a36Sopenharmony_ci			0x00000002,
33562306a36Sopenharmony_ci			0x00000003,
33662306a36Sopenharmony_ci			0x00000004,
33762306a36Sopenharmony_ci			0x00000005,
33862306a36Sopenharmony_ci			0x00000006,
33962306a36Sopenharmony_ci			0x00000007,
34062306a36Sopenharmony_ci			0x00000008,
34162306a36Sopenharmony_ci			0x00000009,
34262306a36Sopenharmony_ci			0x0000000a,
34362306a36Sopenharmony_ci			0x0000000b,
34462306a36Sopenharmony_ci			0x0000000c
34562306a36Sopenharmony_ci		}
34662306a36Sopenharmony_ci	},
34762306a36Sopenharmony_ci	{
34862306a36Sopenharmony_ci		"vphn: garbage after terminator",
34962306a36Sopenharmony_ci		{
35062306a36Sopenharmony_ci			0xffff2bad2bad2bad,
35162306a36Sopenharmony_ci			0x2bad2bad2bad2bad,
35262306a36Sopenharmony_ci			0x2bad2bad2bad2bad,
35362306a36Sopenharmony_ci			0x2bad2bad2bad2bad,
35462306a36Sopenharmony_ci			0x2bad2bad2bad2bad,
35562306a36Sopenharmony_ci			0x2bad2bad2bad2bad
35662306a36Sopenharmony_ci		},
35762306a36Sopenharmony_ci		{
35862306a36Sopenharmony_ci			0x00000000
35962306a36Sopenharmony_ci		}
36062306a36Sopenharmony_ci	},
36162306a36Sopenharmony_ci	{
36262306a36Sopenharmony_ci		NULL
36362306a36Sopenharmony_ci	}
36462306a36Sopenharmony_ci};
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_cistatic int test_one(struct test *test)
36762306a36Sopenharmony_ci{
36862306a36Sopenharmony_ci	__be32 output[VPHN_ASSOC_BUFSIZE] = { 0 };
36962306a36Sopenharmony_ci	int i, len;
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci	vphn_unpack_associativity(test->input, output);
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	len = be32_to_cpu(output[0]);
37462306a36Sopenharmony_ci	if (len != test->expected[0]) {
37562306a36Sopenharmony_ci		printf("expected %d elements, got %d\n", test->expected[0],
37662306a36Sopenharmony_ci		       len);
37762306a36Sopenharmony_ci		return 1;
37862306a36Sopenharmony_ci	}
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci	for (i = 1; i < len; i++) {
38162306a36Sopenharmony_ci		u32 val = be32_to_cpu(output[i]);
38262306a36Sopenharmony_ci		if (val != test->expected[i]) {
38362306a36Sopenharmony_ci			printf("element #%d is 0x%x, should be 0x%x\n", i, val,
38462306a36Sopenharmony_ci			       test->expected[i]);
38562306a36Sopenharmony_ci			return 1;
38662306a36Sopenharmony_ci		}
38762306a36Sopenharmony_ci	}
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci	return 0;
39062306a36Sopenharmony_ci}
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_cistatic int test_vphn(void)
39362306a36Sopenharmony_ci{
39462306a36Sopenharmony_ci	static struct test *test;
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci	for (test = all_tests; test->descr; test++) {
39762306a36Sopenharmony_ci		int ret;
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci		ret = test_one(test);
40062306a36Sopenharmony_ci		test_finish(test->descr, ret);
40162306a36Sopenharmony_ci		if (ret)
40262306a36Sopenharmony_ci			return ret;
40362306a36Sopenharmony_ci	}
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci	return 0;
40662306a36Sopenharmony_ci}
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ciint main(int argc, char **argv)
40962306a36Sopenharmony_ci{
41062306a36Sopenharmony_ci	return test_harness(test_vphn, "test-vphn");
41162306a36Sopenharmony_ci}
412