diff --git a/ui/console.c b/ui/console.c
index 7d0bb819ac..bdecfe7306 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -27,6 +27,7 @@
 #include "hw/qdev-core.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-ui.h"
+#include "qapi/visitor.h"
 #include "qemu/coroutine.h"
 #include "qemu/fifo8.h"
 #include "qemu/error-report.h"
@@ -1253,40 +1254,24 @@ static void text_console_update(void *opaque, console_ch_t *chardata)
     }
 }
 
-static QemuConsole *new_console(console_type_t console_type,
-                                uint32_t head)
+static void
+qemu_console_register(QemuConsole *c, console_type_t console_type)
 {
-    DisplayState *ds = get_alloc_displaystate();
-    Object *obj;
-    QemuConsole *s;
     int i;
 
-    obj = object_new(TYPE_QEMU_CONSOLE);
-    s = QEMU_CONSOLE(obj);
-    qemu_co_queue_init(&s->dump_queue);
-    s->head = head;
-    object_property_add_link(obj, "device", TYPE_DEVICE,
-                             (Object **)&s->device,
-                             object_property_allow_set_link,
-                             OBJ_PROP_LINK_STRONG);
-    object_property_add_uint32_ptr(obj, "head", &s->head,
-                                   OBJ_PROP_FLAG_READ);
-
     if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) &&
-        (console_type == GRAPHIC_CONSOLE))) {
-        active_console = s;
+                            (console_type == GRAPHIC_CONSOLE))) {
+        active_console = c;
     }
-    s->ds = ds;
-    s->console_type = console_type;
-    s->window_id = -1;
+    c->console_type = console_type;
 
     if (QTAILQ_EMPTY(&consoles)) {
-        s->index = 0;
-        QTAILQ_INSERT_TAIL(&consoles, s, next);
+        c->index = 0;
+        QTAILQ_INSERT_TAIL(&consoles, c, next);
     } else if (console_type != GRAPHIC_CONSOLE || phase_check(PHASE_MACHINE_READY)) {
         QemuConsole *last = QTAILQ_LAST(&consoles);
-        s->index = last->index + 1;
-        QTAILQ_INSERT_TAIL(&consoles, s, next);
+        c->index = last->index + 1;
+        QTAILQ_INSERT_TAIL(&consoles, c, next);
     } else {
         /*
          * HACK: Put graphical consoles before text consoles.
@@ -1294,41 +1279,75 @@ static QemuConsole *new_console(console_type_t console_type,
          * Only do that for coldplugged devices.  After initial device
          * initialization we will not renumber the consoles any more.
          */
-        QemuConsole *c = QTAILQ_FIRST(&consoles);
+        QemuConsole *it = QTAILQ_FIRST(&consoles);
 
-        while (QTAILQ_NEXT(c, next) != NULL &&
-               c->console_type == GRAPHIC_CONSOLE) {
-            c = QTAILQ_NEXT(c, next);
+        while (QTAILQ_NEXT(it, next) != NULL &&
+               it->console_type == GRAPHIC_CONSOLE) {
+            it = QTAILQ_NEXT(it, next);
         }
-        if (c->console_type == GRAPHIC_CONSOLE) {
+        if (it->console_type == GRAPHIC_CONSOLE) {
             /* have no text consoles */
-            s->index = c->index + 1;
-            QTAILQ_INSERT_AFTER(&consoles, c, s, next);
+            c->index = it->index + 1;
+            QTAILQ_INSERT_AFTER(&consoles, it, c, next);
         } else {
-            s->index = c->index;
-            QTAILQ_INSERT_BEFORE(c, s, next);
+            c->index = it->index;
+            QTAILQ_INSERT_BEFORE(it, c, next);
             /* renumber text consoles */
-            for (i = s->index + 1; c != NULL; c = QTAILQ_NEXT(c, next), i++) {
-                c->index = i;
+            for (i = c->index + 1; it != NULL; it = QTAILQ_NEXT(it, next), i++) {
+                it->index = i;
             }
         }
     }
-    return s;
 }
 
 static void
 qemu_console_finalize(Object *obj)
 {
+    /* TODO: should unregister from consoles and free itself  */
+}
+
+static void
+qemu_console_prop_get_head(Object *obj, Visitor *v, const char *name,
+                           void *opaque, Error **errp)
+{
+    QemuConsole *c = QEMU_CONSOLE(obj);
+
+    visit_type_uint32(v, name, &c->head, errp);
 }
 
 static void
 qemu_console_class_init(ObjectClass *oc, void *data)
 {
+    object_class_property_add_link(oc, "device", TYPE_DEVICE,
+                                   offsetof(QemuConsole, device),
+                                   object_property_allow_set_link,
+                                   OBJ_PROP_LINK_STRONG);
+    object_class_property_add(oc, "head", "uint32",
+                              qemu_console_prop_get_head,
+                              NULL, NULL, NULL);
 }
 
 static void
 qemu_console_init(Object *obj)
 {
+    QemuConsole *c = QEMU_CONSOLE(obj);
+    DisplayState *ds = get_alloc_displaystate();
+
+    qemu_co_queue_init(&c->dump_queue);
+    c->ds = ds;
+    c->window_id = -1;
+}
+
+static QemuConsole *new_console(console_type_t console_type,
+                                uint32_t head)
+{
+    QemuConsole *c = QEMU_CONSOLE(object_new(TYPE_QEMU_CONSOLE));
+
+    c->head = head;
+    /* TODO: move to console_init() once there is a type hierarchy */
+    qemu_console_register(c, console_type);
+
+    return c;
 }
 
 #ifdef WIN32
