selftests/powerpc: Add test for VPHN

The goal is to verify vphn_unpack_associativity() parses VPHN numbers
correctly. We feed it with a variety of input values and compare with
expected results.

PAPR+ does not say much about VPHN parsing: I came up with a list of
tests that check many simple cases and some corner ones. I wouldn't
dare to say the list is exhaustive though.

Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
[mpe: Rework harness logic, rename to test-vphn, add -m64]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Reviewed-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
This commit is contained in:
Greg Kurz 2015-02-23 16:14:44 +01:00 committed by Michael Ellerman
parent 3338a65bad
commit 58dae82843
7 changed files with 430 additions and 1 deletions

View File

@ -13,7 +13,7 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR
export CC CFLAGS
TARGETS = pmu copyloops mm tm primitives stringloops
TARGETS = pmu copyloops mm tm primitives stringloops vphn
endif

View File

@ -15,6 +15,7 @@ typedef signed long long s64;
/* Just for familiarity */
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;

View File

@ -0,0 +1 @@
test-vphn

View File

@ -0,0 +1,15 @@
PROG := test-vphn
CFLAGS += -m64
all: $(PROG)
$(PROG): ../harness.c
run_tests: all
./$(PROG)
clean:
rm -f $(PROG)
.PHONY: all run_tests clean

View File

@ -0,0 +1,410 @@
#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");
}

View File

@ -0,0 +1 @@
../../../../../arch/powerpc/mm/vphn.c

View File

@ -0,0 +1 @@
../../../../../arch/powerpc/mm/vphn.h