summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2011-04-27 18:24:38 +0300
committerAlon Levy <alevy@redhat.com>2011-05-24 16:33:11 +0300
commitdd6a8d3096febd9dbb5ffa10c38bbe3e90f8ac67 (patch)
treedc72d5bddbfec6dc050914d9dcfaae4963adefd6
parent2769579364275cf9bb19d0e33d58ecd9ac4a2535 (diff)
xspice: implement ioport_write
-rw-r--r--src/spiceqxl_io_port.c181
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();
+ }
}