Add a new file "emulator.c" and keep running tests simple for now (no support for multiple iterations and such stuff). We will get this for free once we switch to a new, general API for running/defining tests. Signed-off-by: David Hildenbrand <david@xxxxxxxxxx> --- s390x/Makefile | 1 + s390x/emulator.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ s390x/unittests.cfg | 3 +++ 3 files changed, 69 insertions(+) create mode 100644 s390x/emulator.c diff --git a/s390x/Makefile b/s390x/Makefile index bc099da..573cba2 100644 --- a/s390x/Makefile +++ b/s390x/Makefile @@ -1,5 +1,6 @@ tests = $(TEST_DIR)/selftest.elf tests += $(TEST_DIR)/intercept.elf +tests += $(TEST_DIR)/emulator.elf all: directories test_cases diff --git a/s390x/emulator.c b/s390x/emulator.c new file mode 100644 index 0000000..7854498 --- /dev/null +++ b/s390x/emulator.c @@ -0,0 +1,65 @@ +/* + * Emulator tests - for s390x CPU instructions that are usually interpreted + * by the hardware + * + * Copyright (c) 2017 Red Hat Inc + * + * Authors: + * David Hildenbrand <david@xxxxxxxxxx> + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License version 2. + */ +#include <libcflat.h> + +static inline void __test_spm_ipm(uint8_t cc, uint8_t key) +{ + uint64_t in = (cc << 28) | (key << 24); + uint64_t out = ~0ULL; + + report_prefix_pushf("cc=%d,key=%x", cc, key); + + asm volatile ("spm %1\n" + "ipm %0\n" + : "+r"(out) : "r"(in) : "cc"); + + report("bit 32 and 33 set to zero", !(out & 0xc0000000UL)); + report("bit 0-31, 40-63 unchanged", + (out & ~0xff000000ULL) == ~0xff000000ULL); + report("cc and key applied", !((in ^ out) & 0x3f000000UL)); + + report_prefix_pop(); +} + +/* Test the SET PROGRAM PARAMETER and INSERT PROGRAM PARAMETER instruction */ +static void test_spm_ipm(void) +{ + __test_spm_ipm(0, 0xf); + __test_spm_ipm(1, 0x9); + __test_spm_ipm(2, 0x5); + __test_spm_ipm(3, 0x3); + __test_spm_ipm(0, 0); +} + +static struct { + const char *name; + void (*func)(void); +} tests[] = { + { "spm/ipm", test_spm_ipm }, + { NULL, NULL } +}; + +int main(int argc, char**argv) +{ + int i; + + report_prefix_push("emulator"); + for (i = 0; tests[i].name; i++) { + report_prefix_push(tests[i].name); + tests[i].func(); + report_prefix_pop(); + } + report_prefix_pop(); + + return report_summary(); +} diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg index 3b6b892..1343a19 100644 --- a/s390x/unittests.cfg +++ b/s390x/unittests.cfg @@ -25,3 +25,6 @@ extra_params = -append 'test 123' [intercept] file = intercept.elf + +[emulator] +file = emulator.elf -- 2.13.5