Re: [Qemu-devel] [PATCH 6/7] s390: sclp ascii console support

2012-07-24 Thread Blue Swirl
On Tue, Jul 24, 2012 at 7:37 AM, Christian Borntraeger
borntrae...@de.ibm.com wrote:
 From: Heinz Graalfs graa...@linux.vnet.ibm.com

 This code adds console support  by implementing SCLP's ASCII Console
 Data event. This is the same console as LPARs ASCII console or z/VMs
 sysascii.

 The console can be specified manually with something like
 -chardev stdio,id=charconsole0 -device 
 sclpconsole,chardev=charconsole0,id=console0

 Newer kernels will autodetect that console and prefer that over virtio
 console.

 When data is received from the character layer it creates a service
 interrupt to trigger a Read Event Data command from the guest that will
 pick up the received character byte-stream.
 When characters are echo'ed by the linux guest a Write Event Data occurs
 which is forwarded by the Event Facility to the console that supports
 a corresponding mask value.
 Console resizing is not supported.
 The character layer byte-stream is buffered using a fixed size iov
 buffer.

 Signed-off-by: Heinz Graalfs graa...@linux.vnet.ibm.com
 Signed-off-by: Christian Borntraeger borntrae...@de.ibm.com
 ---
  hw/s390x/Makefile.objs |2 +-
  hw/s390x/sclpconsole.c |  323 
 
  2 files changed, 324 insertions(+), 1 deletions(-)
  create mode 100644 hw/s390x/sclpconsole.c

 diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
 index ed4e61a..096dfcd 100644
 --- a/hw/s390x/Makefile.objs
 +++ b/hw/s390x/Makefile.objs
 @@ -3,4 +3,4 @@ obj-y = s390-virtio-bus.o s390-virtio.o
  obj-y := $(addprefix ../,$(obj-y))
  obj-y += sclp.o
  obj-y += event-facility.o
 -obj-y += sclpquiesce.o
 +obj-y += sclpquiesce.o sclpconsole.o
 diff --git a/hw/s390x/sclpconsole.c b/hw/s390x/sclpconsole.c
 new file mode 100644
 index 000..9a57032
 --- /dev/null
 +++ b/hw/s390x/sclpconsole.c
 @@ -0,0 +1,323 @@
 +/*
 + * SCLP event type
 + *Ascii Console Data (VT220 Console)
 + *
 + * Copyright IBM, Corp. 2012
 + *
 + * Authors:
 + *  Heinz Graalfs graa...@de.ibm.com
 + *
 + * This work is licensed under the terms of the GNU GPL, version 2 or (at 
 your
 + * option) any later version.  See the COPYING file in the top-level 
 directory.
 + *
 + */
 +
 +#include hw/qdev.h
 +#include qemu-thread.h
 +
 +#include sclp.h
 +#include event-facility.h
 +
 +typedef struct ASCIIConsoleData {
 +EventBufferHeader ebh;
 +char data[0];
 +} QEMU_PACKED ASCIIConsoleData;
 +
 +qemu_irq sclp_read_vt220;

This should go into SCLPConsole.

 +
 +/* max size for ASCII data in 4K SCCB page */
 +#define SIZE_BUFFER_VT220 4080
 +
 +typedef struct SCLPConsole {
 +SCLPEvent event;
 +CharDriverState *chr;
 +/* io vector   */
 +uint8_t *iov;   /* iov buffer pointer  */
 +uint8_t *iov_sclp;  /* pointer to SCLP read offset */
 +uint8_t *iov_bs;/* pointer byte stream read offset */
 +uint32_t iov_data_len;  /* length of byte stream in buffer */
 +uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP */
 +} SCLPConsole;
 +
 +/* character layer call-back functions */
 +
 +/* Return number of bytes that fit into iov buffer */
 +static int chr_can_read(void *opaque)
 +{
 +int can_read;
 +SCLPConsole *scon = opaque;
 +
 +qemu_mutex_lock(scon-event.lock);
 +can_read = SIZE_BUFFER_VT220 - scon-iov_data_len;
 +qemu_mutex_unlock(scon-event.lock);
 +
 +return can_read;
 +}
 +
 +/* Receive n bytes from character layer, save in iov buffer,
 + * and set event pending */
 +static void receive_from_chr_layer(void *opaque, const uint8_t *buf, int 
 size)
 +{
 +SCLPConsole *scon = opaque;
 +
 +assert(scon-iov);
 +
 +qemu_mutex_lock(scon-event.lock);
 +
 +/* if new data do not fit into current buffer */
 +if (scon-iov_data_len + size  SIZE_BUFFER_VT220) {
 +/* character layer sent more than allowed */
 +qemu_mutex_unlock(scon-event.lock);
 +return;
 +}
 +/* put byte-stream from character layer into buffer */
 +memcpy(scon-iov_bs, buf, size);
 +scon-iov_data_len += size;
 +scon-iov_sclp_rest += size;
 +scon-iov_bs += size;
 +scon-event.event_pending = true;
 +
 +qemu_mutex_unlock(scon-event.lock);
 +}
 +
 +/* Send data from a char device over to the guest */
 +static void chr_read(void *opaque, const uint8_t *buf, int size)
 +{
 +assert(opaque);
 +

I'd convert the opaque to SCLPConsole here and use that for
receive_from_chr_layer() instead of opaque.

 +receive_from_chr_layer(opaque, buf, size);
 +/* trigger SCLP read operation */
 +qemu_irq_raise(sclp_read_vt220);
 +}
 +
 +static void chr_event(void *opaque, int event)
 +{
 +SCLPConsole *scon = opaque;
 +
 +switch (event) {
 +case CHR_EVENT_OPENED:
 +if (!scon-iov) {
 +scon-iov = g_malloc0(SIZE_BUFFER_VT220);
 +scon-iov_sclp = scon-iov;
 +

[Qemu-devel] [PATCH 6/7] s390: sclp ascii console support

2012-07-24 Thread Christian Borntraeger
From: Heinz Graalfs graa...@linux.vnet.ibm.com

This code adds console support  by implementing SCLP's ASCII Console
Data event. This is the same console as LPARs ASCII console or z/VMs
sysascii.

The console can be specified manually with something like
-chardev stdio,id=charconsole0 -device 
sclpconsole,chardev=charconsole0,id=console0

Newer kernels will autodetect that console and prefer that over virtio
console.

When data is received from the character layer it creates a service
interrupt to trigger a Read Event Data command from the guest that will
pick up the received character byte-stream.
When characters are echo'ed by the linux guest a Write Event Data occurs
which is forwarded by the Event Facility to the console that supports
a corresponding mask value.
Console resizing is not supported.
The character layer byte-stream is buffered using a fixed size iov
buffer.

Signed-off-by: Heinz Graalfs graa...@linux.vnet.ibm.com
Signed-off-by: Christian Borntraeger borntrae...@de.ibm.com
---
 hw/s390x/Makefile.objs |2 +-
 hw/s390x/sclpconsole.c |  323 
 2 files changed, 324 insertions(+), 1 deletions(-)
 create mode 100644 hw/s390x/sclpconsole.c

diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index ed4e61a..096dfcd 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -3,4 +3,4 @@ obj-y = s390-virtio-bus.o s390-virtio.o
 obj-y := $(addprefix ../,$(obj-y))
 obj-y += sclp.o
 obj-y += event-facility.o
-obj-y += sclpquiesce.o
+obj-y += sclpquiesce.o sclpconsole.o
diff --git a/hw/s390x/sclpconsole.c b/hw/s390x/sclpconsole.c
new file mode 100644
index 000..9a57032
--- /dev/null
+++ b/hw/s390x/sclpconsole.c
@@ -0,0 +1,323 @@
+/*
+ * SCLP event type
+ *Ascii Console Data (VT220 Console)
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Heinz Graalfs graa...@de.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at your
+ * option) any later version.  See the COPYING file in the top-level directory.
+ *
+ */
+
+#include hw/qdev.h
+#include qemu-thread.h
+
+#include sclp.h
+#include event-facility.h
+
+typedef struct ASCIIConsoleData {
+EventBufferHeader ebh;
+char data[0];
+} QEMU_PACKED ASCIIConsoleData;
+
+qemu_irq sclp_read_vt220;
+
+/* max size for ASCII data in 4K SCCB page */
+#define SIZE_BUFFER_VT220 4080
+
+typedef struct SCLPConsole {
+SCLPEvent event;
+CharDriverState *chr;
+/* io vector   */
+uint8_t *iov;   /* iov buffer pointer  */
+uint8_t *iov_sclp;  /* pointer to SCLP read offset */
+uint8_t *iov_bs;/* pointer byte stream read offset */
+uint32_t iov_data_len;  /* length of byte stream in buffer */
+uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP */
+} SCLPConsole;
+
+/* character layer call-back functions */
+
+/* Return number of bytes that fit into iov buffer */
+static int chr_can_read(void *opaque)
+{
+int can_read;
+SCLPConsole *scon = opaque;
+
+qemu_mutex_lock(scon-event.lock);
+can_read = SIZE_BUFFER_VT220 - scon-iov_data_len;
+qemu_mutex_unlock(scon-event.lock);
+
+return can_read;
+}
+
+/* Receive n bytes from character layer, save in iov buffer,
+ * and set event pending */
+static void receive_from_chr_layer(void *opaque, const uint8_t *buf, int size)
+{
+SCLPConsole *scon = opaque;
+
+assert(scon-iov);
+
+qemu_mutex_lock(scon-event.lock);
+
+/* if new data do not fit into current buffer */
+if (scon-iov_data_len + size  SIZE_BUFFER_VT220) {
+/* character layer sent more than allowed */
+qemu_mutex_unlock(scon-event.lock);
+return;
+}
+/* put byte-stream from character layer into buffer */
+memcpy(scon-iov_bs, buf, size);
+scon-iov_data_len += size;
+scon-iov_sclp_rest += size;
+scon-iov_bs += size;
+scon-event.event_pending = true;
+
+qemu_mutex_unlock(scon-event.lock);
+}
+
+/* Send data from a char device over to the guest */
+static void chr_read(void *opaque, const uint8_t *buf, int size)
+{
+assert(opaque);
+
+receive_from_chr_layer(opaque, buf, size);
+/* trigger SCLP read operation */
+qemu_irq_raise(sclp_read_vt220);
+}
+
+static void chr_event(void *opaque, int event)
+{
+SCLPConsole *scon = opaque;
+
+switch (event) {
+case CHR_EVENT_OPENED:
+if (!scon-iov) {
+scon-iov = g_malloc0(SIZE_BUFFER_VT220);
+scon-iov_sclp = scon-iov;
+scon-iov_bs = scon-iov;
+scon-iov_data_len = 0;
+scon-iov_sclp_rest = 0;
+}
+break;
+case CHR_EVENT_CLOSED:
+if (scon-iov) {
+g_free(scon-iov);
+scon-iov = NULL;
+}
+break;
+}
+}
+
+/* functions to be called by event facility */
+
+static int event_type(void)
+{
+return