]> git.proxmox.com Git - mirror_qemu.git/blobdiff - hw/display/ssd0323.c
hw/misc: sifive_u_otp: Use error_report() when block operation fails
[mirror_qemu.git] / hw / display / ssd0323.c
index 46c3b40c795a8b9e49a2afc0901255d22b382112..ab229d32b7f4744547bf14c267c776ccd58df56c 100644 (file)
 /* The controller can support a variety of different displays, but we only
    implement one.  Most of the commends relating to brightness and geometry
    setup are ignored. */
-#include "hw/ssi.h"
+
+#include "qemu/osdep.h"
+#include "hw/ssi/ssi.h"
+#include "migration/vmstate.h"
+#include "qemu/module.h"
 #include "ui/console.h"
+#include "qom/object.h"
 
 //#define DEBUG_SSD0323 1
 
@@ -43,28 +48,32 @@ enum ssd0323_mode
     SSD0323_DATA
 };
 
-typedef struct {
-    SSISlave ssidev;
+struct ssd0323_state {
+    SSIPeripheral ssidev;
     QemuConsole *con;
 
-    int cmd_len;
-    int cmd;
-    int cmd_data[8];
-    int row;
-    int row_start;
-    int row_end;
-    int col;
-    int col_start;
-    int col_end;
-    int redraw;
-    int remap;
-    enum ssd0323_mode mode;
+    uint32_t cmd_len;
+    int32_t cmd;
+    int32_t cmd_data[8];
+    int32_t row;
+    int32_t row_start;
+    int32_t row_end;
+    int32_t col;
+    int32_t col_start;
+    int32_t col_end;
+    int32_t redraw;
+    int32_t remap;
+    uint32_t mode;
     uint8_t framebuffer[128 * 80 / 2];
-} ssd0323_state;
+};
+
+#define TYPE_SSD0323 "ssd0323"
+OBJECT_DECLARE_SIMPLE_TYPE(ssd0323_state, SSD0323)
 
-static uint32_t ssd0323_transfer(SSISlave *dev, uint32_t data)
+
+static uint32_t ssd0323_transfer(SSIPeripheral *dev, uint32_t data)
 {
-    ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, dev);
+    ssd0323_state *s = SSD0323(dev);
 
     switch (s->mode) {
     case SSD0323_DATA:
@@ -278,92 +287,95 @@ static void ssd0323_cd(void *opaque, int n, int level)
     s->mode = level ? SSD0323_DATA : SSD0323_CMD;
 }
 
-static void ssd0323_save(QEMUFile *f, void *opaque)
+static int ssd0323_post_load(void *opaque, int version_id)
 {
-    SSISlave *ss = SSI_SLAVE(opaque);
     ssd0323_state *s = (ssd0323_state *)opaque;
-    int i;
 
-    qemu_put_be32(f, s->cmd_len);
-    qemu_put_be32(f, s->cmd);
-    for (i = 0; i < 8; i++)
-        qemu_put_be32(f, s->cmd_data[i]);
-    qemu_put_be32(f, s->row);
-    qemu_put_be32(f, s->row_start);
-    qemu_put_be32(f, s->row_end);
-    qemu_put_be32(f, s->col);
-    qemu_put_be32(f, s->col_start);
-    qemu_put_be32(f, s->col_end);
-    qemu_put_be32(f, s->redraw);
-    qemu_put_be32(f, s->remap);
-    qemu_put_be32(f, s->mode);
-    qemu_put_buffer(f, s->framebuffer, sizeof(s->framebuffer));
-
-    qemu_put_be32(f, ss->cs);
-}
-
-static int ssd0323_load(QEMUFile *f, void *opaque, int version_id)
-{
-    SSISlave *ss = SSI_SLAVE(opaque);
-    ssd0323_state *s = (ssd0323_state *)opaque;
-    int i;
-
-    if (version_id != 1)
+    if (s->cmd_len > ARRAY_SIZE(s->cmd_data)) {
         return -EINVAL;
-
-    s->cmd_len = qemu_get_be32(f);
-    s->cmd = qemu_get_be32(f);
-    for (i = 0; i < 8; i++)
-        s->cmd_data[i] = qemu_get_be32(f);
-    s->row = qemu_get_be32(f);
-    s->row_start = qemu_get_be32(f);
-    s->row_end = qemu_get_be32(f);
-    s->col = qemu_get_be32(f);
-    s->col_start = qemu_get_be32(f);
-    s->col_end = qemu_get_be32(f);
-    s->redraw = qemu_get_be32(f);
-    s->remap = qemu_get_be32(f);
-    s->mode = qemu_get_be32(f);
-    qemu_get_buffer(f, s->framebuffer, sizeof(s->framebuffer));
-
-    ss->cs = qemu_get_be32(f);
+    }
+    if (s->row < 0 || s->row >= 80) {
+        return -EINVAL;
+    }
+    if (s->row_start < 0 || s->row_start >= 80) {
+        return -EINVAL;
+    }
+    if (s->row_end < 0 || s->row_end >= 80) {
+        return -EINVAL;
+    }
+    if (s->col < 0 || s->col >= 64) {
+        return -EINVAL;
+    }
+    if (s->col_start < 0 || s->col_start >= 64) {
+        return -EINVAL;
+    }
+    if (s->col_end < 0 || s->col_end >= 64) {
+        return -EINVAL;
+    }
+    if (s->mode != SSD0323_CMD && s->mode != SSD0323_DATA) {
+        return -EINVAL;
+    }
 
     return 0;
 }
 
+static const VMStateDescription vmstate_ssd0323 = {
+    .name = "ssd0323_oled",
+    .version_id = 2,
+    .minimum_version_id = 2,
+    .post_load = ssd0323_post_load,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT32(cmd_len, ssd0323_state),
+        VMSTATE_INT32(cmd, ssd0323_state),
+        VMSTATE_INT32_ARRAY(cmd_data, ssd0323_state, 8),
+        VMSTATE_INT32(row, ssd0323_state),
+        VMSTATE_INT32(row_start, ssd0323_state),
+        VMSTATE_INT32(row_end, ssd0323_state),
+        VMSTATE_INT32(col, ssd0323_state),
+        VMSTATE_INT32(col_start, ssd0323_state),
+        VMSTATE_INT32(col_end, ssd0323_state),
+        VMSTATE_INT32(redraw, ssd0323_state),
+        VMSTATE_INT32(remap, ssd0323_state),
+        VMSTATE_UINT32(mode, ssd0323_state),
+        VMSTATE_BUFFER(framebuffer, ssd0323_state),
+        VMSTATE_SSI_PERIPHERAL(ssidev, ssd0323_state),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const GraphicHwOps ssd0323_ops = {
     .invalidate  = ssd0323_invalidate_display,
     .gfx_update  = ssd0323_update_display,
 };
 
-static int ssd0323_init(SSISlave *dev)
+static void ssd0323_realize(SSIPeripheral *d, Error **errp)
 {
-    ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, dev);
+    DeviceState *dev = DEVICE(d);
+    ssd0323_state *s = SSD0323(d);
 
     s->col_end = 63;
     s->row_end = 79;
-    s->con = graphic_console_init(DEVICE(dev), 0, &ssd0323_ops, s);
+    s->con = graphic_console_init(dev, 0, &ssd0323_ops, s);
     qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY);
 
-    qdev_init_gpio_in(&dev->qdev, ssd0323_cd, 1);
-
-    register_savevm(&dev->qdev, "ssd0323_oled", -1, 1,
-                    ssd0323_save, ssd0323_load, s);
-    return 0;
+    qdev_init_gpio_in(dev, ssd0323_cd, 1);
 }
 
 static void ssd0323_class_init(ObjectClass *klass, void *data)
 {
-    SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
 
-    k->init = ssd0323_init;
+    k->realize = ssd0323_realize;
     k->transfer = ssd0323_transfer;
     k->cs_polarity = SSI_CS_HIGH;
+    dc->vmsd = &vmstate_ssd0323;
+    set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
 }
 
 static const TypeInfo ssd0323_info = {
-    .name          = "ssd0323",
-    .parent        = TYPE_SSI_SLAVE,
+    .name          = TYPE_SSD0323,
+    .parent        = TYPE_SSI_PERIPHERAL,
     .instance_size = sizeof(ssd0323_state),
     .class_init    = ssd0323_class_init,
 };