* [Qemu-devel] [PATCH v2 1/4] serial: split serial.c
2012-09-26 12:14 [Qemu-devel] [PATCH v2 0/4] add pci-serial devices Gerd Hoffmann
@ 2012-09-26 12:14 ` Gerd Hoffmann
2012-09-26 12:14 ` [Qemu-devel] [PATCH v2 2/4] serial: add pci variant Gerd Hoffmann
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Gerd Hoffmann @ 2012-09-26 12:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Split serial.c into serial.c, serial.h and serial-isa.c. While being at
creating a serial.h header file move the serial prototypes from pc.h to
the new serial.h. The latter leads to s/pc.h/serial.h/ in tons of
boards which just want the serial bits from pc.h
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/Makefile.objs | 2 +-
hw/alpha_dp264.c | 1 +
hw/kzm.c | 2 +-
hw/mips_fulong2e.c | 1 +
hw/mips_jazz.c | 1 +
hw/mips_malta.c | 1 +
hw/mips_mipssim.c | 2 +-
hw/mips_r4k.c | 1 +
hw/musicpal.c | 2 +-
hw/omap_uart.c | 3 +-
hw/openrisc_sim.c | 3 +-
hw/pc.c | 1 +
hw/pc.h | 27 ---------
hw/petalogix_ml605_mmu.c | 2 +-
hw/ppc/e500.c | 2 +-
hw/ppc405_uc.c | 2 +-
hw/ppc440_bamboo.c | 2 +-
hw/ppc_prep.c | 1 +
hw/pxa2xx.c | 2 +-
hw/serial-isa.c | 130 +++++++++++++++++++++++++++++++++++++++++
hw/serial.c | 143 ++--------------------------------------------
hw/serial.h | 73 +++++++++++++++++++++++
hw/sm501.c | 2 +-
hw/sun4u.c | 1 +
hw/virtex_ml507.c | 2 +-
hw/xtensa_lx60.c | 3 +-
26 files changed, 232 insertions(+), 180 deletions(-)
create mode 100644 hw/serial-isa.c
create mode 100644 hw/serial.h
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 6dfebd2..7a27889 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -20,7 +20,7 @@ hw-obj-$(CONFIG_M48T59) += m48t59.o
hw-obj-$(CONFIG_ESCC) += escc.o
hw-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
-hw-obj-$(CONFIG_SERIAL) += serial.o
+hw-obj-$(CONFIG_SERIAL) += serial.o serial-isa.o
hw-obj-$(CONFIG_PARALLEL) += parallel.o
hw-obj-$(CONFIG_I8254) += i8254_common.o i8254.o
hw-obj-$(CONFIG_PCSPK) += pcspk.o
diff --git a/hw/alpha_dp264.c b/hw/alpha_dp264.c
index 9eb939f..faeb275 100644
--- a/hw/alpha_dp264.c
+++ b/hw/alpha_dp264.c
@@ -15,6 +15,7 @@
#include "mc146818rtc.h"
#include "ide.h"
#include "i8254.h"
+#include "serial.h"
#define MAX_IDE_BUS 2
diff --git a/hw/kzm.c b/hw/kzm.c
index 68cd1b4..1f3082b 100644
--- a/hw/kzm.c
+++ b/hw/kzm.c
@@ -21,7 +21,7 @@
#include "net.h"
#include "sysemu.h"
#include "boards.h"
-#include "pc.h" /* for the FPGA UART that emulates a 16550 */
+#include "serial.h"
#include "imx.h"
/* Memory map for Kzm Emulation Baseboard:
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
index 38e4b86..8a38cd9 100644
--- a/hw/mips_fulong2e.c
+++ b/hw/mips_fulong2e.c
@@ -20,6 +20,7 @@
#include "hw.h"
#include "pc.h"
+#include "serial.h"
#include "fdc.h"
#include "net.h"
#include "boards.h"
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index db927f1..d35cd54 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -26,6 +26,7 @@
#include "mips.h"
#include "mips_cpudevs.h"
#include "pc.h"
+#include "serial.h"
#include "isa.h"
#include "fdc.h"
#include "sysemu.h"
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index ad23f26..05a1eaa 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -24,6 +24,7 @@
#include "hw.h"
#include "pc.h"
+#include "serial.h"
#include "fdc.h"
#include "net.h"
#include "boards.h"
diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c
index 830f635..0ee6756 100644
--- a/hw/mips_mipssim.c
+++ b/hw/mips_mipssim.c
@@ -27,7 +27,7 @@
#include "hw.h"
#include "mips.h"
#include "mips_cpudevs.h"
-#include "pc.h"
+#include "serial.h"
#include "isa.h"
#include "net.h"
#include "sysemu.h"
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 967a76e..b3be80b 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -11,6 +11,7 @@
#include "mips.h"
#include "mips_cpudevs.h"
#include "pc.h"
+#include "serial.h"
#include "isa.h"
#include "net.h"
#include "sysemu.h"
diff --git a/hw/musicpal.c b/hw/musicpal.c
index f305e21..346fe41 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -15,7 +15,7 @@
#include "net.h"
#include "sysemu.h"
#include "boards.h"
-#include "pc.h"
+#include "serial.h"
#include "qemu-timer.h"
#include "ptimer.h"
#include "block.h"
diff --git a/hw/omap_uart.c b/hw/omap_uart.c
index 167d5c4..1c16a54 100644
--- a/hw/omap_uart.c
+++ b/hw/omap_uart.c
@@ -20,8 +20,7 @@
#include "qemu-char.h"
#include "hw.h"
#include "omap.h"
-/* We use pc-style serial ports. */
-#include "pc.h"
+#include "serial.h"
#include "exec-memory.h"
/* UARTs */
diff --git a/hw/openrisc_sim.c b/hw/openrisc_sim.c
index 55e97f0..e484613 100644
--- a/hw/openrisc_sim.c
+++ b/hw/openrisc_sim.c
@@ -21,7 +21,8 @@
#include "hw.h"
#include "boards.h"
#include "elf.h"
-#include "pc.h"
+#include "serial.h"
+#include "net.h"
#include "loader.h"
#include "exec-memory.h"
#include "sysemu.h"
diff --git a/hw/pc.c b/hw/pc.c
index 7e7e0e2..f056777 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -23,6 +23,7 @@
*/
#include "hw.h"
#include "pc.h"
+#include "serial.h"
#include "apic.h"
#include "fdc.h"
#include "ide.h"
diff --git a/hw/pc.h b/hw/pc.h
index e4db071..170a265 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -12,33 +12,6 @@
/* PC-style peripherals (also used by other machines). */
-/* serial.c */
-
-SerialState *serial_init(int base, qemu_irq irq, int baudbase,
- CharDriverState *chr);
-SerialState *serial_mm_init(MemoryRegion *address_space,
- target_phys_addr_t base, int it_shift,
- qemu_irq irq, int baudbase,
- CharDriverState *chr, enum device_endian);
-static inline bool serial_isa_init(ISABus *bus, int index,
- CharDriverState *chr)
-{
- ISADevice *dev;
-
- dev = isa_try_create(bus, "isa-serial");
- if (!dev) {
- return false;
- }
- qdev_prop_set_uint32(&dev->qdev, "index", index);
- qdev_prop_set_chr(&dev->qdev, "chardev", chr);
- if (qdev_init(&dev->qdev) < 0) {
- return false;
- }
- return true;
-}
-
-void serial_set_frequency(SerialState *s, uint32_t frequency);
-
/* parallel.c */
static inline bool parallel_init(ISABus *bus, int index, CharDriverState *chr)
{
diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
index dced648..03f68e8 100644
--- a/hw/petalogix_ml605_mmu.c
+++ b/hw/petalogix_ml605_mmu.c
@@ -34,7 +34,7 @@
#include "boards.h"
#include "xilinx.h"
#include "blockdev.h"
-#include "pc.h"
+#include "serial.h"
#include "exec-memory.h"
#include "microblaze_boot.h"
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 6f0de6d..466435a 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -19,7 +19,7 @@
#include "e500.h"
#include "net.h"
#include "hw/hw.h"
-#include "hw/pc.h"
+#include "hw/serial.h"
#include "hw/pci.h"
#include "hw/boards.h"
#include "sysemu.h"
diff --git a/hw/ppc405_uc.c b/hw/ppc405_uc.c
index 89e5013..3d3c33c 100644
--- a/hw/ppc405_uc.c
+++ b/hw/ppc405_uc.c
@@ -24,7 +24,7 @@
#include "hw.h"
#include "ppc.h"
#include "ppc405.h"
-#include "pc.h"
+#include "serial.h"
#include "qemu-timer.h"
#include "sysemu.h"
#include "qemu-log.h"
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index c198071..7e6fa85 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -23,7 +23,7 @@
#include "loader.h"
#include "elf.h"
#include "exec-memory.h"
-#include "pc.h"
+#include "serial.h"
#include "ppc.h"
#include "ppc405.h"
#include "sysemu.h"
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 592b7b2..0390800 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -24,6 +24,7 @@
#include "hw.h"
#include "nvram.h"
#include "pc.h"
+#include "serial.h"
#include "fdc.h"
#include "net.h"
#include "sysemu.h"
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index d5f1420..4ec904f 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -10,7 +10,7 @@
#include "sysbus.h"
#include "pxa.h"
#include "sysemu.h"
-#include "pc.h"
+#include "serial.h"
#include "i2c.h"
#include "ssi.h"
#include "qemu-char.h"
diff --git a/hw/serial-isa.c b/hw/serial-isa.c
new file mode 100644
index 0000000..96c78f7
--- /dev/null
+++ b/hw/serial-isa.c
@@ -0,0 +1,130 @@
+/*
+ * QEMU 16550A UART emulation
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * Copyright (c) 2008 Citrix Systems, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "serial.h"
+#include "isa.h"
+
+typedef struct ISASerialState {
+ ISADevice dev;
+ uint32_t index;
+ uint32_t iobase;
+ uint32_t isairq;
+ SerialState state;
+} ISASerialState;
+
+static const int isa_serial_io[MAX_SERIAL_PORTS] = {
+ 0x3f8, 0x2f8, 0x3e8, 0x2e8
+};
+static const int isa_serial_irq[MAX_SERIAL_PORTS] = {
+ 4, 3, 4, 3
+};
+
+static int serial_isa_initfn(ISADevice *dev)
+{
+ static int index;
+ ISASerialState *isa = DO_UPCAST(ISASerialState, dev, dev);
+ SerialState *s = &isa->state;
+
+ if (isa->index == -1) {
+ isa->index = index;
+ }
+ if (isa->index >= MAX_SERIAL_PORTS) {
+ return -1;
+ }
+ if (isa->iobase == -1) {
+ isa->iobase = isa_serial_io[isa->index];
+ }
+ if (isa->isairq == -1) {
+ isa->isairq = isa_serial_irq[isa->index];
+ }
+ index++;
+
+ s->baudbase = 115200;
+ isa_init_irq(dev, &s->irq, isa->isairq);
+ serial_init_core(s);
+ qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 3);
+
+ memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8);
+ isa_register_ioport(dev, &s->io, isa->iobase);
+ return 0;
+}
+
+static const VMStateDescription vmstate_isa_serial = {
+ .name = "serial",
+ .version_id = 3,
+ .minimum_version_id = 2,
+ .fields = (VMStateField[]) {
+ VMSTATE_STRUCT(state, ISASerialState, 0, vmstate_serial, SerialState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static Property serial_isa_properties[] = {
+ DEFINE_PROP_UINT32("index", ISASerialState, index, -1),
+ DEFINE_PROP_HEX32("iobase", ISASerialState, iobase, -1),
+ DEFINE_PROP_UINT32("irq", ISASerialState, isairq, -1),
+ DEFINE_PROP_CHR("chardev", ISASerialState, state.chr),
+ DEFINE_PROP_UINT32("wakeup", ISASerialState, state.wakeup, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void serial_isa_class_initfn(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+ ic->init = serial_isa_initfn;
+ dc->vmsd = &vmstate_isa_serial;
+ dc->props = serial_isa_properties;
+}
+
+static TypeInfo serial_isa_info = {
+ .name = "isa-serial",
+ .parent = TYPE_ISA_DEVICE,
+ .instance_size = sizeof(ISASerialState),
+ .class_init = serial_isa_class_initfn,
+};
+
+static void serial_register_types(void)
+{
+ type_register_static(&serial_isa_info);
+}
+
+type_init(serial_register_types)
+
+bool serial_isa_init(ISABus *bus, int index, CharDriverState *chr)
+{
+ ISADevice *dev;
+
+ dev = isa_try_create(bus, "isa-serial");
+ if (!dev) {
+ return false;
+ }
+ qdev_prop_set_uint32(&dev->qdev, "index", index);
+ qdev_prop_set_chr(&dev->qdev, "chardev", chr);
+ if (qdev_init(&dev->qdev) < 0) {
+ return false;
+ }
+ return true;
+}
diff --git a/hw/serial.c b/hw/serial.c
index a421d1e..78e219d 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -22,12 +22,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "hw.h"
+
+#include "serial.h"
#include "qemu-char.h"
-#include "isa.h"
-#include "pc.h"
#include "qemu-timer.h"
-#include "sysemu.h"
//#define DEBUG_SERIAL
@@ -93,8 +91,6 @@
#define UART_FCR_RFR 0x02 /* RCVR Fifo Reset */
#define UART_FCR_FE 0x01 /* FIFO Enable */
-#define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */
-
#define XMIT_FIFO 0
#define RECV_FIFO 1
#define MAX_XMIT_RETRY 4
@@ -107,64 +103,6 @@ do { fprintf(stderr, "serial: " fmt , ## __VA_ARGS__); } while (0)
do {} while (0)
#endif
-typedef struct SerialFIFO {
- uint8_t data[UART_FIFO_LENGTH];
- uint8_t count;
- uint8_t itl; /* Interrupt Trigger Level */
- uint8_t tail;
- uint8_t head;
-} SerialFIFO;
-
-struct SerialState {
- uint16_t divider;
- uint8_t rbr; /* receive register */
- uint8_t thr; /* transmit holding register */
- uint8_t tsr; /* transmit shift register */
- uint8_t ier;
- uint8_t iir; /* read only */
- uint8_t lcr;
- uint8_t mcr;
- uint8_t lsr; /* read only */
- uint8_t msr; /* read only */
- uint8_t scr;
- uint8_t fcr;
- uint8_t fcr_vmstate; /* we can't write directly this value
- it has side effects */
- /* NOTE: this hidden state is necessary for tx irq generation as
- it can be reset while reading iir */
- int thr_ipending;
- qemu_irq irq;
- CharDriverState *chr;
- int last_break_enable;
- int it_shift;
- int baudbase;
- int tsr_retry;
- uint32_t wakeup;
-
- uint64_t last_xmit_ts; /* Time when the last byte was successfully sent out of the tsr */
- SerialFIFO recv_fifo;
- SerialFIFO xmit_fifo;
-
- struct QEMUTimer *fifo_timeout_timer;
- int timeout_ipending; /* timeout interrupt pending state */
- struct QEMUTimer *transmit_timer;
-
-
- uint64_t char_transmit_time; /* time to transmit a char in ticks*/
- int poll_msl;
-
- struct QEMUTimer *modem_status_poll;
- MemoryRegion io;
-};
-
-typedef struct ISASerialState {
- ISADevice dev;
- uint32_t index;
- uint32_t iobase;
- uint32_t isairq;
- SerialState state;
-} ISASerialState;
-
static void serial_receive1(void *opaque, const uint8_t *buf, int size);
static void fifo_clear(SerialState *s, int fifo)
@@ -687,7 +625,7 @@ static int serial_post_load(void *opaque, int version_id)
return 0;
}
-static const VMStateDescription vmstate_serial = {
+const VMStateDescription vmstate_serial = {
.name = "serial",
.version_id = 3,
.minimum_version_id = 2,
@@ -736,7 +674,7 @@ static void serial_reset(void *opaque)
qemu_irq_lower(s->irq);
}
-static void serial_init_core(SerialState *s)
+void serial_init_core(SerialState *s)
{
if (!s->chr) {
fprintf(stderr, "Can't create serial device, empty char device\n");
@@ -761,54 +699,15 @@ void serial_set_frequency(SerialState *s, uint32_t frequency)
serial_update_parameters(s);
}
-static const int isa_serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
-static const int isa_serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
-
static const MemoryRegionPortio serial_portio[] = {
{ 0, 8, 1, .read = serial_ioport_read, .write = serial_ioport_write },
PORTIO_END_OF_LIST()
};
-static const MemoryRegionOps serial_io_ops = {
+const MemoryRegionOps serial_io_ops = {
.old_portio = serial_portio
};
-static int serial_isa_initfn(ISADevice *dev)
-{
- static int index;
- ISASerialState *isa = DO_UPCAST(ISASerialState, dev, dev);
- SerialState *s = &isa->state;
-
- if (isa->index == -1)
- isa->index = index;
- if (isa->index >= MAX_SERIAL_PORTS)
- return -1;
- if (isa->iobase == -1)
- isa->iobase = isa_serial_io[isa->index];
- if (isa->isairq == -1)
- isa->isairq = isa_serial_irq[isa->index];
- index++;
-
- s->baudbase = 115200;
- isa_init_irq(dev, &s->irq, isa->isairq);
- serial_init_core(s);
- qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 3);
-
- memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8);
- isa_register_ioport(dev, &s->io, isa->iobase);
- return 0;
-}
-
-static const VMStateDescription vmstate_isa_serial = {
- .name = "serial",
- .version_id = 3,
- .minimum_version_id = 2,
- .fields = (VMStateField []) {
- VMSTATE_STRUCT(state, ISASerialState, 0, vmstate_serial, SerialState),
- VMSTATE_END_OF_LIST()
- }
-};
-
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
CharDriverState *chr)
{
@@ -886,35 +785,3 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
serial_update_msl(s);
return s;
}
-
-static Property serial_isa_properties[] = {
- DEFINE_PROP_UINT32("index", ISASerialState, index, -1),
- DEFINE_PROP_HEX32("iobase", ISASerialState, iobase, -1),
- DEFINE_PROP_UINT32("irq", ISASerialState, isairq, -1),
- DEFINE_PROP_CHR("chardev", ISASerialState, state.chr),
- DEFINE_PROP_UINT32("wakeup", ISASerialState, state.wakeup, 0),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void serial_isa_class_initfn(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
- ic->init = serial_isa_initfn;
- dc->vmsd = &vmstate_isa_serial;
- dc->props = serial_isa_properties;
-}
-
-static TypeInfo serial_isa_info = {
- .name = "isa-serial",
- .parent = TYPE_ISA_DEVICE,
- .instance_size = sizeof(ISASerialState),
- .class_init = serial_isa_class_initfn,
-};
-
-static void serial_register_types(void)
-{
- type_register_static(&serial_isa_info);
-}
-
-type_init(serial_register_types)
diff --git a/hw/serial.h b/hw/serial.h
new file mode 100644
index 0000000..004a050
--- /dev/null
+++ b/hw/serial.h
@@ -0,0 +1,73 @@
+#include "hw.h"
+#include "sysemu.h"
+#include "memory.h"
+
+#define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */
+
+typedef struct SerialFIFO {
+ uint8_t data[UART_FIFO_LENGTH];
+ uint8_t count;
+ uint8_t itl; /* Interrupt Trigger Level */
+ uint8_t tail;
+ uint8_t head;
+} SerialFIFO;
+
+struct SerialState {
+ uint16_t divider;
+ uint8_t rbr; /* receive register */
+ uint8_t thr; /* transmit holding register */
+ uint8_t tsr; /* transmit shift register */
+ uint8_t ier;
+ uint8_t iir; /* read only */
+ uint8_t lcr;
+ uint8_t mcr;
+ uint8_t lsr; /* read only */
+ uint8_t msr; /* read only */
+ uint8_t scr;
+ uint8_t fcr;
+ uint8_t fcr_vmstate; /* we can't write directly this value
+ it has side effects */
+ /* NOTE: this hidden state is necessary for tx irq generation as
+ it can be reset while reading iir */
+ int thr_ipending;
+ qemu_irq irq;
+ CharDriverState *chr;
+ int last_break_enable;
+ int it_shift;
+ int baudbase;
+ int tsr_retry;
+ uint32_t wakeup;
+
+ /* Time when the last byte was successfully sent out of the tsr */
+ uint64_t last_xmit_ts;
+ SerialFIFO recv_fifo;
+ SerialFIFO xmit_fifo;
+
+ struct QEMUTimer *fifo_timeout_timer;
+ int timeout_ipending; /* timeout interrupt pending state */
+ struct QEMUTimer *transmit_timer;
+
+
+ uint64_t char_transmit_time; /* time to transmit a char in ticks */
+ int poll_msl;
+
+ struct QEMUTimer *modem_status_poll;
+ MemoryRegion io;
+};
+
+extern const VMStateDescription vmstate_serial;
+extern const MemoryRegionOps serial_io_ops;
+
+void serial_init_core(SerialState *s);
+void serial_set_frequency(SerialState *s, uint32_t frequency);
+
+/* legacy pre qom */
+SerialState *serial_init(int base, qemu_irq irq, int baudbase,
+ CharDriverState *chr);
+SerialState *serial_mm_init(MemoryRegion *address_space,
+ target_phys_addr_t base, int it_shift,
+ qemu_irq irq, int baudbase,
+ CharDriverState *chr, enum device_endian end);
+
+/* serial-isa.c */
+bool serial_isa_init(ISABus *bus, int index, CharDriverState *chr);
diff --git a/hw/sm501.c b/hw/sm501.c
index 786e076..050d096 100644
--- a/hw/sm501.c
+++ b/hw/sm501.c
@@ -24,7 +24,7 @@
#include <stdio.h>
#include "hw.h"
-#include "pc.h"
+#include "serial.h"
#include "console.h"
#include "devices.h"
#include "sysbus.h"
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 07cd042..2a85ddb 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -25,6 +25,7 @@
#include "pci.h"
#include "apb_pci.h"
#include "pc.h"
+#include "serial.h"
#include "nvram.h"
#include "fdc.h"
#include "net.h"
diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c
index 79bc0d1..6ae5f60 100644
--- a/hw/virtex_ml507.c
+++ b/hw/virtex_ml507.c
@@ -24,7 +24,7 @@
#include "sysbus.h"
#include "hw.h"
-#include "pc.h"
+#include "serial.h"
#include "net.h"
#include "flash.h"
#include "sysemu.h"
diff --git a/hw/xtensa_lx60.c b/hw/xtensa_lx60.c
index 3653f65..99d8b4f 100644
--- a/hw/xtensa_lx60.c
+++ b/hw/xtensa_lx60.c
@@ -31,7 +31,8 @@
#include "elf.h"
#include "memory.h"
#include "exec-memory.h"
-#include "pc.h"
+#include "serial.h"
+#include "net.h"
#include "sysbus.h"
#include "flash.h"
#include "blockdev.h"
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v2 2/4] serial: add pci variant
2012-09-26 12:14 [Qemu-devel] [PATCH v2 0/4] add pci-serial devices Gerd Hoffmann
2012-09-26 12:14 ` [Qemu-devel] [PATCH v2 1/4] serial: split serial.c Gerd Hoffmann
@ 2012-09-26 12:14 ` Gerd Hoffmann
2012-09-26 12:14 ` [Qemu-devel] [PATCH v2 3/4] serial: add windows inf file for the pci card to docs Gerd Hoffmann
2012-09-26 12:14 ` [Qemu-devel] [PATCH v2 4/4] serial: add 2x + 4x pci variant Gerd Hoffmann
3 siblings, 0 replies; 7+ messages in thread
From: Gerd Hoffmann @ 2012-09-26 12:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
So we get a hot-pluggable 16550 uart.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
default-configs/pci.mak | 2 +
hw/Makefile.objs | 1 +
hw/pci_ids.h | 1 +
hw/serial-pci.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 119 insertions(+), 0 deletions(-)
create mode 100644 hw/serial-pci.c
diff --git a/default-configs/pci.mak b/default-configs/pci.mak
index 69e18f1..ae9d1eb 100644
--- a/default-configs/pci.mak
+++ b/default-configs/pci.mak
@@ -19,3 +19,5 @@ CONFIG_IDE_PCI=y
CONFIG_AHCI=y
CONFIG_ESP=y
CONFIG_ESP_PCI=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_PCI=y
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 7a27889..9ab8878 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -21,6 +21,7 @@ hw-obj-$(CONFIG_ESCC) += escc.o
hw-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
hw-obj-$(CONFIG_SERIAL) += serial.o serial-isa.o
+hw-obj-$(CONFIG_SERIAL_PCI) += serial-pci.o
hw-obj-$(CONFIG_PARALLEL) += parallel.o
hw-obj-$(CONFIG_I8254) += i8254_common.o i8254.o
hw-obj-$(CONFIG_PCSPK) += pcspk.o
diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index 301bf1c..c017a79 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -37,6 +37,7 @@
#define PCI_CLASS_BRIDGE_PCI 0x0604
#define PCI_CLASS_BRIDGE_OTHER 0x0680
+#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700
#define PCI_CLASS_COMMUNICATION_OTHER 0x0780
#define PCI_CLASS_PROCESSOR_CO 0x0b40
diff --git a/hw/serial-pci.c b/hw/serial-pci.c
new file mode 100644
index 0000000..88b71f5
--- /dev/null
+++ b/hw/serial-pci.c
@@ -0,0 +1,115 @@
+/*
+ * QEMU 16550A UART emulation
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * Copyright (c) 2008 Citrix Systems, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/*
+ * pci-serial spec:
+ * pci region 0 is a io bar, 8 bytes long, with the 16550 uart mapped to it.
+ * interrupt is wired to pin A.
+ *
+ * [root@fedora ~]# lspci -vnse
+ * 00:0e.0 0700: 1b36:0002 (rev 01) (prog-if 00 [8250])
+ * Subsystem: 1af4:1100
+ * Physical Slot: 14
+ * Flags: fast devsel, IRQ 11
+ * I/O ports at c130 [size=8]
+ * Kernel driver in use: serial
+ */
+
+#include "serial.h"
+#include "pci.h"
+
+typedef struct PCISerialState {
+ PCIDevice dev;
+ SerialState state;
+} PCISerialState;
+
+static int serial_pci_init(PCIDevice *dev)
+{
+ PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
+ SerialState *s = &pci->state;
+
+ s->baudbase = 115200;
+ serial_init_core(s);
+
+ pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
+ s->irq = pci->dev.irq[0];
+
+ memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8);
+ pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
+ return 0;
+}
+
+static void serial_pci_exit(PCIDevice *dev)
+{
+ PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
+ SerialState *s = &pci->state;
+
+ qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
+ memory_region_destroy(&s->io);
+}
+
+static const VMStateDescription vmstate_pci_serial = {
+ .name = "pci-serial",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_PCI_DEVICE(dev, PCISerialState),
+ VMSTATE_STRUCT(state, PCISerialState, 0, vmstate_serial, SerialState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static Property serial_pci_properties[] = {
+ DEFINE_PROP_CHR("chardev", PCISerialState, state.chr),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void serial_pci_class_initfn(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
+ pc->init = serial_pci_init;
+ pc->exit = serial_pci_exit;
+ pc->vendor_id = 0x1b36; /* Red Hat */
+ pc->device_id = 0x0002;
+ pc->revision = 1;
+ pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL;
+ dc->vmsd = &vmstate_pci_serial;
+ dc->props = serial_pci_properties;
+}
+
+static TypeInfo serial_pci_info = {
+ .name = "pci-serial",
+ .parent = TYPE_PCI_DEVICE,
+ .instance_size = sizeof(PCISerialState),
+ .class_init = serial_pci_class_initfn,
+};
+
+static void serial_pci_register_types(void)
+{
+ type_register_static(&serial_pci_info);
+}
+
+type_init(serial_pci_register_types)
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v2 3/4] serial: add windows inf file for the pci card to docs
2012-09-26 12:14 [Qemu-devel] [PATCH v2 0/4] add pci-serial devices Gerd Hoffmann
2012-09-26 12:14 ` [Qemu-devel] [PATCH v2 1/4] serial: split serial.c Gerd Hoffmann
2012-09-26 12:14 ` [Qemu-devel] [PATCH v2 2/4] serial: add pci variant Gerd Hoffmann
@ 2012-09-26 12:14 ` Gerd Hoffmann
2012-09-29 11:41 ` Blue Swirl
2012-09-26 12:14 ` [Qemu-devel] [PATCH v2 4/4] serial: add 2x + 4x pci variant Gerd Hoffmann
3 siblings, 1 reply; 7+ messages in thread
From: Gerd Hoffmann @ 2012-09-26 12:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
docs/qemupciserial.inf | 107 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 107 insertions(+), 0 deletions(-)
create mode 100644 docs/qemupciserial.inf
diff --git a/docs/qemupciserial.inf b/docs/qemupciserial.inf
new file mode 100644
index 0000000..905a929
--- /dev/null
+++ b/docs/qemupciserial.inf
@@ -0,0 +1,107 @@
+; qemupciserial.inf for qemu, based on MSPORTS.INF
+
+; The driver itself is shipped with windows (serial.sys). This is
+; just a inf file to tell windows which pci id the serial pci card
+; emulated by qemu has, and to apply a name tag to it which windows
+; will show in the device manager.
+
+; Installing the driver: Go to device manager. You should find a "pci
+; serial card" tagged with a yellow question mark. Open properties.
+; Pick "update driver". Then "select driver manually". Pick "Ports
+; (Com+Lpt)" from the list. Click "Have a disk". Select this file.
+; Procedure may vary a bit depending on the windows version.
+
+[Version]
+Signature="$CHICAGO$"
+Class=Ports
+ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
+Provider=%QEMU%
+DriverVer=09/24/2012,1.3.0
+
+[SourceDisksNames]
+3426=windows cd
+
+[SourceDisksFiles]
+serial.sys = 3426
+serenum.sys = 3426
+
+[DestinationDirs]
+DefaultDestDir = 11 ;LDID_SYS
+ComPort.NT.Copy = 12 ;DIRID_DRIVERS
+SerialEnumerator.NT.Copy=12 ;DIRID_DRIVERS
+
+; Drivers
+;----------------------------------------------------------
+[Manufacturer]
+%QEMU%=QEMU,NTx86
+
+[QEMU.NTx86]
+%QEMU-PCI_SERIAL.DeviceDesc% = ComPort, "PCI\VEN_1b36&DEV_0002&CC_0700"
+
+; COM sections
+;----------------------------------------------------------
+[ComPort.AddReg]
+HKR,,PortSubClass,1,01
+
+[ComPort.NT]
+AddReg=ComPort.AddReg, ComPort.NT.AddReg
+LogConfig=caa
+SyssetupPnPFlags = 1
+
+[ComPort.NT.HW]
+AddReg=ComPort.NT.HW.AddReg
+
+[ComPort.NT.AddReg]
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
+
+[ComPort.NT.HW.AddReg]
+HKR,,"UpperFilters",0x00010000,"serenum"
+
+;-------------- Service installation
+; Port Driver (function driver for this device)
+[ComPort.NT.Services]
+AddService = Serial, 0x00000002, Serial_Service_Inst, Serial_EventLog_Inst
+AddService = Serenum,,Serenum_Service_Inst
+
+; -------------- Serial Port Driver install sections
+[Serial_Service_Inst]
+DisplayName = %Serial.SVCDESC%
+ServiceType = 1 ; SERVICE_KERNEL_DRIVER
+StartType = 1 ; SERVICE_SYSTEM_START (this driver may do detection)
+ErrorControl = 0 ; SERVICE_ERROR_IGNORE
+ServiceBinary = %12%\serial.sys
+LoadOrderGroup = Extended base
+
+; -------------- Serenum Driver install section
+[Serenum_Service_Inst]
+DisplayName = %Serenum.SVCDESC%
+ServiceType = 1 ; SERVICE_KERNEL_DRIVER
+StartType = 3 ; SERVICE_DEMAND_START
+ErrorControl = 1 ; SERVICE_ERROR_NORMAL
+ServiceBinary = %12%\serenum.sys
+LoadOrderGroup = PNP Filter
+
+[Serial_EventLog_Inst]
+AddReg = Serial_EventLog_AddReg
+
+[Serial_EventLog_AddReg]
+HKR,,EventMessageFile,0x00020000,"%%SystemRoot%%\System32\IoLogMsg.dll;%%SystemRoot%%\System32\drivers\serial.sys"
+HKR,,TypesSupported,0x00010001,7
+
+; The following sections are COM port resource configs.
+; Section name format means:
+; Char 1 = c (COM port)
+; Char 2 = I/O config: 1 (3f8), 2 (2f8), 3 (3e8), 4 (2e8), a (any)
+; Char 3 = IRQ config: #, a (any)
+
+[caa] ; Any base, any IRQ
+ConfigPriority=HARDRECONFIG
+IOConfig=8@100-ffff%fff8(3ff::)
+IRQConfig=S:3,4,5,7,9,10,11,12,14,15
+
+[Strings]
+QEMU="QEMU"
+QEMU-PCI_SERIAL.DeviceDesc="QEMU Serial PCI Card"
+
+Serial.SVCDESC = "Serial port driver"
+Serenum.SVCDESC = "Serenum Filter Driver"
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v2 4/4] serial: add 2x + 4x pci variant
2012-09-26 12:14 [Qemu-devel] [PATCH v2 0/4] add pci-serial devices Gerd Hoffmann
` (2 preceding siblings ...)
2012-09-26 12:14 ` [Qemu-devel] [PATCH v2 3/4] serial: add windows inf file for the pci card to docs Gerd Hoffmann
@ 2012-09-26 12:14 ` Gerd Hoffmann
2012-09-28 14:08 ` Paolo Bonzini
3 siblings, 1 reply; 7+ messages in thread
From: Gerd Hoffmann @ 2012-09-26 12:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
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 905a929..911eaa6 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 88b71f5..54bd4eb 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.
+ *
* [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;
+ qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
+ 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
^ permalink raw reply related [flat|nested] 7+ messages in thread