[Spice-devel] [RFC 30/33] xspice: implement ioport_write

Alon Levy alevy at redhat.com
Wed Apr 27 08:56:19 PDT 2011


---
 src/spiceqxl_io_port.c |  181 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 181 insertions(+), 0 deletions(-)

diff --git a/src/spiceqxl_io_port.c b/src/spiceqxl_io_port.c
index ba6ac4a..89a9657 100644
--- a/src/spiceqxl_io_port.c
+++ b/src/spiceqxl_io_port.c
@@ -54,8 +54,189 @@ void init_qxl_ram(qxl_screen_t *qxl)
     *item = 0;
 }
 
+static void qxl_reset_state(qxl_screen_t *qxl)
+{
+    QXLRam *ram = get_ram_header(qxl);
+
+    assert(SPICE_RING_IS_EMPTY(&ram->cmd_ring));
+    assert(SPICE_RING_IS_EMPTY(&ram->cursor_ring));
+    qxl->shadow_rom.update_id = 0;
+    *qxl->rom = qxl->shadow_rom;
+    init_qxl_ram(qxl);
+    qxl->num_free_res = 0;
+    qxl->last_release = NULL;
+    // TODO - dirty ?
+    //memset(&qxl->ssd.dirty, 0, sizeof(qxl->ssd.dirty));
+}
+
+static void qxl_check_state(qxl_screen_t *qxl)
+{
+    QXLRam *ram = get_ram_header(qxl);
+
+    assert(SPICE_RING_IS_EMPTY(&ram->cmd_ring));
+    assert(SPICE_RING_IS_EMPTY(&ram->cursor_ring));
+}
+
+static void qxl_soft_reset(qxl_screen_t *qxl)
+{
+    dprint(1, "%s:\n", __FUNCTION__);
+    qxl_check_state(qxl);
+}
+
+static void qxl_reset_surfaces(qxl_screen_t *qxl)
+{
+    dprint(1, "%s:\n", __FUNCTION__);
+    qxl->worker->destroy_surfaces(qxl->worker);
+    // TODO - do we have guest_surfaces?
+    //memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
+}
+
+static void qxl_hard_reset(qxl_screen_t *qxl)
+{
+    dprint(1, "%s: start\n", __FUNCTION__);
+
+    qxl->worker->reset_cursor(qxl->worker);
+    qxl->worker->reset_image_cache(qxl->worker);
+    qxl_reset_surfaces(qxl);
+
+    qxl_reset_state(qxl);
+    qxl_soft_reset(qxl);
+
+    dprint(1, "%s: done\n", __FUNCTION__);
+}
+
+static void qxl_create_guest_primary(qxl_screen_t *qxl)
+{
+    QXLDevSurfaceCreate surface;
+    QXLSurfaceCreate *sc = &qxl->guest_primary.surface;
+
+    dprint(1, "%s: %dx%d\n", __FUNCTION__, sc->width, sc->height);
+
+    surface.format     = sc->format;
+    surface.height     = sc->height;
+    surface.mem        = sc->mem;
+    surface.position   = sc->position;
+    surface.stride     = sc->stride;
+    surface.width      = sc->width;
+    surface.type       = sc->type;
+    surface.flags      = sc->flags;
+
+    surface.mouse_mode = TRUE;
+    surface.group_id   = 0;
+    qxl->cmdflags = 0;
+    qxl->worker->create_primary_surface(qxl->worker, 0, &surface);
+}
+
+static void qxl_destroy_primary(qxl_screen_t *qxl)
+{
+    dprint(1, "%s\n", __FUNCTION__);
+
+    qxl->worker->destroy_primary_surface(qxl->worker, 0);
+}
+
+
+static void qxl_set_mode(qxl_screen_t *qxl, int modenr)
+{
+    struct QXLMode *mode = qxl->modes + modenr;
+    uint64_t devmem = (uint64_t)qxl->ram;
+    QXLSurfaceCreate surface = {
+        .width      = mode->x_res,
+        .height     = mode->y_res,
+        .stride     = -mode->x_res * 4,
+        .format     = SPICE_SURFACE_FMT_32_xRGB,
+        .flags      = 0,
+        .mouse_mode = TRUE,
+        .mem        = devmem + qxl->shadow_rom.draw_area_offset,
+    };
+
+    dprint(1, "%s: mode %d  [ %d x %d @ %d bpp devmem 0x%lx ]\n", __FUNCTION__,
+           modenr, mode->x_res, mode->y_res, mode->bits, devmem);
+    qxl_hard_reset(qxl);
+
+    qxl->guest_primary.surface = surface;
+    qxl_create_guest_primary(qxl);
+
+    qxl->cmdflags = QXL_COMMAND_FLAG_COMPAT;
+#ifdef QXL_COMMAND_FLAG_COMPAT_16BPP /* new in spice 0.6.1 */
+    if (mode->bits == 16) {
+        qxl->cmdflags |= QXL_COMMAND_FLAG_COMPAT_16BPP;
+    }
+#endif
+    qxl->shadow_rom.mode = modenr;
+    qxl->rom->mode = modenr;
+}
+
 /* called from Xorg thread - not worker thread! */
 void ioport_write(qxl_screen_t *qxl, uint32_t io_port, uint32_t val)
 {
+    QXLRam *header = get_ram_header(qxl);
+
+    switch (io_port) {
+    case QXL_IO_UPDATE_AREA:
+    {
+        QXLRect update = *(QXLRect*)&header->update_area;
+        qxl->worker->update_area(qxl->worker, header->update_surface,
+                                   &update, NULL, 0, 0);
+        break;
+    }
+    case QXL_IO_NOTIFY_CMD:
+        qxl->worker->wakeup(qxl->worker);
+        break;
+    case QXL_IO_NOTIFY_CURSOR:
+        qxl->worker->wakeup(qxl->worker);
+        break;
+    case QXL_IO_UPDATE_IRQ:
+        /* qxl_set_irq(d); */
+        printf("QXL_IO_UPDATE_IRQ not implemented\n");
+        break;
+    case QXL_IO_NOTIFY_OOM:
+        if (!SPICE_RING_IS_EMPTY(&header->release_ring)) {
+            break;
+        }
+        pthread_yield();
+        if (!SPICE_RING_IS_EMPTY(&header->release_ring)) {
+            break;
+        }
+        qxl->worker->oom(qxl->worker);
+        break;
+    case QXL_IO_SET_MODE:
+        dprint(1, "QXL_SET_MODE %d\n", val);
+        qxl_set_mode(qxl, val);
+        break;
+    case QXL_IO_LOG:
+        fprintf(stderr, "qxl/guest: %s", header->log_buf);
+        break;
+    case QXL_IO_RESET:
+        dprint(1, "QXL_IO_RESET\n");
+        qxl_hard_reset(qxl);
+        break;
+    case QXL_IO_MEMSLOT_ADD:
+        dprint(1, "QXL_IO_MEMSLOT_ADD - should not be called (this is XSpice)\n");
+        break;
+    case QXL_IO_MEMSLOT_DEL:
+        dprint(1, "QXL_IO_MEMSLOT_DEL - should not be called (this is XSpice)\n");
+        break;
+    case QXL_IO_CREATE_PRIMARY:
+        assert(val == 0);
+        dprint(1, "QXL_IO_CREATE_PRIMARY\n");
+        qxl->guest_primary.surface =
+            *(QXLSurfaceCreate*)&header->create_surface;
+        qxl_create_guest_primary(qxl);
+        break;
+    case QXL_IO_DESTROY_PRIMARY:
+        assert(val == 0);
+        dprint(1, "QXL_IO_DESTROY_PRIMARY\n");
+        qxl_destroy_primary(qxl);
+        break;
+    case QXL_IO_DESTROY_SURFACE_WAIT:
+        qxl->worker->destroy_surface_wait(qxl->worker, val);
+        break;
+    case QXL_IO_DESTROY_ALL_SURFACES:
+        qxl->worker->destroy_surfaces(qxl->worker);
+        break;
+    default:
+        fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port);
+        abort();
+    }
 }
 
-- 
1.7.4.4



More information about the Spice-devel mailing list