]> Git Repo - qemu.git/blobdiff - hw/display/pl110.c
qdev: Replace no_user by cannot_instantiate_with_device_add_yet
[qemu.git] / hw / display / pl110.c
index 60afcf39e1689aa56dfd2deb415947569a242909..7ad5972f0ae0e2ff66b330aae24284b5d9eeb324 100644 (file)
@@ -39,8 +39,12 @@ enum pl110_version
     PL111
 };
 
-typedef struct {
-    SysBusDevice busdev;
+#define TYPE_PL110 "pl110"
+#define PL110(obj) OBJECT_CHECK(PL110State, (obj), TYPE_PL110)
+
+typedef struct PL110State {
+    SysBusDevice parent_obj;
+
     MemoryRegion iomem;
     QemuConsole *con;
 
@@ -59,7 +63,7 @@ typedef struct {
     uint32_t palette[256];
     uint32_t raw_palette[128];
     qemu_irq irq;
-} pl110_state;
+} PL110State;
 
 static int vmstate_pl110_post_load(void *opaque, int version_id);
 
@@ -69,20 +73,20 @@ static const VMStateDescription vmstate_pl110 = {
     .minimum_version_id = 1,
     .post_load = vmstate_pl110_post_load,
     .fields = (VMStateField[]) {
-        VMSTATE_INT32(version, pl110_state),
-        VMSTATE_UINT32_ARRAY(timing, pl110_state, 4),
-        VMSTATE_UINT32(cr, pl110_state),
-        VMSTATE_UINT32(upbase, pl110_state),
-        VMSTATE_UINT32(lpbase, pl110_state),
-        VMSTATE_UINT32(int_status, pl110_state),
-        VMSTATE_UINT32(int_mask, pl110_state),
-        VMSTATE_INT32(cols, pl110_state),
-        VMSTATE_INT32(rows, pl110_state),
-        VMSTATE_UINT32(bpp, pl110_state),
-        VMSTATE_INT32(invalidate, pl110_state),
-        VMSTATE_UINT32_ARRAY(palette, pl110_state, 256),
-        VMSTATE_UINT32_ARRAY(raw_palette, pl110_state, 128),
-        VMSTATE_UINT32_V(mux_ctrl, pl110_state, 2),
+        VMSTATE_INT32(version, PL110State),
+        VMSTATE_UINT32_ARRAY(timing, PL110State, 4),
+        VMSTATE_UINT32(cr, PL110State),
+        VMSTATE_UINT32(upbase, PL110State),
+        VMSTATE_UINT32(lpbase, PL110State),
+        VMSTATE_UINT32(int_status, PL110State),
+        VMSTATE_UINT32(int_mask, PL110State),
+        VMSTATE_INT32(cols, PL110State),
+        VMSTATE_INT32(rows, PL110State),
+        VMSTATE_UINT32(bpp, PL110State),
+        VMSTATE_INT32(invalidate, PL110State),
+        VMSTATE_UINT32_ARRAY(palette, PL110State, 256),
+        VMSTATE_UINT32_ARRAY(raw_palette, PL110State, 128),
+        VMSTATE_UINT32_V(mux_ctrl, PL110State, 2),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -90,23 +94,21 @@ static const VMStateDescription vmstate_pl110 = {
 static const unsigned char pl110_id[] =
 { 0x10, 0x11, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
 
-/* The Arm documentation (DDI0224C) says the CLDC on the Versatile board
-   has a different ID.  However Linux only looks for the normal ID.  */
-#if 0
-static const unsigned char pl110_versatile_id[] =
-{ 0x93, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
-#else
-#define pl110_versatile_id pl110_id
-#endif
-
 static const unsigned char pl111_id[] = {
     0x11, 0x11, 0x24, 0x00, 0x0d, 0xf0, 0x05, 0xb1
 };
 
+
 /* Indexed by pl110_version */
 static const unsigned char *idregs[] = {
     pl110_id,
-    pl110_versatile_id,
+    /* The ARM documentation (DDI0224C) says the CLCDC on the Versatile board
+     * has a different ID (0x93, 0x10, 0x04, 0x00, ...). However the hardware
+     * itself has the same ID values as a stock PL110, and guests (in
+     * particular Linux) rely on this. We emulate what the hardware does,
+     * rather than what the docs claim it ought to do.
+     */
+    pl110_id,
     pl111_id
 };
 
@@ -121,14 +123,15 @@ static const unsigned char *idregs[] = {
 #define BITS 32
 #include "pl110_template.h"
 
-static int pl110_enabled(pl110_state *s)
+static int pl110_enabled(PL110State *s)
 {
   return (s->cr & PL110_CR_EN) && (s->cr & PL110_CR_PWR);
 }
 
 static void pl110_update_display(void *opaque)
 {
-    pl110_state *s = (pl110_state *)opaque;
+    PL110State *s = (PL110State *)opaque;
+    SysBusDevice *sbd;
     DisplaySurface *surface = qemu_console_surface(s->con);
     drawfn* fntable;
     drawfn fn;
@@ -138,8 +141,11 @@ static void pl110_update_display(void *opaque)
     int first;
     int last;
 
-    if (!pl110_enabled(s))
+    if (!pl110_enabled(s)) {
         return;
+    }
+
+    sbd = SYS_BUS_DEVICE(s);
 
     switch (surface_bits_per_pixel(surface)) {
     case 0:
@@ -232,7 +238,7 @@ static void pl110_update_display(void *opaque)
     }
     dest_width *= s->cols;
     first = 0;
-    framebuffer_update_display(surface, sysbus_address_space(&s->busdev),
+    framebuffer_update_display(surface, sysbus_address_space(sbd),
                                s->upbase, s->cols, s->rows,
                                src_width, dest_width, 0,
                                s->invalidate,
@@ -246,14 +252,14 @@ static void pl110_update_display(void *opaque)
 
 static void pl110_invalidate_display(void * opaque)
 {
-    pl110_state *s = (pl110_state *)opaque;
+    PL110State *s = (PL110State *)opaque;
     s->invalidate = 1;
     if (pl110_enabled(s)) {
         qemu_console_resize(s->con, s->cols, s->rows);
     }
 }
 
-static void pl110_update_palette(pl110_state *s, int n)
+static void pl110_update_palette(PL110State *s, int n)
 {
     DisplaySurface *surface = qemu_console_surface(s->con);
     int i;
@@ -289,7 +295,7 @@ static void pl110_update_palette(pl110_state *s, int n)
     }
 }
 
-static void pl110_resize(pl110_state *s, int width, int height)
+static void pl110_resize(PL110State *s, int width, int height)
 {
     if (width != s->cols || height != s->rows) {
         if (pl110_enabled(s)) {
@@ -301,7 +307,7 @@ static void pl110_resize(pl110_state *s, int width, int height)
 }
 
 /* Update interrupts.  */
-static void pl110_update(pl110_state *s)
+static void pl110_update(PL110State *s)
 {
   /* TODO: Implement interrupts.  */
 }
@@ -309,7 +315,7 @@ static void pl110_update(pl110_state *s)
 static uint64_t pl110_read(void *opaque, hwaddr offset,
                            unsigned size)
 {
-    pl110_state *s = (pl110_state *)opaque;
+    PL110State *s = (PL110State *)opaque;
 
     if (offset >= 0xfe0 && offset < 0x1000) {
         return idregs[s->version][(offset - 0xfe0) >> 2];
@@ -359,7 +365,7 @@ static uint64_t pl110_read(void *opaque, hwaddr offset,
 static void pl110_write(void *opaque, hwaddr offset,
                         uint64_t val, unsigned size)
 {
-    pl110_state *s = (pl110_state *)opaque;
+    PL110State *s = (PL110State *)opaque;
     int n;
 
     /* For simplicity invalidate the display whenever a control register
@@ -432,13 +438,13 @@ static const MemoryRegionOps pl110_ops = {
 
 static void pl110_mux_ctrl_set(void *opaque, int line, int level)
 {
-    pl110_state *s = (pl110_state *)opaque;
+    PL110State *s = (PL110State *)opaque;
     s->mux_ctrl = level;
 }
 
 static int vmstate_pl110_post_load(void *opaque, int version_id)
 {
-    pl110_state *s = opaque;
+    PL110State *s = opaque;
     /* Make sure we redraw, and at the right size */
     pl110_invalidate_display(s);
     return 0;
@@ -449,30 +455,38 @@ static const GraphicHwOps pl110_gfx_ops = {
     .gfx_update  = pl110_update_display,
 };
 
-static int pl110_init(SysBusDevice *dev)
+static int pl110_initfn(SysBusDevice *sbd)
 {
-    pl110_state *s = FROM_SYSBUS(pl110_state, dev);
+    DeviceState *dev = DEVICE(sbd);
+    PL110State *s = PL110(dev);
 
     memory_region_init_io(&s->iomem, OBJECT(s), &pl110_ops, s, "pl110", 0x1000);
-    sysbus_init_mmio(dev, &s->iomem);
-    sysbus_init_irq(dev, &s->irq);
-    qdev_init_gpio_in(&s->busdev.qdev, pl110_mux_ctrl_set, 1);
-    s->con = graphic_console_init(DEVICE(dev), &pl110_gfx_ops, s);
+    sysbus_init_mmio(sbd, &s->iomem);
+    sysbus_init_irq(sbd, &s->irq);
+    qdev_init_gpio_in(dev, pl110_mux_ctrl_set, 1);
+    s->con = graphic_console_init(dev, &pl110_gfx_ops, s);
     return 0;
 }
 
-static int pl110_versatile_init(SysBusDevice *dev)
+static void pl110_init(Object *obj)
 {
-    pl110_state *s = FROM_SYSBUS(pl110_state, dev);
+    PL110State *s = PL110(obj);
+
+    s->version = PL110;
+}
+
+static void pl110_versatile_init(Object *obj)
+{
+    PL110State *s = PL110(obj);
+
     s->version = PL110_VERSATILE;
-    return pl110_init(dev);
 }
 
-static int pl111_init(SysBusDevice *dev)
+static void pl111_init(Object *obj)
 {
-    pl110_state *s = FROM_SYSBUS(pl110_state, dev);
+    PL110State *s = PL110(obj);
+
     s->version = PL111;
-    return pl110_init(dev);
 }
 
 static void pl110_class_init(ObjectClass *klass, void *data)
@@ -480,50 +494,30 @@ static void pl110_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    k->init = pl110_init;
-    dc->no_user = 1;
+    k->init = pl110_initfn;
+    set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
+    dc->cannot_instantiate_with_device_add_yet = true; /* FIXME explain why */
     dc->vmsd = &vmstate_pl110;
 }
 
 static const TypeInfo pl110_info = {
-    .name          = "pl110",
+    .name          = TYPE_PL110,
     .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(pl110_state),
+    .instance_size = sizeof(PL110State),
+    .instance_init = pl110_init,
     .class_init    = pl110_class_init,
 };
 
-static void pl110_versatile_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
-    k->init = pl110_versatile_init;
-    dc->no_user = 1;
-    dc->vmsd = &vmstate_pl110;
-}
-
 static const TypeInfo pl110_versatile_info = {
     .name          = "pl110_versatile",
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(pl110_state),
-    .class_init    = pl110_versatile_class_init,
+    .parent        = TYPE_PL110,
+    .instance_init = pl110_versatile_init,
 };
 
-static void pl111_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
-    k->init = pl111_init;
-    dc->no_user = 1;
-    dc->vmsd = &vmstate_pl110;
-}
-
 static const TypeInfo pl111_info = {
     .name          = "pl111",
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(pl110_state),
-    .class_init    = pl111_class_init,
+    .parent        = TYPE_PL110,
+    .instance_init = pl111_init,
 };
 
 static void pl110_register_types(void)
This page took 0.032913 seconds and 4 git commands to generate.