From: Leonid Shatz <leonid.sh...@oracle.com>

According to Linux kernel
drivers/gpu/drm/vmwgfx/device_include/svga_reg.h:

/*
 * SVGA_CMD_FENCE --
 *
 *    Insert a synchronization fence.  When the SVGA device reaches
 *    this command, it will copy the 'fence' value into the
 *    SVGA_FIFO_FENCE register. It will also compare the fence against
 *    SVGA_FIFO_FENCE_GOAL. If the fence matches the goal and the
 *    SVGA_IRQFLAG_FENCE_GOAL interrupt is enabled, the device will
 *    raise this interrupt.
 *
 * Availability:
 *    SVGA_FIFO_FENCE for this command,
 *    SVGA_CAP_IRQMASK for SVGA_FIFO_FENCE_GOAL.
 */

Signed-off-by: Leonid Shatz <leonid.sh...@oracle.com>
Reviewed-by: Darren Kenny <darren.ke...@oracle.com>
Signed-off-by: Liran Alon <liran.a...@oracle.com>
---
 hw/display/vmware_vga.c | 33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c
index dc5f4681f0d3..73e373665bdb 100644
--- a/hw/display/vmware_vga.c
+++ b/hw/display/vmware_vga.c
@@ -217,6 +217,7 @@ enum {
 
     SVGA_FIFO_CAPABILITIES = 4,
     SVGA_FIFO_FLAGS,
+    /* Valid with SVGA_FIFO_CAP_FENCE */
     SVGA_FIFO_FENCE,
 
    /*
@@ -729,6 +730,7 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
     int x, y, dx, dy, width, height;
     struct vmsvga_cursor_definition_s cursor;
     uint32_t cmd_start;
+    uint32_t fence_arg;
     bool cmd_ignored;
     bool irq_pending = false;
     bool fifo_progress = false;
@@ -832,6 +834,28 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
             args = 6;
             goto ignoredcmd;
 
+        case SVGA_CMD_FENCE:
+            len -= 2;
+            if (len < 0) {
+                goto rewind;
+            }
+
+            fence_arg = vmsvga_fifo_read(s);
+            s->fifo[SVGA_FIFO_FENCE] = cpu_to_le32(fence_arg);
+
+            if (s->irq_mask & SVGA_IRQFLAG_ANY_FENCE) {
+                s->irq_status |= SVGA_IRQFLAG_ANY_FENCE;
+                irq_pending = true;
+            }
+            if ((s->irq_mask & SVGA_IRQFLAG_FENCE_GOAL)
+               && (s->fifo_min > SVGA_FIFO_FENCE_GOAL)
+               && (s->fifo[SVGA_FIFO_FENCE_GOAL] == fence_arg)) {
+                s->irq_status |= SVGA_IRQFLAG_FENCE_GOAL;
+                irq_pending = true;
+            }
+
+            break;
+
         /*
          * Deprecated commands are neither documented in VMware SVGA 
development kit
          * nor in Linux kernel vmware-svga driver source code.
@@ -899,13 +923,6 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
         case SVGA_CMD_SURFACE_ALPHA_BLEND: /* deprecated */
             args = 12;
             goto badcmd;
-        case SVGA_CMD_FENCE:
-            len -= 1;
-            if (len < 0) {
-                goto rewind;
-            }
-            args = 1;
-            goto badcmd;
 
         default:
             args = 0;
@@ -1463,7 +1480,7 @@ static void vmsvga_init(DeviceState *dev, struct 
vmsvga_state_s *s,
                            &error_fatal);
     s->fifo = (uint32_t *)memory_region_get_ram_ptr(&s->fifo_ram);
     s->num_fifo_regs = SVGA_FIFO_NUM_REGS;
-    s->fifo[SVGA_FIFO_CAPABILITIES] = 0;
+    s->fifo[SVGA_FIFO_CAPABILITIES] = SVGA_FIFO_CAP_FENCE;
     s->fifo[SVGA_FIFO_FLAGS] = 0;
 
     vga_common_init(&s->vga, OBJECT(dev));
-- 
1.9.1


Reply via email to