| // SPDX-License-Identifier: GPL-2.0 |
| #include <stdio.h> |
| #include <byteswap.h> |
| #include "utils.h" |
| #include "subunit.h" |
| |
| #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ |
| #define cpu_to_be32(x) bswap_32(x) |
| #define be32_to_cpu(x) bswap_32(x) |
| #define be16_to_cpup(x) bswap_16(*x) |
| #define cpu_to_be64(x) bswap_64(x) |
| #else |
| #define cpu_to_be32(x) (x) |
| #define be32_to_cpu(x) (x) |
| #define be16_to_cpup(x) (*x) |
| #define cpu_to_be64(x) (x) |
| #endif |
| |
| #include "vphn.c" |
| |
| static struct test { |
| char *descr; |
| long input[VPHN_REGISTER_COUNT]; |
| u32 expected[VPHN_ASSOC_BUFSIZE]; |
| } all_tests[] = { |
| { |
| "vphn: no data", |
| { |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| }, |
| { |
| 0x00000000 |
| } |
| }, |
| { |
| "vphn: 1 x 16-bit value", |
| { |
| 0x8001ffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| }, |
| { |
| 0x00000001, |
| 0x00000001 |
| } |
| }, |
| { |
| "vphn: 2 x 16-bit values", |
| { |
| 0x80018002ffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| }, |
| { |
| 0x00000002, |
| 0x00000001, |
| 0x00000002 |
| } |
| }, |
| { |
| "vphn: 3 x 16-bit values", |
| { |
| 0x800180028003ffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| }, |
| { |
| 0x00000003, |
| 0x00000001, |
| 0x00000002, |
| 0x00000003 |
| } |
| }, |
| { |
| "vphn: 4 x 16-bit values", |
| { |
| 0x8001800280038004, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| }, |
| { |
| 0x00000004, |
| 0x00000001, |
| 0x00000002, |
| 0x00000003, |
| 0x00000004 |
| } |
| }, |
| { |
| /* Parsing the next 16-bit value out of the next 64-bit input |
| * value. |
| */ |
| "vphn: 5 x 16-bit values", |
| { |
| 0x8001800280038004, |
| 0x8005ffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| }, |
| { |
| 0x00000005, |
| 0x00000001, |
| 0x00000002, |
| 0x00000003, |
| 0x00000004, |
| 0x00000005 |
| } |
| }, |
| { |
| /* Parse at most 6 x 64-bit input values */ |
| "vphn: 24 x 16-bit values", |
| { |
| 0x8001800280038004, |
| 0x8005800680078008, |
| 0x8009800a800b800c, |
| 0x800d800e800f8010, |
| 0x8011801280138014, |
| 0x8015801680178018 |
| }, |
| { |
| 0x00000018, |
| 0x00000001, |
| 0x00000002, |
| 0x00000003, |
| 0x00000004, |
| 0x00000005, |
| 0x00000006, |
| 0x00000007, |
| 0x00000008, |
| 0x00000009, |
| 0x0000000a, |
| 0x0000000b, |
| 0x0000000c, |
| 0x0000000d, |
| 0x0000000e, |
| 0x0000000f, |
| 0x00000010, |
| 0x00000011, |
| 0x00000012, |
| 0x00000013, |
| 0x00000014, |
| 0x00000015, |
| 0x00000016, |
| 0x00000017, |
| 0x00000018 |
| } |
| }, |
| { |
| "vphn: 1 x 32-bit value", |
| { |
| 0x00000001ffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff |
| }, |
| { |
| 0x00000001, |
| 0x00000001 |
| } |
| }, |
| { |
| "vphn: 2 x 32-bit values", |
| { |
| 0x0000000100000002, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff |
| }, |
| { |
| 0x00000002, |
| 0x00000001, |
| 0x00000002 |
| } |
| }, |
| { |
| /* Parsing the next 32-bit value out of the next 64-bit input |
| * value. |
| */ |
| "vphn: 3 x 32-bit values", |
| { |
| 0x0000000100000002, |
| 0x00000003ffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff |
| }, |
| { |
| 0x00000003, |
| 0x00000001, |
| 0x00000002, |
| 0x00000003 |
| } |
| }, |
| { |
| /* Parse at most 6 x 64-bit input values */ |
| "vphn: 12 x 32-bit values", |
| { |
| 0x0000000100000002, |
| 0x0000000300000004, |
| 0x0000000500000006, |
| 0x0000000700000008, |
| 0x000000090000000a, |
| 0x0000000b0000000c |
| }, |
| { |
| 0x0000000c, |
| 0x00000001, |
| 0x00000002, |
| 0x00000003, |
| 0x00000004, |
| 0x00000005, |
| 0x00000006, |
| 0x00000007, |
| 0x00000008, |
| 0x00000009, |
| 0x0000000a, |
| 0x0000000b, |
| 0x0000000c |
| } |
| }, |
| { |
| "vphn: 16-bit value followed by 32-bit value", |
| { |
| 0x800100000002ffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff |
| }, |
| { |
| 0x00000002, |
| 0x00000001, |
| 0x00000002 |
| } |
| }, |
| { |
| "vphn: 32-bit value followed by 16-bit value", |
| { |
| 0x000000018002ffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff |
| }, |
| { |
| 0x00000002, |
| 0x00000001, |
| 0x00000002 |
| } |
| }, |
| { |
| /* Parse a 32-bit value split accross two consecutives 64-bit |
| * input values. |
| */ |
| "vphn: 16-bit value followed by 2 x 32-bit values", |
| { |
| 0x8001000000020000, |
| 0x0003ffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff |
| }, |
| { |
| 0x00000003, |
| 0x00000001, |
| 0x00000002, |
| 0x00000003, |
| 0x00000004, |
| 0x00000005 |
| } |
| }, |
| { |
| /* The lower bits in 0x0001ffff don't get mixed up with the |
| * 0xffff terminator. |
| */ |
| "vphn: 32-bit value has all ones in 16 lower bits", |
| { |
| 0x0001ffff80028003, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff, |
| 0xffffffffffffffff |
| }, |
| { |
| 0x00000003, |
| 0x0001ffff, |
| 0x00000002, |
| 0x00000003 |
| } |
| }, |
| { |
| /* The following input doesn't follow the specification. |
| */ |
| "vphn: last 32-bit value is truncated", |
| { |
| 0x0000000100000002, |
| 0x0000000300000004, |
| 0x0000000500000006, |
| 0x0000000700000008, |
| 0x000000090000000a, |
| 0x0000000b800c2bad |
| }, |
| { |
| 0x0000000c, |
| 0x00000001, |
| 0x00000002, |
| 0x00000003, |
| 0x00000004, |
| 0x00000005, |
| 0x00000006, |
| 0x00000007, |
| 0x00000008, |
| 0x00000009, |
| 0x0000000a, |
| 0x0000000b, |
| 0x0000000c |
| } |
| }, |
| { |
| "vphn: garbage after terminator", |
| { |
| 0xffff2bad2bad2bad, |
| 0x2bad2bad2bad2bad, |
| 0x2bad2bad2bad2bad, |
| 0x2bad2bad2bad2bad, |
| 0x2bad2bad2bad2bad, |
| 0x2bad2bad2bad2bad |
| }, |
| { |
| 0x00000000 |
| } |
| }, |
| { |
| NULL |
| } |
| }; |
| |
| static int test_one(struct test *test) |
| { |
| __be32 output[VPHN_ASSOC_BUFSIZE] = { 0 }; |
| int i, len; |
| |
| vphn_unpack_associativity(test->input, output); |
| |
| len = be32_to_cpu(output[0]); |
| if (len != test->expected[0]) { |
| printf("expected %d elements, got %d\n", test->expected[0], |
| len); |
| return 1; |
| } |
| |
| for (i = 1; i < len; i++) { |
| u32 val = be32_to_cpu(output[i]); |
| if (val != test->expected[i]) { |
| printf("element #%d is 0x%x, should be 0x%x\n", i, val, |
| test->expected[i]); |
| return 1; |
| } |
| } |
| |
| return 0; |
| } |
| |
| static int test_vphn(void) |
| { |
| static struct test *test; |
| |
| for (test = all_tests; test->descr; test++) { |
| int ret; |
| |
| ret = test_one(test); |
| test_finish(test->descr, ret); |
| if (ret) |
| return ret; |
| } |
| |
| return 0; |
| } |
| |
| int main(int argc, char **argv) |
| { |
| return test_harness(test_vphn, "test-vphn"); |
| } |