SerialState currently inherits just from DeviceState and serial devices use SerialState as an "IP block". Since DeviceState doesn't have an API to provide MMIO regions or IRQs, all serial devices access attributes internal to SerialState directly. Fix this by having SerialState inherit from SysBusDevice.
In addition, DeviceState doesn't participate in the reset framework while SysBusDevice does. This allows for implementing reset functionality more idiomatically. Signed-off-by: Bernhard Beschow <[email protected]> --- include/hw/char/serial.h | 4 ++-- hw/char/diva-gsp.c | 18 +++++++++--------- hw/char/serial-isa.c | 16 ++++++++++------ hw/char/serial-mm.c | 8 ++++---- hw/char/serial-pci-multi.c | 18 +++++++++--------- hw/char/serial-pci.c | 10 +++++----- hw/char/serial.c | 5 ++++- 7 files changed, 43 insertions(+), 36 deletions(-) diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h index 0cf641a860..2ee9e5984c 100644 --- a/include/hw/char/serial.h +++ b/include/hw/char/serial.h @@ -26,7 +26,7 @@ #ifndef HW_SERIAL_H #define HW_SERIAL_H -#include "hw/core/qdev.h" +#include "hw/core/sysbus.h" #include "chardev/char-fe.h" #include "system/memory.h" #include "qemu/fifo8.h" @@ -35,7 +35,7 @@ #define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */ struct SerialState { - DeviceState parent; + SysBusDevice parent; uint16_t divider; uint8_t rbr; /* receive register */ diff --git a/hw/char/diva-gsp.c b/hw/char/diva-gsp.c index 2ea60103ea..55c42effe9 100644 --- a/hw/char/diva-gsp.c +++ b/hw/char/diva-gsp.c @@ -56,13 +56,13 @@ typedef struct PCIDivaSerialState { static void diva_pci_exit(PCIDevice *dev) { PCIDivaSerialState *pci = DO_UPCAST(PCIDivaSerialState, dev, dev); - SerialState *s; int i; for (i = 0; i < pci->ports; i++) { - s = pci->state + i; - qdev_unrealize(DEVICE(s)); - memory_region_del_subregion(&pci->membar, &s->io); + SysBusDevice *sbd = SYS_BUS_DEVICE(pci->state + i); + qdev_unrealize(DEVICE(sbd)); + memory_region_del_subregion(&pci->membar, + sysbus_mmio_get_region(sbd, 0)); } qemu_free_irqs(pci->irqs, pci->ports); } @@ -116,7 +116,6 @@ static void diva_pci_realize(PCIDevice *dev, Error **errp) { PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); PCIDivaSerialState *pci = DO_UPCAST(PCIDivaSerialState, dev, dev); - SerialState *s; struct diva_info di = diva_get_diva_info(pc); size_t i, offset = 0; size_t portmask = di.omask; @@ -128,19 +127,20 @@ static void diva_pci_realize(PCIDevice *dev, Error **errp) pci->irqs = qemu_allocate_irqs(multi_serial_irq_mux, pci, di.nports); for (i = 0; i < di.nports; i++) { - s = pci->state + i; - if (!qdev_realize(DEVICE(s), NULL, errp)) { + SysBusDevice *sbd = SYS_BUS_DEVICE(pci->state + i); + if (!sysbus_realize(sbd, errp)) { diva_pci_exit(dev); return; } - s->irq = pci->irqs[i]; + sysbus_connect_irq(sbd, 0, pci->irqs[i]); /* calculate offset of given port based on bitmask */ while ((portmask & BIT(0)) == 0) { offset += 8; portmask >>= 1; } - memory_region_add_subregion(&pci->membar, offset, &s->io); + memory_region_add_subregion(&pci->membar, offset, + sysbus_mmio_get_region(sbd, 0)); offset += 8; portmask >>= 1; pci->ports++; diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c index 3a48b2495e..5eb2dc6350 100644 --- a/hw/char/serial-isa.c +++ b/hw/char/serial-isa.c @@ -58,7 +58,7 @@ static void serial_isa_realizefn(DeviceState *dev, Error **errp) static int index; ISADevice *isadev = ISA_DEVICE(dev); ISASerialState *isa = ISA_SERIAL(dev); - SerialState *s = &isa->state; + SysBusDevice *sbd = SYS_BUS_DEVICE(&isa->state); if (isa->index == -1) { isa->index = index; @@ -76,11 +76,11 @@ static void serial_isa_realizefn(DeviceState *dev, Error **errp) } index++; - s->irq = isa_get_irq(isadev, isa->isairq); - qdev_realize(DEVICE(s), NULL, errp); + sysbus_realize(sbd, errp); + sysbus_connect_irq(sbd, 0, isa_get_irq(isadev, isa->isairq)); qdev_set_legacy_instance_id(dev, isa->iobase, 3); - isa_register_ioport(isadev, &s->io, isa->iobase); + isa_register_ioport(isadev, sysbus_mmio_get_region(sbd, 0), isa->iobase); } static void serial_isa_build_aml(AcpiDevAmlIf *adev, Aml *scope) @@ -187,13 +187,17 @@ void serial_hds_isa_init(ISABus *bus, int from, int to) void isa_serial_set_iobase(ISADevice *serial, hwaddr iobase) { ISASerialState *s = ISA_SERIAL(serial); + SysBusDevice *sbd = SYS_BUS_DEVICE(&s->state); serial->ioport_id = iobase; s->iobase = iobase; - memory_region_set_address(&s->state.io, s->iobase); + memory_region_set_address(sysbus_mmio_get_region(sbd, 0), s->iobase); } void isa_serial_set_enabled(ISADevice *serial, bool enabled) { - memory_region_set_enabled(&ISA_SERIAL(serial)->state.io, enabled); + ISASerialState *s = ISA_SERIAL(serial); + SysBusDevice *sbd = SYS_BUS_DEVICE(&s->state); + + memory_region_set_enabled(sysbus_mmio_get_region(sbd, 0), enabled); } diff --git a/hw/char/serial-mm.c b/hw/char/serial-mm.c index 1dba4fc694..ba4061aa69 100644 --- a/hw/char/serial-mm.c +++ b/hw/char/serial-mm.c @@ -33,14 +33,14 @@ static void serial_mm_realize(DeviceState *dev, Error **errp) { SerialMM *smm = SERIAL_MM(dev); - SerialState *s = &smm->serial; + SysBusDevice *sbd = SYS_BUS_DEVICE(&smm->serial); - if (!qdev_realize(DEVICE(s), NULL, errp)) { + if (!sysbus_realize(sbd, errp)) { return; } - sysbus_init_mmio(SYS_BUS_DEVICE(smm), &s->io); - sysbus_init_irq(SYS_BUS_DEVICE(smm), &smm->serial.irq); + sysbus_init_mmio(SYS_BUS_DEVICE(smm), sysbus_mmio_get_region(sbd, 0)); + sysbus_pass_irq(SYS_BUS_DEVICE(smm), SYS_BUS_DEVICE(sbd)); } static const VMStateDescription vmstate_serial_mm = { diff --git a/hw/char/serial-pci-multi.c b/hw/char/serial-pci-multi.c index 38e5a78e6f..4e51d14111 100644 --- a/hw/char/serial-pci-multi.c +++ b/hw/char/serial-pci-multi.c @@ -50,13 +50,13 @@ typedef struct PCIMultiSerialState { 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; - qdev_unrealize(DEVICE(s)); - memory_region_del_subregion(&pci->iobar, &s->io); + SysBusDevice *sbd = SYS_BUS_DEVICE(pci->state + i); + qdev_unrealize(DEVICE(sbd)); + memory_region_del_subregion(&pci->iobar, + sysbus_mmio_get_region(sbd, 0)); } } @@ -91,7 +91,6 @@ static void multi_serial_pci_realize(PCIDevice *dev, Error **errp) { PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev); - SerialState *s; size_t i, nports = multi_serial_get_port_count(pc); pci->dev.config[PCI_CLASS_PROG] = 2; /* 16550 compatible */ @@ -100,13 +99,14 @@ static void multi_serial_pci_realize(PCIDevice *dev, Error **errp) pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->iobar); for (i = 0; i < nports; i++) { - s = pci->state + i; - if (!qdev_realize(DEVICE(s), NULL, errp)) { + SysBusDevice *sbd = SYS_BUS_DEVICE(pci->state + i); + if (!sysbus_realize(sbd, errp)) { multi_serial_pci_exit(dev); return; } - s->irq = &pci->irqs[i]; - memory_region_add_subregion(&pci->iobar, 8 * i, &s->io); + sysbus_connect_irq(sbd, 0, &pci->irqs[i]); + memory_region_add_subregion(&pci->iobar, 8 * i, + sysbus_mmio_get_region(sbd, 0)); pci->ports++; } } diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c index 9a0bf2d890..b702de8219 100644 --- a/hw/char/serial-pci.c +++ b/hw/char/serial-pci.c @@ -46,17 +46,18 @@ OBJECT_DECLARE_SIMPLE_TYPE(PCISerialState, PCI_SERIAL) static void serial_pci_realize(PCIDevice *dev, Error **errp) { PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev); - SerialState *s = &pci->state; + SysBusDevice *sbd = SYS_BUS_DEVICE(&pci->state); - if (!qdev_realize(DEVICE(s), NULL, errp)) { + if (!sysbus_realize(sbd, errp)) { return; } pci->dev.config[PCI_CLASS_PROG] = 2; /* 16550 compatible */ pci->dev.config[PCI_INTERRUPT_PIN] = 1; - s->irq = pci_allocate_irq(&pci->dev); + sysbus_connect_irq(sbd, 0, pci_allocate_irq(&pci->dev)); - pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io); + pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, + sysbus_mmio_get_region(sbd, 0)); } static void serial_pci_exit(PCIDevice *dev) @@ -65,7 +66,6 @@ static void serial_pci_exit(PCIDevice *dev) SerialState *s = &pci->state; qdev_unrealize(DEVICE(s)); - qemu_free_irq(s->irq); } static const VMStateDescription vmstate_pci_serial = { diff --git a/hw/char/serial.c b/hw/char/serial.c index 49227830e1..fc92897376 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -991,6 +991,9 @@ static void serial_realize(DeviceState *dev, Error **errp) serial_event, serial_be_change, s, NULL, true); fifo8_create(&s->recv_fifo, UART_FIFO_LENGTH); fifo8_create(&s->xmit_fifo, UART_FIFO_LENGTH); + + sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->io); + sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq); } static void serial_unrealize(DeviceState *dev) @@ -1034,7 +1037,7 @@ static void serial_class_init(ObjectClass *klass, const void *data) static const TypeInfo serial_info = { .name = TYPE_SERIAL, - .parent = TYPE_DEVICE, + .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(SerialState), .class_init = serial_class_init, }; -- 2.53.0
