aboutsummaryrefslogtreecommitdiff
path: root/hw/char/serial.c
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2019-10-21 23:32:12 +0200
committerMarc-André Lureau <marcandre.lureau@redhat.com>2020-01-07 16:50:15 +0400
commit7781b88ee458ff933459503ade0b0a6ddaad08de (patch)
tree9bbe400fc3c5d02e5b36ebb89ce4db84f2bef2f3 /hw/char/serial.c
parent4305d4825c729222926ef498189e03cdccf125ae (diff)
serial: initial qom-ification
Make SerialState a device (the following patches will introduce IO/MM sysbus serial devices) None of the serial_{,mm}_init() callers actually free the returned value (even if they did, it would be quite harmless), so we can change the object allocation at will. However, the devices that embed SerialState must now have their field QOM-initialized manually (isa, pci, pci-multi). Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/char/serial.c')
-rw-r--r--hw/char/serial.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/hw/char/serial.c b/hw/char/serial.c
index b4aa250950..233a9e2076 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -983,9 +983,8 @@ const MemoryRegionOps serial_io_ops = {
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
Chardev *chr, MemoryRegion *system_io)
{
- SerialState *s;
-
- s = g_malloc0(sizeof(SerialState));
+ DeviceState *dev = DEVICE(object_new(TYPE_SERIAL));
+ SerialState *s = SERIAL(dev);
s->irq = irq;
s->baudbase = baudbase;
@@ -993,6 +992,7 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
serial_realize_core(s, &error_fatal);
vmstate_register(NULL, base, &vmstate_serial, s);
+ qdev_init_nofail(dev);
memory_region_init_io(&s->io, NULL, &serial_io_ops, s, "serial", 8);
memory_region_add_subregion(system_io, base, &s->io);
@@ -1000,6 +1000,21 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
return s;
}
+static void serial_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ /* internal device for serialio/serialmm, not user-creatable */
+ dc->user_creatable = false;
+}
+
+static const TypeInfo serial_info = {
+ .name = TYPE_SERIAL,
+ .parent = TYPE_DEVICE,
+ .instance_size = sizeof(SerialState),
+ .class_init = serial_class_init,
+};
+
/* Memory mapped interface */
static uint64_t serial_mm_read(void *opaque, hwaddr addr,
unsigned size)
@@ -1045,9 +1060,8 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
qemu_irq irq, int baudbase,
Chardev *chr, enum device_endian end)
{
- SerialState *s;
-
- s = g_malloc0(sizeof(SerialState));
+ DeviceState *dev = DEVICE(object_new(TYPE_SERIAL));
+ SerialState *s = SERIAL(dev);
s->it_shift = it_shift;
s->irq = irq;
@@ -1056,9 +1070,17 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
serial_realize_core(s, &error_fatal);
vmstate_register(NULL, base, &vmstate_serial, s);
+ qdev_init_nofail(dev);
memory_region_init_io(&s->io, NULL, &serial_mm_ops[end], s,
"serial", 8 << it_shift);
memory_region_add_subregion(address_space, base, &s->io);
return s;
}
+
+static void serial_register_types(void)
+{
+ type_register_static(&serial_info);
+}
+
+type_init(serial_register_types)