On 29.10.2012, at 13:13, Jens Freimann wrote: > From: Heinz Graalfs <[email protected]> > > 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 <[email protected]> > Signed-off-by: Christian Borntraeger <[email protected]> > Signed-off-by: Jens Freimann <[email protected]> > --- > hw/s390x/Makefile.objs | 2 +- > hw/s390x/sclpconsole.c | 306 +++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 307 insertions(+), 1 deletion(-) > 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 0000000..0ec5623 > --- /dev/null > +++ b/hw/s390x/sclpconsole.c > @@ -0,0 +1,306 @@ > +/* > + * SCLP event type > + * Ascii Console Data (VT220 Console) > + * > + * Copyright IBM, Corp. 2012 > + * > + * Authors: > + * Heinz Graalfs <[email protected]> > + * > + * 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; > + > +/* 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 */ > + qemu_irq irq_read_vt220; > +} 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; > + > + can_read = SIZE_BUFFER_VT220 - scon->iov_data_len; > + > + return can_read; > +} > + > +/* Receive n bytes from character layer, save in iov buffer, > + * and set event pending */ > +static void receive_from_chr_layer(SCLPConsole *scon, const uint8_t *buf, > + int size) > +{ > + assert(scon->iov); > + > + /* read data must fit into current buffer */ > + assert(size <= SIZE_BUFFER_VT220 - scon->iov_data_len); > + > + /* 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; > +} > + > +/* Send data from a char device over to the guest */ > +static void chr_read(void *opaque, const uint8_t *buf, int size) > +{ > + SCLPConsole *scon = opaque; > + > + assert(scon); > + > + receive_from_chr_layer(scon, buf, size); > + /* trigger SCLP read operation */ > + qemu_irq_raise(scon->irq_read_vt220);
I don't think you need to model this through a qemu_irq here. Just directly call your interrupt injection function. Maybe we want to later add real payloaded s390 style qemu_s390_irq support. By that time we can reconsider that decision. Either way, the code as is is functional, so I'll apply it nevertheless :) Alex
