* [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console @ 2013-09-18 10:19 Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 01/11] s390/sclpconsole: modify definition of input buffer Christian Borntraeger ` (11 more replies) 0 siblings, 12 replies; 18+ messages in thread From: Christian Borntraeger @ 2013-09-18 10:19 UTC (permalink / raw) To: Alexander Graf Cc: Christian Borntraeger, Jens Freimann, Heinz Graalfs, qemu-devel Alex, here is a bunch of fixes/changes for sclp/eventfacility followed by a move of the ebcdic conversion into a stand-alone header file and the sclp line mode console. Christian Borntraeger (3): s390/eventfacility: Fix receive/send masks s390/eventfacility: remove unused event_type variable s390/eventfacility: allow childs to handle more than 1 event type Heinz Graalfs (7): s390/sclpconsole: modify definition of input buffer s390/sclpconsole: Add code to support live migration for sclpconsole s390/sclpquiesce: Add code to support live migration s390/event-facility: Add code to support live migration s390/sclp: add reset() functions s390/ebcdic: Move conversion tables to header file s390/sclplmconsole: Add support for SCLP line-mode console Ralf Hoppe (1): s390/eventfacility: fix multiple Read Event Data sources hw/char/Makefile.objs | 2 +- hw/char/sclpconsole-lm.c | 393 ++++++++++++++++++++++++++++++++++++++ hw/char/sclpconsole.c | 89 ++++----- hw/s390x/event-facility.c | 30 ++- hw/s390x/sclpquiesce.c | 30 ++- include/hw/s390x/ebcdic.h | 107 +++++++++++ include/hw/s390x/event-facility.h | 86 ++++++++- target-s390x/misc_helper.c | 81 +------- 8 files changed, 678 insertions(+), 140 deletions(-) create mode 100644 hw/char/sclpconsole-lm.c create mode 100644 include/hw/s390x/ebcdic.h -- 1.8.3.1 ^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 01/11] s390/sclpconsole: modify definition of input buffer 2013-09-18 10:19 [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console Christian Borntraeger @ 2013-09-18 10:19 ` Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 02/11] s390/sclpconsole: Add code to support live migration for sclpconsole Christian Borntraeger ` (10 subsequent siblings) 11 siblings, 0 replies; 18+ messages in thread From: Christian Borntraeger @ 2013-09-18 10:19 UTC (permalink / raw) To: Alexander Graf Cc: Christian Borntraeger, Jens Freimann, Heinz Graalfs, qemu-devel From: Heinz Graalfs <graalfs@linux.vnet.ibm.com> To use VMState for migration, we need to adapt some sclp code: - allocate console buffer as part of the console - change semantic of sclpconsole offset fields Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> --- hw/char/sclpconsole.c | 54 +++++++++++++++------------------------------------ 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c index eb3988c..fd270be 100644 --- a/hw/char/sclpconsole.c +++ b/hw/char/sclpconsole.c @@ -31,12 +31,11 @@ typedef struct ASCIIConsoleData { 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 */ + uint8_t iov[SIZE_BUFFER_VT220]; + uint32_t iov_sclp; /* offset in buf for SCLP read operation */ + uint32_t iov_bs; /* offset in buf for char layer read operation */ + 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; @@ -47,7 +46,7 @@ static int chr_can_read(void *opaque) { SCLPConsole *scon = opaque; - return scon->iov ? SIZE_BUFFER_VT220 - scon->iov_data_len : 0; + return SIZE_BUFFER_VT220 - scon->iov_data_len; } /* Receive n bytes from character layer, save in iov buffer, @@ -55,13 +54,11 @@ static int chr_can_read(void *opaque) 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); + memcpy(&scon->iov[scon->iov_bs], buf, size); scon->iov_data_len += size; scon->iov_sclp_rest += size; scon->iov_bs += size; @@ -80,29 +77,6 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) qemu_irq_raise(scon->irq_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) @@ -134,17 +108,17 @@ static void get_console_data(SCLPEvent *event, uint8_t *buf, size_t *size, /* if all data fit into provided SCLP buffer */ if (avail >= cons->iov_sclp_rest) { /* copy character byte-stream to SCLP buffer */ - memcpy(buf, cons->iov_sclp, cons->iov_sclp_rest); + memcpy(buf, &cons->iov[cons->iov_sclp], cons->iov_sclp_rest); *size = cons->iov_sclp_rest + 1; - cons->iov_sclp = cons->iov; - cons->iov_bs = cons->iov; + cons->iov_sclp = 0; + cons->iov_bs = 0; cons->iov_data_len = 0; cons->iov_sclp_rest = 0; event->event_pending = false; /* data provided and no more data pending */ } else { /* if provided buffer is too small, just copy part */ - memcpy(buf, cons->iov_sclp, avail); + memcpy(buf, &cons->iov[cons->iov_sclp], avail); *size = avail + 1; cons->iov_sclp_rest -= avail; cons->iov_sclp += avail; @@ -237,10 +211,14 @@ static int console_init(SCLPEvent *event) return -1; } console_available = true; + scon->iov_sclp = 0; + scon->iov_bs = 0; + scon->iov_data_len = 0; + scon->iov_sclp_rest = 0; event->event_type = SCLP_EVENT_ASCII_CONSOLE_DATA; if (scon->chr) { qemu_chr_add_handlers(scon->chr, chr_can_read, - chr_read, chr_event, scon); + chr_read, NULL, scon); } scon->irq_read_vt220 = *qemu_allocate_irqs(trigger_ascii_console_data, NULL, 1); -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 02/11] s390/sclpconsole: Add code to support live migration for sclpconsole 2013-09-18 10:19 [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 01/11] s390/sclpconsole: modify definition of input buffer Christian Borntraeger @ 2013-09-18 10:19 ` Christian Borntraeger 2013-09-20 3:07 ` Alexander Graf 2013-09-18 10:19 ` [Qemu-devel] [PATCH 03/11] s390/sclpquiesce: Add code to support live migration Christian Borntraeger ` (9 subsequent siblings) 11 siblings, 1 reply; 18+ messages in thread From: Christian Borntraeger @ 2013-09-18 10:19 UTC (permalink / raw) To: Alexander Graf Cc: Christian Borntraeger, Jens Freimann, Heinz Graalfs, qemu-devel From: Heinz Graalfs <graalfs@linux.vnet.ibm.com> This patch adds the necessary life migration pieces to the sclp code by using vmstate_register. Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> --- hw/char/sclpconsole.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c index fd270be..856230f 100644 --- a/hw/char/sclpconsole.c +++ b/hw/char/sclpconsole.c @@ -197,9 +197,26 @@ static void trigger_ascii_console_data(void *opaque, int n, int level) sclp_service_interrupt(0); } +static const VMStateDescription vmstate_sclpconsole = { + .name = "sclpconsole", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_BOOL(event.event_pending, SCLPConsole), + VMSTATE_UINT8_ARRAY(iov, SCLPConsole, SIZE_BUFFER_VT220), + VMSTATE_UINT32(iov_sclp, SCLPConsole), + VMSTATE_UINT32(iov_bs, SCLPConsole), + VMSTATE_UINT32(iov_data_len, SCLPConsole), + VMSTATE_UINT32(iov_sclp_rest, SCLPConsole), + VMSTATE_END_OF_LIST() + } +}; + /* qemu object creation and initialization functions */ /* tell character layer our call-back functions */ + static int console_init(SCLPEvent *event) { static bool console_available; @@ -223,7 +240,7 @@ static int console_init(SCLPEvent *event) scon->irq_read_vt220 = *qemu_allocate_irqs(trigger_ascii_console_data, NULL, 1); - return 0; + return vmstate_register(NULL, 0, &vmstate_sclpconsole, scon); } static int console_exit(SCLPEvent *event) -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] s390/sclpconsole: Add code to support live migration for sclpconsole 2013-09-18 10:19 ` [Qemu-devel] [PATCH 02/11] s390/sclpconsole: Add code to support live migration for sclpconsole Christian Borntraeger @ 2013-09-20 3:07 ` Alexander Graf 2013-09-20 3:24 ` Anthony Liguori 0 siblings, 1 reply; 18+ messages in thread From: Alexander Graf @ 2013-09-20 3:07 UTC (permalink / raw) To: Christian Borntraeger Cc: Jens Freimann, Heinz Graalfs, qemu-devel, Anthony Liguori On 18.09.2013, at 05:19, Christian Borntraeger wrote: > From: Heinz Graalfs <graalfs@linux.vnet.ibm.com> > > This patch adds the necessary life migration pieces to the sclp code > by using vmstate_register. > > Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com> > Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> > --- > hw/char/sclpconsole.c | 19 ++++++++++++++++++- > 1 file changed, 18 insertions(+), 1 deletion(-) > > diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c > index fd270be..856230f 100644 > --- a/hw/char/sclpconsole.c > +++ b/hw/char/sclpconsole.c > @@ -197,9 +197,26 @@ static void trigger_ascii_console_data(void *opaque, int n, int level) > sclp_service_interrupt(0); > } > > +static const VMStateDescription vmstate_sclpconsole = { > + .name = "sclpconsole", > + .version_id = 0, > + .minimum_version_id = 0, > + .minimum_version_id_old = 0, > + .fields = (VMStateField[]) { > + VMSTATE_BOOL(event.event_pending, SCLPConsole), > + VMSTATE_UINT8_ARRAY(iov, SCLPConsole, SIZE_BUFFER_VT220), > + VMSTATE_UINT32(iov_sclp, SCLPConsole), > + VMSTATE_UINT32(iov_bs, SCLPConsole), > + VMSTATE_UINT32(iov_data_len, SCLPConsole), > + VMSTATE_UINT32(iov_sclp_rest, SCLPConsole), > + VMSTATE_END_OF_LIST() > + } > +}; > + > /* qemu object creation and initialization functions */ > > /* tell character layer our call-back functions */ > + > static int console_init(SCLPEvent *event) > { > static bool console_available; > @@ -223,7 +240,7 @@ static int console_init(SCLPEvent *event) > scon->irq_read_vt220 = *qemu_allocate_irqs(trigger_ascii_console_data, > NULL, 1); > > - return 0; > + return vmstate_register(NULL, 0, &vmstate_sclpconsole, scon); If I understand Anthony correctly a vmstate_register() call means you didn't convert something to QOM correctly :). Alex ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] s390/sclpconsole: Add code to support live migration for sclpconsole 2013-09-20 3:07 ` Alexander Graf @ 2013-09-20 3:24 ` Anthony Liguori 0 siblings, 0 replies; 18+ messages in thread From: Anthony Liguori @ 2013-09-20 3:24 UTC (permalink / raw) To: Alexander Graf Cc: Christian Borntraeger, Jens Freimann, Heinz Graalfs, qemu-devel On Thu, Sep 19, 2013 at 10:07 PM, Alexander Graf <agraf@suse.de> wrote: > > On 18.09.2013, at 05:19, Christian Borntraeger wrote: > >> From: Heinz Graalfs <graalfs@linux.vnet.ibm.com> >> >> This patch adds the necessary life migration pieces to the sclp code >> by using vmstate_register. >> >> Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com> >> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> >> --- >> hw/char/sclpconsole.c | 19 ++++++++++++++++++- >> 1 file changed, 18 insertions(+), 1 deletion(-) >> >> diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c >> index fd270be..856230f 100644 >> --- a/hw/char/sclpconsole.c >> +++ b/hw/char/sclpconsole.c >> @@ -197,9 +197,26 @@ static void trigger_ascii_console_data(void *opaque, int n, int level) >> sclp_service_interrupt(0); >> } >> >> +static const VMStateDescription vmstate_sclpconsole = { >> + .name = "sclpconsole", >> + .version_id = 0, >> + .minimum_version_id = 0, >> + .minimum_version_id_old = 0, >> + .fields = (VMStateField[]) { >> + VMSTATE_BOOL(event.event_pending, SCLPConsole), >> + VMSTATE_UINT8_ARRAY(iov, SCLPConsole, SIZE_BUFFER_VT220), >> + VMSTATE_UINT32(iov_sclp, SCLPConsole), >> + VMSTATE_UINT32(iov_bs, SCLPConsole), >> + VMSTATE_UINT32(iov_data_len, SCLPConsole), >> + VMSTATE_UINT32(iov_sclp_rest, SCLPConsole), >> + VMSTATE_END_OF_LIST() >> + } >> +}; >> + >> /* qemu object creation and initialization functions */ >> >> /* tell character layer our call-back functions */ >> + >> static int console_init(SCLPEvent *event) >> { >> static bool console_available; >> @@ -223,7 +240,7 @@ static int console_init(SCLPEvent *event) >> scon->irq_read_vt220 = *qemu_allocate_irqs(trigger_ascii_console_data, >> NULL, 1); >> >> - return 0; >> + return vmstate_register(NULL, 0, &vmstate_sclpconsole, scon); > > If I understand Anthony correctly a vmstate_register() call means you didn't convert something to QOM correctly :). In this case, the line is just wrong. In console_class_init, you should assign dc->vmsd = &vmstate_slcpconsole. Regards, Anthony Liguori > > > Alex > ^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 03/11] s390/sclpquiesce: Add code to support live migration 2013-09-18 10:19 [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 01/11] s390/sclpconsole: modify definition of input buffer Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 02/11] s390/sclpconsole: Add code to support live migration for sclpconsole Christian Borntraeger @ 2013-09-18 10:19 ` Christian Borntraeger 2013-09-20 3:08 ` Alexander Graf 2013-09-18 10:19 ` [Qemu-devel] [PATCH 04/11] s390/event-facility: " Christian Borntraeger ` (8 subsequent siblings) 11 siblings, 1 reply; 18+ messages in thread From: Christian Borntraeger @ 2013-09-18 10:19 UTC (permalink / raw) To: Alexander Graf Cc: Christian Borntraeger, Jens Freimann, Heinz Graalfs, qemu-devel From: Heinz Graalfs <graalfs@linux.vnet.ibm.com> This patch adds the necessary life migration pieces to sclpquiesce by using the vmstate_register. Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> --- hw/s390x/sclpquiesce.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/hw/s390x/sclpquiesce.c b/hw/s390x/sclpquiesce.c index 5fadc86..eba0e6e 100644 --- a/hw/s390x/sclpquiesce.c +++ b/hw/s390x/sclpquiesce.c @@ -65,6 +65,17 @@ static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr, return 1; } +static const VMStateDescription vmstate_sclpquiesce = { + .name = "sclpquiesce", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_BOOL(event_pending, SCLPEvent), + VMSTATE_END_OF_LIST() + } +}; + typedef struct QuiesceNotifier QuiesceNotifier; static struct QuiesceNotifier { @@ -91,7 +102,7 @@ static int quiesce_init(SCLPEvent *event) qemu_register_powerdown_notifier(&qn.notifier); - return 0; + return vmstate_register(NULL, 0, &vmstate_sclpquiesce, event); } static void quiesce_class_init(ObjectClass *klass, void *data) -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 03/11] s390/sclpquiesce: Add code to support live migration 2013-09-18 10:19 ` [Qemu-devel] [PATCH 03/11] s390/sclpquiesce: Add code to support live migration Christian Borntraeger @ 2013-09-20 3:08 ` Alexander Graf 0 siblings, 0 replies; 18+ messages in thread From: Alexander Graf @ 2013-09-20 3:08 UTC (permalink / raw) To: Christian Borntraeger; +Cc: Jens Freimann, Heinz Graalfs, qemu-devel On 18.09.2013, at 05:19, Christian Borntraeger wrote: > From: Heinz Graalfs <graalfs@linux.vnet.ibm.com> > > This patch adds the necessary life migration pieces to sclpquiesce > by using the vmstate_register. > > Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com> > Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> > --- > hw/s390x/sclpquiesce.c | 13 ++++++++++++- > 1 file changed, 12 insertions(+), 1 deletion(-) > > diff --git a/hw/s390x/sclpquiesce.c b/hw/s390x/sclpquiesce.c > index 5fadc86..eba0e6e 100644 > --- a/hw/s390x/sclpquiesce.c > +++ b/hw/s390x/sclpquiesce.c > @@ -65,6 +65,17 @@ static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr, > return 1; > } > > +static const VMStateDescription vmstate_sclpquiesce = { > + .name = "sclpquiesce", > + .version_id = 0, > + .minimum_version_id = 0, > + .minimum_version_id_old = 0, > + .fields = (VMStateField[]) { > + VMSTATE_BOOL(event_pending, SCLPEvent), > + VMSTATE_END_OF_LIST() > + } > +}; > + > typedef struct QuiesceNotifier QuiesceNotifier; > > static struct QuiesceNotifier { > @@ -91,7 +102,7 @@ static int quiesce_init(SCLPEvent *event) > > qemu_register_powerdown_notifier(&qn.notifier); > > - return 0; > + return vmstate_register(NULL, 0, &vmstate_sclpquiesce, event); Same thing here. Maybe this should be a device? Alex > } > > static void quiesce_class_init(ObjectClass *klass, void *data) > -- > 1.8.3.1 > ^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 04/11] s390/event-facility: Add code to support live migration 2013-09-18 10:19 [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console Christian Borntraeger ` (2 preceding siblings ...) 2013-09-18 10:19 ` [Qemu-devel] [PATCH 03/11] s390/sclpquiesce: Add code to support live migration Christian Borntraeger @ 2013-09-18 10:19 ` Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 05/11] s390/sclp: add reset() functions Christian Borntraeger ` (7 subsequent siblings) 11 siblings, 0 replies; 18+ messages in thread From: Christian Borntraeger @ 2013-09-18 10:19 UTC (permalink / raw) To: Alexander Graf Cc: Christian Borntraeger, Jens Freimann, Heinz Graalfs, qemu-devel From: Heinz Graalfs <graalfs@linux.vnet.ibm.com> This patch adds the necessary life migration pieces to the event facility by using the vmstate_register. Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> --- hw/s390x/event-facility.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c index a3aceef..225b42c 100644 --- a/hw/s390x/event-facility.c +++ b/hw/s390x/event-facility.c @@ -313,6 +313,17 @@ static void command_handler(SCLPEventFacility *ef, SCCB *sccb, uint64_t code) } } +static const VMStateDescription vmstate_eventfacility = { + .name = "sclpeventfacility", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT32(receive_mask, SCLPEventFacility), + VMSTATE_END_OF_LIST() + } +}; + static int init_event_facility(S390SCLPDevice *sdev) { SCLPEventFacility *event_facility; @@ -335,7 +346,7 @@ static int init_event_facility(S390SCLPDevice *sdev) } qdev_init_nofail(quiesce); - return 0; + return vmstate_register(NULL, 0, &vmstate_eventfacility, sdev->ef); } static void init_event_facility_class(ObjectClass *klass, void *data) -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 05/11] s390/sclp: add reset() functions 2013-09-18 10:19 [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console Christian Borntraeger ` (3 preceding siblings ...) 2013-09-18 10:19 ` [Qemu-devel] [PATCH 04/11] s390/event-facility: " Christian Borntraeger @ 2013-09-18 10:19 ` Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 06/11] s390/eventfacility: fix multiple Read Event Data sources Christian Borntraeger ` (6 subsequent siblings) 11 siblings, 0 replies; 18+ messages in thread From: Christian Borntraeger @ 2013-09-18 10:19 UTC (permalink / raw) To: Alexander Graf Cc: Christian Borntraeger, Jens Freimann, Heinz Graalfs, qemu-devel From: Heinz Graalfs <graalfs@linux.vnet.ibm.com> Add reset() functions for event-facility, sclpconsole, and sclpquiesce. The reset() functions perform variable initialization at IPL and e.g. when monitor system_reset is called. Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com> Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> --- hw/char/sclpconsole.c | 17 +++++++++++++---- hw/s390x/event-facility.c | 9 +++++++++ hw/s390x/sclpquiesce.c | 9 +++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c index 856230f..138b017 100644 --- a/hw/char/sclpconsole.c +++ b/hw/char/sclpconsole.c @@ -228,10 +228,6 @@ static int console_init(SCLPEvent *event) return -1; } console_available = true; - scon->iov_sclp = 0; - scon->iov_bs = 0; - scon->iov_data_len = 0; - scon->iov_sclp_rest = 0; event->event_type = SCLP_EVENT_ASCII_CONSOLE_DATA; if (scon->chr) { qemu_chr_add_handlers(scon->chr, chr_can_read, @@ -243,6 +239,18 @@ static int console_init(SCLPEvent *event) return vmstate_register(NULL, 0, &vmstate_sclpconsole, scon); } +static void console_reset(DeviceState *dev) +{ + SCLPEvent *event = SCLP_EVENT(dev); + SCLPConsole *scon = DO_UPCAST(SCLPConsole, event, event); + + event->event_pending = false; + scon->iov_sclp = 0; + scon->iov_bs = 0; + scon->iov_data_len = 0; + scon->iov_sclp_rest = 0; +} + static int console_exit(SCLPEvent *event) { return 0; @@ -259,6 +267,7 @@ static void console_class_init(ObjectClass *klass, void *data) SCLPEventClass *ec = SCLP_EVENT_CLASS(klass); dc->props = console_properties; + dc->reset = console_reset; ec->init = console_init; ec->exit = console_exit; ec->get_send_mask = send_mask; diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c index 225b42c..c8f62bf 100644 --- a/hw/s390x/event-facility.c +++ b/hw/s390x/event-facility.c @@ -349,10 +349,19 @@ static int init_event_facility(S390SCLPDevice *sdev) return vmstate_register(NULL, 0, &vmstate_eventfacility, sdev->ef); } +static void reset_event_facility(DeviceState *dev) +{ + S390SCLPDevice *sdev = SCLP_S390_DEVICE(dev); + + sdev->ef->receive_mask = 0; +} + static void init_event_facility_class(ObjectClass *klass, void *data) { + DeviceClass *dc = DEVICE_CLASS(klass); S390SCLPDeviceClass *k = SCLP_S390_DEVICE_CLASS(klass); + dc->reset = reset_event_facility; k->init = init_event_facility; } diff --git a/hw/s390x/sclpquiesce.c b/hw/s390x/sclpquiesce.c index eba0e6e..8981f4a 100644 --- a/hw/s390x/sclpquiesce.c +++ b/hw/s390x/sclpquiesce.c @@ -105,10 +105,19 @@ static int quiesce_init(SCLPEvent *event) return vmstate_register(NULL, 0, &vmstate_sclpquiesce, event); } +static void quiesce_reset(DeviceState *dev) +{ + SCLPEvent *event = SCLP_EVENT(dev); + + event->event_pending = false; +} + static void quiesce_class_init(ObjectClass *klass, void *data) { + DeviceClass *dc = DEVICE_CLASS(klass); SCLPEventClass *k = SCLP_EVENT_CLASS(klass); + dc->reset = quiesce_reset; k->init = quiesce_init; k->get_send_mask = send_mask; -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 06/11] s390/eventfacility: fix multiple Read Event Data sources 2013-09-18 10:19 [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console Christian Borntraeger ` (4 preceding siblings ...) 2013-09-18 10:19 ` [Qemu-devel] [PATCH 05/11] s390/sclp: add reset() functions Christian Borntraeger @ 2013-09-18 10:19 ` Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 07/11] s390/eventfacility: Fix receive/send masks Christian Borntraeger ` (5 subsequent siblings) 11 siblings, 0 replies; 18+ messages in thread From: Christian Borntraeger @ 2013-09-18 10:19 UTC (permalink / raw) To: Alexander Graf Cc: Christian Borntraeger, Jens Freimann, Heinz Graalfs, Ralf Hoppe, qemu-devel From: Ralf Hoppe <rhoppe@de.ibm.com> Make the handler for SCLP Read Event Data deal with notifications for multiple sources correctly. Signed-off-by: Ralf Hoppe <rhoppe@de.ibm.com> Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> [split bigger patch into smaller independent chunks] --- hw/s390x/event-facility.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c index c8f62bf..4347a48 100644 --- a/hw/s390x/event-facility.c +++ b/hw/s390x/event-facility.c @@ -183,7 +183,7 @@ static uint16_t handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb, { uint16_t rc; int slen; - unsigned elen = 0; + unsigned elen; BusChild *kid; SCLPEvent *event; SCLPEventClass *ec; @@ -203,11 +203,11 @@ static uint16_t handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb, if (mask & ec->get_send_mask()) { if (ec->read_event_data(event, event_buf, &slen)) { + elen = be16_to_cpu(event_buf->length); + event_buf = (EventBufferHeader *) ((char *)event_buf + elen); rc = SCLP_RC_NORMAL_COMPLETION; } } - elen = be16_to_cpu(event_buf->length); - event_buf = (void *) event_buf + elen; } if (sccb->h.control_mask[2] & SCLP_VARIABLE_LENGTH_RESPONSE) { -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 07/11] s390/eventfacility: Fix receive/send masks 2013-09-18 10:19 [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console Christian Borntraeger ` (5 preceding siblings ...) 2013-09-18 10:19 ` [Qemu-devel] [PATCH 06/11] s390/eventfacility: fix multiple Read Event Data sources Christian Borntraeger @ 2013-09-18 10:19 ` Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 08/11] s390/eventfacility: remove unused event_type variable Christian Borntraeger ` (4 subsequent siblings) 11 siblings, 0 replies; 18+ messages in thread From: Christian Borntraeger @ 2013-09-18 10:19 UTC (permalink / raw) To: Alexander Graf Cc: Christian Borntraeger, Jens Freimann, Heinz Graalfs, qemu-devel Currently we announce interchanged receive/send masks. This did not trigger a bug, since the sclp console has the same masks for send/receive and the Linux guest does not check the sclp mask for simple events like quiesce. With other event users like the sclp line mode console, we will have different send/receive bits. Fix it. Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> --- include/hw/s390x/event-facility.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hw/s390x/event-facility.h b/include/hw/s390x/event-facility.h index 791ab2a..727ef4f 100644 --- a/include/hw/s390x/event-facility.h +++ b/include/hw/s390x/event-facility.h @@ -43,8 +43,8 @@ typedef struct WriteEventMask { uint16_t mask_length; uint32_t cp_receive_mask; uint32_t cp_send_mask; - uint32_t send_mask; uint32_t receive_mask; + uint32_t send_mask; } QEMU_PACKED WriteEventMask; typedef struct EventBufferHeader { -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 08/11] s390/eventfacility: remove unused event_type variable 2013-09-18 10:19 [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console Christian Borntraeger ` (6 preceding siblings ...) 2013-09-18 10:19 ` [Qemu-devel] [PATCH 07/11] s390/eventfacility: Fix receive/send masks Christian Borntraeger @ 2013-09-18 10:19 ` Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 09/11] s390/eventfacility: allow childs to handle more than 1 event type Christian Borntraeger ` (3 subsequent siblings) 11 siblings, 0 replies; 18+ messages in thread From: Christian Borntraeger @ 2013-09-18 10:19 UTC (permalink / raw) To: Alexander Graf Cc: Christian Borntraeger, Jens Freimann, Heinz Graalfs, qemu-devel The event_type variable is never used. Get rid of it. Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> --- hw/char/sclpconsole.c | 1 - hw/s390x/sclpquiesce.c | 2 -- include/hw/s390x/event-facility.h | 1 - 3 files changed, 4 deletions(-) diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c index 138b017..9469979 100644 --- a/hw/char/sclpconsole.c +++ b/hw/char/sclpconsole.c @@ -228,7 +228,6 @@ static int console_init(SCLPEvent *event) return -1; } console_available = true; - event->event_type = SCLP_EVENT_ASCII_CONSOLE_DATA; if (scon->chr) { qemu_chr_add_handlers(scon->chr, chr_can_read, chr_read, NULL, scon); diff --git a/hw/s390x/sclpquiesce.c b/hw/s390x/sclpquiesce.c index 8981f4a..1a528c0 100644 --- a/hw/s390x/sclpquiesce.c +++ b/hw/s390x/sclpquiesce.c @@ -95,8 +95,6 @@ static void quiesce_powerdown_req(Notifier *n, void *opaque) static int quiesce_init(SCLPEvent *event) { - event->event_type = SCLP_EVENT_SIGNAL_QUIESCE; - qn.notifier.notify = quiesce_powerdown_req; qn.event = event; diff --git a/include/hw/s390x/event-facility.h b/include/hw/s390x/event-facility.h index 727ef4f..ff0f625 100644 --- a/include/hw/s390x/event-facility.h +++ b/include/hw/s390x/event-facility.h @@ -68,7 +68,6 @@ typedef struct ReadEventData { typedef struct SCLPEvent { DeviceState qdev; bool event_pending; - uint32_t event_type; char *name; } SCLPEvent; -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 09/11] s390/eventfacility: allow childs to handle more than 1 event type 2013-09-18 10:19 [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console Christian Borntraeger ` (7 preceding siblings ...) 2013-09-18 10:19 ` [Qemu-devel] [PATCH 08/11] s390/eventfacility: remove unused event_type variable Christian Borntraeger @ 2013-09-18 10:19 ` Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 10/11] s390/ebcdic: Move conversion tables to header file Christian Borntraeger ` (2 subsequent siblings) 11 siblings, 0 replies; 18+ messages in thread From: Christian Borntraeger @ 2013-09-18 10:19 UTC (permalink / raw) To: Alexander Graf Cc: Christian Borntraeger, Jens Freimann, Heinz Graalfs, qemu-devel Currently all handlers (quiesce, console) only handle one event type. Some drivers will handle multiple (compatible) event types. Rework the code accordingly. Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> --- hw/char/sclpconsole.c | 6 +++--- hw/s390x/event-facility.c | 2 +- hw/s390x/sclpquiesce.c | 6 +++--- include/hw/s390x/event-facility.h | 5 ++--- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c index 9469979..69ac5b3 100644 --- a/hw/char/sclpconsole.c +++ b/hw/char/sclpconsole.c @@ -79,9 +79,9 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) /* functions to be called by event facility */ -static int event_type(void) +static bool can_handle_event(uint8_t type) { - return SCLP_EVENT_ASCII_CONSOLE_DATA; + return type == SCLP_EVENT_ASCII_CONSOLE_DATA; } static unsigned int send_mask(void) @@ -271,7 +271,7 @@ static void console_class_init(ObjectClass *klass, void *data) ec->exit = console_exit; ec->get_send_mask = send_mask; ec->get_receive_mask = receive_mask; - ec->event_type = event_type; + ec->can_handle_event = can_handle_event; ec->read_event_data = read_event_data; ec->write_event_data = write_event_data; } diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c index 4347a48..b1afa7e 100644 --- a/hw/s390x/event-facility.c +++ b/hw/s390x/event-facility.c @@ -120,7 +120,7 @@ static uint16_t handle_write_event_buf(SCLPEventFacility *ef, ec = SCLP_EVENT_GET_CLASS(event); if (ec->write_event_data && - ec->event_type() == event_buf->type) { + ec->can_handle_event(event_buf->type)) { rc = ec->write_event_data(event, event_buf); break; } diff --git a/hw/s390x/sclpquiesce.c b/hw/s390x/sclpquiesce.c index 1a528c0..4c67bac 100644 --- a/hw/s390x/sclpquiesce.c +++ b/hw/s390x/sclpquiesce.c @@ -22,9 +22,9 @@ typedef struct SignalQuiesce { uint8_t unit; } QEMU_PACKED SignalQuiesce; -static int event_type(void) +static bool can_handle_event(uint8_t type) { - return SCLP_EVENT_SIGNAL_QUIESCE; + return type == SCLP_EVENT_SIGNAL_QUIESCE; } static unsigned int send_mask(void) @@ -120,7 +120,7 @@ static void quiesce_class_init(ObjectClass *klass, void *data) k->get_send_mask = send_mask; k->get_receive_mask = receive_mask; - k->event_type = event_type; + k->can_handle_event = can_handle_event; k->read_event_data = read_event_data; k->write_event_data = NULL; } diff --git a/include/hw/s390x/event-facility.h b/include/hw/s390x/event-facility.h index ff0f625..c0f5d19 100644 --- a/include/hw/s390x/event-facility.h +++ b/include/hw/s390x/event-facility.h @@ -87,9 +87,8 @@ typedef struct SCLPEventClass { int (*write_event_data)(SCLPEvent *event, EventBufferHeader *evt_buf_hdr); - /* returns the supported event type */ - int (*event_type)(void); - + /* can we handle this event type? */ + bool (*can_handle_event)(uint8_t type); } SCLPEventClass; #endif -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 10/11] s390/ebcdic: Move conversion tables to header file 2013-09-18 10:19 [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console Christian Borntraeger ` (8 preceding siblings ...) 2013-09-18 10:19 ` [Qemu-devel] [PATCH 09/11] s390/eventfacility: allow childs to handle more than 1 event type Christian Borntraeger @ 2013-09-18 10:19 ` Christian Borntraeger 2013-09-20 3:21 ` Alexander Graf 2013-09-18 10:19 ` [Qemu-devel] [PATCH 11/11] s390/sclplmconsole: Add support for SCLP line-mode console Christian Borntraeger 2013-09-20 3:32 ` [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console Alexander Graf 11 siblings, 1 reply; 18+ messages in thread From: Christian Borntraeger @ 2013-09-18 10:19 UTC (permalink / raw) To: Alexander Graf Cc: Christian Borntraeger, Jens Freimann, Heinz Graalfs, qemu-devel From: Heinz Graalfs <graalfs@linux.vnet.ibm.com> Move conversion tables to header file. - In SCLP line mode processing EBCDIC/ASCII conversion is needed. - An additional EBCDIC to ASCII conversion function is added. Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> --- include/hw/s390x/ebcdic.h | 107 +++++++++++++++++++++++++++++++++++++++++++++ target-s390x/misc_helper.c | 81 +--------------------------------- 2 files changed, 108 insertions(+), 80 deletions(-) create mode 100644 include/hw/s390x/ebcdic.h diff --git a/include/hw/s390x/ebcdic.h b/include/hw/s390x/ebcdic.h new file mode 100644 index 0000000..992f8c6 --- /dev/null +++ b/include/hw/s390x/ebcdic.h @@ -0,0 +1,107 @@ +/* + * EBCDIC/ASCII conversion Support + * + * Copyright (c) 2011 Alexander Graf + * Copyright IBM, Corp. 2013 + * + * 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. + * + */ + +#ifndef EBCDIC_H_ +#define EBCDIC_H_ + +#ifndef CONFIG_USER_ONLY + +/* EBCDIC handling */ +static const uint8_t ebcdic2ascii[] = { + 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F, + 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07, + 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07, + 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04, + 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A, + 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86, + 0x87, 0xA4, 0x5B, 0x2E, 0x3C, 0x28, 0x2B, 0x21, + 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07, + 0x8D, 0xE1, 0x5D, 0x24, 0x2A, 0x29, 0x3B, 0x5E, + 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F, + 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, + 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, + 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1, + 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, + 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07, + 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07, + 0x9B, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC, + 0xAB, 0x07, 0xAA, 0x7C, 0x07, 0x07, 0x07, 0x07, + 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07, + 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, + 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98, + 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07, +}; + +static const uint8_t ascii2ebcdic[] = { + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, + 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, + 0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F, + 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, + 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, + 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, + 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, + 0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D, + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF +}; + +static inline void ebcdic_put(uint8_t *p, const char *ascii, int len) +{ + int i; + + for (i = 0; i < len; i++) { + p[i] = ascii2ebcdic[(uint8_t)ascii[i]]; + } +} + +static inline void ascii_put(uint8_t *p, const char *ebcdic, int len) +{ + int i; + + for (i = 0; i < len; i++) { + p[i] = ebcdic2ascii[(uint8_t)ebcdic[i]]; + } +} +#endif + +#endif /* EBCDIC_H_ */ diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c index 1690907..fdace0c 100644 --- a/target-s390x/misc_helper.c +++ b/target-s390x/misc_helper.c @@ -33,6 +33,7 @@ #include "exec/softmmu_exec.h" #include "sysemu/cpus.h" #include "sysemu/sysemu.h" +#include "hw/s390x/ebcdic.h" #endif /* #define DEBUG_HELPER */ @@ -72,86 +73,6 @@ void HELPER(exception)(CPUS390XState *env, uint32_t excp) #ifndef CONFIG_USER_ONLY -/* EBCDIC handling */ -static const uint8_t ebcdic2ascii[] = { - 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F, - 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07, - 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07, - 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04, - 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A, - 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86, - 0x87, 0xA4, 0x5B, 0x2E, 0x3C, 0x28, 0x2B, 0x21, - 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07, - 0x8D, 0xE1, 0x5D, 0x24, 0x2A, 0x29, 0x3B, 0x5E, - 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F, - 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, - 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, - 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1, - 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, - 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07, - 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07, - 0x9B, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC, - 0xAB, 0x07, 0xAA, 0x7C, 0x07, 0x07, 0x07, 0x07, - 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07, - 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, - 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98, - 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07, -}; - -static const uint8_t ascii2ebcdic[] = { - 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, - 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, - 0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F, - 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, - 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, - 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, - 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, - 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, - 0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D, - 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF -}; - -static inline void ebcdic_put(uint8_t *p, const char *ascii, int len) -{ - int i; - - for (i = 0; i < len; i++) { - p[i] = ascii2ebcdic[(uint8_t)ascii[i]]; - } -} - void program_interrupt(CPUS390XState *env, uint32_t code, int ilen) { qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n", -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 10/11] s390/ebcdic: Move conversion tables to header file 2013-09-18 10:19 ` [Qemu-devel] [PATCH 10/11] s390/ebcdic: Move conversion tables to header file Christian Borntraeger @ 2013-09-20 3:21 ` Alexander Graf 0 siblings, 0 replies; 18+ messages in thread From: Alexander Graf @ 2013-09-20 3:21 UTC (permalink / raw) To: Christian Borntraeger; +Cc: Jens Freimann, Heinz Graalfs, qemu-devel On 18.09.2013, at 05:19, Christian Borntraeger wrote: > From: Heinz Graalfs <graalfs@linux.vnet.ibm.com> > > Move conversion tables to header file. > - In SCLP line mode processing EBCDIC/ASCII conversion is needed. > - An additional EBCDIC to ASCII conversion function is added. > > Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com> > Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> > --- > include/hw/s390x/ebcdic.h | 107 +++++++++++++++++++++++++++++++++++++++++++++ > target-s390x/misc_helper.c | 81 +--------------------------------- > 2 files changed, 108 insertions(+), 80 deletions(-) > create mode 100644 include/hw/s390x/ebcdic.h > > diff --git a/include/hw/s390x/ebcdic.h b/include/hw/s390x/ebcdic.h > new file mode 100644 > index 0000000..992f8c6 > --- /dev/null > +++ b/include/hw/s390x/ebcdic.h > @@ -0,0 +1,107 @@ > +/* > + * EBCDIC/ASCII conversion Support > + * > + * Copyright (c) 2011 Alexander Graf > + * Copyright IBM, Corp. 2013 > + * > + * 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. > + * > + */ > + > +#ifndef EBCDIC_H_ > +#define EBCDIC_H_ > + > +#ifndef CONFIG_USER_ONLY No need for the #ifndef. You're already in hw/ :). Alex ^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 11/11] s390/sclplmconsole: Add support for SCLP line-mode console 2013-09-18 10:19 [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console Christian Borntraeger ` (9 preceding siblings ...) 2013-09-18 10:19 ` [Qemu-devel] [PATCH 10/11] s390/ebcdic: Move conversion tables to header file Christian Borntraeger @ 2013-09-18 10:19 ` Christian Borntraeger 2013-09-20 3:31 ` Alexander Graf 2013-09-20 3:32 ` [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console Alexander Graf 11 siblings, 1 reply; 18+ messages in thread From: Christian Borntraeger @ 2013-09-18 10:19 UTC (permalink / raw) To: Alexander Graf Cc: Christian Borntraeger, Jens Freimann, Heinz Graalfs, qemu-devel From: Heinz Graalfs <graalfs@linux.vnet.ibm.com> Add simple support for SCLP line-mode also known as operating system messages. This can be added in addition to or instead of the SCLP full screen console with -device sclplmconsole. Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> --- hw/char/Makefile.objs | 2 +- hw/char/sclpconsole-lm.c | 393 ++++++++++++++++++++++++++++++++++++++ include/hw/s390x/event-facility.h | 78 ++++++++ 3 files changed, 472 insertions(+), 1 deletion(-) create mode 100644 hw/char/sclpconsole-lm.c diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs index f8f3dbc..cbd6a00 100644 --- a/hw/char/Makefile.objs +++ b/hw/char/Makefile.objs @@ -22,6 +22,6 @@ common-obj-$(CONFIG_IMX) += imx_serial.o common-obj-$(CONFIG_LM32) += lm32_juart.o common-obj-$(CONFIG_LM32) += lm32_uart.o common-obj-$(CONFIG_MILKYMIST) += milkymist-uart.o -common-obj-$(CONFIG_SCLPCONSOLE) += sclpconsole.o +common-obj-$(CONFIG_SCLPCONSOLE) += sclpconsole.o sclpconsole-lm.o obj-$(CONFIG_VIRTIO) += virtio-serial-bus.o diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c new file mode 100644 index 0000000..a0eb59b --- /dev/null +++ b/hw/char/sclpconsole-lm.c @@ -0,0 +1,393 @@ +/* + * SCLP event types + * Operations Command - Line Mode input + * Message - Line Mode output + * + * Copyright IBM, Corp. 2013 + * + * Authors: + * Heinz Graalfs <graalfs@linux.vnet.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 "qemu/error-report.h" +#include "sysemu/char.h" + +#include "hw/s390x/sclp.h" +#include "hw/s390x/event-facility.h" +#include "hw/s390x/ebcdic.h" + +typedef struct OprtnsCommand { + EventBufferHeader header; + MDMSU message_unit; + char data[0]; +} QEMU_PACKED OprtnsCommand; + +/* max size for line-mode data in 4K SCCB page */ +#define SIZE_CONSOLE_BUFFER (SCCB_DATA_LEN - sizeof(OprtnsCommand)) + +typedef struct SCLPConsoleLM { + SCLPEvent event; + CharDriverState *chr; + bool echo; /* immediate echo of input if true */ + uint32_t write_errors; /* errors writing to char layer */ + uint32_t length; /* length of byte stream in buffer */ + uint8_t buf[SIZE_CONSOLE_BUFFER]; + qemu_irq irq_console_read; +} SCLPConsoleLM; + +/* +* Character layer call-back functions + * + * Allow 1 character at a time + * + * Accumulate bytes from character layer in console buffer, + * event_pending is set when a newline character is encountered + * + * The maximum command line length is limited by the maximum + * space available in an SCCB + */ + +static int chr_can_read(void *opaque) +{ + SCLPConsoleLM *scon = opaque; + + if (scon->event.event_pending) { + return 0; + } else if (SIZE_CONSOLE_BUFFER - scon->length) { + return 1; + } + return 0; +} + +static void receive_from_chr_layer(SCLPConsoleLM *scon, const uint8_t *buf, + int size) +{ + assert(size == 1); + + if (*buf == '\r' || *buf == '\n') { + scon->event.event_pending = true; + return; + } + memcpy(&scon->buf[scon->length], buf, 1); + scon->length += 1; + if (scon->echo) { + qemu_chr_fe_write(scon->chr, buf, size); + } +} + +/* + * Send data from a char device over to the guest + */ +static void chr_read(void *opaque, const uint8_t *buf, int size) +{ + SCLPConsoleLM *scon = opaque; + + receive_from_chr_layer(scon, buf, size); + if (scon->event.event_pending) { + /* trigger SCLP read operation */ + qemu_irq_raise(scon->irq_console_read); + } +} + +/* functions to be called by event facility */ + +static bool can_handle_event(uint8_t type) +{ + return type == SCLP_EVENT_MESSAGE || type == SCLP_EVENT_PMSGCMD; +} + +static unsigned int send_mask(void) +{ + return SCLP_EVENT_MASK_OP_CMD | SCLP_EVENT_MASK_PMSGCMD; +} + +static unsigned int receive_mask(void) +{ + return SCLP_EVENT_MASK_MSG | SCLP_EVENT_MASK_PMSGCMD; +} + +/* + * Triggered by SCLP's read_event_data + * - convert ASCII byte stream to EBCDIC and + * - copy converted data into provided (SCLP) buffer + */ +static int get_console_data(SCLPEvent *event, uint8_t *buf, size_t *size, + int avail) +{ + int len; + + SCLPConsoleLM *cons = DO_UPCAST(SCLPConsoleLM, event, event); + + len = cons->length; + /* data need to fit into provided SCLP buffer */ + if (len > avail) { + return 1; + } + + ebcdic_put(buf, (char *)&cons->buf, len); + *size = len; + cons->length = 0; + /* data provided and no more data pending */ + event->event_pending = false; + return 0; +} + +static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr, + int *slen) +{ + int avail, rc; + size_t src_len; + uint8_t *to; + OprtnsCommand *oc = (OprtnsCommand *) evt_buf_hdr; + + if (!event->event_pending) { + /* no data pending */ + return 0; + } + + to = (uint8_t *)&oc->data; + avail = *slen - sizeof(OprtnsCommand); + rc = get_console_data(event, to, &src_len, avail); + if (rc) { + /* data didn't fit, try next SCCB */ + return 1; + } + + oc->message_unit.mdmsu.gds_id = GDS_ID_MDSMU; + oc->message_unit.mdmsu.length = cpu_to_be16(sizeof(struct MDMSU)); + + oc->message_unit.cpmsu.gds_id = GDS_ID_CPMSU; + oc->message_unit.cpmsu.length = + cpu_to_be16(sizeof(struct MDMSU) - sizeof(GdsVector)); + + oc->message_unit.text_command.gds_id = GDS_ID_TEXTCMD; + oc->message_unit.text_command.length = + cpu_to_be16(sizeof(struct MDMSU) - (2 * sizeof(GdsVector))); + + oc->message_unit.self_def_text_message.key = GDS_KEY_SELFDEFTEXTMSG; + oc->message_unit.self_def_text_message.length = + cpu_to_be16(sizeof(struct MDMSU) - (3 * sizeof(GdsVector))); + + oc->message_unit.text_message.key = GDS_KEY_TEXTMSG; + oc->message_unit.text_message.length = + cpu_to_be16(sizeof(GdsSubvector) + src_len); + + oc->header.length = cpu_to_be16(sizeof(OprtnsCommand) + src_len); + oc->header.type = SCLP_EVENT_OPRTNS_COMMAND; + *slen = avail - src_len; + + return 1; +} + +/* + * Triggered by SCLP's write_event_data + * - write console data to character layer + * returns < 0 if an error occurred + */ +static int write_console_data(SCLPEvent *event, const uint8_t *buf, int len) +{ + int ret = 0; + const uint8_t *buf_offset; + + SCLPConsoleLM *scon = DO_UPCAST(SCLPConsoleLM, event, event); + + if (!scon->chr) { + /* If there's no backend, we can just say we consumed all data. */ + return len; + } + + buf_offset = buf; + while (len > 0) { + ret = qemu_chr_fe_write(scon->chr, buf, len); + if (ret == 0) { + /* a pty doesn't seem to be connected - no error */ + len = 0; + } else if (ret == -EAGAIN || (ret > 0 && ret < len)) { + len -= ret; + buf_offset += ret; + } else { + len = 0; + } + } + + return ret; +} + +#define SIZE_BUFFER 4096 +#define NEWLINE "\n" + +static int process_mdb(SCLPEvent *event, MDBO *mdbo) +{ + int rc; + int len; + uint8_t buffer[SIZE_BUFFER]; + + len = be16_to_cpu(mdbo->length); + len -= sizeof(mdbo->length) + sizeof(mdbo->type) + + sizeof(mdbo->mto.line_type_flags) + + sizeof(mdbo->mto.alarm_control) + + sizeof(mdbo->mto._reserved); + + assert(len <= SIZE_BUFFER); + + /* convert EBCDIC SCLP contents to ASCII console message */ + ascii_put(buffer, mdbo->mto.message, len); + rc = write_console_data(event, (uint8_t *)NEWLINE, 1); + if (rc < 0) { + return rc; + } + return write_console_data(event, buffer, len); +} + +static int write_event_data(SCLPEvent *event, EventBufferHeader *ebh) +{ + int len; + int written; + int errors = 0; + MDBO *mdbo; + SclpMsg *data = (SclpMsg *) ebh; + SCLPConsoleLM *scon = DO_UPCAST(SCLPConsoleLM, event, event); + + len = be16_to_cpu(data->mdb.header.length) - sizeof(data->mdb.header); + + /* first check message buffers */ + mdbo = data->mdb.mdbo; + while (len > 0) { + if (be16_to_cpu(mdbo->length) > len + || be16_to_cpu(mdbo->length) == 0) { + return SCLP_RC_INCONSISTENT_LENGTHS; + } + len -= be16_to_cpu(mdbo->length); + mdbo = (void *) mdbo + be16_to_cpu(mdbo->length); + } + + /* then execute */ + len = be16_to_cpu(data->mdb.header.length) - sizeof(data->mdb.header); + mdbo = data->mdb.mdbo; + while (len > 0) { + switch (be16_to_cpu(mdbo->type)) { + case 4: + /* message text object */ + written = process_mdb(event, mdbo); + if (written < 0) { + /* character layer error */ + errors++; + } + break; + default: /* ignore */ + break; + } + len -= be16_to_cpu(mdbo->length); + mdbo = (void *) mdbo + be16_to_cpu(mdbo->length); + } + if (errors) { + scon->write_errors += errors; + } + data->header.flags = SCLP_EVENT_BUFFER_ACCEPTED; + + return SCLP_RC_NORMAL_COMPLETION; +} + +static void trigger_console_data(void *opaque, int n, int level) +{ + sclp_service_interrupt(0); +} + +/* functions for live migration */ + +static const VMStateDescription vmstate_sclplmconsole = { + .name = "sclplmconsole", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_BOOL(event.event_pending, SCLPConsoleLM), + VMSTATE_UINT32(write_errors, SCLPConsoleLM), + VMSTATE_UINT32(length, SCLPConsoleLM), + VMSTATE_UINT8_ARRAY(buf, SCLPConsoleLM, SIZE_CONSOLE_BUFFER), + VMSTATE_END_OF_LIST() + } +}; + +/* qemu object creation and initialization functions */ + +/* tell character layer our call-back functions */ + +static int console_init(SCLPEvent *event) +{ + static bool console_available; + + SCLPConsoleLM *scon = DO_UPCAST(SCLPConsoleLM, event, event); + + if (console_available) { + error_report("Multiple line-mode operator consoles are not supported"); + return -1; + } + console_available = true; + + if (scon->chr) { + qemu_chr_add_handlers(scon->chr, chr_can_read, chr_read, NULL, scon); + } + scon->irq_console_read = *qemu_allocate_irqs(trigger_console_data, NULL, 1); + + return vmstate_register(NULL, 0, &vmstate_sclplmconsole, scon); +} + +static int console_exit(SCLPEvent *event) +{ + return 0; +} + +static void console_reset(DeviceState *dev) +{ + SCLPEvent *event = SCLP_EVENT(dev); + SCLPConsoleLM *scon = DO_UPCAST(SCLPConsoleLM, event, event); + + event->event_pending = false; + scon->length = 0; + scon->write_errors = 0; +} + +static Property console_properties[] = { + DEFINE_PROP_CHR("chardev", SCLPConsoleLM, chr), + DEFINE_PROP_UINT32("write_errors", SCLPConsoleLM, write_errors, 0), + DEFINE_PROP_BOOL("echo", SCLPConsoleLM, echo, true), + DEFINE_PROP_END_OF_LIST(), +}; + +static void console_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SCLPEventClass *ec = SCLP_EVENT_CLASS(klass); + + dc->props = console_properties; + dc->reset = console_reset; + ec->init = console_init; + ec->exit = console_exit; + ec->get_send_mask = send_mask; + ec->get_receive_mask = receive_mask; + ec->can_handle_event = can_handle_event; + ec->read_event_data = read_event_data; + ec->write_event_data = write_event_data; +} + +static const TypeInfo sclp_console_info = { + .name = "sclplmconsole", + .parent = TYPE_SCLP_EVENT, + .instance_size = sizeof(SCLPConsoleLM), + .class_init = console_class_init, + .class_size = sizeof(SCLPEventClass), +}; + +static void register_types(void) +{ + type_register_static(&sclp_console_info); +} + +type_init(register_types) diff --git a/include/hw/s390x/event-facility.h b/include/hw/s390x/event-facility.h index c0f5d19..242ee0b 100644 --- a/include/hw/s390x/event-facility.h +++ b/include/hw/s390x/event-facility.h @@ -19,12 +19,18 @@ #include "qemu/thread.h" /* SCLP event types */ +#define SCLP_EVENT_OPRTNS_COMMAND 0x01 +#define SCLP_EVENT_MESSAGE 0x02 +#define SCLP_EVENT_PMSGCMD 0x09 #define SCLP_EVENT_ASCII_CONSOLE_DATA 0x1a #define SCLP_EVENT_SIGNAL_QUIESCE 0x1d /* SCLP event masks */ #define SCLP_EVENT_MASK_SIGNAL_QUIESCE 0x00000008 #define SCLP_EVENT_MASK_MSG_ASCII 0x00000040 +#define SCLP_EVENT_MASK_OP_CMD 0x80000000 +#define SCLP_EVENT_MASK_MSG 0x40000000 +#define SCLP_EVENT_MASK_PMSGCMD 0x00800000 #define SCLP_UNCONDITIONAL_READ 0x00 #define SCLP_SELECTIVE_READ 0x01 @@ -54,6 +60,78 @@ typedef struct EventBufferHeader { uint16_t _reserved; } QEMU_PACKED EventBufferHeader; +typedef struct MdbHeader { + uint16_t length; + uint16_t type; + uint32_t tag; + uint32_t revision_code; +} QEMU_PACKED MdbHeader; + +typedef struct MTO { + uint16_t line_type_flags; + uint8_t alarm_control; + uint8_t _reserved[3]; + char message[]; +} QEMU_PACKED MTO; + +typedef struct GO { + uint32_t domid; + uint8_t hhmmss_time[8]; + uint8_t th_time[3]; + uint8_t _reserved_0; + uint8_t dddyyyy_date[7]; + uint8_t _reserved_1; + uint16_t general_msg_flags; + uint8_t _reserved_2[10]; + uint8_t originating_system_name[8]; + uint8_t job_guest_name[8]; +} QEMU_PACKED GO; + +typedef struct MDBO { + uint16_t length; + uint16_t type; + union { + GO go; + MTO mto; + }; +} QEMU_PACKED MDBO; + +typedef struct MDB { + MdbHeader header; + MDBO mdbo[0]; +} QEMU_PACKED MDB; + +typedef struct SclpMsg { + EventBufferHeader header; + MDB mdb; +} QEMU_PACKED SclpMsg; + +#define GDS_ID_MDSMU 0x1310 +#define GDS_ID_CPMSU 0x1212 +#define GDS_ID_TEXTCMD 0x1320 + +typedef struct GdsVector { + uint16_t length; + uint16_t gds_id; +} QEMU_PACKED GdsVector; + +#define GDS_KEY_SELFDEFTEXTMSG 0x31 +#define GDS_KEY_TEXTMSG 0x30 + +typedef struct GdsSubvector { + uint8_t length; + uint8_t key; +} QEMU_PACKED GdsSubvector; + +/* MDS Message Unit */ +typedef struct MDMSU { + GdsVector mdmsu; + GdsVector cpmsu; + GdsVector text_command; + GdsSubvector self_def_text_message; + GdsSubvector text_message; +} QEMU_PACKED MDMSU; + typedef struct WriteEventData { SCCBHeader h; EventBufferHeader ebh; -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 11/11] s390/sclplmconsole: Add support for SCLP line-mode console 2013-09-18 10:19 ` [Qemu-devel] [PATCH 11/11] s390/sclplmconsole: Add support for SCLP line-mode console Christian Borntraeger @ 2013-09-20 3:31 ` Alexander Graf 0 siblings, 0 replies; 18+ messages in thread From: Alexander Graf @ 2013-09-20 3:31 UTC (permalink / raw) To: Christian Borntraeger; +Cc: Jens Freimann, Heinz Graalfs, qemu-devel On 18.09.2013, at 05:19, Christian Borntraeger wrote: > From: Heinz Graalfs <graalfs@linux.vnet.ibm.com> > > Add simple support for SCLP line-mode also known as operating > system messages. This can be added in addition to or instead of > the SCLP full screen console with -device sclplmconsole. > > Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com> > Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> > --- > hw/char/Makefile.objs | 2 +- > hw/char/sclpconsole-lm.c | 393 ++++++++++++++++++++++++++++++++++++++ > include/hw/s390x/event-facility.h | 78 ++++++++ > 3 files changed, 472 insertions(+), 1 deletion(-) > create mode 100644 hw/char/sclpconsole-lm.c > > diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs > index f8f3dbc..cbd6a00 100644 > --- a/hw/char/Makefile.objs > +++ b/hw/char/Makefile.objs > @@ -22,6 +22,6 @@ common-obj-$(CONFIG_IMX) += imx_serial.o > common-obj-$(CONFIG_LM32) += lm32_juart.o > common-obj-$(CONFIG_LM32) += lm32_uart.o > common-obj-$(CONFIG_MILKYMIST) += milkymist-uart.o > -common-obj-$(CONFIG_SCLPCONSOLE) += sclpconsole.o > +common-obj-$(CONFIG_SCLPCONSOLE) += sclpconsole.o sclpconsole-lm.o > > obj-$(CONFIG_VIRTIO) += virtio-serial-bus.o > diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c > new file mode 100644 > index 0000000..a0eb59b > --- /dev/null > +++ b/hw/char/sclpconsole-lm.c > @@ -0,0 +1,393 @@ > +/* > + * SCLP event types > + * Operations Command - Line Mode input > + * Message - Line Mode output > + * > + * Copyright IBM, Corp. 2013 > + * > + * Authors: > + * Heinz Graalfs <graalfs@linux.vnet.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 "qemu/error-report.h" > +#include "sysemu/char.h" > + > +#include "hw/s390x/sclp.h" > +#include "hw/s390x/event-facility.h" > +#include "hw/s390x/ebcdic.h" > + > +typedef struct OprtnsCommand { > + EventBufferHeader header; > + MDMSU message_unit; > + char data[0]; > +} QEMU_PACKED OprtnsCommand; > + > +/* max size for line-mode data in 4K SCCB page */ > +#define SIZE_CONSOLE_BUFFER (SCCB_DATA_LEN - sizeof(OprtnsCommand)) > + > +typedef struct SCLPConsoleLM { > + SCLPEvent event; > + CharDriverState *chr; > + bool echo; /* immediate echo of input if true */ > + uint32_t write_errors; /* errors writing to char layer */ > + uint32_t length; /* length of byte stream in buffer */ > + uint8_t buf[SIZE_CONSOLE_BUFFER]; > + qemu_irq irq_console_read; > +} SCLPConsoleLM; > + > +/* > +* Character layer call-back functions > + * > + * Allow 1 character at a time > + * > + * Accumulate bytes from character layer in console buffer, > + * event_pending is set when a newline character is encountered > + * > + * The maximum command line length is limited by the maximum > + * space available in an SCCB > + */ > + > +static int chr_can_read(void *opaque) > +{ > + SCLPConsoleLM *scon = opaque; > + > + if (scon->event.event_pending) { > + return 0; > + } else if (SIZE_CONSOLE_BUFFER - scon->length) { > + return 1; > + } > + return 0; > +} > + > +static void receive_from_chr_layer(SCLPConsoleLM *scon, const uint8_t *buf, > + int size) > +{ > + assert(size == 1); > + > + if (*buf == '\r' || *buf == '\n') { > + scon->event.event_pending = true; > + return; > + } > + memcpy(&scon->buf[scon->length], buf, 1); Why use memcpy here? > + scon->length += 1; > + if (scon->echo) { > + qemu_chr_fe_write(scon->chr, buf, size); > + } > +} > + > +/* > + * Send data from a char device over to the guest > + */ > +static void chr_read(void *opaque, const uint8_t *buf, int size) > +{ > + SCLPConsoleLM *scon = opaque; > + > + receive_from_chr_layer(scon, buf, size); > + if (scon->event.event_pending) { > + /* trigger SCLP read operation */ > + qemu_irq_raise(scon->irq_console_read); > + } > +} > + > +/* functions to be called by event facility */ > + > +static bool can_handle_event(uint8_t type) > +{ > + return type == SCLP_EVENT_MESSAGE || type == SCLP_EVENT_PMSGCMD; > +} > + > +static unsigned int send_mask(void) > +{ > + return SCLP_EVENT_MASK_OP_CMD | SCLP_EVENT_MASK_PMSGCMD; > +} > + > +static unsigned int receive_mask(void) > +{ > + return SCLP_EVENT_MASK_MSG | SCLP_EVENT_MASK_PMSGCMD; > +} > + > +/* > + * Triggered by SCLP's read_event_data > + * - convert ASCII byte stream to EBCDIC and > + * - copy converted data into provided (SCLP) buffer > + */ > +static int get_console_data(SCLPEvent *event, uint8_t *buf, size_t *size, > + int avail) > +{ > + int len; > + > + SCLPConsoleLM *cons = DO_UPCAST(SCLPConsoleLM, event, event); > + > + len = cons->length; > + /* data need to fit into provided SCLP buffer */ > + if (len > avail) { > + return 1; > + } > + > + ebcdic_put(buf, (char *)&cons->buf, len); > + *size = len; > + cons->length = 0; > + /* data provided and no more data pending */ > + event->event_pending = false; > + return 0; > +} > + > +static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr, > + int *slen) > +{ > + int avail, rc; > + size_t src_len; > + uint8_t *to; > + OprtnsCommand *oc = (OprtnsCommand *) evt_buf_hdr; > + > + if (!event->event_pending) { > + /* no data pending */ > + return 0; > + } > + > + to = (uint8_t *)&oc->data; > + avail = *slen - sizeof(OprtnsCommand); > + rc = get_console_data(event, to, &src_len, avail); > + if (rc) { > + /* data didn't fit, try next SCCB */ > + return 1; > + } > + > + oc->message_unit.mdmsu.gds_id = GDS_ID_MDSMU; > + oc->message_unit.mdmsu.length = cpu_to_be16(sizeof(struct MDMSU)); > + > + oc->message_unit.cpmsu.gds_id = GDS_ID_CPMSU; > + oc->message_unit.cpmsu.length = > + cpu_to_be16(sizeof(struct MDMSU) - sizeof(GdsVector)); > + > + oc->message_unit.text_command.gds_id = GDS_ID_TEXTCMD; > + oc->message_unit.text_command.length = > + cpu_to_be16(sizeof(struct MDMSU) - (2 * sizeof(GdsVector))); > + > + oc->message_unit.self_def_text_message.key = GDS_KEY_SELFDEFTEXTMSG; > + oc->message_unit.self_def_text_message.length = > + cpu_to_be16(sizeof(struct MDMSU) - (3 * sizeof(GdsVector))); > + > + oc->message_unit.text_message.key = GDS_KEY_TEXTMSG; > + oc->message_unit.text_message.length = > + cpu_to_be16(sizeof(GdsSubvector) + src_len); > + > + oc->header.length = cpu_to_be16(sizeof(OprtnsCommand) + src_len); > + oc->header.type = SCLP_EVENT_OPRTNS_COMMAND; > + *slen = avail - src_len; > + > + return 1; > +} > + > +/* > + * Triggered by SCLP's write_event_data > + * - write console data to character layer > + * returns < 0 if an error occurred > + */ > +static int write_console_data(SCLPEvent *event, const uint8_t *buf, int len) > +{ > + int ret = 0; > + const uint8_t *buf_offset; > + > + SCLPConsoleLM *scon = DO_UPCAST(SCLPConsoleLM, event, event); > + > + if (!scon->chr) { > + /* If there's no backend, we can just say we consumed all data. */ > + return len; > + } > + > + buf_offset = buf; > + while (len > 0) { > + ret = qemu_chr_fe_write(scon->chr, buf, len); > + if (ret == 0) { > + /* a pty doesn't seem to be connected - no error */ > + len = 0; > + } else if (ret == -EAGAIN || (ret > 0 && ret < len)) { > + len -= ret; > + buf_offset += ret; > + } else { > + len = 0; > + } > + } > + > + return ret; > +} > + > +#define SIZE_BUFFER 4096 > +#define NEWLINE "\n" Why are these in the middle of the file? > + > +static int process_mdb(SCLPEvent *event, MDBO *mdbo) > +{ > + int rc; > + int len; > + uint8_t buffer[SIZE_BUFFER]; > + > + len = be16_to_cpu(mdbo->length); > + len -= sizeof(mdbo->length) + sizeof(mdbo->type) > + + sizeof(mdbo->mto.line_type_flags) > + + sizeof(mdbo->mto.alarm_control) > + + sizeof(mdbo->mto._reserved); > + > + assert(len <= SIZE_BUFFER); > + > + /* convert EBCDIC SCLP contents to ASCII console message */ > + ascii_put(buffer, mdbo->mto.message, len); > + rc = write_console_data(event, (uint8_t *)NEWLINE, 1); > + if (rc < 0) { > + return rc; > + } > + return write_console_data(event, buffer, len); > +} > + > +static int write_event_data(SCLPEvent *event, EventBufferHeader *ebh) > +{ > + int len; > + int written; > + int errors = 0; > + MDBO *mdbo; > + SclpMsg *data = (SclpMsg *) ebh; > + SCLPConsoleLM *scon = DO_UPCAST(SCLPConsoleLM, event, event); > + > + len = be16_to_cpu(data->mdb.header.length) - sizeof(data->mdb.header); > + > + /* first check message buffers */ > + mdbo = data->mdb.mdbo; > + while (len > 0) { > + if (be16_to_cpu(mdbo->length) > len > + || be16_to_cpu(mdbo->length) == 0) { > + return SCLP_RC_INCONSISTENT_LENGTHS; > + } > + len -= be16_to_cpu(mdbo->length); > + mdbo = (void *) mdbo + be16_to_cpu(mdbo->length); > + } > + > + /* then execute */ > + len = be16_to_cpu(data->mdb.header.length) - sizeof(data->mdb.header); Can this overflow? > + mdbo = data->mdb.mdbo; > + while (len > 0) { > + switch (be16_to_cpu(mdbo->type)) { > + case 4: What is 4? This wants to be a #define. > + /* message text object */ > + written = process_mdb(event, mdbo); > + if (written < 0) { > + /* character layer error */ > + errors++; > + } > + break; > + default: /* ignore */ > + break; > + } > + len -= be16_to_cpu(mdbo->length); > + mdbo = (void *) mdbo + be16_to_cpu(mdbo->length); > + } > + if (errors) { > + scon->write_errors += errors; > + } > + data->header.flags = SCLP_EVENT_BUFFER_ACCEPTED; > + > + return SCLP_RC_NORMAL_COMPLETION; > +} > + > +static void trigger_console_data(void *opaque, int n, int level) > +{ > + sclp_service_interrupt(0); > +} > + > +/* functions for live migration */ > + > +static const VMStateDescription vmstate_sclplmconsole = { > + .name = "sclplmconsole", > + .version_id = 0, > + .minimum_version_id = 0, > + .minimum_version_id_old = 0, > + .fields = (VMStateField[]) { > + VMSTATE_BOOL(event.event_pending, SCLPConsoleLM), > + VMSTATE_UINT32(write_errors, SCLPConsoleLM), > + VMSTATE_UINT32(length, SCLPConsoleLM), > + VMSTATE_UINT8_ARRAY(buf, SCLPConsoleLM, SIZE_CONSOLE_BUFFER), > + VMSTATE_END_OF_LIST() > + } > +}; > + > +/* qemu object creation and initialization functions */ > + > +/* tell character layer our call-back functions */ > + > +static int console_init(SCLPEvent *event) > +{ > + static bool console_available; > + > + SCLPConsoleLM *scon = DO_UPCAST(SCLPConsoleLM, event, event); > + > + if (console_available) { > + error_report("Multiple line-mode operator consoles are not supported"); > + return -1; > + } > + console_available = true; > + > + if (scon->chr) { > + qemu_chr_add_handlers(scon->chr, chr_can_read, chr_read, NULL, scon); > + } > + scon->irq_console_read = *qemu_allocate_irqs(trigger_console_data, NULL, 1); > + > + return vmstate_register(NULL, 0, &vmstate_sclplmconsole, scon); This should go into your QOM class. Alex ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console 2013-09-18 10:19 [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console Christian Borntraeger ` (10 preceding siblings ...) 2013-09-18 10:19 ` [Qemu-devel] [PATCH 11/11] s390/sclplmconsole: Add support for SCLP line-mode console Christian Borntraeger @ 2013-09-20 3:32 ` Alexander Graf 11 siblings, 0 replies; 18+ messages in thread From: Alexander Graf @ 2013-09-20 3:32 UTC (permalink / raw) To: Christian Borntraeger; +Cc: Jens Freimann, Heinz Graalfs, qemu-devel On 18.09.2013, at 05:19, Christian Borntraeger wrote: > Alex, > > here is a bunch of fixes/changes for sclp/eventfacility followed by a > move of the ebcdic conversion into a stand-alone header file and the > sclp line mode console. Reviewed-by: Alexander Graf <agraf@suse.de> Alex ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2013-09-20 3:32 UTC | newest] Thread overview: 18+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-09-18 10:19 [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 01/11] s390/sclpconsole: modify definition of input buffer Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 02/11] s390/sclpconsole: Add code to support live migration for sclpconsole Christian Borntraeger 2013-09-20 3:07 ` Alexander Graf 2013-09-20 3:24 ` Anthony Liguori 2013-09-18 10:19 ` [Qemu-devel] [PATCH 03/11] s390/sclpquiesce: Add code to support live migration Christian Borntraeger 2013-09-20 3:08 ` Alexander Graf 2013-09-18 10:19 ` [Qemu-devel] [PATCH 04/11] s390/event-facility: " Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 05/11] s390/sclp: add reset() functions Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 06/11] s390/eventfacility: fix multiple Read Event Data sources Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 07/11] s390/eventfacility: Fix receive/send masks Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 08/11] s390/eventfacility: remove unused event_type variable Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 09/11] s390/eventfacility: allow childs to handle more than 1 event type Christian Borntraeger 2013-09-18 10:19 ` [Qemu-devel] [PATCH 10/11] s390/ebcdic: Move conversion tables to header file Christian Borntraeger 2013-09-20 3:21 ` Alexander Graf 2013-09-18 10:19 ` [Qemu-devel] [PATCH 11/11] s390/sclplmconsole: Add support for SCLP line-mode console Christian Borntraeger 2013-09-20 3:31 ` Alexander Graf 2013-09-20 3:32 ` [Qemu-devel] [PATCH 00/11] sclp related fixes and sclp line mode console Alexander Graf
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).