From: Anthony Liguori <anthony@codemonkey.ws>
To: Gerd Hoffmann <kraxel@redhat.com>, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v3 4/9] serial: add 2x + 4x pci variant
Date: Mon, 15 Oct 2012 09:18:00 -0500 [thread overview]
Message-ID: <874nlvg6p3.fsf@codemonkey.ws> (raw)
In-Reply-To: <1350288417-24350-5-git-send-email-kraxel@redhat.com>
Gerd Hoffmann <kraxel@redhat.com> writes:
> Add multiport serial card implementation, with two variants,
> one featuring two and one featuring four ports.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> docs/qemupciserial.inf | 2 +
> hw/serial-pci.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 159 insertions(+), 0 deletions(-)
>
> diff --git a/docs/qemupciserial.inf b/docs/qemupciserial.inf
> index c7cea99..3474310 100644
> --- a/docs/qemupciserial.inf
> +++ b/docs/qemupciserial.inf
> @@ -11,6 +11,8 @@
> ; (Com+Lpt)" from the list. Click "Have a disk". Select this file.
> ; Procedure may vary a bit depending on the windows version.
>
> +; FIXME: This file covers the single port version only.
> +
> [Version]
> Signature="$CHICAGO$"
> Class=Ports
> diff --git a/hw/serial-pci.c b/hw/serial-pci.c
> index 17247a8..c89e8b0 100644
> --- a/hw/serial-pci.c
> +++ b/hw/serial-pci.c
> @@ -28,6 +28,14 @@
> * pci region 0 is a io bar, 8 bytes long, with the 16550 uart mapped to it.
> * interrupt is wired to pin A.
> *
> + * pci-serial-4x spec:
> + * pci region 0 is a io bar, with four 16550 uarts mapped after each other,
> + * the first at offset 0, second at 8, third at 16 and fourth at 24.
> + * interrupt is wired to pin A.
> + *
> + * pci-serial-2x spec:
> + * same as pci-serial-4x but with two uarts only.
> + *
I know I neglected to respond to your previous note in this thread, but
I'd prefer this be made a file in docs/.
That way, you can look in docs and discover all of the QEMU-invented
devices. Having to troll through hw/*.c to find which new devices were
added is a bit painful.
This is important for people looking to implement guest support for
QEMU.
Regards,
Anthony Liguori
> * [root@fedora ~]# lspci -vnse
> * 00:0e.0 0700: 1b36:0002 (rev 01) (prog-if 00 [8250])
> * Subsystem: 1af4:1100
> @@ -40,11 +48,23 @@
> #include "serial.h"
> #include "pci.h"
>
> +#define PCI_SERIAL_MAX_PORTS 4
> +
> typedef struct PCISerialState {
> PCIDevice dev;
> SerialState state;
> } PCISerialState;
>
> +typedef struct PCIMultiSerialState {
> + PCIDevice dev;
> + MemoryRegion iobar;
> + uint32_t ports;
> + char *name[PCI_SERIAL_MAX_PORTS];
> + SerialState state[PCI_SERIAL_MAX_PORTS];
> + uint32_t level[PCI_SERIAL_MAX_PORTS];
> + qemu_irq *irqs;
> +} PCIMultiSerialState;
> +
> static int serial_pci_init(PCIDevice *dev)
> {
> PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
> @@ -61,6 +81,56 @@ static int serial_pci_init(PCIDevice *dev)
> return 0;
> }
>
> +static void multi_serial_irq_mux(void *opaque, int n, int level)
> +{
> + PCIMultiSerialState *pci = opaque;
> + int i, pending = 0;
> +
> + pci->level[n] = level;
> + for (i = 0; i < pci->ports; i++) {
> + if (pci->level[i]) {
> + pending = 1;
> + }
> + }
> + qemu_set_irq(pci->dev.irq[0], pending);
> +}
> +
> +static int multi_serial_pci_init(PCIDevice *dev)
> +{
> + PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
> + PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev);
> + SerialState *s;
> + int i;
> +
> + switch (pc->device_id) {
> + case 0x0003:
> + pci->ports = 2;
> + break;
> + case 0x0004:
> + pci->ports = 4;
> + break;
> + }
> + assert(pci->ports > 0);
> + assert(pci->ports <= PCI_SERIAL_MAX_PORTS);
> +
> + pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
> + memory_region_init(&pci->iobar, "multiserial", 8 * pci->ports);
> + pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->iobar);
> + pci->irqs = qemu_allocate_irqs(multi_serial_irq_mux, pci,
> + pci->ports);
> +
> + for (i = 0; i < pci->ports; i++) {
> + s = pci->state + i;
> + s->baudbase = 115200;
> + serial_init_core(s);
> + s->irq = pci->irqs[i];
> + pci->name[i] = g_strdup_printf("uart #%d", i+1);
> + memory_region_init_io(&s->io, &serial_io_ops, s, pci->name[i], 8);
> + memory_region_add_subregion(&pci->iobar, 8 * i, &s->io);
> + }
> + return 0;
> +}
> +
> static void serial_pci_exit(PCIDevice *dev)
> {
> PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
> @@ -70,6 +140,22 @@ static void serial_pci_exit(PCIDevice *dev)
> memory_region_destroy(&s->io);
> }
>
> +static void multi_serial_pci_exit(PCIDevice *dev)
> +{
> + PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev);
> + SerialState *s;
> + int i;
> +
> + for (i = 0; i < pci->ports; i++) {
> + s = pci->state + i;
> + serial_exit_core(s);
> + memory_region_destroy(&s->io);
> + g_free(pci->name[i]);
> + }
> + memory_region_destroy(&pci->iobar);
> + qemu_free_irqs(pci->irqs);
> +}
> +
> static const VMStateDescription vmstate_pci_serial = {
> .name = "pci-serial",
> .version_id = 1,
> @@ -81,11 +167,38 @@ static const VMStateDescription vmstate_pci_serial = {
> }
> };
>
> +static const VMStateDescription vmstate_pci_multi_serial = {
> + .name = "pci-serial-multi",
> + .version_id = 1,
> + .minimum_version_id = 1,
> + .fields = (VMStateField[]) {
> + VMSTATE_PCI_DEVICE(dev, PCIMultiSerialState),
> + VMSTATE_STRUCT_ARRAY(state, PCIMultiSerialState, PCI_SERIAL_MAX_PORTS,
> + 0, vmstate_serial, SerialState),
> + VMSTATE_UINT32_ARRAY(level, PCIMultiSerialState, PCI_SERIAL_MAX_PORTS),
> + VMSTATE_END_OF_LIST()
> + }
> +};
> +
> static Property serial_pci_properties[] = {
> DEFINE_PROP_CHR("chardev", PCISerialState, state.chr),
> DEFINE_PROP_END_OF_LIST(),
> };
>
> +static Property multi_2x_serial_pci_properties[] = {
> + DEFINE_PROP_CHR("chardev1", PCIMultiSerialState, state[0].chr),
> + DEFINE_PROP_CHR("chardev2", PCIMultiSerialState, state[1].chr),
> + DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static Property multi_4x_serial_pci_properties[] = {
> + DEFINE_PROP_CHR("chardev1", PCIMultiSerialState, state[0].chr),
> + DEFINE_PROP_CHR("chardev2", PCIMultiSerialState, state[1].chr),
> + DEFINE_PROP_CHR("chardev3", PCIMultiSerialState, state[2].chr),
> + DEFINE_PROP_CHR("chardev4", PCIMultiSerialState, state[3].chr),
> + DEFINE_PROP_END_OF_LIST(),
> +};
> +
> static void serial_pci_class_initfn(ObjectClass *klass, void *data)
> {
> DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -100,6 +213,34 @@ static void serial_pci_class_initfn(ObjectClass *klass, void *data)
> dc->props = serial_pci_properties;
> }
>
> +static void multi_2x_serial_pci_class_initfn(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
> + pc->init = multi_serial_pci_init;
> + pc->exit = multi_serial_pci_exit;
> + pc->vendor_id = 0x1b36; /* Red Hat */
> + pc->device_id = 0x0003;
> + pc->revision = 1;
> + pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL;
> + dc->vmsd = &vmstate_pci_multi_serial;
> + dc->props = multi_2x_serial_pci_properties;
> +}
> +
> +static void multi_4x_serial_pci_class_initfn(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
> + pc->init = multi_serial_pci_init;
> + pc->exit = multi_serial_pci_exit;
> + pc->vendor_id = 0x1b36; /* Red Hat */
> + pc->device_id = 0x0004;
> + pc->revision = 1;
> + pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL;
> + dc->vmsd = &vmstate_pci_multi_serial;
> + dc->props = multi_4x_serial_pci_properties;
> +}
> +
> static TypeInfo serial_pci_info = {
> .name = "pci-serial",
> .parent = TYPE_PCI_DEVICE,
> @@ -107,9 +248,25 @@ static TypeInfo serial_pci_info = {
> .class_init = serial_pci_class_initfn,
> };
>
> +static TypeInfo multi_2x_serial_pci_info = {
> + .name = "pci-serial-2x",
> + .parent = TYPE_PCI_DEVICE,
> + .instance_size = sizeof(PCIMultiSerialState),
> + .class_init = multi_2x_serial_pci_class_initfn,
> +};
> +
> +static TypeInfo multi_4x_serial_pci_info = {
> + .name = "pci-serial-4x",
> + .parent = TYPE_PCI_DEVICE,
> + .instance_size = sizeof(PCIMultiSerialState),
> + .class_init = multi_4x_serial_pci_class_initfn,
> +};
> +
> static void serial_pci_register_types(void)
> {
> type_register_static(&serial_pci_info);
> + type_register_static(&multi_2x_serial_pci_info);
> + type_register_static(&multi_4x_serial_pci_info);
> }
>
> type_init(serial_pci_register_types)
> --
> 1.7.1
next prev parent reply other threads:[~2012-10-15 14:18 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-15 8:06 [Qemu-devel] [PATCH v3 0/9] serial device hotplug patch series Gerd Hoffmann
2012-10-15 8:06 ` [Qemu-devel] [PATCH v3 1/9] serial: split serial.c Gerd Hoffmann
2012-10-15 14:16 ` Anthony Liguori
2012-10-15 8:06 ` [Qemu-devel] [PATCH v3 2/9] serial: add pci variant Gerd Hoffmann
2012-10-15 8:06 ` [Qemu-devel] [PATCH v3 3/9] serial: add windows inf file for the pci card to docs Gerd Hoffmann
2012-10-15 8:06 ` [Qemu-devel] [PATCH v3 4/9] serial: add 2x + 4x pci variant Gerd Hoffmann
2012-10-15 14:18 ` Anthony Liguori [this message]
2012-10-15 8:06 ` [Qemu-devel] [PATCH v3 5/9] usb-serial: don't magically zap chardev on umplug Gerd Hoffmann
2012-10-15 8:06 ` [Qemu-devel] [PATCH v3 6/9] usb-serial: only expose device in guest when the chardev is open Gerd Hoffmann
2012-10-15 8:06 ` [Qemu-devel] [PATCH v3 7/9] chardev: add error reporting for qemu_chr_new_from_opts Gerd Hoffmann
2012-10-17 1:12 ` Luiz Capitulino
2012-10-17 1:13 ` Luiz Capitulino
2012-10-15 8:06 ` [Qemu-devel] [PATCH v3 8/9] chardev: fix QemuOpts lifecycle Gerd Hoffmann
2012-10-17 1:18 ` Luiz Capitulino
2012-10-15 8:06 ` [Qemu-devel] [PATCH v3 9/9] chardev: add hotplug support Gerd Hoffmann
2012-10-15 14:22 ` Anthony Liguori
2012-10-15 18:04 ` Eric Blake
2012-10-17 1:49 ` Luiz Capitulino
2012-10-16 9:13 ` Lei Li
2012-10-17 9:27 ` Gerd Hoffmann
2012-10-17 1:28 ` Luiz Capitulino
2012-10-17 1:52 ` [Qemu-devel] [PATCH v3 0/9] serial device hotplug patch series Luiz Capitulino
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=874nlvg6p3.fsf@codemonkey.ws \
--to=anthony@codemonkey.ws \
--cc=kraxel@redhat.com \
--cc=qemu-devel@nongnu.org \
/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.