All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Huth <thuth@redhat.com>
To: kvm@vger.kernel.org, "Paolo Bonzini" <pbonzini@redhat.com>,
	"Radim Krčmář" <rkrcmar@redhat.com>
Cc: David Hildenbrand <david@redhat.com>,
	Janosch Frank <frankja@linux.ibm.com>
Subject: [kvm-unit-tests PULL 12/17] s390x: Add linemode console
Date: Wed, 25 Sep 2019 18:37:09 +0200	[thread overview]
Message-ID: <20190925163714.27519-13-thuth@redhat.com> (raw)
In-Reply-To: <20190925163714.27519-1-thuth@redhat.com>

From: Janosch Frank <frankja@linux.ibm.com>

z/VM isn't fond of vt220, so we need line mode when running under
z/VM.

Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Acked-by: David Hildenbrand <david@redhat.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20190920080356.1948-3-frankja@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
 lib/s390x/sclp-console.c | 181 +++++++++++++++++++++++++++++++++++----
 lib/s390x/sclp.h         |  55 +++++++++++-
 2 files changed, 218 insertions(+), 18 deletions(-)

diff --git a/lib/s390x/sclp-console.c b/lib/s390x/sclp-console.c
index a5ef45f..19416b5 100644
--- a/lib/s390x/sclp-console.c
+++ b/lib/s390x/sclp-console.c
@@ -11,21 +11,165 @@
 #include <libcflat.h>
 #include <string.h>
 #include <asm/page.h>
+#include <asm/arch_def.h>
+#include <asm/io.h>
 #include "sclp.h"
 
+/*
+ * ASCII (IBM PC 437) -> EBCDIC 037
+ */
+static uint8_t _ascebc[256] = {
+ /*00 NUL   SOH   STX   ETX   EOT   ENQ   ACK   BEL */
+     0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
+ /*08  BS    HT    LF    VT    FF    CR    SO    SI */
+ /*              ->NL                               */
+     0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ /*10 DLE   DC1   DC2   DC3   DC4   NAK   SYN   ETB */
+     0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
+ /*18 CAN    EM   SUB   ESC    FS    GS    RS    US */
+ /*                               ->IGS ->IRS ->IUS */
+     0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F,
+ /*20  SP     !     "     #     $     %     &     ' */
+     0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
+ /*28   (     )     *     +     ,     -    .      / */
+     0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
+ /*30   0     1     2     3     4     5     6     7 */
+     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+ /*38   8     9     :     ;     <     =     >     ? */
+     0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
+ /*40   @     A     B     C     D     E     F     G */
+     0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+ /*48   H     I     J     K     L     M     N     O */
+     0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
+ /*50   P     Q     R     S     T     U     V     W */
+     0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
+ /*58   X     Y     Z     [     \     ]     ^     _ */
+     0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D,
+ /*60   `     a     b     c     d     e     f     g */
+     0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ /*68   h     i     j     k     l     m     n     o */
+     0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ /*70   p     q     r     s     t     u     v     w */
+     0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
+ /*78   x     y     z     {     |     }     ~    DL */
+     0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
+ /*80*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*88*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*90*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*98*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*A0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*A8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*B0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*B8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*C0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*C8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*D0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*D8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*E0        sz	*/
+     0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*E8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*F0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*F8*/
+     0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF
+};
+
+static void sclp_print_ascii(const char *str)
+{
+	int len = strlen(str);
+	WriteEventData *sccb = (void *)_sccb;
+
+	sclp_mark_busy();
+	memset(sccb, 0, sizeof(*sccb));
+	sccb->h.length = offsetof(WriteEventData, msg) + len;
+	sccb->h.function_code = SCLP_FC_NORMAL_WRITE;
+	sccb->ebh.length = sizeof(EventBufferHeader) + len;
+	sccb->ebh.type = SCLP_EVENT_ASCII_CONSOLE_DATA;
+	memcpy(&sccb->msg, str, len);
+
+	sclp_service_call(SCLP_CMD_WRITE_EVENT_DATA, sccb);
+}
+
+static void sclp_print_lm(const char *str)
+{
+	unsigned char *ptr, *end, ch;
+	unsigned int count, offset, len;
+	struct WriteEventData *sccb;
+	struct mdb *mdb;
+	struct mto *mto;
+	struct go *go;
+
+	sclp_mark_busy();
+	sccb = (struct WriteEventData *) _sccb;
+	end = (unsigned char *) sccb + 4096 - 1;
+	memset(sccb, 0, sizeof(*sccb));
+	ptr = (unsigned char *) &sccb->msg.mdb.mto;
+	len = strlen(str);
+	offset = 0;
+	do {
+		for (count = sizeof(*mto); offset < len; count++) {
+			ch = str[offset++];
+			if (ch == 0x0a || ptr + count > end)
+				break;
+			ptr[count] = _ascebc[ch];
+		}
+		mto = (struct mto *) ptr;
+		mto->length = count;
+		mto->type = 4;
+		mto->line_type_flags = LNTPFLGS_ENDTEXT;
+		ptr += count;
+	} while (offset < len && ptr + sizeof(*mto) <= end);
+	len = ptr - (unsigned char *) sccb;
+	sccb->h.length = len - offsetof(struct WriteEventData, h);
+	sccb->h.function_code = SCLP_FC_NORMAL_WRITE;
+	sccb->ebh.type = EVTYP_MSG;
+	sccb->ebh.length = len - offsetof(struct WriteEventData, ebh);
+	mdb = &sccb->msg.mdb;
+	mdb->header.type = 1;
+	mdb->header.tag = 0xD4C4C240;
+	mdb->header.revision_code = 1;
+	mdb->header.length = len - offsetof(struct WriteEventData, msg.mdb.header);
+	go = &mdb->go;
+	go->length = sizeof(*go);
+	go->type = 1;
+	sclp_service_call(SCLP_CMD_WRITE_EVENT_DATA, sccb);
+}
+
+/*
+ * SCLP needs to be initialized by setting a send and receive mask,
+ * indicating which messages the control program (we) want(s) to
+ * send/receive.
+ */
 static void sclp_set_write_mask(void)
 {
 	WriteEventMask *sccb = (void *)_sccb;
 
 	sclp_mark_busy();
+	memset(_sccb, 0, sizeof(*sccb));
 	sccb->h.length = sizeof(WriteEventMask);
-	sccb->mask_length = sizeof(unsigned int);
-	sccb->receive_mask = SCLP_EVENT_MASK_MSG_ASCII;
-	sccb->cp_receive_mask = SCLP_EVENT_MASK_MSG_ASCII;
-	sccb->send_mask = SCLP_EVENT_MASK_MSG_ASCII;
-	sccb->cp_send_mask = SCLP_EVENT_MASK_MSG_ASCII;
+	sccb->h.function_code = SCLP_FC_NORMAL_WRITE;
+	sccb->mask_length = sizeof(sccb_mask_t);
+
+	/* For now we don't process sclp input. */
+	sccb->cp_receive_mask = 0;
+	/* We send ASCII and line mode. */
+	sccb->cp_send_mask = SCLP_EVENT_MASK_MSG_ASCII | SCLP_EVENT_MASK_MSG;
 
 	sclp_service_call(SCLP_CMD_WRITE_EVENT_MASK, sccb);
+	assert(sccb->h.response_code == SCLP_RC_NORMAL_COMPLETION);
 }
 
 void sclp_console_setup(void)
@@ -35,16 +179,19 @@ void sclp_console_setup(void)
 
 void sclp_print(const char *str)
 {
-	int len = strlen(str);
-	WriteEventData *sccb = (void *)_sccb;
-
-	sclp_mark_busy();
-	sccb->h.length = sizeof(WriteEventData) + len;
-	sccb->h.function_code = SCLP_FC_NORMAL_WRITE;
-	sccb->ebh.length = sizeof(EventBufferHeader) + len;
-	sccb->ebh.type = SCLP_EVENT_ASCII_CONSOLE_DATA;
-	sccb->ebh.flags = 0;
-	memcpy(sccb->data, str, len);
-
-	sclp_service_call(SCLP_CMD_WRITE_EVENT_DATA, sccb);
+	/*
+	 * z/VM advertises a vt220 console which is not functional:
+	 * (response code 05F0, "not active because of the state of
+	 * the machine"). Hence testing the masks would only work if
+	 * we also use stsi data to distinguish z/VM.
+	 *
+	 * Let's rather print on all available consoles.
+	 */
+	if (strlen(str) > (PAGE_SIZE / 2)) {
+		sclp_print_ascii("Warning: Printing is limited to 2KB of data.");
+		sclp_print_lm("Warning: Printing is limited to 2KB of data.");
+		return;
+	}
+	sclp_print_ascii(str);
+	sclp_print_lm(str);
 }
diff --git a/lib/s390x/sclp.h b/lib/s390x/sclp.h
index 63cf609..98c482a 100644
--- a/lib/s390x/sclp.h
+++ b/lib/s390x/sclp.h
@@ -179,6 +179,7 @@ typedef struct SCCB {
 /* SCLP event masks */
 #define SCLP_EVENT_MASK_SIGNAL_QUIESCE          0x00000008
 #define SCLP_EVENT_MASK_MSG_ASCII               0x00000040
+#define SCLP_EVENT_MASK_MSG          		0x40000000
 
 #define SCLP_UNCONDITIONAL_READ                 0x00
 #define SCLP_SELECTIVE_READ                     0x01
@@ -193,6 +194,55 @@ typedef struct WriteEventMask {
     uint32_t receive_mask;
 } __attribute__((packed)) WriteEventMask;
 
+#define MDBTYP_GO               0x0001
+#define MDBTYP_MTO              0x0004
+#define EVTYP_MSG               0x02
+#define LNTPFLGS_CNTLTEXT       0x8000
+#define LNTPFLGS_LABELTEXT      0x4000
+#define LNTPFLGS_DATATEXT       0x2000
+#define LNTPFLGS_ENDTEXT        0x1000
+#define LNTPFLGS_PROMPTTEXT     0x0800
+
+typedef uint32_t sccb_mask_t;
+
+/* SCLP line mode console related structures. */
+
+struct mto {
+	u16 length;
+	u16 type;
+	u16 line_type_flags;
+	u8  alarm_control;
+	u8  _reserved[3];
+} __attribute__((packed));
+
+struct go {
+	u16 length;
+	u16 type;
+	u32 domid;
+	u8  hhmmss_time[8];
+	u8  th_time[3];
+	u8  reserved_0;
+	u8  dddyyyy_date[7];
+	u8  _reserved_1;
+	u16 general_msg_flags;
+	u8  _reserved_2[10];
+	u8  originating_system_name[8];
+	u8  job_guest_name[8];
+} __attribute__((packed));
+
+struct mdb_header {
+	u16 length;
+	u16 type;
+	u32 tag;
+	u32 revision_code;
+} __attribute__((packed));
+
+struct mdb {
+	struct mdb_header header;
+	struct go go;
+	struct mto mto;
+} __attribute__((packed));
+
 typedef struct EventBufferHeader {
     uint16_t length;
     uint8_t  type;
@@ -203,7 +253,10 @@ typedef struct EventBufferHeader {
 typedef struct WriteEventData {
     SCCBHeader h;
     EventBufferHeader ebh;
-    char data[0];
+    union {
+	char data[0];
+	struct mdb mdb;
+    } msg;
 } __attribute__((packed)) WriteEventData;
 
 typedef struct ReadEventData {
-- 
2.18.1


  parent reply	other threads:[~2019-09-25 16:38 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-25 16:36 [kvm-unit-tests PULL 00/17] New s390x kvm-unit-tests and some fixes Thomas Huth
2019-09-25 16:36 ` [kvm-unit-tests PULL 01/17] s390x: Support PSW restart boot Thomas Huth
2019-09-25 16:36 ` [kvm-unit-tests PULL 02/17] s390x: Diag288 test Thomas Huth
2019-09-25 16:37 ` [kvm-unit-tests PULL 03/17] s390x: Move stsi to library Thomas Huth
2019-09-25 16:37 ` [kvm-unit-tests PULL 04/17] s390x: STSI tests Thomas Huth
2019-09-25 16:37 ` [kvm-unit-tests PULL 05/17] s390x: Add diag308 subcode 0 testing Thomas Huth
2019-09-25 16:37 ` [kvm-unit-tests PULL 06/17] s390x: Move pfmf to lib and make address void Thomas Huth
2019-09-25 16:37 ` [kvm-unit-tests PULL 07/17] s390x: Storage key library functions now take void ptr addresses Thomas Huth
2019-09-25 16:37 ` [kvm-unit-tests PULL 08/17] s390x: Bump march to zEC12 Thomas Huth
2019-09-25 16:37 ` [kvm-unit-tests PULL 09/17] s390x: Add storage key removal facility Thomas Huth
2019-09-25 16:37 ` [kvm-unit-tests PULL 10/17] s390x: Fix stsi unaligned test and add selector tests Thomas Huth
2019-09-25 16:37 ` [kvm-unit-tests PULL 11/17] s390x: Use interrupts in SCLP and add locking Thomas Huth
2019-09-25 16:37 ` Thomas Huth [this message]
2019-09-25 16:37 ` [kvm-unit-tests PULL 13/17] s390x: Add linemode buffer to fix newline on every print Thomas Huth
2019-09-25 16:37 ` [kvm-unit-tests PULL 14/17] s390x: Add initial smp code Thomas Huth
2019-09-25 16:37 ` [kvm-unit-tests PULL 15/17] s390x: Prepare for external calls Thomas Huth
2019-09-25 16:37 ` [kvm-unit-tests PULL 16/17] s390x: SMP test Thomas Huth
2019-09-25 16:37 ` [kvm-unit-tests PULL 17/17] s390x: Free allocated page in iep test Thomas Huth
2019-09-25 16:39 ` [kvm-unit-tests PULL 00/17] New s390x kvm-unit-tests and some fixes Paolo Bonzini

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=20190925163714.27519-13-thuth@redhat.com \
    --to=thuth@redhat.com \
    --cc=david@redhat.com \
    --cc=frankja@linux.ibm.com \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@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.