From: Pierre Morel <pmorel@linux.ibm.com>
To: kvm@vger.kernel.org
Cc: linux-s390@vger.kernel.org, frankja@linux.ibm.com,
david@redhat.com, thuth@redhat.com, cohuck@redhat.com
Subject: [kvm-unit-tests PATCH v6 09/10] s390x: css: ssch/tsch with sense and interrupt
Date: Fri, 24 Apr 2020 12:45:51 +0200 [thread overview]
Message-ID: <1587725152-25569-10-git-send-email-pmorel@linux.ibm.com> (raw)
In-Reply-To: <1587725152-25569-1-git-send-email-pmorel@linux.ibm.com>
We add a new css_lib file to contain the I/O function we may
share with different tests.
First function is the subchannel_enable() function.
When a channel is enabled we can start a SENSE_ID command using
the SSCH instruction to recognize the control unit and device.
This tests the success of SSCH, the I/O interruption and the TSCH
instructions.
The test expects a device with a control unit type of 0xC0CA as the
first subchannel of the CSS.
Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
---
lib/s390x/asm/arch_def.h | 1 +
lib/s390x/css.h | 20 ++++++
lib/s390x/css_lib.c | 55 +++++++++++++++
s390x/Makefile | 1 +
s390x/css.c | 149 +++++++++++++++++++++++++++++++++++++++
5 files changed, 226 insertions(+)
create mode 100644 lib/s390x/css_lib.c
diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h
index e04866c..7a63ab7 100644
--- a/lib/s390x/asm/arch_def.h
+++ b/lib/s390x/asm/arch_def.h
@@ -10,6 +10,7 @@
#ifndef _ASM_S390X_ARCH_DEF_H_
#define _ASM_S390X_ARCH_DEF_H_
+#define PSW_MASK_IO 0x0200000000000000UL
#define PSW_MASK_EXT 0x0100000000000000UL
#define PSW_MASK_DAT 0x0400000000000000UL
#define PSW_MASK_SHORT_PSW 0x0008000000000000UL
diff --git a/lib/s390x/css.h b/lib/s390x/css.h
index 9417541..f278d0b 100644
--- a/lib/s390x/css.h
+++ b/lib/s390x/css.h
@@ -97,6 +97,19 @@ struct irb {
uint32_t emw[8];
} __attribute__ ((aligned(4)));
+#define CCW_CMD_SENSE_ID 0xe4
+#define PONG_CU 0xc0ca
+struct senseid {
+ /* common part */
+ uint8_t reserved; /* always 0x'FF' */
+ uint16_t cu_type; /* control unit type */
+ uint8_t cu_model; /* control unit model */
+ uint16_t dev_type; /* device type */
+ uint8_t dev_model; /* device model */
+ uint8_t unused; /* padding byte */
+ uint8_t padding[256 - 10]; /* Extra padding for CCW */
+} __attribute__ ((aligned(4))) __attribute__ ((packed));
+
/* CSS low level access functions */
static inline int ssch(unsigned long schid, struct orb *addr)
@@ -254,4 +267,11 @@ static inline struct ccw *dump_ccw(struct ccw *cp)
return NULL;
}
#endif /* DEBUG_CSS */
+
+#define SID_ONE 0x00010000
+
+/* Library functions */
+int enable_subchannel(unsigned int sid);
+int start_ccw1_chain(unsigned int sid, struct ccw1 *ccw);
+
#endif
diff --git a/lib/s390x/css_lib.c b/lib/s390x/css_lib.c
new file mode 100644
index 0000000..80b9359
--- /dev/null
+++ b/lib/s390x/css_lib.c
@@ -0,0 +1,55 @@
+/*
+ * Channel subsystem library functions
+ *
+ * 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 <stdint.h>
+#include <stddef.h>
+#include <css.h>
+
+int enable_subchannel(unsigned int sid)
+{
+ struct schib schib;
+ struct pmcw *pmcw = &schib.pmcw;
+ int try_count = 5;
+ int cc;
+
+ if (!(sid & SID_ONE))
+ return -1;
+
+ cc = stsch(sid, &schib);
+ if (cc)
+ return -cc;
+
+ do {
+ pmcw->flags |= PMCW_ENABLE;
+
+ cc = msch(sid, &schib);
+ if (cc)
+ return -cc;
+
+ cc = stsch(sid, &schib);
+ if (cc)
+ return -cc;
+
+ } while (!(pmcw->flags & PMCW_ENABLE) && --try_count);
+
+ return try_count;
+}
+
+int start_ccw1_chain(unsigned int sid, struct ccw1 *ccw)
+{
+ struct orb orb;
+
+ orb.intparm = sid;
+ orb.ctrl = ORB_F_INIT_IRQ|ORB_F_FORMAT|ORB_F_LPM_DFLT;
+ orb.cpa = (unsigned int) (unsigned long)ccw;
+
+ return ssch(sid, &orb);
+}
diff --git a/s390x/Makefile b/s390x/Makefile
index baebf18..166cb5c 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -53,6 +53,7 @@ cflatobjs += lib/s390x/interrupt.o
cflatobjs += lib/s390x/mmu.o
cflatobjs += lib/s390x/smp.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
index fa068bf..b9dbf01 100644
--- a/s390x/css.c
+++ b/s390x/css.c
@@ -20,9 +20,26 @@
#include <css.h>
#define SID_ONE 0x00010000
+#define PSW_PRG_MASK (PSW_MASK_EA | PSW_MASK_BA)
+
+#define PONG_CU_TYPE 0xc0ca
+
+struct lowcore *lowcore = (void *)0x0;
static struct schib schib;
static int test_device_sid;
+#define NUM_CCW 100
+static struct ccw1 ccw[NUM_CCW];
+static struct irb irb;
+static struct senseid senseid;
+
+static void set_io_irq_subclass_mask(uint64_t const new_mask)
+{
+ asm volatile (
+ "lctlg %%c6, %%c6, %[source]\n"
+ : /* No outputs */
+ : [source] "R" (new_mask));
+}
static void test_enumerate(void)
{
@@ -115,12 +132,143 @@ static void test_enable(void)
report(1, "Tested");
}
+static void enable_io_isc(void)
+{
+ /* Let's enable all ISCs for I/O interrupt */
+ set_io_irq_subclass_mask(0x00000000ff000000);
+}
+
+static void irq_io(void)
+{
+ int ret = 0;
+ char *flags;
+ int sid;
+
+ report_prefix_push("Interrupt");
+ /* Lowlevel set the SID as interrupt parameter. */
+ if (lowcore->io_int_param != test_device_sid) {
+ report(0,
+ "Bad io_int_param: %x expected %x",
+ lowcore->io_int_param, test_device_sid);
+ goto pop;
+ }
+ report_prefix_pop();
+
+ report_prefix_push("tsch");
+ sid = lowcore->subsys_id_word;
+ ret = tsch(sid, &irb);
+ switch (ret) {
+ case 1:
+ dump_irb(&irb);
+ flags = dump_scsw_flags(irb.scsw.ctrl);
+ report(0,
+ "I/O interrupt, but sch not status pending: %s", flags);
+ break;
+ case 2:
+ report(0, "TSCH returns unexpected CC 2");
+ break;
+ case 3:
+ report(0, "Subchannel %08x not operational", sid);
+ break;
+ case 0:
+ /* Stay humble on success */
+ break;
+ }
+pop:
+ report_prefix_pop();
+ lowcore->io_old_psw.mask &= ~PSW_MASK_WAIT;
+}
+
+static int start_subchannel(int code, void *data, int count)
+{
+ int ret;
+
+ report_prefix_push("start_senseid");
+ /* Build the CCW chain with a single CCW */
+ ccw[0].code = code;
+ ccw[0].flags = 0; /* No flags need to be set */
+ ccw[0].count = count;
+ ccw[0].data_address = (int)(unsigned long)data;
+
+ ret = start_ccw1_chain(test_device_sid, ccw);
+ if (ret) {
+ report(0, "start_ccw_chain failed ret=%d", ret);
+ report_prefix_pop();
+ return 0;
+ }
+ report_prefix_pop();
+ return 1;
+}
+
+/*
+ * test_sense
+ * Pre-requisits:
+ * - We need the QEMU PONG device as the first recognized
+ * device by the enumeration.
+ * - ./s390x-run s390x/css.elf -device ccw-pong,cu_type=0xc0ca
+ */
+static void test_sense(void)
+{
+ int ret;
+
+ if (!test_device_sid) {
+ report_skip("No device");
+ return;
+ }
+
+ ret = enable_subchannel(test_device_sid);
+ if (ret < 0) {
+ report(0,
+ "Could not enable the subchannel: %08x",
+ test_device_sid);
+ return;
+ }
+
+ ret = register_io_int_func(irq_io);
+ if (ret) {
+ report(0, "Could not register IRQ handler");
+ goto unreg_cb;
+ }
+
+ lowcore->io_int_param = 0;
+
+ ret = start_subchannel(CCW_CMD_SENSE_ID, &senseid, sizeof(senseid));
+ if (!ret) {
+ report(0, "start_senseid failed");
+ goto unreg_cb;
+ }
+
+ wfi(PSW_MASK_IO);
+
+ if (lowcore->io_int_param != test_device_sid) {
+ report(0,
+ "No interrupts. io_int_param: expect 0x%08x, got 0x%08x",
+ test_device_sid, lowcore->io_int_param);
+ goto unreg_cb;
+ }
+
+ report_info("reserved %02x cu_type %04x cu_model %02x dev_type %04x dev_model %02x",
+ senseid.reserved, senseid.cu_type, senseid.cu_model,
+ senseid.dev_type, senseid.dev_model);
+
+ if (senseid.cu_type == PONG_CU)
+ report(1, "cu_type: expect 0x%04x got 0x%04x",
+ PONG_CU_TYPE, senseid.cu_type);
+ else
+ report(0, "cu_type: expect 0x%04x got 0x%04x",
+ PONG_CU_TYPE, senseid.cu_type);
+
+unreg_cb:
+ unregister_io_int_func(irq_io);
+}
+
static struct {
const char *name;
void (*func)(void);
} tests[] = {
{ "enumerate (stsch)", test_enumerate },
{ "enable (msch)", test_enable },
+ { "sense (ssch/tsch)", test_sense },
{ NULL, NULL }
};
@@ -129,6 +277,7 @@ int main(int argc, char *argv[])
int i;
report_prefix_push("Channel Subsystem");
+ enable_io_isc();
for (i = 0; tests[i].name; i++) {
report_prefix_push(tests[i].name);
tests[i].func();
--
2.25.1
next prev parent reply other threads:[~2020-04-24 10:46 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-24 10:45 [kvm-unit-tests PATCH v6 00/10] s390x: Testing the Channel Subsystem I/O Pierre Morel
2020-04-24 10:45 ` [kvm-unit-tests PATCH v6 01/10] s390x: saving regs for interrupts Pierre Morel
2020-04-27 8:59 ` David Hildenbrand
2020-04-27 10:50 ` Pierre Morel
2020-04-24 10:45 ` [kvm-unit-tests PATCH v6 02/10] s390x: Use PSW bits definitions in cstart Pierre Morel
2020-04-27 9:01 ` David Hildenbrand
2020-04-28 8:10 ` Pierre Morel
2020-04-24 10:45 ` [kvm-unit-tests PATCH v6 03/10] s390x: Move control register bit definitions and add AFP to them Pierre Morel
2020-04-24 10:45 ` [kvm-unit-tests PATCH v6 04/10] s390x: interrupt registration Pierre Morel
2020-05-14 11:58 ` Cornelia Huck
2020-05-15 6:57 ` Pierre Morel
2020-05-15 7:57 ` David Hildenbrand
2020-04-24 10:45 ` [kvm-unit-tests PATCH v6 05/10] s390x: Library resources for CSS tests Pierre Morel
2020-05-14 12:03 ` Cornelia Huck
2020-05-15 7:02 ` Pierre Morel
2020-05-15 7:11 ` Cornelia Huck
2020-05-15 7:14 ` Pierre Morel
2020-04-24 10:45 ` [kvm-unit-tests PATCH v6 06/10] s390x: css: stsch, enumeration test Pierre Morel
2020-04-27 13:06 ` Janosch Frank
2020-04-28 8:17 ` Pierre Morel
2020-05-14 12:05 ` Cornelia Huck
2020-05-15 7:05 ` Pierre Morel
2020-04-24 10:45 ` [kvm-unit-tests PATCH v6 07/10] s390x: css: msch, enable test Pierre Morel
2020-04-27 13:11 ` Janosch Frank
2020-04-28 8:27 ` Pierre Morel
2020-05-14 12:08 ` Cornelia Huck
2020-05-15 7:11 ` Pierre Morel
2020-05-15 8:25 ` Cornelia Huck
2020-05-15 8:53 ` Janosch Frank
2020-05-15 11:34 ` Pierre Morel
2020-04-24 10:45 ` [kvm-unit-tests PATCH v6 08/10] s390x: define wfi: wait for interrupt Pierre Morel
2020-04-27 12:59 ` Janosch Frank
2020-04-28 8:44 ` Pierre Morel
2020-04-28 9:20 ` Janosch Frank
2020-04-28 9:27 ` Pierre Morel
2020-04-24 10:45 ` Pierre Morel [this message]
2020-05-14 12:24 ` [kvm-unit-tests PATCH v6 09/10] s390x: css: ssch/tsch with sense and interrupt Cornelia Huck
2020-05-15 7:37 ` Pierre Morel
2020-04-24 10:45 ` [kvm-unit-tests PATCH v6 10/10] s390x: css: ping pong Pierre Morel
2020-04-27 13:14 ` Janosch Frank
2020-04-28 8:50 ` Pierre Morel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1587725152-25569-10-git-send-email-pmorel@linux.ibm.com \
--to=pmorel@linux.ibm.com \
--cc=cohuck@redhat.com \
--cc=david@redhat.com \
--cc=frankja@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.