diff mbox series

[v3,17/33] serial: make SerialIO a sysbus device

Message ID 20191023173154.30051-18-marcandre.lureau@redhat.com
State New
Headers show
Series Clean-ups: qom-ify serial and remove QDEV_PROP_PTR | expand

Commit Message

Marc-André Lureau Oct. 23, 2019, 5:31 p.m. UTC
Make serial IO a proper sysbus device, similar to serial MM.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/char/serial.c         | 58 ++++++++++++++++++++++++++++++++--------
 include/hw/char/serial.h | 13 +++++++--
 2 files changed, 58 insertions(+), 13 deletions(-)

Comments

Peter Maydell Nov. 18, 2019, 3:16 p.m. UTC | #1
On Wed, 23 Oct 2019 at 18:34, Marc-André Lureau
<marcandre.lureau@redhat.com> wrote:
>
> Make serial IO a proper sysbus device, similar to serial MM.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  hw/char/serial.c         | 58 ++++++++++++++++++++++++++++++++--------
>  include/hw/char/serial.h | 13 +++++++--
>  2 files changed, 58 insertions(+), 13 deletions(-)
>
> diff --git a/hw/char/serial.c b/hw/char/serial.c
> index a40bc3ab81..84de2740a7 100644
> --- a/hw/char/serial.c
> +++ b/hw/char/serial.c
> @@ -986,22 +986,57 @@ const MemoryRegionOps serial_io_ops = {
>      .endianness = DEVICE_LITTLE_ENDIAN,
>  };
>
> -SerialState *serial_init(int base, qemu_irq irq, int baudbase,
> -                         Chardev *chr, MemoryRegion *system_io)
> +static void serial_io_realize(DeviceState *dev, Error **errp)
>  {
> -    DeviceState *dev = DEVICE(object_new(TYPE_SERIAL));
> -    SerialState *s = SERIAL(dev);
> +    SerialIO *self = SERIAL_IO(dev);

"sio" or something rather than "self".

> +    SerialState *s = &self->serial;
>
> -    s->irq = irq;
> -    qdev_prop_set_uint32(dev, "baudbase", baudbase);
> -    qdev_prop_set_chr(dev, "chardev", chr);
> -    qdev_prop_set_int32(dev, "instance-id", base);
> -    qdev_init_nofail(dev);
> +    qdev_init_nofail(DEVICE(s));
>
>      memory_region_init_io(&s->io, NULL, &serial_io_ops, s, "serial", 8);
> -    memory_region_add_subregion(system_io, base, &s->io);
> +    sysbus_init_irq(SYS_BUS_DEVICE(self), &self->serial.irq);

You could say '&s->irq' here, since you have the local variable.

> +}
> +
> +static void serial_io_class_init(ObjectClass *klass, void* data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    dc->realize = serial_io_realize;

For class methods where the class has no data that needs
to be migrated it's helpful to have a comment
  /* No dc->vmsd: class has no migratable state */
(which lets us know that it's intentional and not a forgotten
thing). Some day I will get round to writing a patch so you
can say "dc->vmsd = no_migratable_state;" ...

> +}
> +
> +static void serial_io_instance_init(Object *o)
> +{
> +    SerialIO *self = SERIAL_IO(o);
> +
> +    object_initialize_child(o, "serial", &self->serial, sizeof(self->serial),
> +                            TYPE_SERIAL, &error_abort, NULL);
> +
> +    qdev_alias_all_properties(DEVICE(&self->serial), o);
> +}
> +
> +
> +static const TypeInfo serial_io_info = {
> +    .name = TYPE_SERIAL_IO,
> +    .parent = TYPE_SYS_BUS_DEVICE,
> +    .instance_size = sizeof(SerialIO),
> +    .instance_init = serial_io_instance_init,
> +    .class_init = serial_io_class_init,
> +};
> +
> +SerialIO *serial_init(int base, qemu_irq irq, int baudbase,
> +                         Chardev *chr, MemoryRegion *system_io)
> +{
> +    SerialIO *self = SERIAL_IO(qdev_create(NULL, TYPE_SERIAL_IO));
>
> -    return s;
> +    qdev_prop_set_uint32(DEVICE(self), "baudbase", baudbase);
> +    qdev_prop_set_chr(DEVICE(self), "chardev", chr);
> +    qdev_prop_set_int32(DEVICE(self), "instance-id", base);
> +    qdev_init_nofail(DEVICE(self));
> +
> +    sysbus_connect_irq(SYS_BUS_DEVICE(self), 0, irq);
> +    memory_region_add_subregion(system_io, base, &self->serial.io);
> +
> +    return self;
>  }

thanks
-- PMM
Marc-André Lureau Nov. 20, 2019, 8:41 a.m. UTC | #2
Hi

On Mon, Nov 18, 2019 at 7:17 PM Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Wed, 23 Oct 2019 at 18:34, Marc-André Lureau
> <marcandre.lureau@redhat.com> wrote:
> >
> > Make serial IO a proper sysbus device, similar to serial MM.
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> >  hw/char/serial.c         | 58 ++++++++++++++++++++++++++++++++--------
> >  include/hw/char/serial.h | 13 +++++++--
> >  2 files changed, 58 insertions(+), 13 deletions(-)
> >
> > diff --git a/hw/char/serial.c b/hw/char/serial.c
> > index a40bc3ab81..84de2740a7 100644
> > --- a/hw/char/serial.c
> > +++ b/hw/char/serial.c
> > @@ -986,22 +986,57 @@ const MemoryRegionOps serial_io_ops = {
> >      .endianness = DEVICE_LITTLE_ENDIAN,
> >  };
> >
> > -SerialState *serial_init(int base, qemu_irq irq, int baudbase,
> > -                         Chardev *chr, MemoryRegion *system_io)
> > +static void serial_io_realize(DeviceState *dev, Error **errp)
> >  {
> > -    DeviceState *dev = DEVICE(object_new(TYPE_SERIAL));
> > -    SerialState *s = SERIAL(dev);
> > +    SerialIO *self = SERIAL_IO(dev);
>
> "sio" or something rather than "self".

"sio", or something, "s", "si", "serialio"... "self"? Isn't it more
clear that we are talking about the instance itself? No ambiguity,
less weird naming. Isn't this more familar to any OO programmer? Let's
keep the discussion in "serial: start making SerialMM a sysbus
device".


>
> > +    SerialState *s = &self->serial;
> >
> > -    s->irq = irq;
> > -    qdev_prop_set_uint32(dev, "baudbase", baudbase);
> > -    qdev_prop_set_chr(dev, "chardev", chr);
> > -    qdev_prop_set_int32(dev, "instance-id", base);
> > -    qdev_init_nofail(dev);
> > +    qdev_init_nofail(DEVICE(s));
> >
> >      memory_region_init_io(&s->io, NULL, &serial_io_ops, s, "serial", 8);
> > -    memory_region_add_subregion(system_io, base, &s->io);
> > +    sysbus_init_irq(SYS_BUS_DEVICE(self), &self->serial.irq);
>
> You could say '&s->irq' here, since you have the local variable.

right, fixed

>
> > +}
> > +
> > +static void serial_io_class_init(ObjectClass *klass, void* data)
> > +{
> > +    DeviceClass *dc = DEVICE_CLASS(klass);
> > +
> > +    dc->realize = serial_io_realize;
>
> For class methods where the class has no data that needs
> to be migrated it's helpful to have a comment
>   /* No dc->vmsd: class has no migratable state */
> (which lets us know that it's intentional and not a forgotten
> thing). Some day I will get round to writing a patch so you
> can say "dc->vmsd = no_migratable_state;" ...
>

added

thanks

> > +}
> > +
> > +static void serial_io_instance_init(Object *o)
> > +{
> > +    SerialIO *self = SERIAL_IO(o);
> > +
> > +    object_initialize_child(o, "serial", &self->serial, sizeof(self->serial),
> > +                            TYPE_SERIAL, &error_abort, NULL);
> > +
> > +    qdev_alias_all_properties(DEVICE(&self->serial), o);
> > +}
> > +
> > +
> > +static const TypeInfo serial_io_info = {
> > +    .name = TYPE_SERIAL_IO,
> > +    .parent = TYPE_SYS_BUS_DEVICE,
> > +    .instance_size = sizeof(SerialIO),
> > +    .instance_init = serial_io_instance_init,
> > +    .class_init = serial_io_class_init,
> > +};
> > +
> > +SerialIO *serial_init(int base, qemu_irq irq, int baudbase,
> > +                         Chardev *chr, MemoryRegion *system_io)
> > +{
> > +    SerialIO *self = SERIAL_IO(qdev_create(NULL, TYPE_SERIAL_IO));
> >
> > -    return s;
> > +    qdev_prop_set_uint32(DEVICE(self), "baudbase", baudbase);
> > +    qdev_prop_set_chr(DEVICE(self), "chardev", chr);
> > +    qdev_prop_set_int32(DEVICE(self), "instance-id", base);
> > +    qdev_init_nofail(DEVICE(self));
> > +
> > +    sysbus_connect_irq(SYS_BUS_DEVICE(self), 0, irq);
> > +    memory_region_add_subregion(system_io, base, &self->serial.io);
> > +
> > +    return self;
> >  }
>
> thanks
> -- PMM
>
diff mbox series

Patch

diff --git a/hw/char/serial.c b/hw/char/serial.c
index a40bc3ab81..84de2740a7 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -986,22 +986,57 @@  const MemoryRegionOps serial_io_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-SerialState *serial_init(int base, qemu_irq irq, int baudbase,
-                         Chardev *chr, MemoryRegion *system_io)
+static void serial_io_realize(DeviceState *dev, Error **errp)
 {
-    DeviceState *dev = DEVICE(object_new(TYPE_SERIAL));
-    SerialState *s = SERIAL(dev);
+    SerialIO *self = SERIAL_IO(dev);
+    SerialState *s = &self->serial;
 
-    s->irq = irq;
-    qdev_prop_set_uint32(dev, "baudbase", baudbase);
-    qdev_prop_set_chr(dev, "chardev", chr);
-    qdev_prop_set_int32(dev, "instance-id", base);
-    qdev_init_nofail(dev);
+    qdev_init_nofail(DEVICE(s));
 
     memory_region_init_io(&s->io, NULL, &serial_io_ops, s, "serial", 8);
-    memory_region_add_subregion(system_io, base, &s->io);
+    sysbus_init_irq(SYS_BUS_DEVICE(self), &self->serial.irq);
+}
+
+static void serial_io_class_init(ObjectClass *klass, void* data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = serial_io_realize;
+}
+
+static void serial_io_instance_init(Object *o)
+{
+    SerialIO *self = SERIAL_IO(o);
+
+    object_initialize_child(o, "serial", &self->serial, sizeof(self->serial),
+                            TYPE_SERIAL, &error_abort, NULL);
+
+    qdev_alias_all_properties(DEVICE(&self->serial), o);
+}
+
+
+static const TypeInfo serial_io_info = {
+    .name = TYPE_SERIAL_IO,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SerialIO),
+    .instance_init = serial_io_instance_init,
+    .class_init = serial_io_class_init,
+};
+
+SerialIO *serial_init(int base, qemu_irq irq, int baudbase,
+                         Chardev *chr, MemoryRegion *system_io)
+{
+    SerialIO *self = SERIAL_IO(qdev_create(NULL, TYPE_SERIAL_IO));
 
-    return s;
+    qdev_prop_set_uint32(DEVICE(self), "baudbase", baudbase);
+    qdev_prop_set_chr(DEVICE(self), "chardev", chr);
+    qdev_prop_set_int32(DEVICE(self), "instance-id", base);
+    qdev_init_nofail(DEVICE(self));
+
+    sysbus_connect_irq(SYS_BUS_DEVICE(self), 0, irq);
+    memory_region_add_subregion(system_io, base, &self->serial.io);
+
+    return self;
 }
 
 static Property serial_properties[] = {
@@ -1138,6 +1173,7 @@  static const TypeInfo serial_mm_info = {
 static void serial_register_types(void)
 {
     type_register_static(&serial_info);
+    type_register_static(&serial_io_info);
     type_register_static(&serial_mm_info);
 }
 
diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
index 2d0802a909..cf9cdafaee 100644
--- a/include/hw/char/serial.h
+++ b/include/hw/char/serial.h
@@ -89,6 +89,12 @@  typedef struct SerialMM {
     uint8_t endianness;
 } SerialMM;
 
+typedef struct SerialIO {
+    SysBusDevice parent;
+
+    SerialState serial;
+} SerialIO;
+
 extern const VMStateDescription vmstate_serial;
 extern const MemoryRegionOps serial_io_ops;
 
@@ -100,8 +106,11 @@  void serial_set_frequency(SerialState *s, uint32_t frequency);
 #define TYPE_SERIAL_MM "serial-mm"
 #define SERIAL_MM(s) OBJECT_CHECK(SerialMM, (s), TYPE_SERIAL_MM)
 
-SerialState *serial_init(int base, qemu_irq irq, int baudbase,
-                         Chardev *chr, MemoryRegion *system_io);
+#define TYPE_SERIAL_IO "serial-io"
+#define SERIAL_IO(s) OBJECT_CHECK(SerialIO, (s), TYPE_SERIAL_IO)
+
+SerialIO *serial_init(int base, qemu_irq irq, int baudbase,
+                      Chardev *chr, MemoryRegion *system_io);
 SerialMM *serial_mm_init(MemoryRegion *address_space,
                          hwaddr base, int regshift,
                          qemu_irq irq, int baudbase,