qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 26/29] vmsvga: Add basic support for display topolog


From: Liran Alon
Subject: [Qemu-devel] [PATCH 26/29] vmsvga: Add basic support for display topology
Date: Thu, 9 Aug 2018 14:46:39 +0300

From: Leonid Shatz <address@hidden>

Report SVGA_CAP_DISPLAY_TOPOLOGY capability and support single
legacy screen at fixed offset of (0,0).

This is a pre-requesite for supporting PITCHLOCK feature which is
required by Linux kernel vmsvga driver (See Linux kernel
vmw_driver_load()).

Signed-off-by: Leonid Shatz <address@hidden>
Reviewed-by: Darren Kenny <address@hidden>
Signed-off-by: Liran Alon <address@hidden>
---
 hw/display/vmware_vga.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c
index b2f3456357bd..edd336e65005 100644
--- a/hw/display/vmware_vga.c
+++ b/hw/display/vmware_vga.c
@@ -81,6 +81,7 @@ struct vmsvga_state_s {
     uint32_t num_fifo_regs;
     uint32_t irq_mask;
     uint32_t irq_status;
+    uint32_t display_id;
 };
 
 #define TYPE_VMWARE_SVGA "vmware-svga"
@@ -103,6 +104,9 @@ struct pci_vmsvga_state_s {
 #define SVGA_ID_1               SVGA_MAKE_ID(1)
 #define SVGA_ID_2               SVGA_MAKE_ID(2)
 
+/* "Invalid" value for all SVGA IDs. (Version ID, screen object ID, surface 
ID...) */
+#define SVGA_ID_INVALID         0xFFFFFFFF
+
 #define SVGA_LEGACY_BASE_PORT   0x4560
 #define SVGA_INDEX_PORT         0x0
 #define SVGA_VALUE_PORT         0x1
@@ -164,6 +168,15 @@ enum {
     SVGA_REG_PITCHLOCK = 32,            /* Fixed pitch for all modes */
     SVGA_REG_IRQMASK = 33,              /* Interrupt mask */
 
+    /* Legacy multi-monitor support */
+    SVGA_REG_NUM_GUEST_DISPLAYS = 34,   /* Number of guest displays in X/Y 
direction */
+    SVGA_REG_DISPLAY_ID = 35,           /* Display ID for the following 
display attributes */
+    SVGA_REG_DISPLAY_IS_PRIMARY = 36,   /* Whether this is a primary display */
+    SVGA_REG_DISPLAY_POSITION_X = 37,   /* The display position x */
+    SVGA_REG_DISPLAY_POSITION_Y = 38,   /* The display position y */
+    SVGA_REG_DISPLAY_WIDTH = 39,        /* The display's width */
+    SVGA_REG_DISPLAY_HEIGHT = 40,       /* The display's height */
+
     /* Guest memory regions */
     SVGA_REG_GMR_ID = 41,
     SVGA_REG_GMR_DESCRIPTOR = 42,
@@ -195,6 +208,7 @@ enum {
 #define SVGA_CAP_MULTIMON               (1 << 16)
 #define SVGA_CAP_PITCHLOCK              (1 << 17)
 #define SVGA_CAP_IRQMASK                (1 << 18)
+#define SVGA_CAP_DISPLAY_TOPOLOGY       (1 << 19)   // Legacy multi-monitor 
support
 
 /*
  * FIFO offsets (seen as an array of 32-bit words)
@@ -1227,6 +1241,7 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t 
address)
 #endif
         caps |= SVGA_CAP_EXTENDED_FIFO;
         caps |= SVGA_CAP_IRQMASK;
+        caps |= SVGA_CAP_DISPLAY_TOPOLOGY;
         ret = caps;
         break;
 
@@ -1288,6 +1303,32 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t 
address)
         ret = s->irq_mask;
         break;
 
+    case SVGA_REG_NUM_GUEST_DISPLAYS:
+        ret = 1;
+        break;
+    case SVGA_REG_DISPLAY_ID:
+        ret = s->display_id;
+        break;
+    case SVGA_REG_DISPLAY_IS_PRIMARY:
+        ret = s->display_id == 0 ? 1 : 0;
+        break;
+    case SVGA_REG_DISPLAY_POSITION_X:
+    case SVGA_REG_DISPLAY_POSITION_Y:
+        ret = 0;
+        break;
+    case SVGA_REG_DISPLAY_WIDTH:
+        if ((s->display_id == 0) || (s->display_id == SVGA_ID_INVALID))
+            ret = s->new_width ? s->new_width : surface_width(surface);
+        else
+            ret = 0;
+        break;
+    case SVGA_REG_DISPLAY_HEIGHT:
+        if ((s->display_id == 0) || (s->display_id == SVGA_ID_INVALID))
+            ret = s->new_height ? s->new_height : surface_height(surface);
+        else
+            ret = 0;
+        break;
+
     /* Guest memory regions */
     case SVGA_REG_GMR_ID:
     case SVGA_REG_GMR_DESCRIPTOR:
@@ -1431,6 +1472,28 @@ static void vmsvga_value_write(void *opaque, uint32_t 
address, uint32_t value)
         s->irq_mask = value;
         break;
 
+    /* We support single legacy screen at fixed offset of (0,0) */
+    case SVGA_REG_DISPLAY_ID:
+        s->display_id = value;
+        break;
+    case SVGA_REG_NUM_GUEST_DISPLAYS:
+    case SVGA_REG_DISPLAY_IS_PRIMARY:
+    case SVGA_REG_DISPLAY_POSITION_X:
+    case SVGA_REG_DISPLAY_POSITION_Y:
+        break;
+    case SVGA_REG_DISPLAY_WIDTH:
+        if ((s->display_id == 0) && (value <= SVGA_MAX_WIDTH)) {
+            s->new_width = value;
+            s->invalidated = 1;
+        }
+        break;
+    case SVGA_REG_DISPLAY_HEIGHT:
+        if ((s->display_id == 0) && (value <= SVGA_MAX_HEIGHT)) {
+            s->new_height = value;
+            s->invalidated = 1;
+        }
+        break;
+
     default:
         if (s->index >= SVGA_SCRATCH_BASE &&
                 s->index < SVGA_SCRATCH_BASE + s->scratch_size) {
@@ -1534,6 +1597,7 @@ static void vmsvga_reset(DeviceState *dev)
     s->irq_mask = 0;
     s->irq_status = 0;
     s->last_fifo_cursor_count = 0;
+    s->display_id = SVGA_ID_INVALID;
 
     vga_dirty_log_start(&s->vga);
 }
@@ -1568,6 +1632,7 @@ static int vmsvga_post_load(void *opaque, int version_id)
         s->irq_mask = 0;
         s->irq_status = 0;
         s->last_fifo_cursor_count = 0;
+        s->display_id = SVGA_ID_INVALID;
     }
 
     return 0;
@@ -1598,6 +1663,7 @@ static const VMStateDescription 
vmstate_vmware_vga_internal = {
         VMSTATE_UINT32_V(irq_mask, struct vmsvga_state_s, 1),
         VMSTATE_UINT32_V(irq_status, struct vmsvga_state_s, 1),
         VMSTATE_UINT32_V(last_fifo_cursor_count, struct vmsvga_state_s, 1),
+        VMSTATE_UINT32_V(display_id, struct vmsvga_state_s, 1),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
1.9.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]