[PATCH v14 7/9] s390x: css: stsch, enumeration test

Pierre Morel
2020-07-16T13:02:54Z

First step for testing the channel subsystem is to enumerate the css and
retrieve the css devices.

We currently don't enable multiple subchannel sets and therefore only
look in subchannel set 0

This tests the success of STSCH I/O instruction, we do not test the
reaction of the VM for an instruction with wrong parameters.

Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
Acked-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
---
lib/s390x/css_lib.c | 70 +++++++++++++++++++++++++++++++++++++++++++++
s390x/Makefile | 2 ++
s390x/css.c | 55 +++++++++++++++++++++++++++++++++++
s390x/unittests.cfg | 4 +++
4 files changed, 131 insertions(+)
create mode 100644 lib/s390x/css_lib.c
create mode 100644 s390x/css.c

diff --git a/lib/s390x/css_lib.c b/lib/s390x/css_lib.c
new file mode 100644
index 0000000..fd087ce
--- /dev/null
+++ b/lib/s390x/css_lib.c
@@ -0,0 +1,70 @@
+/*
+ * Channel Subsystem tests library
+ *
+ * Copyright (c) 2020 IBM Corp
+ *
+ * Authors:
+ * Pierre Morel <pmorel@linux.ibm.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2.
+ */
+#include <libcflat.h>
+#include <alloc_phys.h>
+#include <asm/page.h>
+#include <string.h>
+#include <interrupt.h>
+#include <asm/arch_def.h>
+
+#include <css.h>
+
+static struct schib schib;
+
+/*
+ * css_enumerate:
+ * On success return the first subchannel ID found.
+ * On error return an invalid subchannel ID containing cc
+ */
+int css_enumerate(void)
+{
+ struct pmcw *pmcw = &schib.pmcw;
+ int scn_found = 0;
+ int dev_found = 0;
+ int schid = 0;
+ int cc;
+ int scn;
+
+ for (scn = 0; scn < 0xffff; scn++) {
+ cc = stsch(scn | SCHID_ONE, &schib);
+ switch (cc) {
+ case 0: /* 0 means SCHIB stored */
+ break;
+ case 3: /* 3 means no more channels */
+ goto out;
+ default: /* 1 or 2 should never happen for STSCH */
+ report_abort("Unexpected error %d on subchannel %08x",
+ cc, scn | SCHID_ONE);
+ return cc;
+ }
+
+ /* We currently only support type 0, a.k.a. I/O channels */
+ if (PMCW_CHANNEL_TYPE(pmcw) != 0)
+ continue;
+
+ /* We ignore I/O channels without valid devices */
+ scn_found++;
+ if (!(pmcw->flags & PMCW_DNV))
+ continue;
+
+ /* We keep track of the first device as our test device */
+ if (!schid)
+ schid = scn | SCHID_ONE;
+ report_info("Found subchannel %08x", scn | SCHID_ONE);
+ dev_found++;
+ }
+
+out:
+ report_info("Tested subchannels: %d, I/O subchannels: %d, I/O devices: %d",
+ scn, scn_found, dev_found);
+ return schid;
+}
diff --git a/s390x/Makefile b/s390x/Makefile
index 07d3c4b..0f54bf4 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -17,6 +17,7 @@ tests += $(TEST_DIR)/stsi.elf
tests += $(TEST_DIR)/skrf.elf
tests += $(TEST_DIR)/smp.elf
tests += $(TEST_DIR)/sclp.elf
+tests += $(TEST_DIR)/css.elf
tests_binary = $(patsubst %.elf,%.bin,$(tests))

all: directories test_cases test_cases_binary
@@ -53,6 +54,7 @@ cflatobjs += lib/s390x/mmu.o
cflatobjs += lib/s390x/smp.o
cflatobjs += lib/s390x/vm.o
cflatobjs += lib/s390x/css_dump.o
+cflatobjs += lib/s390x/css_lib.o

OBJDIRS += lib/s390x

diff --git a/s390x/css.c b/s390x/css.c
new file mode 100644
index 0000000..e19ffc8
--- /dev/null
+++ b/s390x/css.c
@@ -0,0 +1,55 @@
+/*
+ * Channel Subsystem tests
+ *
+ * Copyright (c) 2020 IBM Corp
+ *
+ * Authors:
+ * Pierre Morel <pmorel@linux.ibm.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2.
+ */
+
+#include <libcflat.h>
+#include <alloc_phys.h>
+#include <asm/page.h>
+#include <string.h>
+#include <interrupt.h>
+#include <asm/arch_def.h>
+
+#include <css.h>
+
+static int test_device_sid;
+
+static void test_enumerate(void)
+{
+ test_device_sid = css_enumerate();
+ if (test_device_sid & SCHID_ONE) {
+ report(1, "Schid of first I/O device: 0x%08x", test_device_sid);
+ return;
+ }
+ report(0, "No I/O device found");
+}
+
+static struct {
+ const char *name;
+ void (*func)(void);
+} tests[] = {
+ { "enumerate (stsch)", test_enumerate },
+ { NULL, NULL }
+};
+
+int main(int argc, char *argv[])
+{
+ int i;
+
+ report_prefix_push("Channel Subsystem");
+ 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 b307329..0f156af 100644
--- a/s390x/unittests.cfg
+++ b/s390x/unittests.cfg
@@ -84,3 +84,7 @@ extra_params = -m 1G
[sclp-3g]
file = sclp.elf
extra_params = -m 3G
+
+[css]
+file = css.elf
+extra_params = -device virtio-net-ccw
--
2.25.1