On Sat, Sep 25, 2021 at 11:34 PM Philippe Mathieu-Daudé <f4...@amsat.org> wrote: > > - Embed SerialMM in MchpPfSoCMMUartState and QOM-initialize it > - Alias SERIAL_MM 'chardev' property on MCHP_PFSOC_UART > - Forward SerialMM sysbus IRQ in mchp_pfsoc_mmuart_realize() > - Add DeviceReset() method > - Add vmstate structure for migration > - Register device in 'input' category > - Keep mchp_pfsoc_mmuart_create() behavior > > Note, serial_mm_init() calls qdev_set_legacy_instance_id(). > This call is only needed for backwards-compatibility of incoming > migration data with old versions of QEMU which implemented migration > of devices with hand-rolled code. Since this device didn't previously > handle migration at all, then it doesn't need to set the legacy > instance ID. > > Signed-off-by: Philippe Mathieu-Daudé <f4...@amsat.org>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > Cc: Peter Maydell <peter.mayd...@linaro.org> > > I haven't kept Alistair R-b tag from v1. > --- > include/hw/char/mchp_pfsoc_mmuart.h | 12 +++- > hw/char/mchp_pfsoc_mmuart.c | 105 +++++++++++++++++++++++----- > 2 files changed, 97 insertions(+), 20 deletions(-) > > diff --git a/include/hw/char/mchp_pfsoc_mmuart.h > b/include/hw/char/mchp_pfsoc_mmuart.h > index 864ac1a36b5..b0e14ca3554 100644 > --- a/include/hw/char/mchp_pfsoc_mmuart.h > +++ b/include/hw/char/mchp_pfsoc_mmuart.h > @@ -28,17 +28,23 @@ > #ifndef HW_MCHP_PFSOC_MMUART_H > #define HW_MCHP_PFSOC_MMUART_H > > +#include "hw/sysbus.h" > #include "hw/char/serial.h" > > #define MCHP_PFSOC_MMUART_REG_COUNT 13 > > +#define TYPE_MCHP_PFSOC_UART "mchp.pfsoc.uart" > +OBJECT_DECLARE_SIMPLE_TYPE(MchpPfSoCMMUartState, MCHP_PFSOC_UART) > + > typedef struct MchpPfSoCMMUartState { > + /*< private >*/ > + SysBusDevice parent_obj; > + > + /*< public >*/ > MemoryRegion container; > MemoryRegion iomem; > - hwaddr base; > - qemu_irq irq; > > - SerialMM *serial; > + SerialMM serial_mm; > > uint32_t reg[MCHP_PFSOC_MMUART_REG_COUNT]; > } MchpPfSoCMMUartState; > diff --git a/hw/char/mchp_pfsoc_mmuart.c b/hw/char/mchp_pfsoc_mmuart.c > index ea586559761..22f3e78eb9e 100644 > --- a/hw/char/mchp_pfsoc_mmuart.c > +++ b/hw/char/mchp_pfsoc_mmuart.c > @@ -22,8 +22,10 @@ > > #include "qemu/osdep.h" > #include "qemu/log.h" > -#include "chardev/char.h" > +#include "qapi/error.h" > +#include "migration/vmstate.h" > #include "hw/char/mchp_pfsoc_mmuart.h" > +#include "hw/qdev-properties.h" > > #define REGS_OFFSET 0x20 > > @@ -67,26 +69,95 @@ static const MemoryRegionOps mchp_pfsoc_mmuart_ops = { > }, > }; > > -MchpPfSoCMMUartState *mchp_pfsoc_mmuart_create(MemoryRegion *sysmem, > - hwaddr base, qemu_irq irq, Chardev *chr) > +static void mchp_pfsoc_mmuart_reset(DeviceState *dev) > { > - MchpPfSoCMMUartState *s; > + MchpPfSoCMMUartState *s = MCHP_PFSOC_UART(dev); > > - s = g_new0(MchpPfSoCMMUartState, 1); > + memset(s->reg, 0, sizeof(s->reg)); > + device_cold_reset(DEVICE(&s->serial_mm)); > +} > > - memory_region_init(&s->container, NULL, "mchp.pfsoc.mmuart", 0x1000); > +static void mchp_pfsoc_mmuart_init(Object *obj) > +{ > + MchpPfSoCMMUartState *s = MCHP_PFSOC_UART(obj); > > - memory_region_init_io(&s->iomem, NULL, &mchp_pfsoc_mmuart_ops, s, > + object_initialize_child(obj, "serial-mm", &s->serial_mm, TYPE_SERIAL_MM); > + object_property_add_alias(obj, "chardev", OBJECT(&s->serial_mm), > "chardev"); > +} > + > +static void mchp_pfsoc_mmuart_realize(DeviceState *dev, Error **errp) > +{ > + MchpPfSoCMMUartState *s = MCHP_PFSOC_UART(dev); > + > + qdev_prop_set_uint8(DEVICE(&s->serial_mm), "regshift", 2); > + qdev_prop_set_uint32(DEVICE(&s->serial_mm), "baudbase", 399193); > + qdev_prop_set_uint8(DEVICE(&s->serial_mm), "endianness", > + DEVICE_LITTLE_ENDIAN); > + if (!sysbus_realize(SYS_BUS_DEVICE(&s->serial_mm), errp)) { > + return; > + } > + > + sysbus_pass_irq(SYS_BUS_DEVICE(dev), SYS_BUS_DEVICE(&s->serial_mm)); > + > + memory_region_init(&s->container, OBJECT(s), "mchp.pfsoc.mmuart", > 0x1000); > + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container); > + > + memory_region_add_subregion(&s->container, 0, > + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->serial_mm), > 0)); > + > + memory_region_init_io(&s->iomem, OBJECT(s), &mchp_pfsoc_mmuart_ops, s, > "mchp.pfsoc.mmuart.regs", 0x1000 - REGS_OFFSET); > memory_region_add_subregion(&s->container, REGS_OFFSET, &s->iomem); > - > - s->base = base; > - s->irq = irq; > - > - s->serial = serial_mm_init(&s->container, 0, 2, irq, 399193, chr, > - DEVICE_LITTLE_ENDIAN); > - > - memory_region_add_subregion(sysmem, base, &s->container); > - > - return s; > +} > + > +static const VMStateDescription mchp_pfsoc_mmuart_vmstate = { > + .name = "mchp.pfsoc.uart", > + .version_id = 0, > + .minimum_version_id = 0, > + .fields = (VMStateField[]) { > + VMSTATE_UINT32_ARRAY(reg, MchpPfSoCMMUartState, > + MCHP_PFSOC_MMUART_REG_COUNT), > + VMSTATE_END_OF_LIST() > + } > +}; > + > +static void mchp_pfsoc_mmuart_class_init(ObjectClass *oc, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(oc); > + > + dc->realize = mchp_pfsoc_mmuart_realize; > + dc->reset = mchp_pfsoc_mmuart_reset; > + dc->vmsd = &mchp_pfsoc_mmuart_vmstate; > + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); > +} > + > +static const TypeInfo mchp_pfsoc_mmuart_info = { > + .name = TYPE_MCHP_PFSOC_UART, > + .parent = TYPE_SYS_BUS_DEVICE, > + .instance_size = sizeof(MchpPfSoCMMUartState), > + .instance_init = mchp_pfsoc_mmuart_init, > + .class_init = mchp_pfsoc_mmuart_class_init, > +}; > + > +static void mchp_pfsoc_mmuart_register_types(void) > +{ > + type_register_static(&mchp_pfsoc_mmuart_info); > +} > + > +type_init(mchp_pfsoc_mmuart_register_types) > + > +MchpPfSoCMMUartState *mchp_pfsoc_mmuart_create(MemoryRegion *sysmem, > + hwaddr base, > + qemu_irq irq, Chardev *chr) > +{ > + DeviceState *dev = qdev_new(TYPE_MCHP_PFSOC_UART); > + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); > + > + qdev_prop_set_chr(dev, "chardev", chr); > + sysbus_realize(sbd, &error_fatal); > + > + memory_region_add_subregion(sysmem, base, sysbus_mmio_get_region(sbd, > 0)); > + sysbus_connect_irq(sbd, 0, irq); > + > + return MCHP_PFSOC_UART(dev); > } > -- > 2.31.1 >