summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2011-12-19 20:25:43 +0100
committerThomas Hellstrom <thellstrom@vmware.com>2011-12-19 20:25:43 +0100
commitb5546fb1de3f3859151a91e98ab0bd24b6789e2e (patch)
tree8e5283d6610e87d796e0d64b0a06c42469422b0d /src
parentabf9cb75630cb27bb4741d194cb23014fe3d09b1 (diff)
parent5748c33535bc7d3009b9758653885e6ae0e73002 (diff)
Merge branch 'vmwgfx_branch'
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am27
-rw-r--r--src/svga_reg.h1433
-rw-r--r--src/vmware.c547
-rw-r--r--src/vmware_bootstrap.c503
-rw-r--r--src/vmware_bootstrap.h59
-rw-r--r--src/vmware_common.c163
-rw-r--r--src/vmware_common.h41
-rw-r--r--src/vmwaremodule.c256
8 files changed, 1875 insertions, 1154 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 7c972cf..64a9069 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -24,12 +24,14 @@
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
-vmwlegacy_drv_la_LTLIBRARIES = vmwlegacy_drv.la
-vmwlegacy_drv_la_LDFLAGS = -module -avoid-version
-vmwlegacy_drv_la_CFLAGS = @XORG_CFLAGS@
-vmwlegacy_drv_ladir = @moduledir@/drivers
+vmware_drv_la_LTLIBRARIES = vmware_drv.la
+vmware_drv_la_LDFLAGS = -module -avoid-version
+vmware_drv_la_CFLAGS = @XORG_CFLAGS@
+vmware_drv_ladir = @moduledir@/drivers
+vmware_drv_la_LIBADD = @VMWGFX_LIBADD@
+vmware_drv_la_DEPENDENCIES = @VMWGFX_LIBADD@
-vmwlegacy_drv_la_SOURCES = \
+vmware_drv_la_SOURCES = \
bits2pixels.c \
bits2pixels.h \
guest_os.h \
@@ -50,13 +52,8 @@ vmwlegacy_drv_la_SOURCES = \
vmwarectrlproto.h \
vmwarexinerama.c \
vmwarevideo.c \
- vmwaremodes.c
-
-vmware_drv_la_LTLIBRARIES = vmware_drv.la
-vmware_drv_la_LDFLAGS = -module -avoid-version
-vmware_drv_la_CFLAGS = @XORG_CFLAGS@ @LIBDRM_CFLAGS@
-vmware_drv_la_LIBADD = @LIBDRM_LIBS@
-vmware_drv_ladir = @moduledir@/drivers
-
-vmware_drv_la_SOURCES = \
- vmwaremodule.c
+ vmwaremodes.c \
+ vmware_bootstrap.h \
+ vmware_bootstrap.c \
+ vmware_common.c \
+ vmware_common.h
diff --git a/src/svga_reg.h b/src/svga_reg.h
index 4fa363a..6757aa6 100644
--- a/src/svga_reg.h
+++ b/src/svga_reg.h
@@ -1,52 +1,81 @@
-/* **********************************************************
- * Copyright 1998 VMware, Inc. All rights reserved.
- * **********************************************************/
+/**********************************************************
+ * Copyright 1998-2009 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
/*
* svga_reg.h --
*
- * SVGA hardware definitions
+ * Virtual hardware definitions for the VMware SVGA II device.
*/
#ifndef _SVGA_REG_H_
#define _SVGA_REG_H_
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_VMCORE
-#include "includeCheck.h"
+/*
+ * PCI device IDs.
+ */
+#define PCI_VENDOR_ID_VMWARE 0x15AD
+#define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405
/*
- * Memory and port addresses and fundamental constants
+ * SVGA_REG_ENABLE bit definitions.
*/
+#define SVGA_REG_ENABLE_DISABLE 0
+#define SVGA_REG_ENABLE_ENABLE 1
+#define SVGA_REG_ENABLE_HIDE 2
+#define SVGA_REG_ENABLE_ENABLE_HIDE (SVGA_REG_ENABLE_ENABLE |\
+ SVGA_REG_ENABLE_HIDE)
/*
- * Note-- MAX_WIDTH and MAX_HEIGHT are largely ignored by the code. This
- * isn't such a bad thing for forward compatibility. --Jeremy.
+ * Legal values for the SVGA_REG_CURSOR_ON register in old-fashioned
+ * cursor bypass mode. This is still supported, but no new guest
+ * drivers should use it.
*/
-#define SVGA_MAX_WIDTH 2360
-#define SVGA_MAX_HEIGHT 1770
-#define SVGA_MAX_BITS_PER_PIXEL 32
-#define SVGA_MAX_DEPTH 24
-#define SVGA_MAX_DISPLAYS 10
+#define SVGA_CURSOR_ON_HIDE 0x0 /* Must be 0 to maintain backward compatibility */
+#define SVGA_CURSOR_ON_SHOW 0x1 /* Must be 1 to maintain backward compatibility */
+#define SVGA_CURSOR_ON_REMOVE_FROM_FB 0x2 /* Remove the cursor from the framebuffer because we need to see what's under it */
+#define SVGA_CURSOR_ON_RESTORE_TO_FB 0x3 /* Put the cursor back in the framebuffer so the user can see it */
/*
- * The maximum size of the onscreen framebuffer. The size of the
- * changeMap in the monitor is proportional to this number since it's
- * the amount of memory we need to trace in VESA mode. Therefore, we'd
+ * The maximum framebuffer size that can traced for e.g. guests in VESA mode.
+ * The changeMap in the monitor is proportional to this number. Therefore, we'd
* like to keep it as small as possible to reduce monitor overhead (using
- * SVGA_VRAM_MAX_SIZE for this increases the size of the shared area
- * by over 4k!).
+ * SVGA_VRAM_MAX_SIZE for this increases the size of the shared area by over
+ * 4k!).
+ *
+ * NB: For compatibility reasons, this value must be greater than 0xff0000.
+ * See bug 335072.
*/
-
-#define SVGA_FB_MAX_SIZE \
- ((((SVGA_MAX_WIDTH * SVGA_MAX_HEIGHT * \
- SVGA_MAX_BITS_PER_PIXEL / 8) >> PAGE_SHIFT) + 1) << PAGE_SHIFT)
+#define SVGA_FB_MAX_TRACEABLE_SIZE 0x1000000
-#define SVGA_MAX_PSEUDOCOLOR_DEPTH 8
-#define SVGA_MAX_PSEUDOCOLORS (1 << SVGA_MAX_PSEUDOCOLOR_DEPTH)
+#define SVGA_MAX_PSEUDOCOLOR_DEPTH 8
+#define SVGA_MAX_PSEUDOCOLORS (1 << SVGA_MAX_PSEUDOCOLOR_DEPTH)
#define SVGA_NUM_PALETTE_REGS (3 * SVGA_MAX_PSEUDOCOLORS)
+/* Base and Offset gets us headed the right way for PCI Base Addr Registers */
+#define SVGA_LEGACY_BASE_PORT 0x4560
+
#define SVGA_MAGIC 0x900000UL
#define SVGA_MAKE_ID(ver) (SVGA_MAGIC << 8 | (ver))
@@ -63,19 +92,14 @@
#define SVGA_VERSION_0 0
#define SVGA_ID_0 SVGA_MAKE_ID(SVGA_VERSION_0)
-/* Invalid SVGA_ID_ */
+/* "Invalid" value for all SVGA IDs. (Version ID, screen object ID, surface ID...) */
#define SVGA_ID_INVALID 0xFFFFFFFF
-/* More backwards compatibility, old location of color map: */
-#define SVGA_OLD_PALETTE_BASE 17
-
-/* Base and Offset gets us headed the right way for PCI Base Addr Registers */
-#define SVGA_LEGACY_BASE_PORT 0x4560
-#define SVGA_INDEX_PORT 0x0
-#define SVGA_VALUE_PORT 0x1
-#define SVGA_BIOS_PORT 0x2
-#define SVGA_NUM_PORTS 0x3
-#define SVGA_IRQSTATUS_PORT 0x8
+/* Port offsets, relative to BAR0 */
+#define SVGA_INDEX_PORT 0x0
+#define SVGA_VALUE_PORT 0x1
+#define SVGA_BIOS_PORT 0x2
+#define SVGA_IRQSTATUS_PORT 0x8
/*
* Interrupt source flags for IRQSTATUS_PORT and IRQMASK.
@@ -87,15 +111,6 @@
#define SVGA_IRQFLAG_FIFO_PROGRESS 0x2 /* Made forward progress in the FIFO */
#define SVGA_IRQFLAG_FENCE_GOAL 0x4 /* SVGA_FIFO_FENCE_GOAL reached */
-/* This port is deprecated, but retained because of old drivers. */
-#define SVGA_LEGACY_ACCEL_PORT 0x3
-
-/* Legal values for the SVGA_REG_CURSOR_ON register in cursor bypass mode */
-#define SVGA_CURSOR_ON_HIDE 0x0 /* Must be 0 to maintain backward compatibility */
-#define SVGA_CURSOR_ON_SHOW 0x1 /* Must be 1 to maintain backward compatibility */
-#define SVGA_CURSOR_ON_REMOVE_FROM_FB 0x2 /* Remove the cursor from the framebuffer because we need to see what's under it */
-#define SVGA_CURSOR_ON_RESTORE_TO_FB 0x3 /* Put the cursor back in the framebuffer so the user can see it */
-
/*
* Registers
*/
@@ -108,13 +123,13 @@ enum {
SVGA_REG_MAX_WIDTH = 4,
SVGA_REG_MAX_HEIGHT = 5,
SVGA_REG_DEPTH = 6,
- SVGA_REG_BITS_PER_PIXEL = 7, /* Current bpp in the guest */
+ SVGA_REG_BITS_PER_PIXEL = 7, /* Current bpp in the guest */
SVGA_REG_PSEUDOCOLOR = 8,
SVGA_REG_RED_MASK = 9,
SVGA_REG_GREEN_MASK = 10,
SVGA_REG_BLUE_MASK = 11,
SVGA_REG_BYTES_PER_LINE = 12,
- SVGA_REG_FB_START = 13,
+ SVGA_REG_FB_START = 13, /* (Deprecated) */
SVGA_REG_FB_OFFSET = 14,
SVGA_REG_VRAM_SIZE = 15,
SVGA_REG_FB_SIZE = 16,
@@ -122,33 +137,46 @@ enum {
/* ID 0 implementation only had the above registers, then the palette */
SVGA_REG_CAPABILITIES = 17,
- SVGA_REG_MEM_START = 18, /* Memory for command FIFO and bitmaps */
+ SVGA_REG_MEM_START = 18, /* (Deprecated) */
SVGA_REG_MEM_SIZE = 19,
- SVGA_REG_CONFIG_DONE = 20, /* Set when memory area configured */
- SVGA_REG_SYNC = 21, /* See "FIFO Synchronization Registers" */
- SVGA_REG_BUSY = 22, /* See "FIFO Synchronization Registers" */
- SVGA_REG_GUEST_ID = 23, /* Set guest OS identifier */
- SVGA_REG_CURSOR_ID = 24, /* ID of cursor */
- SVGA_REG_CURSOR_X = 25, /* Set cursor X position */
- SVGA_REG_CURSOR_Y = 26, /* Set cursor Y position */
- SVGA_REG_CURSOR_ON = 27, /* Turn cursor on/off */
- SVGA_REG_HOST_BITS_PER_PIXEL = 28, /* Current bpp in the host */
- SVGA_REG_SCRATCH_SIZE = 29, /* Number of scratch registers */
- SVGA_REG_MEM_REGS = 30, /* Number of FIFO registers */
- SVGA_REG_NUM_DISPLAYS = 31, /* Number of guest displays */
- SVGA_REG_PITCHLOCK = 32, /* Fixed pitch for all modes */
- SVGA_REG_IRQMASK = 33, /* Interrupt mask */
+ SVGA_REG_CONFIG_DONE = 20, /* Set when memory area configured */
+ SVGA_REG_SYNC = 21, /* See "FIFO Synchronization Registers" */
+ SVGA_REG_BUSY = 22, /* See "FIFO Synchronization Registers" */
+ SVGA_REG_GUEST_ID = 23, /* Set guest OS identifier */
+ SVGA_REG_CURSOR_ID = 24, /* (Deprecated) */
+ SVGA_REG_CURSOR_X = 25, /* (Deprecated) */
+ SVGA_REG_CURSOR_Y = 26, /* (Deprecated) */
+ SVGA_REG_CURSOR_ON = 27, /* (Deprecated) */
+ SVGA_REG_HOST_BITS_PER_PIXEL = 28, /* (Deprecated) */
+ SVGA_REG_SCRATCH_SIZE = 29, /* Number of scratch registers */
+ SVGA_REG_MEM_REGS = 30, /* Number of FIFO registers */
+ SVGA_REG_NUM_DISPLAYS = 31, /* (Deprecated) */
+ 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, /* The display ID for the following display attributes */
+ 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 */
- SVGA_REG_TOP = 41, /* Must be 1 more than the last register */
- SVGA_PALETTE_BASE = 1024, /* Base of SVGA color map */
+ /* See "Guest memory regions" below. */
+ SVGA_REG_GMR_ID = 41,
+ SVGA_REG_GMR_DESCRIPTOR = 42,
+ SVGA_REG_GMR_MAX_IDS = 43,
+ SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH = 44,
+
+ SVGA_REG_TRACES = 45, /* Enable trace-based updates even when FIFO is on */
+ SVGA_REG_GMRS_MAX_PAGES = 46, /* Maximum number of 4KB pages for all GMRs */
+ SVGA_REG_MEMORY_SIZE = 47, /* Total dedicated device memory excluding FIFO */
+ SVGA_REG_TOP = 48, /* Must be 1 more than the last register */
+
+ SVGA_PALETTE_BASE = 1024, /* Base of SVGA color map */
/* Next 768 (== 256*3) registers exist for colormap */
+
SVGA_SCRATCH_BASE = SVGA_PALETTE_BASE + SVGA_NUM_PALETTE_REGS
/* Base of scratch registers */
/* Next reg[SVGA_REG_SCRATCH_SIZE] registers exist for scratch usage:
@@ -156,126 +184,264 @@ enum {
the use of the current SVGA driver. */
};
+/*
+ * Macros to compute variable length items (sizes in 32-bit words, except
+ * for SVGA_GLYPH_SCANLINE_SIZE, which is in bytes).
+ */
+#define SVGA_BITMAP_SIZE(w,h) ((((w)+31) >> 5) * (h))
+#define SVGA_PIXMAP_SIZE(w,h,bpp) ((( ((w)*(bpp))+31 ) >> 5) * (h))
+#define SVGA_BITMAP_INCREMENT(w) ((( (w)+31 ) >> 5) * sizeof (uint32))
+#define SVGA_PIXMAP_INCREMENT(w,bpp) ((( ((w)*(bpp))+31 ) >> 5) * sizeof (uint32))
/*
- * Capabilities
+ * Guest memory regions (GMRs):
+ *
+ * This is a new memory mapping feature available in SVGA devices
+ * which have the SVGA_CAP_GMR bit set. Previously, there were two
+ * fixed memory regions available with which to share data between the
+ * device and the driver: the FIFO ('MEM') and the framebuffer. GMRs
+ * are our name for an extensible way of providing arbitrary DMA
+ * buffers for use between the driver and the SVGA device. They are a
+ * new alternative to framebuffer memory, usable for both 2D and 3D
+ * graphics operations.
+ *
+ * Since GMR mapping must be done synchronously with guest CPU
+ * execution, we use a new pair of SVGA registers:
+ *
+ * SVGA_REG_GMR_ID --
+ *
+ * Read/write.
+ * This register holds the 32-bit ID (a small positive integer)
+ * of a GMR to create, delete, or redefine. Writing this register
+ * has no side-effects.
+ *
+ * SVGA_REG_GMR_DESCRIPTOR --
+ *
+ * Write-only.
+ * Writing this register will create, delete, or redefine the GMR
+ * specified by the above ID register. If this register is zero,
+ * the GMR is deleted. Any pointers into this GMR (including those
+ * currently being processed by FIFO commands) will be
+ * synchronously invalidated.
+ *
+ * If this register is nonzero, it must be the physical page
+ * number (PPN) of a data structure which describes the physical
+ * layout of the memory region this GMR should describe. The
+ * descriptor structure will be read synchronously by the SVGA
+ * device when this register is written. The descriptor need not
+ * remain allocated for the lifetime of the GMR.
+ *
+ * The guest driver should write SVGA_REG_GMR_ID first, then
+ * SVGA_REG_GMR_DESCRIPTOR.
+ *
+ * SVGA_REG_GMR_MAX_IDS --
+ *
+ * Read-only.
+ * The SVGA device may choose to support a maximum number of
+ * user-defined GMR IDs. This register holds the number of supported
+ * IDs. (The maximum supported ID plus 1)
+ *
+ * SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH --
+ *
+ * Read-only.
+ * The SVGA device may choose to put a limit on the total number
+ * of SVGAGuestMemDescriptor structures it will read when defining
+ * a single GMR.
+ *
+ * The descriptor structure is an array of SVGAGuestMemDescriptor
+ * structures. Each structure may do one of three things:
+ *
+ * - Terminate the GMR descriptor list.
+ * (ppn==0, numPages==0)
+ *
+ * - Add a PPN or range of PPNs to the GMR's virtual address space.
+ * (ppn != 0, numPages != 0)
+ *
+ * - Provide the PPN of the next SVGAGuestMemDescriptor, in order to
+ * support multi-page GMR descriptor tables without forcing the
+ * driver to allocate physically contiguous memory.
+ * (ppn != 0, numPages == 0)
+ *
+ * Note that each physical page of SVGAGuestMemDescriptor structures
+ * can describe at least 2MB of guest memory. If the driver needs to
+ * use more than one page of descriptor structures, it must use one of
+ * its SVGAGuestMemDescriptors to point to an additional page. The
+ * device will never automatically cross a page boundary.
+ *
+ * Once the driver has described a GMR, it is immediately available
+ * for use via any FIFO command that uses an SVGAGuestPtr structure.
+ * These pointers include a GMR identifier plus an offset into that
+ * GMR.
+ *
+ * The driver must check the SVGA_CAP_GMR bit before using the GMR
+ * registers.
*/
-#define SVGA_CAP_NONE 0x00000000
-#define SVGA_CAP_RECT_FILL 0x00000001
-#define SVGA_CAP_RECT_COPY 0x00000002
-#define SVGA_CAP_RECT_PAT_FILL 0x00000004
-#define SVGA_CAP_LEGACY_OFFSCREEN 0x00000008
-#define SVGA_CAP_RASTER_OP 0x00000010
-#define SVGA_CAP_CURSOR 0x00000020
-#define SVGA_CAP_CURSOR_BYPASS 0x00000040
-#define SVGA_CAP_CURSOR_BYPASS_2 0x00000080
-#define SVGA_CAP_8BIT_EMULATION 0x00000100
-#define SVGA_CAP_ALPHA_CURSOR 0x00000200
-#define SVGA_CAP_GLYPH 0x00000400
-#define SVGA_CAP_GLYPH_CLIPPING 0x00000800
-#define SVGA_CAP_OFFSCREEN_1 0x00001000
-#define SVGA_CAP_ALPHA_BLEND 0x00002000
-#define SVGA_CAP_3D 0x00004000
-#define SVGA_CAP_EXTENDED_FIFO 0x00008000
-#define SVGA_CAP_MULTIMON 0x00010000
-#define SVGA_CAP_PITCHLOCK 0x00020000
-#define SVGA_CAP_IRQMASK 0x00040000
-#define SVGA_CAP_DISPLAY_TOPOLOGY 0x00080000
+/*
+ * Special GMR IDs, allowing SVGAGuestPtrs to point to framebuffer
+ * memory as well. In the future, these IDs could even be used to
+ * allow legacy memory regions to be redefined by the guest as GMRs.
+ *
+ * Using the guest framebuffer (GFB) at BAR1 for general purpose DMA
+ * is being phased out. Please try to use user-defined GMRs whenever
+ * possible.
+ */
+#define SVGA_GMR_NULL ((uint32) -1)
+#define SVGA_GMR_FRAMEBUFFER ((uint32) -2) /* Guest Framebuffer (GFB) */
+
+typedef
+struct SVGAGuestMemDescriptor {
+ uint32 ppn;
+ uint32 numPages;
+} SVGAGuestMemDescriptor;
+
+typedef
+struct SVGAGuestPtr {
+ uint32 gmrId;
+ uint32 offset;
+} SVGAGuestPtr;
/*
- * Raster op codes (same encoding as X) used by FIFO drivers.
+ * SVGAGMRImageFormat --
+ *
+ * This is a packed representation of the source 2D image format
+ * for a GMR-to-screen blit. Currently it is defined as an encoding
+ * of the screen's color depth and bits-per-pixel, however, 16 bits
+ * are reserved for future use to identify other encodings (such as
+ * RGBA or higher-precision images).
+ *
+ * Currently supported formats:
+ *
+ * bpp depth Format Name
+ * --- ----- -----------
+ * 32 24 32-bit BGRX
+ * 24 24 24-bit BGR
+ * 16 16 RGB 5-6-5
+ * 16 15 RGB 5-5-5
+ *
*/
-#define SVGA_ROP_CLEAR 0x00 /* 0 */
-#define SVGA_ROP_AND 0x01 /* src AND dst */
-#define SVGA_ROP_AND_REVERSE 0x02 /* src AND NOT dst */
-#define SVGA_ROP_COPY 0x03 /* src */
-#define SVGA_ROP_AND_INVERTED 0x04 /* NOT src AND dst */
-#define SVGA_ROP_NOOP 0x05 /* dst */
-#define SVGA_ROP_XOR 0x06 /* src XOR dst */
-#define SVGA_ROP_OR 0x07 /* src OR dst */
-#define SVGA_ROP_NOR 0x08 /* NOT src AND NOT dst */
-#define SVGA_ROP_EQUIV 0x09 /* NOT src XOR dst */
-#define SVGA_ROP_INVERT 0x0a /* NOT dst */
-#define SVGA_ROP_OR_REVERSE 0x0b /* src OR NOT dst */
-#define SVGA_ROP_COPY_INVERTED 0x0c /* NOT src */
-#define SVGA_ROP_OR_INVERTED 0x0d /* NOT src OR dst */
-#define SVGA_ROP_NAND 0x0e /* NOT src OR NOT dst */
-#define SVGA_ROP_SET 0x0f /* 1 */
-#define SVGA_ROP_UNSUPPORTED 0x10
+typedef
+struct SVGAGMRImageFormat {
+ union {
+ struct {
+ uint32 bitsPerPixel : 8;
+ uint32 colorDepth : 8;
+ uint32 reserved : 16; /* Must be zero */
+ };
-#define SVGA_NUM_SUPPORTED_ROPS 16
-#define SVGA_ROP_ALL (MASK(SVGA_NUM_SUPPORTED_ROPS))
-#define SVGA_IS_VALID_ROP(rop) (rop < SVGA_NUM_SUPPORTED_ROPS)
+ uint32 value;
+ };
+} SVGAGMRImageFormat;
-#define SVGA_INVALID_DISPLAY_ID ((uint32)-1)
+typedef
+struct SVGAGuestImage {
+ SVGAGuestPtr ptr;
+
+ /*
+ * A note on interpretation of pitch: This value of pitch is the
+ * number of bytes between vertically adjacent image
+ * blocks. Normally this is the number of bytes between the first
+ * pixel of two adjacent scanlines. With compressed textures,
+ * however, this may represent the number of bytes between
+ * compression blocks rather than between rows of pixels.
+ *
+ * XXX: Compressed textures currently must be tightly packed in guest memory.
+ *
+ * If the image is 1-dimensional, pitch is ignored.
+ *
+ * If 'pitch' is zero, the SVGA3D device calculates a pitch value
+ * assuming each row of blocks is tightly packed.
+ */
+ uint32 pitch;
+} SVGAGuestImage;
/*
- * Ops
- * For each pixel, the four channels of the image are computed with:
- *
- * C = Ca * Fa + Cb * Fb
- *
- * where C, Ca, Cb are the values of the respective channels and Fa
- * and Fb come from the following table:
- *
- * BlendOp Fa Fb
- * ------------------------------------------
- * Clear 0 0
- * Src 1 0
- * Dst 0 1
- * Over 1 1-Aa
- * OverReverse 1-Ab 1
- * In Ab 0
- * InReverse 0 Aa
- * Out 1-Ab 0
- * OutReverse 0 1-Aa
- * Atop Ab 1-Aa
- * AtopReverse 1-Ab Aa
- * Xor 1-Ab 1-Aa
- * Add 1 1
- * Saturate min(1,(1-Ab)/Aa) 1
- *
- * Flags
- * You can use the following flags to achieve additional affects:
- *
- * Flag Effect
- * ------------------------------------------
- * ConstantSourceAlpha Ca = Ca * Param0
- * ConstantDestAlpha Cb = Cb * Param1
- *
- * Flag effects resolve before the op. For example
- * BlendOp == Add && Flags == ConstantSourceAlpha |
- * ConstantDestAlpha results in:
- *
- * C = (Ca * Param0) + (Cb * Param1)
- */
-
-#define SVGA_BLENDOP_CLEAR 0
-#define SVGA_BLENDOP_SRC 1
-#define SVGA_BLENDOP_DST 2
-#define SVGA_BLENDOP_OVER 3
-#define SVGA_BLENDOP_OVER_REVERSE 4
-#define SVGA_BLENDOP_IN 5
-#define SVGA_BLENDOP_IN_REVERSE 6
-#define SVGA_BLENDOP_OUT 7
-#define SVGA_BLENDOP_OUT_REVERSE 8
-#define SVGA_BLENDOP_ATOP 9
-#define SVGA_BLENDOP_ATOP_REVERSE 10
-#define SVGA_BLENDOP_XOR 11
-#define SVGA_BLENDOP_ADD 12
-#define SVGA_BLENDOP_SATURATE 13
-
-#define SVGA_NUM_BLENDOPS 14
-#define SVGA_IS_VALID_BLENDOP(op) (op >= 0 && op < SVGA_NUM_BLENDOPS)
-
-#define SVGA_BLENDFLAG_CONSTANT_SOURCE_ALPHA 0x01
-#define SVGA_BLENDFLAG_CONSTANT_DEST_ALPHA 0x02
-#define SVGA_NUM_BLENDFLAGS 2
-#define SVGA_BLENDFLAG_ALL (MASK(SVGA_NUM_BLENDFLAGS))
-#define SVGA_IS_VALID_BLENDFLAG(flag) ((flag & ~SVGA_BLENDFLAG_ALL) == 0)
+ * SVGAColorBGRX --
+ *
+ * A 24-bit color format (BGRX), which does not depend on the
+ * format of the legacy guest framebuffer (GFB) or the current
+ * GMRFB state.
+ */
+
+typedef
+struct SVGAColorBGRX {
+ union {
+ struct {
+ uint32 b : 8;
+ uint32 g : 8;
+ uint32 r : 8;
+ uint32 x : 8; /* Unused */
+ };
+
+ uint32 value;
+ };
+} SVGAColorBGRX;
+
+
+/*
+ * SVGASignedRect --
+ * SVGASignedPoint --
+ *
+ * Signed rectangle and point primitives. These are used by the new
+ * 2D primitives for drawing to Screen Objects, which can occupy a
+ * signed virtual coordinate space.
+ *
+ * SVGASignedRect specifies a half-open interval: the (left, top)
+ * pixel is part of the rectangle, but the (right, bottom) pixel is
+ * not.
+ */
+
+typedef
+struct SVGASignedRect {
+ int32 left;
+ int32 top;
+ int32 right;
+ int32 bottom;
+} SVGASignedRect;
+
+typedef
+struct SVGASignedPoint {
+ int32 x;
+ int32 y;
+} SVGASignedPoint;
+
+
+/*
+ * Capabilities
+ *
+ * Note the holes in the bitfield. Missing bits have been deprecated,
+ * and must not be reused. Those capabilities will never be reported
+ * by new versions of the SVGA device.
+ *
+ * SVGA_CAP_GMR2 --
+ * Provides asynchronous commands to define and remap guest memory
+ * regions. Adds device registers SVGA_REG_GMRS_MAX_PAGES and
+ * SVGA_REG_MEMORY_SIZE.
+ *
+ * SVGA_CAP_SCREEN_OBJECT_2 --
+ * Allow screen object support, and require backing stores from the
+ * guest for each screen object.
+ */
+
+#define SVGA_CAP_NONE 0x00000000
+#define SVGA_CAP_RECT_COPY 0x00000002
+#define SVGA_CAP_CURSOR 0x00000020
+#define SVGA_CAP_CURSOR_BYPASS 0x00000040 /* Legacy (Use Cursor Bypass 3 instead) */
+#define SVGA_CAP_CURSOR_BYPASS_2 0x00000080 /* Legacy (Use Cursor Bypass 3 instead) */
+#define SVGA_CAP_8BIT_EMULATION 0x00000100
+#define SVGA_CAP_ALPHA_CURSOR 0x00000200
+#define SVGA_CAP_3D 0x00004000
+#define SVGA_CAP_EXTENDED_FIFO 0x00008000
+#define SVGA_CAP_MULTIMON 0x00010000 /* Legacy multi-monitor support */
+#define SVGA_CAP_PITCHLOCK 0x00020000
+#define SVGA_CAP_IRQMASK 0x00040000
+#define SVGA_CAP_DISPLAY_TOPOLOGY 0x00080000 /* Legacy multi-monitor support */
+#define SVGA_CAP_GMR 0x00100000
+#define SVGA_CAP_TRACES 0x00200000
+#define SVGA_CAP_GMR2 0x00400000
+#define SVGA_CAP_SCREEN_OBJECT_2 0x00800000
/*
@@ -332,19 +498,47 @@ enum {
* These in block 3a, the VMX currently considers mandatory for the
* extended FIFO.
*/
-
+
/* Valid if exists (i.e. if extended FIFO enabled): */
SVGA_FIFO_3D_HWVERSION, /* See SVGA3dHardwareVersion in svga3d_reg.h */
/* Valid with SVGA_FIFO_CAP_PITCHLOCK: */
SVGA_FIFO_PITCHLOCK,
+
/* Valid with SVGA_FIFO_CAP_CURSOR_BYPASS_3: */
SVGA_FIFO_CURSOR_ON, /* Cursor bypass 3 show/hide register */
SVGA_FIFO_CURSOR_X, /* Cursor bypass 3 x register */
SVGA_FIFO_CURSOR_Y, /* Cursor bypass 3 y register */
SVGA_FIFO_CURSOR_COUNT, /* Incremented when any of the other 3 change */
SVGA_FIFO_CURSOR_LAST_UPDATED,/* Last time the host updated the cursor */
+
/* Valid with SVGA_FIFO_CAP_RESERVE: */
SVGA_FIFO_RESERVED, /* Bytes past NEXT_CMD with real contents */
+
+ /*
+ * Valid with SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2:
+ *
+ * By default this is SVGA_ID_INVALID, to indicate that the cursor
+ * coordinates are specified relative to the virtual root. If this
+ * is set to a specific screen ID, cursor position is reinterpreted
+ * as a signed offset relative to that screen's origin.
+ */
+ SVGA_FIFO_CURSOR_SCREEN_ID,
+
+ /*
+ * Valid with SVGA_FIFO_CAP_DEAD
+ *
+ * An arbitrary value written by the host, drivers should not use it.
+ */
+ SVGA_FIFO_DEAD,
+
+ /*
+ * Valid with SVGA_FIFO_CAP_3D_HWVERSION_REVISED:
+ *
+ * Contains 3D HWVERSION (see SVGA3dHardwareVersion in svga3d_reg.h)
+ * on platforms that can enforce graphics resource limits.
+ */
+ SVGA_FIFO_3D_HWVERSION_REVISED,
+
/*
* XXX: The gap here, up until SVGA_FIFO_3D_CAPS, can be used for new
* registers, but this must be done carefully and with judicious use of
@@ -361,6 +555,7 @@ enum {
* before 3D_CAPS, needs to reason about something other than
* SVGA_FIFO_MIN.
*/
+
/*
* 3D caps block space; valid with 3D hardware version >=
* SVGA3D_HWVERSION_WS6_B1.
@@ -533,6 +728,87 @@ enum {
* Pitch Lock -- Pitch lock register is supported
* Video -- SVGA Video overlay units are supported
* Escape -- Escape command is supported
+ *
+ * XXX: Add longer descriptions for each capability, including a list
+ * of the new features that each capability provides.
+ *
+ * SVGA_FIFO_CAP_SCREEN_OBJECT --
+ *
+ * Provides dynamic multi-screen rendering, for improved Unity and
+ * multi-monitor modes. With Screen Object, the guest can
+ * dynamically create and destroy 'screens', which can represent
+ * Unity windows or virtual monitors. Screen Object also provides
+ * strong guarantees that DMA operations happen only when
+ * guest-initiated. Screen Object deprecates the BAR1 guest
+ * framebuffer (GFB) and all commands that work only with the GFB.
+ *
+ * New registers:
+ * FIFO_CURSOR_SCREEN_ID, VIDEO_DATA_GMRID, VIDEO_DST_SCREEN_ID
+ *
+ * New 2D commands:
+ * DEFINE_SCREEN, DESTROY_SCREEN, DEFINE_GMRFB, BLIT_GMRFB_TO_SCREEN,
+ * BLIT_SCREEN_TO_GMRFB, ANNOTATION_FILL, ANNOTATION_COPY
+ *
+ * New 3D commands:
+ * BLIT_SURFACE_TO_SCREEN
+ *
+ * New guarantees:
+ *
+ * - The host will not read or write guest memory, including the GFB,
+ * except when explicitly initiated by a DMA command.
+ *
+ * - All DMA, including legacy DMA like UPDATE and PRESENT_READBACK,
+ * is guaranteed to complete before any subsequent FENCEs.
+ *
+ * - All legacy commands which affect a Screen (UPDATE, PRESENT,
+ * PRESENT_READBACK) as well as new Screen blit commands will
+ * all behave consistently as blits, and memory will be read
+ * or written in FIFO order.
+ *
+ * For example, if you PRESENT from one SVGA3D surface to multiple
+ * places on the screen, the data copied will always be from the
+ * SVGA3D surface at the time the PRESENT was issued in the FIFO.
+ * This was not necessarily true on devices without Screen Object.
+ *
+ * This means that on devices that support Screen Object, the
+ * PRESENT_READBACK command should not be necessary unless you
+ * actually want to read back the results of 3D rendering into
+ * system memory. (And for that, the BLIT_SCREEN_TO_GMRFB
+ * command provides a strict superset of functionality.)
+ *
+ * - When a screen is resized, either using Screen Object commands or
+ * legacy multimon registers, its contents are preserved.
+ *
+ * SVGA_FIFO_CAP_GMR2 --
+ *
+ * Provides new commands to define and remap guest memory regions (GMR).
+ *
+ * New 2D commands:
+ * DEFINE_GMR2, REMAP_GMR2.
+ *
+ * SVGA_FIFO_CAP_3D_HWVERSION_REVISED --
+ *
+ * Indicates new register SVGA_FIFO_3D_HWVERSION_REVISED exists.
+ * This register may replace SVGA_FIFO_3D_HWVERSION on platforms
+ * that enforce graphics resource limits. This allows the platform
+ * to clear SVGA_FIFO_3D_HWVERSION and disable 3D in legacy guest
+ * drivers that do not limit their resources.
+ *
+ * Note this is an alias to SVGA_FIFO_CAP_GMR2 because these indicators
+ * are codependent (and thus we use a single capability bit).
+ *
+ * SVGA_FIFO_CAP_SCREEN_OBJECT_2 --
+ *
+ * Modifies the DEFINE_SCREEN command to include a guest provided
+ * backing store in GMR memory and the bytesPerLine for the backing
+ * store. This capability requires the use of a backing store when
+ * creating screen objects. However if SVGA_FIFO_CAP_SCREEN_OBJECT
+ * is present then backing stores are optional.
+ *
+ * SVGA_FIFO_CAP_DEAD --
+ *
+ * Drivers should not use this cap bit. This cap bit can not be
+ * reused since some hosts already expose it.
*/
#define SVGA_FIFO_CAP_NONE 0
@@ -543,6 +819,11 @@ enum {
#define SVGA_FIFO_CAP_CURSOR_BYPASS_3 (1<<4)
#define SVGA_FIFO_CAP_ESCAPE (1<<5)
#define SVGA_FIFO_CAP_RESERVE (1<<6)
+#define SVGA_FIFO_CAP_SCREEN_OBJECT (1<<7)
+#define SVGA_FIFO_CAP_GMR2 (1<<8)
+#define SVGA_FIFO_CAP_3D_HWVERSION_REVISED SVGA_FIFO_CAP_GMR2
+#define SVGA_FIFO_CAP_SCREEN_OBJECT_2 (1<<9)
+#define SVGA_FIFO_CAP_DEAD (1<<10)
/*
@@ -586,20 +867,22 @@ enum {
SVGA_VIDEO_DATA_OFFSET,
SVGA_VIDEO_FORMAT,
SVGA_VIDEO_COLORKEY,
- SVGA_VIDEO_SIZE,
+ SVGA_VIDEO_SIZE, /* Deprecated */
SVGA_VIDEO_WIDTH,
SVGA_VIDEO_HEIGHT,
SVGA_VIDEO_SRC_X,
SVGA_VIDEO_SRC_Y,
SVGA_VIDEO_SRC_WIDTH,
SVGA_VIDEO_SRC_HEIGHT,
- SVGA_VIDEO_DST_X,
- SVGA_VIDEO_DST_Y,
+ SVGA_VIDEO_DST_X, /* Signed int32 */
+ SVGA_VIDEO_DST_Y, /* Signed int32 */
SVGA_VIDEO_DST_WIDTH,
SVGA_VIDEO_DST_HEIGHT,
SVGA_VIDEO_PITCH_1,
SVGA_VIDEO_PITCH_2,
SVGA_VIDEO_PITCH_3,
+ SVGA_VIDEO_DATA_GMRID, /* Optional, defaults to SVGA_GMR_FRAMEBUFFER */
+ SVGA_VIDEO_DST_SCREEN_ID, /* Optional, defaults to virtual coords (SVGA_ID_INVALID) */
SVGA_VIDEO_NUM_REGS
};
@@ -625,242 +908,658 @@ typedef struct SVGAOverlayUnit {
uint32 srcY;
uint32 srcWidth;
uint32 srcHeight;
- uint32 dstX;
- uint32 dstY;
+ int32 dstX;
+ int32 dstY;
uint32 dstWidth;
uint32 dstHeight;
uint32 pitches[3];
+ uint32 dataGMRId;
+ uint32 dstScreenId;
} SVGAOverlayUnit;
/*
- * Drawing object ID's, in the range 0 to SVGA_MAX_ID
+ * SVGAScreenObject --
+ *
+ * This is a new way to represent a guest's multi-monitor screen or
+ * Unity window. Screen objects are only supported if the
+ * SVGA_FIFO_CAP_SCREEN_OBJECT capability bit is set.
+ *
+ * If Screen Objects are supported, they can be used to fully
+ * replace the functionality provided by the framebuffer registers
+ * (SVGA_REG_WIDTH, HEIGHT, etc.) and by SVGA_CAP_DISPLAY_TOPOLOGY.
+ *
+ * The screen object is a struct with guaranteed binary
+ * compatibility. New flags can be added, and the struct may grow,
+ * but existing fields must retain their meaning.
+ *
+ * Added with SVGA_FIFO_CAP_SCREEN_OBJECT_2 are required fields of
+ * a SVGAGuestPtr that is used to back the screen contents. This
+ * memory must come from the GFB. The guest is not allowed to
+ * access the memory and doing so will have undefined results. The
+ * backing store is required to be page aligned and the size is
+ * padded to the next page boundry. The number of pages is:
+ * (bytesPerLine * size.width * 4 + PAGE_SIZE - 1) / PAGE_SIZE
+ *
+ * The pitch in the backingStore is required to be at least large
+ * enough to hold a 32bbp scanline. It is recommended that the
+ * driver pad bytesPerLine for a potential performance win.
+ *
+ * The cloneCount field is treated as a hint from the guest that
+ * the user wants this display to be cloned, countCount times. A
+ * value of zero means no cloning should happen.
*/
-#define SVGA_MAX_ID 499
+#define SVGA_SCREEN_MUST_BE_SET (1 << 0) /* Must be set or results undefined */
+#define SVGA_SCREEN_HAS_ROOT SVGA_SCREEN_MUST_BE_SET /* Deprecated */
+#define SVGA_SCREEN_IS_PRIMARY (1 << 1) /* Guest considers this screen to be 'primary' */
+#define SVGA_SCREEN_FULLSCREEN_HINT (1 << 2) /* Guest is running a fullscreen app here */
/*
- * Macros to compute variable length items (sizes in 32-bit words, except
- * for SVGA_GLYPH_SCANLINE_SIZE, which is in bytes).
+ * Added with SVGA_FIFO_CAP_SCREEN_OBJECT_2. When the screen is
+ * deactivated the base layer is defined to lose all contents and
+ * become black. When a screen is deactivated the backing store is
+ * optional. When set backingPtr and bytesPerLine will be ignored.
*/
+#define SVGA_SCREEN_DEACTIVATE (1 << 3)
+
+/*
+ * Added with SVGA_FIFO_CAP_SCREEN_OBJECT_2. When this flag is set
+ * the screen contents will be outputted as all black to the user
+ * though the base layer contents is preserved. The screen base layer
+ * can still be read and written to like normal though the no visible
+ * effect will be seen by the user. When the flag is changed the
+ * screen will be blanked or redrawn to the current contents as needed
+ * without any extra commands from the driver. This flag only has an
+ * effect when the screen is not deactivated.
+ */
+#define SVGA_SCREEN_BLANKING (1 << 4)
+
+typedef
+struct SVGAScreenObject {
+ uint32 structSize; /* sizeof(SVGAScreenObject) */
+ uint32 id;
+ uint32 flags;
+ struct {
+ uint32 width;
+ uint32 height;
+ } size;
+ struct {
+ int32 x;
+ int32 y;
+ } root;
+
+ /*
+ * Added and required by SVGA_FIFO_CAP_SCREEN_OBJECT_2, optional
+ * with SVGA_FIFO_CAP_SCREEN_OBJECT.
+ */
+ SVGAGuestImage backingStore;
+ uint32 cloneCount;
+} SVGAScreenObject;
-#define SVGA_BITMAP_SIZE(w,h) ((((w)+31) >> 5) * (h))
-#define SVGA_BITMAP_SCANLINE_SIZE(w) (( (w)+31 ) >> 5)
-#define SVGA_PIXMAP_SIZE(w,h,bpp) ((( ((w)*(bpp))+31 ) >> 5) * (h))
-#define SVGA_PIXMAP_SCANLINE_SIZE(w,bpp) (( ((w)*(bpp))+31 ) >> 5)
-#define SVGA_GLYPH_SIZE(w,h) ((((((w) + 7) >> 3) * (h)) + 3) >> 2)
-#define SVGA_GLYPH_SCANLINE_SIZE(w) (((w) + 7) >> 3)
-#define SVGA_ESCAPE_SIZE(s) (((s) + 3) >> 2)
/*
- * Increment from one scanline to the next of a bitmap or pixmap
+ * Commands in the command FIFO:
+ *
+ * Command IDs defined below are used for the traditional 2D FIFO
+ * communication (not all commands are available for all versions of the
+ * SVGA FIFO protocol).
+ *
+ * Note the holes in the command ID numbers: These commands have been
+ * deprecated, and the old IDs must not be reused.
+ *
+ * Command IDs from 1000 to 1999 are reserved for use by the SVGA3D
+ * protocol.
+ *
+ * Each command's parameters are described by the comments and
+ * structs below.
*/
-#define SVGA_BITMAP_INCREMENT(w) ((( (w)+31 ) >> 5) * sizeof (uint32))
-#define SVGA_PIXMAP_INCREMENT(w,bpp) ((( ((w)*(bpp))+31 ) >> 5) * sizeof (uint32))
+
+typedef enum {
+ SVGA_CMD_INVALID_CMD = 0,
+ SVGA_CMD_UPDATE = 1,
+ SVGA_CMD_RECT_COPY = 3,
+ SVGA_CMD_DEFINE_CURSOR = 19,
+ SVGA_CMD_DEFINE_ALPHA_CURSOR = 22,
+ SVGA_CMD_UPDATE_VERBOSE = 25,
+ SVGA_CMD_FRONT_ROP_FILL = 29,
+ SVGA_CMD_FENCE = 30,
+ SVGA_CMD_ESCAPE = 33,
+ SVGA_CMD_DEFINE_SCREEN = 34,
+ SVGA_CMD_DESTROY_SCREEN = 35,
+ SVGA_CMD_DEFINE_GMRFB = 36,
+ SVGA_CMD_BLIT_GMRFB_TO_SCREEN = 37,
+ SVGA_CMD_BLIT_SCREEN_TO_GMRFB = 38,
+ SVGA_CMD_ANNOTATION_FILL = 39,
+ SVGA_CMD_ANNOTATION_COPY = 40,
+ SVGA_CMD_DEFINE_GMR2 = 41,
+ SVGA_CMD_REMAP_GMR2 = 42,
+ SVGA_CMD_MAX
+} SVGAFifoCmdId;
+
+#define SVGA_CMD_MAX_ARGS 64
+
/*
- * Transparent color for DRAW_GLYPH_CLIPPED
+ * SVGA_CMD_UPDATE --
+ *
+ * This is a DMA transfer which copies from the Guest Framebuffer
+ * (GFB) at BAR1 + SVGA_REG_FB_OFFSET to any screens which
+ * intersect with the provided virtual rectangle.
+ *
+ * This command does not support using arbitrary guest memory as a
+ * data source- it only works with the pre-defined GFB memory.
+ * This command also does not support signed virtual coordinates.
+ * If you have defined screens (using SVGA_CMD_DEFINE_SCREEN) with
+ * negative root x/y coordinates, the negative portion of those
+ * screens will not be reachable by this command.
+ *
+ * This command is not necessary when using framebuffer
+ * traces. Traces are automatically enabled if the SVGA FIFO is
+ * disabled, and you may explicitly enable/disable traces using
+ * SVGA_REG_TRACES. With traces enabled, any write to the GFB will
+ * automatically act as if a subsequent SVGA_CMD_UPDATE was issued.
+ *
+ * Traces and SVGA_CMD_UPDATE are the only supported ways to render
+ * pseudocolor screen updates. The newer Screen Object commands
+ * only support true color formats.
+ *
+ * Availability:
+ * Always available.
*/
-#define SVGA_COLOR_TRANSPARENT (~0)
+
+typedef
+struct SVGAFifoCmdUpdate {
+ uint32 x;
+ uint32 y;
+ uint32 width;
+ uint32 height;
+} SVGAFifoCmdUpdate;
+
/*
- * Commands in the command FIFO
+ * SVGA_CMD_RECT_COPY --
+ *
+ * Perform a rectangular DMA transfer from one area of the GFB to
+ * another, and copy the result to any screens which intersect it.
+ *
+ * Availability:
+ * SVGA_CAP_RECT_COPY
*/
-#define SVGA_CMD_INVALID_CMD 0
- /* FIFO layout:
- <nothing> (well, undefined) */
+typedef
+struct SVGAFifoCmdRectCopy {
+ uint32 srcX;
+ uint32 srcY;
+ uint32 destX;
+ uint32 destY;
+ uint32 width;
+ uint32 height;
+} SVGAFifoCmdRectCopy;
-#define SVGA_CMD_UPDATE 1
- /* FIFO layout:
- X, Y, Width, Height */
-#define SVGA_CMD_RECT_FILL 2
- /* FIFO layout:
- Color, X, Y, Width, Height */
+/*
+ * SVGA_CMD_DEFINE_CURSOR --
+ *
+ * Provide a new cursor image, as an AND/XOR mask.
+ *
+ * The recommended way to position the cursor overlay is by using
+ * the SVGA_FIFO_CURSOR_* registers, supported by the
+ * SVGA_FIFO_CAP_CURSOR_BYPASS_3 capability.
+ *
+ * Availability:
+ * SVGA_CAP_CURSOR
+ */
-#define SVGA_CMD_RECT_COPY 3
- /* FIFO layout:
- Source X, Source Y, Dest X, Dest Y, Width, Height */
+typedef
+struct SVGAFifoCmdDefineCursor {
+ uint32 id; /* Reserved, must be zero. */
+ uint32 hotspotX;
+ uint32 hotspotY;
+ uint32 width;
+ uint32 height;
+ uint32 andMaskDepth; /* Value must be 1 or equal to BITS_PER_PIXEL */
+ uint32 xorMaskDepth; /* Value must be 1 or equal to BITS_PER_PIXEL */
+ /*
+ * Followed by scanline data for AND mask, then XOR mask.
+ * Each scanline is padded to a 32-bit boundary.
+ */
+} SVGAFifoCmdDefineCursor;
-#define SVGA_CMD_DEFINE_BITMAP 4
- /* FIFO layout:
- Pixmap ID, Width, Height, <scanlines> */
-#define SVGA_CMD_DEFINE_BITMAP_SCANLINE 5
- /* FIFO layout:
- Pixmap ID, Width, Height, Line #, scanline */
+/*
+ * SVGA_CMD_DEFINE_ALPHA_CURSOR --
+ *
+ * Provide a new cursor image, in 32-bit BGRA format.
+ *
+ * The recommended way to position the cursor overlay is by using
+ * the SVGA_FIFO_CURSOR_* registers, supported by the
+ * SVGA_FIFO_CAP_CURSOR_BYPASS_3 capability.
+ *
+ * Availability:
+ * SVGA_CAP_ALPHA_CURSOR
+ */
-#define SVGA_CMD_DEFINE_PIXMAP 6
- /* FIFO layout:
- Pixmap ID, Width, Height, Depth, <scanlines> */
+typedef
+struct SVGAFifoCmdDefineAlphaCursor {
+ uint32 id; /* Reserved, must be zero. */
+ uint32 hotspotX;
+ uint32 hotspotY;
+ uint32 width;
+ uint32 height;
+ /* Followed by scanline data */
+} SVGAFifoCmdDefineAlphaCursor;
-#define SVGA_CMD_DEFINE_PIXMAP_SCANLINE 7
- /* FIFO layout:
- Pixmap ID, Width, Height, Depth, Line #, scanline */
-#define SVGA_CMD_RECT_BITMAP_FILL 8
- /* FIFO layout:
- Bitmap ID, X, Y, Width, Height, Foreground, Background */
+/*
+ * SVGA_CMD_UPDATE_VERBOSE --
+ *
+ * Just like SVGA_CMD_UPDATE, but also provide a per-rectangle
+ * 'reason' value, an opaque cookie which is used by internal
+ * debugging tools. Third party drivers should not use this
+ * command.
+ *
+ * Availability:
+ * SVGA_CAP_EXTENDED_FIFO
+ */
-#define SVGA_CMD_RECT_PIXMAP_FILL 9
- /* FIFO layout:
- Pixmap ID, X, Y, Width, Height */
+typedef
+struct SVGAFifoCmdUpdateVerbose {
+ uint32 x;
+ uint32 y;
+ uint32 width;
+ uint32 height;
+ uint32 reason;
+} SVGAFifoCmdUpdateVerbose;
-#define SVGA_CMD_RECT_BITMAP_COPY 10
- /* FIFO layout:
- Bitmap ID, Source X, Source Y, Dest X, Dest Y,
- Width, Height, Foreground, Background */
-#define SVGA_CMD_RECT_PIXMAP_COPY 11
- /* FIFO layout:
- Pixmap ID, Source X, Source Y, Dest X, Dest Y, Width, Height */
+/*
+ * SVGA_CMD_FRONT_ROP_FILL --
+ *
+ * This is a hint which tells the SVGA device that the driver has
+ * just filled a rectangular region of the GFB with a solid
+ * color. Instead of reading these pixels from the GFB, the device
+ * can assume that they all equal 'color'. This is primarily used
+ * for remote desktop protocols.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_ACCELFRONT
+ */
+
+#define SVGA_ROP_COPY 0x03
-#define SVGA_CMD_FREE_OBJECT 12
- /* FIFO layout:
- Object (pixmap, bitmap, ...) ID */
+#define SVGA_INVALID_DISPLAY_ID ((uint32)-1)
-#define SVGA_CMD_RECT_ROP_FILL 13
- /* FIFO layout:
- Color, X, Y, Width, Height, ROP */
+typedef
+struct SVGAFifoCmdFrontRopFill {
+ uint32 color; /* In the same format as the GFB */
+ uint32 x;
+ uint32 y;
+ uint32 width;
+ uint32 height;
+ uint32 rop; /* Must be SVGA_ROP_COPY */
+} SVGAFifoCmdFrontRopFill;
-#define SVGA_CMD_RECT_ROP_COPY 14
- /* FIFO layout:
- Source X, Source Y, Dest X, Dest Y, Width, Height, ROP */
-#define SVGA_CMD_RECT_ROP_BITMAP_FILL 15
- /* FIFO layout:
- ID, X, Y, Width, Height, Foreground, Background, ROP */
+/*
+ * 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.
+ */
-#define SVGA_CMD_RECT_ROP_PIXMAP_FILL 16
- /* FIFO layout:
- ID, X, Y, Width, Height, ROP */
+typedef
+struct {
+ uint32 fence;
+} SVGAFifoCmdFence;
-#define SVGA_CMD_RECT_ROP_BITMAP_COPY 17
- /* FIFO layout:
- ID, Source X, Source Y,
- Dest X, Dest Y, Width, Height, Foreground, Background, ROP */
-#define SVGA_CMD_RECT_ROP_PIXMAP_COPY 18
- /* FIFO layout:
- ID, Source X, Source Y, Dest X, Dest Y, Width, Height, ROP */
+/*
+ * SVGA_CMD_ESCAPE --
+ *
+ * Send an extended or vendor-specific variable length command.
+ * This is used for video overlay, third party plugins, and
+ * internal debugging tools. See svga_escape.h
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_ESCAPE
+ */
-#define SVGA_CMD_DEFINE_CURSOR 19
- /* FIFO layout:
- ID, Hotspot X, Hotspot Y, Width, Height,
- Depth for AND mask, Depth for XOR mask,
- <scanlines for AND mask>, <scanlines for XOR mask> */
+typedef
+struct SVGAFifoCmdEscape {
+ uint32 nsid;
+ uint32 size;
+ /* followed by 'size' bytes of data */
+} SVGAFifoCmdEscape;
-#define SVGA_CMD_DISPLAY_CURSOR 20
- /* FIFO layout:
- ID, On/Off (1 or 0) */
-#define SVGA_CMD_MOVE_CURSOR 21
- /* FIFO layout:
- X, Y */
+/*
+ * SVGA_CMD_DEFINE_SCREEN --
+ *
+ * Define or redefine an SVGAScreenObject. See the description of
+ * SVGAScreenObject above. The video driver is responsible for
+ * generating new screen IDs. They should be small positive
+ * integers. The virtual device will have an implementation
+ * specific upper limit on the number of screen IDs
+ * supported. Drivers are responsible for recycling IDs. The first
+ * valid ID is zero.
+ *
+ * - Interaction with other registers:
+ *
+ * For backwards compatibility, when the GFB mode registers (WIDTH,
+ * HEIGHT, PITCHLOCK, BITS_PER_PIXEL) are modified, the SVGA device
+ * deletes all screens other than screen #0, and redefines screen
+ * #0 according to the specified mode. Drivers that use
+ * SVGA_CMD_DEFINE_SCREEN should destroy or redefine screen #0.
+ *
+ * If you use screen objects, do not use the legacy multi-mon
+ * registers (SVGA_REG_NUM_GUEST_DISPLAYS, SVGA_REG_DISPLAY_*).
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
-#define SVGA_CMD_DEFINE_ALPHA_CURSOR 22
- /* FIFO layout:
- ID, Hotspot X, Hotspot Y, Width, Height,
- <scanlines> */
+typedef
+struct {
+ SVGAScreenObject screen; /* Variable-length according to version */
+} SVGAFifoCmdDefineScreen;
-#define SVGA_CMD_DRAW_GLYPH 23
- /* FIFO layout:
- X, Y, W, H, FGCOLOR, <stencil buffer> */
-
-#define SVGA_CMD_DRAW_GLYPH_CLIPPED 24
- /* FIFO layout:
- X, Y, W, H, FGCOLOR, BGCOLOR, <cliprect>, <stencil buffer>
- Transparent color expands are done by setting BGCOLOR to ~0 */
-
-#define SVGA_CMD_UPDATE_VERBOSE 25
- /* FIFO layout:
- X, Y, Width, Height, Reason */
-
-#define SVGA_CMD_SURFACE_FILL 26
- /* FIFO layout:
- color, dstSurfaceOffset, x, y, w, h, rop */
-
-#define SVGA_CMD_SURFACE_COPY 27
- /* FIFO layout:
- srcSurfaceOffset, dstSurfaceOffset, srcX, srcY,
- destX, destY, w, h, rop */
-
-#define SVGA_CMD_SURFACE_ALPHA_BLEND 28
- /* FIFO layout:
- srcSurfaceOffset, dstSurfaceOffset, srcX, srcY,
- destX, destY, w, h, op (SVGA_BLENDOP*), flags (SVGA_BLENDFLAGS*),
- param1, param2 */
-
-#define SVGA_CMD_FRONT_ROP_FILL 29
- /* FIFO layout:
- Color, X, Y, Width, Height, ROP */
-
-#define SVGA_CMD_FENCE 30
- /* FIFO layout:
- Fence value */
-
-#define SVGA_CMD_VIDEO_PLAY_OBSOLETE 31
- /* Obsolete; do not use. */
-
-#define SVGA_CMD_VIDEO_END_OBSOLETE 32
- /* Obsolete; do not use. */
-
-#define SVGA_CMD_ESCAPE 33
- /* FIFO layout:
- Namespace ID, size(bytes), data */
-
-#define SVGA_CMD_MAX 34
-
-#define SVGA_CMD_MAX_ARGS 64
-
-/*
- * Location and size of SVGA frame buffer and the FIFO.
- */
-#define SVGA_VRAM_MIN_SIZE (4 * 640 * 480) /* bytes */
-#define SVGA_VRAM_MAX_SIZE (128 * 1024 * 1024)
-
-#define SVGA_VRAM_SIZE_WS (16 * 1024 * 1024) /* 16 MB */
-#define SVGA_MEM_SIZE_WS (2 * 1024 * 1024) /* 2 MB */
-#define SVGA_VRAM_SIZE_SERVER (4 * 1024 * 1024) /* 4 MB */
-#define SVGA_MEM_SIZE_SERVER (256 * 1024) /* 256 KB */
-
-#if /* defined(VMX86_WGS) || */ defined(VMX86_SERVER)
-#define SVGA_VRAM_SIZE SVGA_VRAM_SIZE_SERVER
-#define SVGA_MEM_SIZE SVGA_MEM_SIZE_SERVER
-#else
-#define SVGA_VRAM_SIZE SVGA_VRAM_SIZE_WS
-#define SVGA_MEM_SIZE SVGA_MEM_SIZE_WS
-#endif
/*
- * SVGA_FB_START is the default starting address of the SVGA frame
- * buffer in the guest's physical address space.
- * SVGA_FB_START_BIGMEM is the starting address of the SVGA frame
- * buffer for VMs that have a large amount of physical memory.
- *
- * The address of SVGA_FB_START is set to 2GB - (SVGA_FB_MAX_SIZE + SVGA_MEM_SIZE),
- * thus the SVGA frame buffer sits at [SVGA_FB_START .. 2GB-1] in the
- * physical address space. Our older SVGA drivers for NT treat the
- * address of the frame buffer as a signed integer. For backwards
- * compatibility, we keep the default location of the frame buffer
- * at under 2GB in the address space. This restricts VMs to have "only"
- * up to ~2031MB (i.e., up to SVGA_FB_START) of physical memory.
- *
- * For VMs that want more memory than the ~2031MB, we place the SVGA
- * frame buffer at SVGA_FB_START_BIGMEM. This allows VMs to have up
- * to 3584MB, at least as far as the SVGA frame buffer is concerned
- * (note that there may be other issues that limit the VM memory
- * size). PCI devices use high memory addresses, so we have to put
- * SVGA_FB_START_BIGMEM low enough so that it doesn't overlap with any
- * of these devices. Placing SVGA_FB_START_BIGMEM at 0xE0000000
- * should leave plenty of room for the PCI devices.
- *
- * NOTE: All of that is only true for the 0710 chipset. As of the 0405
- * chipset, the framebuffer start is determined solely based on the value
- * the guest BIOS or OS programs into the PCI base address registers.
- */
-#define SVGA_FB_LEGACY_START 0x7EFC0000
-#define SVGA_FB_LEGACY_START_BIGMEM 0xE0000000
+ * SVGA_CMD_DESTROY_SCREEN --
+ *
+ * Destroy an SVGAScreenObject. Its ID is immediately available for
+ * re-use.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ uint32 screenId;
+} SVGAFifoCmdDestroyScreen;
+
+
+/*
+ * SVGA_CMD_DEFINE_GMRFB --
+ *
+ * This command sets a piece of SVGA device state called the
+ * Guest Memory Region Framebuffer, or GMRFB. The GMRFB is a
+ * piece of light-weight state which identifies the location and
+ * format of an image in guest memory or in BAR1. The GMRFB has
+ * an arbitrary size, and it doesn't need to match the geometry
+ * of the GFB or any screen object.
+ *
+ * The GMRFB can be redefined as often as you like. You could
+ * always use the same GMRFB, you could redefine it before
+ * rendering from a different guest screen, or you could even
+ * redefine it before every blit.
+ *
+ * There are multiple ways to use this command. The simplest way is
+ * to use it to move the framebuffer either to elsewhere in the GFB
+ * (BAR1) memory region, or to a user-defined GMR. This lets a
+ * driver use a framebuffer allocated entirely out of normal system
+ * memory, which we encourage.
+ *
+ * Another way to use this command is to set up a ring buffer of
+ * updates in GFB memory. If a driver wants to ensure that no
+ * frames are skipped by the SVGA device, it is important that the
+ * driver not modify the source data for a blit until the device is
+ * done processing the command. One efficient way to accomplish
+ * this is to use a ring of small DMA buffers. Each buffer is used
+ * for one blit, then we move on to the next buffer in the
+ * ring. The FENCE mechanism is used to protect each buffer from
+ * re-use until the device is finished with that buffer's
+ * corresponding blit.
+ *
+ * This command does not affect the meaning of SVGA_CMD_UPDATE.
+ * UPDATEs always occur from the legacy GFB memory area. This
+ * command has no support for pseudocolor GMRFBs. Currently only
+ * true-color 15, 16, and 24-bit depths are supported. Future
+ * devices may expose capabilities for additional framebuffer
+ * formats.
+ *
+ * The default GMRFB value is undefined. Drivers must always send
+ * this command at least once before performing any blit from the
+ * GMRFB.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGAGuestPtr ptr;
+ uint32 bytesPerLine;
+ SVGAGMRImageFormat format;
+} SVGAFifoCmdDefineGMRFB;
+
+
+/*
+ * SVGA_CMD_BLIT_GMRFB_TO_SCREEN --
+ *
+ * This is a guest-to-host blit. It performs a DMA operation to
+ * copy a rectangular region of pixels from the current GMRFB to
+ * one or more Screen Objects.
+ *
+ * The destination coordinate may be specified relative to a
+ * screen's origin (if a screen ID is specified) or relative to the
+ * virtual coordinate system's origin (if the screen ID is
+ * SVGA_ID_INVALID). The actual destination may span zero or more
+ * screens, in the case of a virtual destination rect or a rect
+ * which extends off the edge of the specified screen.
+ *
+ * This command writes to the screen's "base layer": the underlying
+ * framebuffer which exists below any cursor or video overlays. No
+ * action is necessary to explicitly hide or update any overlays
+ * which exist on top of the updated region.
+ *
+ * The SVGA device is guaranteed to finish reading from the GMRFB
+ * by the time any subsequent FENCE commands are reached.
+ *
+ * This command consumes an annotation. See the
+ * SVGA_CMD_ANNOTATION_* commands for details.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGASignedPoint srcOrigin;
+ SVGASignedRect destRect;
+ uint32 destScreenId;
+} SVGAFifoCmdBlitGMRFBToScreen;
+
+
+/*
+ * SVGA_CMD_BLIT_SCREEN_TO_GMRFB --
+ *
+ * This is a host-to-guest blit. It performs a DMA operation to
+ * copy a rectangular region of pixels from a single Screen Object
+ * back to the current GMRFB.
+ *
+ * Usage note: This command should be used rarely. It will
+ * typically be inefficient, but it is necessary for some types of
+ * synchronization between 3D (GPU) and 2D (CPU) rendering into
+ * overlapping areas of a screen.
+ *
+ * The source coordinate is specified relative to a screen's
+ * origin. The provided screen ID must be valid. If any parameters
+ * are invalid, the resulting pixel values are undefined.
+ *
+ * This command reads the screen's "base layer". Overlays like
+ * video and cursor are not included, but any data which was sent
+ * using a blit-to-screen primitive will be available, no matter
+ * whether the data's original source was the GMRFB or the 3D
+ * acceleration hardware.
+ *
+ * Note that our guest-to-host blits and host-to-guest blits aren't
+ * symmetric in their current implementation. While the parameters
+ * are identical, host-to-guest blits are a lot less featureful.
+ * They do not support clipping: If the source parameters don't
+ * fully fit within a screen, the blit fails. They must originate
+ * from exactly one screen. Virtual coordinates are not directly
+ * supported.
+ *
+ * Host-to-guest blits do support the same set of GMRFB formats
+ * offered by guest-to-host blits.
+ *
+ * The SVGA device is guaranteed to finish writing to the GMRFB by
+ * the time any subsequent FENCE commands are reached.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGASignedPoint destOrigin;
+ SVGASignedRect srcRect;
+ uint32 srcScreenId;
+} SVGAFifoCmdBlitScreenToGMRFB;
+
+
+/*
+ * SVGA_CMD_ANNOTATION_FILL --
+ *
+ * This is a blit annotation. This command stores a small piece of
+ * device state which is consumed by the next blit-to-screen
+ * command. The state is only cleared by commands which are
+ * specifically documented as consuming an annotation. Other
+ * commands (such as ESCAPEs for debugging) may intervene between
+ * the annotation and its associated blit.
+ *
+ * This annotation is a promise about the contents of the next
+ * blit: The video driver is guaranteeing that all pixels in that
+ * blit will have the same value, specified here as a color in
+ * SVGAColorBGRX format.
+ *
+ * The SVGA device can still render the blit correctly even if it
+ * ignores this annotation, but the annotation may allow it to
+ * perform the blit more efficiently, for example by ignoring the
+ * source data and performing a fill in hardware.
+ *
+ * This annotation is most important for performance when the
+ * user's display is being remoted over a network connection.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGAColorBGRX color;
+} SVGAFifoCmdAnnotationFill;
+
+
+/*
+ * SVGA_CMD_ANNOTATION_COPY --
+ *
+ * This is a blit annotation. See SVGA_CMD_ANNOTATION_FILL for more
+ * information about annotations.
+ *
+ * This annotation is a promise about the contents of the next
+ * blit: The video driver is guaranteeing that all pixels in that
+ * blit will have the same value as those which already exist at an
+ * identically-sized region on the same or a different screen.
+ *
+ * Note that the source pixels for the COPY in this annotation are
+ * sampled before applying the anqnotation's associated blit. They
+ * are allowed to overlap with the blit's destination pixels.
+ *
+ * The copy source rectangle is specified the same way as the blit
+ * destination: it can be a rectangle which spans zero or more
+ * screens, specified relative to either a screen or to the virtual
+ * coordinate system's origin. If the source rectangle includes
+ * pixels which are not from exactly one screen, the results are
+ * undefined.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGASignedPoint srcOrigin;
+ uint32 srcScreenId;
+} SVGAFifoCmdAnnotationCopy;
+
+
+/*
+ * SVGA_CMD_DEFINE_GMR2 --
+ *
+ * Define guest memory region v2. See the description of GMRs above.
+ *
+ * Availability:
+ * SVGA_CAP_GMR2
+ */
+
+typedef
+struct {
+ uint32 gmrId;
+ uint32 numPages;
+} SVGAFifoCmdDefineGMR2;
+
+
+/*
+ * SVGA_CMD_REMAP_GMR2 --
+ *
+ * Remap guest memory region v2. See the description of GMRs above.
+ *
+ * This command allows guest to modify a portion of an existing GMR by
+ * invalidating it or reassigning it to different guest physical pages.
+ * The pages are identified by physical page number (PPN). The pages
+ * are assumed to be pinned and valid for DMA operations.
+ *
+ * Description of command flags:
+ *
+ * SVGA_REMAP_GMR2_VIA_GMR: If enabled, references a PPN list in a GMR.
+ * The PPN list must not overlap with the remap region (this can be
+ * handled trivially by referencing a separate GMR). If flag is
+ * disabled, PPN list is appended to SVGARemapGMR command.
+ *
+ * SVGA_REMAP_GMR2_PPN64: If set, PPN list is in PPN64 format, otherwise
+ * it is in PPN32 format.
+ *
+ * SVGA_REMAP_GMR2_SINGLE_PPN: If set, PPN list contains a single entry.
+ * A single PPN can be used to invalidate a portion of a GMR or
+ * map it to to a single guest scratch page.
+ *
+ * Availability:
+ * SVGA_CAP_GMR2
+ */
+
+typedef enum {
+ SVGA_REMAP_GMR2_PPN32 = 0,
+ SVGA_REMAP_GMR2_VIA_GMR = (1 << 0),
+ SVGA_REMAP_GMR2_PPN64 = (1 << 1),
+ SVGA_REMAP_GMR2_SINGLE_PPN = (1 << 2),
+} SVGARemapGMR2Flags;
+
+typedef
+struct {
+ uint32 gmrId;
+ SVGARemapGMR2Flags flags;
+ uint32 offsetPages; /* offset in pages to begin remap */
+ uint32 numPages; /* number of pages to remap */
+ /*
+ * Followed by additional data depending on SVGARemapGMR2Flags.
+ *
+ * If flag SVGA_REMAP_GMR2_VIA_GMR is set, single SVGAGuestPtr follows.
+ * Otherwise an array of page descriptors in PPN32 or PPN64 format
+ * (according to flag SVGA_REMAP_GMR2_PPN64) follows. If flag
+ * SVGA_REMAP_GMR2_SINGLE_PPN is set, array contains a single entry.
+ */
+} SVGAFifoCmdRemapGMR2;
#endif
diff --git a/src/vmware.c b/src/vmware.c
index fa01dca..9160cf2 100644
--- a/src/vmware.c
+++ b/src/vmware.c
@@ -39,195 +39,17 @@ char rcsId_vmware[] =
#include "guest_os.h"
#include "vm_device_version.h"
#include "svga_modes.h"
+#include "vmware_bootstrap.h"
+#include "vmware_common.h"
#ifndef HAVE_XORG_SERVER_1_5_0
#include <xf86_ansic.h>
#include <xf86_libc.h>
#endif
-#ifdef HaveDriverFuncs
-#define VMWARE_DRIVER_FUNC HaveDriverFuncs
-#else
-#define VMWARE_DRIVER_FUNC 0
-#endif
-
-/*
- * So that the file compiles unmodified when dropped in to a < 6.9 source tree.
- */
-#ifndef _X_EXPORT
-#define _X_EXPORT
-#endif
-/*
- * So that the file compiles unmodified when dropped into an xfree source tree.
- */
-#ifndef XORG_VERSION_CURRENT
-#define XORG_VERSION_CURRENT XF86_VERSION_CURRENT
-#endif
-
-/*
- * Sanity check that xf86PciInfo.h has the correct values (which come from
- * the VMware source tree in vm_device_version.h.
- */
-#if PCI_CHIP_VMWARE0405 != PCI_DEVICE_ID_VMWARE_SVGA2
-#error "PCI_CHIP_VMWARE0405 is wrong, update it from vm_device_version.h"
-#endif
-#if PCI_CHIP_VMWARE0710 != PCI_DEVICE_ID_VMWARE_SVGA
-#error "PCI_CHIP_VMWARE0710 is wrong, update it from vm_device_version.h"
-#endif
-#if PCI_VENDOR_VMWARE != PCI_VENDOR_ID_VMWARE
-#error "PCI_VENDOR_VMWARE is wrong, update it from vm_device_version.h"
-#endif
-
-#define VMWARE_INCHTOMM 25.4
-
-/*
- * This is the only way I know to turn a #define of an integer constant into
- * a constant string.
- */
-#define VMW_INNERSTRINGIFY(s) #s
-#define VMW_STRING(str) VMW_INNERSTRINGIFY(str)
-
-#define VMWARE_NAME "vmwlegacy"
-#define VMWARE_DRIVER_NAME "vmwlegacy"
-#define VMWARE_DRIVER_VERSION \
- (PACKAGE_VERSION_MAJOR * 65536 + PACKAGE_VERSION_MINOR * 256 + PACKAGE_VERSION_PATCHLEVEL)
-#define VMWARE_DRIVER_VERSION_STRING \
- VMW_STRING(PACKAGE_VERSION_MAJOR) "." VMW_STRING(PACKAGE_VERSION_MINOR) \
- "." VMW_STRING(PACKAGE_VERSION_PATCHLEVEL)
-
-static const char VMWAREBuildStr[] = "VMware Guest X Server "
- VMWARE_DRIVER_VERSION_STRING " - build=$Name$\n";
-
-/*
- * Standard four digit version string expected by VMware Tools installer.
- * As the driver's version is only {major, minor, patchlevel},
- * The fourth digit may describe the commit number relative to the
- * last version tag as output from `git describe`
- */
-
-#ifdef __GNUC__
-#ifdef VMW_SUBPATCH
-const char vmwlegacy_drv_modinfo[]
-__attribute__((section(".modinfo"),unused)) =
- "version=" VMWARE_DRIVER_VERSION_STRING "." VMW_STRING(VMW_SUBPATCH);
-#else
-const char vmwlegacy_drv_modinfo[]
-__attribute__((section(".modinfo"),unused)) =
- "version=" VMWARE_DRIVER_VERSION_STRING ".0";
-#endif /*VMW_SUBPATCH*/
-#endif
-
-static SymTabRec VMWAREChipsets[] = {
- { PCI_CHIP_VMWARE0405, "vmware0405" },
- { PCI_CHIP_VMWARE0710, "vmware0710" },
- { -1, NULL }
-};
-
-#ifndef XSERVER_LIBPCIACCESS
-static resRange vmwareLegacyRes[] = {
- { ResExcIoBlock, SVGA_LEGACY_BASE_PORT,
- SVGA_LEGACY_BASE_PORT + SVGA_NUM_PORTS*sizeof(uint32)},
- _VGA_EXCLUSIVE, _END
-};
-#else
-#define vmwareLegacyRes NULL
-#endif
-
-#if XSERVER_LIBPCIACCESS
-
-#define VMWARE_DEVICE_MATCH(d, i) \
- {PCI_VENDOR_VMWARE, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
-
-static const struct pci_id_match VMwareDeviceMatch[] = {
- VMWARE_DEVICE_MATCH (PCI_CHIP_VMWARE0405, 0 ),
- VMWARE_DEVICE_MATCH (PCI_CHIP_VMWARE0710, 0 ),
- { 0, 0, 0 },
-};
-#endif
-
-/*
- * Currently, even the PCI obedient 0405 chip still only obeys IOSE and
- * MEMSE for the SVGA resources. Thus, RES_EXCLUSIVE_VGA is required.
- *
- * The 0710 chip also uses hardcoded IO ports that aren't disablable.
- */
-
-static PciChipsets VMWAREPciChipsets[] = {
- { PCI_CHIP_VMWARE0405, PCI_CHIP_VMWARE0405, RES_EXCLUSIVE_VGA },
- { PCI_CHIP_VMWARE0710, PCI_CHIP_VMWARE0710, vmwareLegacyRes },
- { -1, -1, RES_UNDEFINED }
-};
-
-#if HAVE_XORG_SERVER_1_7_0
-
+#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5)
#define xf86LoaderReqSymLists(...) do {} while (0)
-#define LoaderRefSymLists(...) do {} while (0)
-
-#else
-
-static const char *vgahwSymbols[] = {
- "vgaHWGetHWRec",
- "vgaHWGetIOBase",
- "vgaHWGetIndex",
- "vgaHWInit",
- "vgaHWProtect",
- "vgaHWRestore",
- "vgaHWSave",
- "vgaHWSaveScreen",
- "vgaHWUnlock",
- NULL
-};
-
-static const char *fbSymbols[] = {
- "fbCreateDefColormap",
- "fbPictureInit",
- "fbScreenInit",
- NULL
-};
-
-static const char *ramdacSymbols[] = {
- "xf86CreateCursorInfoRec",
- "xf86DestroyCursorInfoRec",
- "xf86InitCursor",
- NULL
-};
-
-static const char *shadowfbSymbols[] = {
- "ShadowFBInit2",
- NULL
-};
-
-#endif /* HAVE_XORG_SERVER_1_7_0 */
-
-#ifdef XFree86LOADER
-static XF86ModuleVersionInfo vmwlegacyVersRec = {
- VMWARE_DRIVER_NAME,
- MODULEVENDORSTRING,
- MODINFOSTRING1,
- MODINFOSTRING2,
- XORG_VERSION_CURRENT,
- PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
- ABI_CLASS_VIDEODRV,
- ABI_VIDEODRV_VERSION,
- MOD_CLASS_VIDEODRV,
- { 0, 0, 0, 0}
-};
-#endif /* XFree86LOADER */
-
-typedef enum {
- OPTION_HW_CURSOR,
- OPTION_XINERAMA,
- OPTION_STATIC_XINERAMA,
- OPTION_DEFAULT_MODE,
-} VMWAREOpts;
-
-static const OptionInfoRec VMWAREOptions[] = {
- { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_XINERAMA, "Xinerama", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_STATIC_XINERAMA, "StaticXinerama", OPTV_STRING, {0}, FALSE },
- { OPTION_DEFAULT_MODE, "AddDefaultMode", OPTV_BOOLEAN, {0}, FALSE },
- { -1, NULL, OPTV_NONE, {0}, FALSE }
-};
+#endif
/* Table of default modes to always add to the mode list. */
@@ -466,141 +288,6 @@ RewriteTagString(const char *istr, char *ostr, int osize)
}
#endif
-static void
-VMWAREIdentify(int flags)
-{
- xf86PrintChipsets(VMWARE_NAME, "driver for VMware SVGA", VMWAREChipsets);
-}
-
-static const OptionInfoRec *
-VMWAREAvailableOptions(int chipid, int busid)
-{
- return VMWAREOptions;
-}
-
-static int
-VMWAREParseTopologyElement(ScrnInfoPtr pScrn,
- unsigned int output,
- const char *elementName,
- const char *element,
- const char *expectedTerminators,
- Bool needTerminator,
- unsigned int *outValue)
-{
- char buf[10] = {0, };
- size_t i = 0;
- int retVal = -1;
- const char *str = element;
-
- for (i = 0; str[i] >= '0' && str[i] <= '9'; i++);
- if (i == 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: unable to parse %s.\n",
- output, elementName);
- goto exit;
- }
-
- strncpy(buf, str, i);
- *outValue = atoi(buf);
-
- if (*outValue > (unsigned short)-1) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: %s must be less than %hu.\n",
- output, elementName, (unsigned short)-1);
- goto exit;
- }
-
- str += i;
-
- if (needTerminator || str[0] != '\0') {
- Bool unexpected = TRUE;
-
- for (i = 0; i < strlen(expectedTerminators); i++) {
- if (str[0] == expectedTerminators[i]) {
- unexpected = FALSE;
- }
- }
-
- if (unexpected) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Output %u: unexpected character '%c' after %s.\n",
- output, str[0], elementName);
- goto exit;
- } else {
- str++;
- }
- }
-
- retVal = str - element;
-
- exit:
- return retVal;
-}
-
-static xXineramaScreenInfo *
-VMWAREParseTopologyString(ScrnInfoPtr pScrn,
- const char *topology,
- unsigned int *retNumOutputs)
-{
- xXineramaScreenInfo *extents = NULL;
- unsigned int numOutputs = 0;
- const char *str = topology;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing static Xinerama topology: Starting...\n");
-
- do {
- unsigned int x, y, width, height;
- int i;
-
- i = VMWAREParseTopologyElement(pScrn, numOutputs, "width", str, "xX", TRUE, &width);
- if (i == -1) {
- goto error;
- }
- str += i;
-
- i = VMWAREParseTopologyElement(pScrn, numOutputs, "height", str, "+", TRUE, &height);
- if (i == -1) {
- goto error;
- }
- str += i;
-
- i= VMWAREParseTopologyElement(pScrn, numOutputs, "X offset", str, "+", TRUE, &x);
- if (i == -1) {
- goto error;
- }
- str += i;
-
- i = VMWAREParseTopologyElement(pScrn, numOutputs, "Y offset", str, ";", FALSE, &y);
- if (i == -1) {
- goto error;
- }
- str += i;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: %ux%u+%u+%u\n",
- numOutputs, width, height, x, y);
-
- numOutputs++;
- extents = realloc(extents, numOutputs * sizeof (xXineramaScreenInfo));
- extents[numOutputs - 1].x_org = x;
- extents[numOutputs - 1].y_org = y;
- extents[numOutputs - 1].width = width;
- extents[numOutputs - 1].height = height;
- } while (*str != 0);
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing static Xinerama topology: Succeeded.\n");
- goto exit;
-
- error:
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing static Xinerama topology: Failed.\n");
-
- free(extents);
- extents = NULL;
- numOutputs = 0;
-
- exit:
- *retNumOutputs = numOutputs;
- return extents;
-}
-
-
static Bool
VMWAREPreInit(ScrnInfoPtr pScrn, int flags)
{
@@ -899,18 +586,14 @@ VMWAREPreInit(ScrnInfoPtr pScrn, int flags)
#endif
xf86CollectOptions(pScrn, NULL);
- if (!(options = malloc(sizeof(VMWAREOptions))))
+ if (!(options = VMWARECopyOptions()))
return FALSE;
- memcpy(options, VMWAREOptions, sizeof(VMWAREOptions));
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
if (pScrn->depth <= 8) {
pScrn->rgbBits = 8;
}
- from = X_PROBED;
- pScrn->chipset = (char*)xf86TokenToString(VMWAREChipsets, DEVICE_ID(pVMWARE->PciInfo));
-
if (!pScrn->chipset) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ChipID 0x%04x is not recognised\n", DEVICE_ID(pVMWARE->PciInfo));
return FALSE;
@@ -1608,46 +1291,6 @@ vmwareIsRegionEqual(const RegionPtr reg1,
return TRUE;
}
-#if VMWARE_DRIVER_FUNC
-static Bool
-VMWareDriverFunc(ScrnInfoPtr pScrn,
- xorgDriverFuncOp op,
- pointer data)
-{
- CARD32 *flag;
- xorgRRModeMM *modemm;
-
- switch (op) {
- case GET_REQUIRED_HW_INTERFACES:
- flag = (CARD32 *)data;
-
- if (flag) {
- *flag = HW_IO | HW_MMIO;
- }
- return TRUE;
- case RR_GET_MODE_MM:
- modemm = (xorgRRModeMM *)data;
-
- /*
- * Because changing the resolution of the guest is usually changing the size
- * of a window on the host desktop, the real physical DPI will not change. To
- * keep the guest in sync, we scale the 'physical' screen dimensions to
- * keep the DPI constant.
- */
- if (modemm && modemm->mode) {
- modemm->mmWidth = (modemm->mode->HDisplay * VMWARE_INCHTOMM +
- pScrn->xDpi / 2) / pScrn->xDpi;
- modemm->mmHeight = (modemm->mode->VDisplay * VMWARE_INCHTOMM +
- pScrn->yDpi / 2) / pScrn->yDpi;
- }
- return TRUE;
- default:
- return FALSE;
- }
-}
-#endif
-
-
static Bool
VMWAREScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
{
@@ -1663,9 +1306,8 @@ VMWAREScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
xf86CollectOptions(pScrn, NULL);
- if (!(options = malloc(sizeof(VMWAREOptions))))
+ if (!(options = VMWARECopyOptions()))
return FALSE;
- memcpy(options, VMWAREOptions, sizeof(VMWAREOptions));
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
/*
@@ -1680,11 +1322,25 @@ VMWAREScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
}
- if (useXinerama && xf86IsOptionSet(options, OPTION_STATIC_XINERAMA)) {
+ if (useXinerama && xf86IsOptionSet(options, OPTION_GUI_LAYOUT)) {
+ char *topology = xf86GetOptValString(options, OPTION_GUI_LAYOUT);
+ if (topology) {
+ pVMWARE->xineramaState =
+ VMWAREParseTopologyString(pScrn, topology,
+ &pVMWARE->xineramaNumOutputs, "gui");
+
+ pVMWARE->xineramaStatic = pVMWARE->xineramaState != NULL;
+
+ free(topology);
+ }
+ } else if (useXinerama &&
+ xf86IsOptionSet(options, OPTION_STATIC_XINERAMA)) {
char *topology = xf86GetOptValString(options, OPTION_STATIC_XINERAMA);
if (topology) {
pVMWARE->xineramaState =
- VMWAREParseTopologyString(pScrn, topology, &pVMWARE->xineramaNumOutputs);
+ VMWAREParseTopologyString(pScrn, topology,
+ &pVMWARE->xineramaNumOutputs,
+ "static Xinerama");
pVMWARE->xineramaStatic = pVMWARE->xineramaState != NULL;
@@ -1986,155 +1642,14 @@ VMWAREValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
return MODE_OK;
}
-#if XSERVER_LIBPCIACCESS
-static Bool
-VMwarePciProbe (DriverPtr drv,
- int entity_num,
- struct pci_device *device,
- intptr_t match_data)
-{
- ScrnInfoPtr scrn = NULL;
- EntityInfoPtr entity;
-
- scrn = xf86ConfigPciEntity(scrn, 0, entity_num, VMWAREPciChipsets,
- NULL, NULL, NULL, NULL, NULL);
- if (scrn != NULL) {
- scrn->driverVersion = VMWARE_DRIVER_VERSION;
- scrn->driverName = VMWARE_DRIVER_NAME;
- scrn->name = VMWARE_NAME;
- scrn->Probe = NULL;
- }
-
- entity = xf86GetEntityInfo(entity_num);
- switch (DEVICE_ID(device)) {
- case PCI_CHIP_VMWARE0405:
- case PCI_CHIP_VMWARE0710:
- xf86MsgVerb(X_INFO, 4, "VMwarePciProbe: Valid device\n");
- scrn->PreInit = VMWAREPreInit;
- scrn->ScreenInit = VMWAREScreenInit;
- scrn->SwitchMode = VMWARESwitchMode;
- scrn->EnterVT = VMWAREEnterVT;
- scrn->LeaveVT = VMWARELeaveVT;
- scrn->FreeScreen = VMWAREFreeScreen;
- scrn->ValidMode = VMWAREValidMode;
- break;
- default:
- xf86MsgVerb(X_INFO, 4, "VMwarePciProbe: Unknown device\n");
- }
- return scrn != NULL;
-}
-#else
-
-static Bool
-VMWAREProbe(DriverPtr drv, int flags)
-{
- int numDevSections, numUsed;
- GDevPtr *devSections;
- int *usedChips;
- int i;
- Bool foundScreen = FALSE;
- char buildString[sizeof(VMWAREBuildStr)];
-
- RewriteTagString(VMWAREBuildStr, buildString, sizeof(VMWAREBuildStr));
- xf86MsgVerb(X_PROBED, 4, "%s", buildString);
-
- numDevSections = xf86MatchDevice(VMWARE_DRIVER_NAME, &devSections);
- if (numDevSections <= 0) {
-#ifdef DEBUG
- xf86MsgVerb(X_ERROR, 0, "No vmware driver section\n");
-#endif
- return FALSE;
- }
- if (xf86GetPciVideoInfo()) {
- VmwareLog(("Some PCI Video Info Exists\n"));
- numUsed = xf86MatchPciInstances(VMWARE_NAME, PCI_VENDOR_VMWARE,
- VMWAREChipsets, VMWAREPciChipsets, devSections,
- numDevSections, drv, &usedChips);
- free(devSections);
- if (numUsed <= 0)
- return FALSE;
- if (flags & PROBE_DETECT)
- foundScreen = TRUE;
- else
- for (i = 0; i < numUsed; i++) {
- ScrnInfoPtr pScrn = NULL;
-
- VmwareLog(("Even some VMware SVGA PCI instances exists\n"));
- pScrn = xf86ConfigPciEntity(pScrn, flags, usedChips[i],
- VMWAREPciChipsets, NULL, NULL, NULL,
- NULL, NULL);
- if (pScrn) {
- VmwareLog(("And even configuration suceeded\n"));
- pScrn->driverVersion = VMWARE_DRIVER_VERSION;
- pScrn->driverName = VMWARE_DRIVER_NAME;
- pScrn->name = VMWARE_NAME;
- pScrn->Probe = VMWAREProbe;
- pScrn->PreInit = VMWAREPreInit;
- pScrn->ScreenInit = VMWAREScreenInit;
- pScrn->SwitchMode = VMWARESwitchMode;
- pScrn->AdjustFrame = VMWAREAdjustFrame;
- pScrn->EnterVT = VMWAREEnterVT;
- pScrn->LeaveVT = VMWARELeaveVT;
- pScrn->FreeScreen = VMWAREFreeScreen;
- pScrn->ValidMode = VMWAREValidMode;
- foundScreen = TRUE;
- }
- }
- free(usedChips);
- }
- return foundScreen;
-}
-#endif
-
-
-_X_EXPORT DriverRec vmwlegacy = {
- VMWARE_DRIVER_VERSION,
- VMWARE_DRIVER_NAME,
- VMWAREIdentify,
-#if XSERVER_LIBPCIACCESS
- NULL,
-#else
- VMWAREProbe,
-#endif
- VMWAREAvailableOptions,
- NULL,
- 0,
-#if VMWARE_DRIVER_FUNC
- VMWareDriverFunc,
-#endif
-#if XSERVER_LIBPCIACCESS
- VMwareDeviceMatch,
- VMwarePciProbe,
-#endif
-};
-
-#ifdef XFree86LOADER
-static MODULESETUPPROTO(vmwlegacySetup);
-
-_X_EXPORT XF86ModuleData vmwlegacyModuleData = {
- &vmwlegacyVersRec,
- vmwlegacySetup,
- NULL
-};
-
-static pointer
-vmwlegacySetup(pointer module, pointer opts, int *errmaj, int *errmin)
+void
+vmwlegacy_hookup(ScrnInfoPtr pScrn)
{
- static Bool setupDone = FALSE;
-
- if (!setupDone) {
- setupDone = TRUE;
-
- xf86AddDriver(&vmwlegacy, module, VMWARE_DRIVER_FUNC);
-
- LoaderRefSymLists(vgahwSymbols, fbSymbols, ramdacSymbols,
- shadowfbSymbols, NULL);
-
- return (pointer)1;
- }
- if (errmaj) {
- *errmaj = LDR_ONCEONLY;
- }
- return NULL;
+ pScrn->PreInit = VMWAREPreInit;
+ pScrn->ScreenInit = VMWAREScreenInit;
+ pScrn->SwitchMode = VMWARESwitchMode;
+ pScrn->EnterVT = VMWAREEnterVT;
+ pScrn->LeaveVT = VMWARELeaveVT;
+ pScrn->FreeScreen = VMWAREFreeScreen;
+ pScrn->ValidMode = VMWAREValidMode;
}
-#endif /* XFree86LOADER */
diff --git a/src/vmware_bootstrap.c b/src/vmware_bootstrap.c
new file mode 100644
index 0000000..522fec0
--- /dev/null
+++ b/src/vmware_bootstrap.c
@@ -0,0 +1,503 @@
+/*
+ * Copyright 2011 VMWare, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Unknown at vmware
+ * Author: Thomas Hellstrom <thellstrom@vmware.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "compiler.h"
+#include "xf86PciInfo.h" /* pci vendor id */
+#include "xf86Pci.h" /* pci */
+#include "vm_device_version.h"
+#include "vmware_bootstrap.h"
+
+#ifndef HAVE_XORG_SERVER_1_5_0
+#include <xf86_ansic.h>
+#include <xf86_libc.h>
+#endif
+
+#ifdef HaveDriverFuncs
+#define VMWARE_DRIVER_FUNC HaveDriverFuncs
+#else
+#define VMWARE_DRIVER_FUNC 0
+#endif
+
+/*
+ * So that the file compiles unmodified when dropped in to a < 6.9 source tree.
+ */
+#ifndef _X_EXPORT
+#define _X_EXPORT
+#endif
+/*
+ * So that the file compiles unmodified when dropped into an xfree source tree.
+ */
+#ifndef XORG_VERSION_CURRENT
+#define XORG_VERSION_CURRENT XF86_VERSION_CURRENT
+#endif
+
+/*
+ * Sanity check that xf86PciInfo.h has the correct values (which come from
+ * the VMware source tree in vm_device_version.h.
+ */
+#if PCI_CHIP_VMWARE0405 != PCI_DEVICE_ID_VMWARE_SVGA2
+#error "PCI_CHIP_VMWARE0405 is wrong, update it from vm_device_version.h"
+#endif
+#if PCI_CHIP_VMWARE0710 != PCI_DEVICE_ID_VMWARE_SVGA
+#error "PCI_CHIP_VMWARE0710 is wrong, update it from vm_device_version.h"
+#endif
+#if PCI_VENDOR_VMWARE != PCI_VENDOR_ID_VMWARE
+#error "PCI_VENDOR_VMWARE is wrong, update it from vm_device_version.h"
+#endif
+
+/*
+ * This is the only way I know to turn a #define of an integer constant into
+ * a constant string.
+ */
+#define VMW_INNERSTRINGIFY(s) #s
+#define VMW_STRING(str) VMW_INNERSTRINGIFY(str)
+
+#define VMWARE_NAME "vmware"
+#define VMWARE_DRIVER_NAME "vmware"
+#define VMWARE_DRIVER_VERSION \
+ (PACKAGE_VERSION_MAJOR * 65536 + PACKAGE_VERSION_MINOR * 256 + PACKAGE_VERSION_PATCHLEVEL)
+#define VMWARE_DRIVER_VERSION_STRING \
+ VMW_STRING(PACKAGE_VERSION_MAJOR) "." VMW_STRING(PACKAGE_VERSION_MINOR) \
+ "." VMW_STRING(PACKAGE_VERSION_PATCHLEVEL)
+
+static const char VMWAREBuildStr[] = "VMware Guest X Server "
+ VMWARE_DRIVER_VERSION_STRING " - build=$Name$\n";
+
+/*
+ * Standard four digit version string expected by VMware Tools installer.
+ * As the driver's version is only {major, minor, patchlevel},
+ * The fourth digit may describe the commit number relative to the
+ * last version tag as output from `git describe`
+ */
+
+#ifdef __GNUC__
+#ifdef VMW_SUBPATCH
+const char vmware_drv_modinfo[]
+__attribute__((section(".modinfo"),unused)) =
+ "version=" VMWARE_DRIVER_VERSION_STRING "." VMW_STRING(VMW_SUBPATCH);
+#else
+const char vmware_drv_modinfo[]
+__attribute__((section(".modinfo"),unused)) =
+ "version=" VMWARE_DRIVER_VERSION_STRING ".0";
+#endif /*VMW_SUBPATCH*/
+#endif
+
+#ifndef XSERVER_LIBPCIACCESS
+static resRange vmwareLegacyRes[] = {
+ { ResExcIoBlock, SVGA_LEGACY_BASE_PORT,
+ SVGA_LEGACY_BASE_PORT + SVGA_NUM_PORTS*sizeof(uint32)},
+ _VGA_EXCLUSIVE, _END
+};
+#else
+#define vmwareLegacyRes NULL
+#endif
+
+#if XSERVER_LIBPCIACCESS
+#define VENDOR_ID(p) (p)->vendor_id
+#define DEVICE_ID(p) (p)->device_id
+#define SUBVENDOR_ID(p) (p)->subvendor_id
+#define SUBSYS_ID(p) (p)->subdevice_id
+#define CHIP_REVISION(p) (p)->revision
+#else
+#define VENDOR_ID(p) (p)->vendor
+#define DEVICE_ID(p) (p)->chipType
+#define SUBVENDOR_ID(p) (p)->subsysVendor
+#define SUBSYS_ID(p) (p)->subsysCard
+#define CHIP_REVISION(p) (p)->chipRev
+#endif
+
+#if XSERVER_LIBPCIACCESS
+
+#define VMWARE_DEVICE_MATCH(d, i) \
+ {PCI_VENDOR_VMWARE, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
+
+static const struct pci_id_match VMwareDeviceMatch[] = {
+ VMWARE_DEVICE_MATCH (PCI_CHIP_VMWARE0405, 0 ),
+ VMWARE_DEVICE_MATCH (PCI_CHIP_VMWARE0710, 0 ),
+ { 0, 0, 0 },
+};
+#endif
+
+/*
+ * Currently, even the PCI obedient 0405 chip still only obeys IOSE and
+ * MEMSE for the SVGA resources. Thus, RES_EXCLUSIVE_VGA is required.
+ *
+ * The 0710 chip also uses hardcoded IO ports that aren't disablable.
+ */
+
+static PciChipsets VMWAREPciChipsets[] = {
+ { PCI_CHIP_VMWARE0405, PCI_CHIP_VMWARE0405, RES_EXCLUSIVE_VGA },
+ { PCI_CHIP_VMWARE0710, PCI_CHIP_VMWARE0710, vmwareLegacyRes },
+ { -1, -1, RES_UNDEFINED }
+};
+
+static SymTabRec VMWAREChipsets[] = {
+ { PCI_CHIP_VMWARE0405, "vmware0405" },
+ { PCI_CHIP_VMWARE0710, "vmware0710" },
+ { -1, NULL }
+};
+
+#ifdef XFree86LOADER
+static XF86ModuleVersionInfo vmwareVersRec = {
+ VMWARE_DRIVER_NAME,
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ { 0, 0, 0, 0}
+};
+#endif /* XFree86LOADER */
+
+static const OptionInfoRec VMWAREOptions[] = {
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_XINERAMA, "Xinerama", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_STATIC_XINERAMA, "StaticXinerama", OPTV_STRING, {0}, FALSE },
+ { OPTION_GUI_LAYOUT, "GuiLayout", OPTV_STRING, {0}, FALSE },
+ { OPTION_DEFAULT_MODE, "AddDefaultMode", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_RENDER_ACCEL, "RenderAccel", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_DIRECT_PRESENTS, "DirectPresents", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_HW_PRESENTS, "HWPresents", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_RENDERCHECK, "RenderCheck", OPTV_BOOLEAN, {0}, FALSE},
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+OptionInfoPtr VMWARECopyOptions(void)
+{
+ OptionInfoPtr options;
+ if (!(options = malloc(sizeof(VMWAREOptions))))
+ return NULL;
+
+ memcpy(options, VMWAREOptions, sizeof(VMWAREOptions));
+ return options;
+}
+
+static Bool
+VMwarePreinitStub(ScrnInfoPtr pScrn, int flags)
+{
+#if XSERVER_LIBPCIACCESS
+ struct pci_device *pciInfo;
+#else
+ pciVideoPtr pciInfo;
+#endif /* XSERVER_LIBPCIACCESS */
+ EntityInfoPtr pEnt;
+
+ pScrn->PreInit = pScrn->driverPrivate;
+
+#ifdef BUILD_VMWGFX
+ pScrn->driverPrivate = NULL;
+
+ /*
+ * Try vmwgfx path.
+ */
+ if ((*pScrn->PreInit)(pScrn, flags))
+ return TRUE;
+
+#else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Driver was compiled without KMS- and 3D support.\n");
+#endif /* defined(BUILD_VMWGFX) */
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling 3D support.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling Render Acceleration.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling RandR12+ support.\n");
+
+ pScrn->driverPrivate = NULL;
+ vmwlegacy_hookup(pScrn);
+
+ pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pEnt->location.type != BUS_PCI)
+ return FALSE;
+
+ pciInfo = xf86GetPciInfoForEntity(pEnt->index);
+ if (pciInfo == NULL)
+ return FALSE;
+
+ pScrn->chipset = (char*)xf86TokenToString(VMWAREChipsets,
+ DEVICE_ID(pciInfo));
+
+ return (*pScrn->PreInit)(pScrn, flags);
+};
+
+#if XSERVER_LIBPCIACCESS
+static Bool
+VMwarePciProbe (DriverPtr drv,
+ int entity_num,
+ struct pci_device *device,
+ intptr_t match_data)
+{
+ ScrnInfoPtr scrn = NULL;
+ EntityInfoPtr entity;
+
+ scrn = xf86ConfigPciEntity(scrn, 0, entity_num, VMWAREPciChipsets,
+ NULL, NULL, NULL, NULL, NULL);
+ if (scrn != NULL) {
+ scrn->driverVersion = VMWARE_DRIVER_VERSION;
+ scrn->driverName = VMWARE_DRIVER_NAME;
+ scrn->name = VMWARE_NAME;
+ scrn->Probe = NULL;
+ }
+
+ entity = xf86GetEntityInfo(entity_num);
+ switch (DEVICE_ID(device)) {
+ case PCI_CHIP_VMWARE0405:
+ case PCI_CHIP_VMWARE0710:
+ xf86MsgVerb(X_INFO, 4, "VMwarePciProbe: Valid device\n");
+
+#ifdef BUILD_VMWGFX
+ vmwgfx_hookup(scrn);
+#else
+ vmwlegacy_hookup(scrn);
+#endif /* defined(BUILD_VMWGFX) */
+
+ scrn->driverPrivate = scrn->PreInit;
+ scrn->PreInit = VMwarePreinitStub;
+ break;
+ default:
+ xf86MsgVerb(X_INFO, 4, "VMwarePciProbe: Unknown device\n");
+ }
+ return scrn != NULL;
+}
+#else
+
+static Bool
+VMWAREProbe(DriverPtr drv, int flags)
+{
+ int numDevSections, numUsed;
+ GDevPtr *devSections;
+ int *usedChips;
+ int i;
+ Bool foundScreen = FALSE;
+ char buildString[sizeof(VMWAREBuildStr)];
+
+ RewriteTagString(VMWAREBuildStr, buildString, sizeof(VMWAREBuildStr));
+ xf86MsgVerb(X_PROBED, 4, "%s", buildString);
+
+ numDevSections = xf86MatchDevice(VMWARE_DRIVER_NAME, &devSections);
+ if (numDevSections <= 0) {
+#ifdef DEBUG
+ xf86MsgVerb(X_ERROR, 0, "No vmware driver section\n");
+#endif
+ return FALSE;
+ }
+ if (xf86GetPciVideoInfo()) {
+ VmwareLog(("Some PCI Video Info Exists\n"));
+ numUsed = xf86MatchPciInstances(VMWARE_NAME, PCI_VENDOR_VMWARE,
+ VMWAREChipsets, VMWAREPciChipsets, devSections,
+ numDevSections, drv, &usedChips);
+ free(devSections);
+ if (numUsed <= 0)
+ return FALSE;
+ if (flags & PROBE_DETECT)
+ foundScreen = TRUE;
+ else
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = NULL;
+
+ VmwareLog(("Even some VMware SVGA PCI instances exists\n"));
+ pScrn = xf86ConfigPciEntity(pScrn, flags, usedChips[i],
+ VMWAREPciChipsets, NULL, NULL, NULL,
+ NULL, NULL);
+ if (pScrn) {
+ VmwareLog(("And even configuration suceeded\n"));
+ pScrn->driverVersion = VMWARE_DRIVER_VERSION;
+ pScrn->driverName = VMWARE_DRIVER_NAME;
+ pScrn->name = VMWARE_NAME;
+ pScrn->Probe = VMWAREProbe;
+ pScrn->PreInit = VMWAREPreInit;
+
+#ifdef BUILD_VMWGFX
+ vmwgfx_hookup(scrn);
+#else
+ vmwlegacy_hookup(scrn);
+#endif /* defined(BUILD_VMWGFX) */
+
+ scrn->driverPrivate = scrn->PreInit;
+ scrn->PreInit = VMwarePreinitStub;
+ foundScreen = TRUE;
+ }
+ }
+ free(usedChips);
+ }
+ return foundScreen;
+}
+#endif
+
+static void
+VMWAREIdentify(int flags)
+{
+ xf86PrintChipsets(VMWARE_NAME, "driver for VMware SVGA", VMWAREChipsets);
+}
+
+static const OptionInfoRec *
+VMWAREAvailableOptions(int chipid, int busid)
+{
+ return VMWAREOptions;
+}
+
+#if VMWARE_DRIVER_FUNC
+static Bool
+VMWareDriverFunc(ScrnInfoPtr pScrn,
+ xorgDriverFuncOp op,
+ pointer data)
+{
+ CARD32 *flag;
+ xorgRRModeMM *modemm;
+
+ switch (op) {
+ case GET_REQUIRED_HW_INTERFACES:
+ flag = (CARD32 *)data;
+
+ if (flag) {
+ *flag = HW_IO | HW_MMIO;
+ }
+ return TRUE;
+ case RR_GET_MODE_MM:
+ modemm = (xorgRRModeMM *)data;
+
+ /*
+ * Because changing the resolution of the guest is usually changing the size
+ * of a window on the host desktop, the real physical DPI will not change. To
+ * keep the guest in sync, we scale the 'physical' screen dimensions to
+ * keep the DPI constant.
+ */
+ if (modemm && modemm->mode) {
+ modemm->mmWidth = (modemm->mode->HDisplay * VMWARE_INCHTOMM +
+ pScrn->xDpi / 2) / pScrn->xDpi;
+ modemm->mmHeight = (modemm->mode->VDisplay * VMWARE_INCHTOMM +
+ pScrn->yDpi / 2) / pScrn->yDpi;
+ }
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+#endif
+
+
+_X_EXPORT DriverRec vmware = {
+ VMWARE_DRIVER_VERSION,
+ VMWARE_DRIVER_NAME,
+ VMWAREIdentify,
+#if XSERVER_LIBPCIACCESS
+ NULL,
+#else
+ VMWAREProbe,
+#endif
+ VMWAREAvailableOptions,
+ NULL,
+ 0,
+#if VMWARE_DRIVER_FUNC
+ VMWareDriverFunc,
+#endif
+#if XSERVER_LIBPCIACCESS
+ VMwareDeviceMatch,
+ VMwarePciProbe,
+#endif
+};
+
+#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5)
+
+#define xf86LoaderReqSymLists(...) do {} while (0)
+#define LoaderRefSymLists(...) do {} while (0)
+
+#else
+
+const char *vgahwSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWGetIOBase",
+ "vgaHWGetIndex",
+ "vgaHWInit",
+ "vgaHWProtect",
+ "vgaHWRestore",
+ "vgaHWSave",
+ "vgaHWSaveScreen",
+ "vgaHWUnlock",
+ NULL
+};
+
+static const char *fbSymbols[] = {
+ "fbCreateDefColormap",
+ "fbPictureInit",
+ "fbScreenInit",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ "xf86InitCursor",
+ NULL
+};
+
+static const char *shadowfbSymbols[] = {
+ "ShadowFBInit2",
+ NULL
+};
+#endif
+
+#ifdef XFree86LOADER
+static MODULESETUPPROTO(vmwareSetup);
+
+_X_EXPORT XF86ModuleData vmwareModuleData = {
+ &vmwareVersRec,
+ vmwareSetup,
+ NULL
+};
+
+static pointer
+vmwareSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+
+ xf86AddDriver(&vmware, module, VMWARE_DRIVER_FUNC);
+
+ LoaderRefSymLists(vgahwSymbols, fbSymbols, ramdacSymbols,
+ shadowfbSymbols, NULL);
+
+ return (pointer)1;
+ }
+ if (errmaj) {
+ *errmaj = LDR_ONCEONLY;
+ }
+ return NULL;
+}
+#endif /* XFree86LOADER */
diff --git a/src/vmware_bootstrap.h b/src/vmware_bootstrap.h
new file mode 100644
index 0000000..172deb8
--- /dev/null
+++ b/src/vmware_bootstrap.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2011 VMWare, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Thomas Hellstrom <thellstrom@vmware.com>
+ */
+#ifndef _VMWARE_BOOTSTRAP_H_
+#define _VMWARE_BOOTSTRAP_H_
+
+#include <xf86.h>
+
+#define VMWARE_INCHTOMM 25.4
+
+typedef enum {
+ OPTION_HW_CURSOR,
+ OPTION_XINERAMA,
+ OPTION_STATIC_XINERAMA,
+ OPTION_GUI_LAYOUT,
+ OPTION_DEFAULT_MODE,
+ OPTION_RENDER_ACCEL,
+ OPTION_DRI,
+ OPTION_DIRECT_PRESENTS,
+ OPTION_HW_PRESENTS,
+ OPTION_RENDERCHECK
+} VMWAREOpts;
+
+OptionInfoPtr VMWARECopyOptions(void);
+const char **vgahwSymbols;
+
+void
+vmwlegacy_hookup(ScrnInfoPtr pScrn);
+
+#ifdef BUILD_VMWGFX
+void
+vmwgfx_hookup(ScrnInfoPtr pScrn);
+#endif /* defined(BUILD_VMWGFX) */
+
+
+#endif
diff --git a/src/vmware_common.c b/src/vmware_common.c
new file mode 100644
index 0000000..6ef7ca6
--- /dev/null
+++ b/src/vmware_common.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2011 VMWare, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Unknown at vmware
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <xf86.h>
+#include "vmware_common.h"
+
+#ifndef HAVE_XORG_SERVER_1_5_0
+#include <xf86_ansic.h>
+#include <xf86_libc.h>
+#endif
+
+static int
+VMWAREParseTopologyElement(ScrnInfoPtr pScrn,
+ unsigned int output,
+ const char *elementName,
+ const char *element,
+ const char *expectedTerminators,
+ Bool needTerminator,
+ unsigned int *outValue)
+{
+ char buf[10] = {0, };
+ size_t i = 0;
+ int retVal = -1;
+ const char *str = element;
+
+ for (i = 0; str[i] >= '0' && str[i] <= '9'; i++);
+ if (i == 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: unable to parse %s.\n",
+ output, elementName);
+ goto exit;
+ }
+
+ strncpy(buf, str, i);
+ *outValue = atoi(buf);
+
+ if (*outValue > (unsigned short)-1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: %s must be less than %hu.\n",
+ output, elementName, (unsigned short)-1);
+ goto exit;
+ }
+
+ str += i;
+
+ if (needTerminator || str[0] != '\0') {
+ Bool unexpected = TRUE;
+
+ for (i = 0; i < strlen(expectedTerminators); i++) {
+ if (str[0] == expectedTerminators[i]) {
+ unexpected = FALSE;
+ }
+ }
+
+ if (unexpected) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Output %u: unexpected character '%c' after %s.\n",
+ output, str[0], elementName);
+ goto exit;
+ } else {
+ str++;
+ }
+ }
+
+ retVal = str - element;
+
+ exit:
+ return retVal;
+}
+
+xXineramaScreenInfo *
+VMWAREParseTopologyString(ScrnInfoPtr pScrn,
+ const char *topology,
+ unsigned int *retNumOutputs,
+ const char info[])
+{
+ xXineramaScreenInfo *extents = NULL;
+ unsigned int numOutputs = 0;
+ const char *str = topology;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing %s topology: Starting...\n",
+ info);
+
+ do {
+ unsigned int x, y, width, height;
+ int i;
+
+ i = VMWAREParseTopologyElement(pScrn, numOutputs, "width", str, "xX", TRUE, &width);
+ if (i == -1) {
+ goto error;
+ }
+ str += i;
+
+ i = VMWAREParseTopologyElement(pScrn, numOutputs, "height", str, "+", TRUE, &height);
+ if (i == -1) {
+ goto error;
+ }
+ str += i;
+
+ i= VMWAREParseTopologyElement(pScrn, numOutputs, "X offset", str, "+", TRUE, &x);
+ if (i == -1) {
+ goto error;
+ }
+ str += i;
+
+ i = VMWAREParseTopologyElement(pScrn, numOutputs, "Y offset", str, ";", FALSE, &y);
+ if (i == -1) {
+ goto error;
+ }
+ str += i;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: %ux%u+%u+%u\n",
+ numOutputs, width, height, x, y);
+
+ numOutputs++;
+ extents = realloc(extents, numOutputs * sizeof (xXineramaScreenInfo));
+ extents[numOutputs - 1].x_org = x;
+ extents[numOutputs - 1].y_org = y;
+ extents[numOutputs - 1].width = width;
+ extents[numOutputs - 1].height = height;
+ } while (*str != 0);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing %s topology: Succeeded.\n",
+ info);
+ goto exit;
+
+ error:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing %s topology: Failed.\n",
+ info);
+
+ free(extents);
+ extents = NULL;
+ numOutputs = 0;
+
+ exit:
+ *retNumOutputs = numOutputs;
+ return extents;
+}
diff --git a/src/vmware_common.h b/src/vmware_common.h
new file mode 100644
index 0000000..9cd7194
--- /dev/null
+++ b/src/vmware_common.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2011 VMWare, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Unknown at vmware
+ * Author: Thomas Hellstrom <thellstrom@vmware.com>
+ */
+
+#ifndef _VMWARE_COMMON_H_
+#define _VMWARE_COMMON_H_
+
+#include <X11/extensions/panoramiXproto.h>
+#include <xf86.h>
+
+xXineramaScreenInfo *
+VMWAREParseTopologyString(ScrnInfoPtr pScrn,
+ const char *topology,
+ unsigned int *retNumOutputs,
+ const char info[]);
+
+#endif
diff --git a/src/vmwaremodule.c b/src/vmwaremodule.c
deleted file mode 100644
index 0da2440..0000000
--- a/src/vmwaremodule.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/**********************************************************
- * Copyright 2010 VMware, Inc. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- **********************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef HAVE_LIBDRM
-#include <xf86drm.h>
-#endif
-
-#include <xorg-server.h>
-#include <xf86.h>
-
-#ifndef HAVE_XORG_SERVER_1_5_0
-#include <xf86_ansic.h>
-#include <xf86_libc.h>
-#endif
-
-/*
- * Defines and exported module info.
- */
-
-#define VMWARE_DRIVER_NAME "vmware"
-#define VMWGFX_DRIVER_NAME "vmwgfx"
-#define VMWGFX_MODULE_NAME "vmwgfx"
-#define VMWGFX_COMPAT_MAJOR 11
-#define VMWGFX_REQUIRED_MAJOR 11
-#define VMWGFX_REQUIRED_MINOR 0
-#define VMWLEGACY_DRIVER_NAME "vmwlegacy"
-
-#define VMW_STRING_INNER(s) #s
-#define VMW_STRING(str) VMW_STRING_INNER(str)
-
-#define VMWARE_DRIVER_VERSION \
- (PACKAGE_VERSION_MAJOR * 65536 + PACKAGE_VERSION_MINOR * 256 + PACKAGE_VERSION_PATCHLEVEL)
-#define VMWARE_DRIVER_VERSION_STRING \
- VMW_STRING(PACKAGE_VERSION_MAJOR) "." VMW_STRING(PACKAGE_VERSION_MINOR) \
- "." VMW_STRING(PACKAGE_VERSION_PATCHLEVEL)
-
-/*
- * Standard four digit version string expected by VMware Tools installer.
- * As the driver's version is only {major, minor, patchlevel},
- * the fourth digit may describe the commit number relative to the
- * last version tag as output from `git describe`
- */
-
-#ifdef __GNUC__
-#ifdef VMW_SUBPATCH
-const char vmware_drv_modinfo[] __attribute__((section(".modinfo"),unused)) =
- "version=" VMWARE_DRIVER_VERSION_STRING "." VMW_STRING(VMW_SUBPATCH);
-#else
-const char vmware_drv_modinfo[] __attribute__((section(".modinfo"),unused)) =
- "version=" VMWARE_DRIVER_VERSION_STRING ".0";
-#endif /*VMW_SUBPATCH*/
-#endif
-
-static XF86ModuleVersionInfo vmware_version;
-static MODULESETUPPROTO(vmware_setup);
-
-_X_EXPORT XF86ModuleData vmwareModuleData = {
- &vmware_version,
- vmware_setup,
- NULL
-};
-
-extern XF86ModuleData *VMWGFX_MODULE_DATA;
-
-/*
- * Chain loading functions
- */
-
-static Bool
-vmware_check_kernel_module()
-{
-#ifdef HAVE_LIBDRM
- /* Super simple way of knowing if the kernel driver is loaded */
- int ret = drmOpen(VMWGFX_MODULE_NAME, NULL);
- if (ret < 0) {
- /* This shouldn't go in the log as the original message does not */
- fprintf(stderr, "%s: Please ignore above \"FATAL: Module %s not found."
- "\"\n", VMWARE_DRIVER_NAME, VMWGFX_MODULE_NAME);
- /* This is what goes into the log on the other hand */
- xf86DrvMsg(-1, X_PROBED, "%s: Please ignore above \"[drm] failed to "
- "load kernel module \"%s\"\"\n", VMWARE_DRIVER_NAME,
- VMWGFX_MODULE_NAME);
- return FALSE;
- }
-
- drmClose(ret);
-
- return TRUE;
-#else
- return FALSE;
-#endif /* HAVE_LIBDRM */
-}
-
-static Bool
-vmware_check_vmwgfx_driver(int matched, pointer opts)
-{
-#ifdef HAVE_LIBDRM
- int major; int minor;
- pointer module;
- CARD32 version;
-
- if (matched) {
- xf86DrvMsg(-1, X_PROBED, "%s: X configured to use %s X driver assume "
- "who ever did that knows what they are doing\n",
- VMWARE_DRIVER_NAME, VMWGFX_DRIVER_NAME);
- /* Also how did they end up here, if the configured X to use vmwgfx and
- * X should load that driver for that hardware. And since there is only
- * one SVGA device this driver shouldn't be loaded. Weird...
- */
- return TRUE;
- }
-
- module = xf86LoadOneModule(VMWGFX_DRIVER_NAME, opts);
- if (!module) {
- xf86DrvMsg(-1, X_ERROR, "%s: Please ignore the above warnings about "
- "not being able to to load module/driver %s\n",
- VMWARE_DRIVER_NAME, VMWGFX_DRIVER_NAME);
- return FALSE;
- }
-
- version = xf86GetModuleVersion(module);
- major = GET_MODULE_MAJOR_VERSION(version);
- minor = GET_MODULE_MINOR_VERSION(version);
-
- if (major > VMWGFX_COMPAT_MAJOR ||
- major < VMWGFX_REQUIRED_MAJOR ||
- (major == VMWGFX_REQUIRED_MAJOR && minor < VMWGFX_REQUIRED_MINOR)) {
- xf86DrvMsg(-1, X_PROBED, "%s: The %s X driver failed version "
- "checking.\n", VMWARE_DRIVER_NAME, VMWGFX_DRIVER_NAME);
- goto err;
- }
-
- return TRUE;
-
-err:
- /* XXX We should drop the reference on the module here */
-#endif /* HAVE_LIBDRM */
- return FALSE;
-}
-
-static Bool
-vmware_chain_module(pointer opts)
-{
- int vmwlegacy_devices;
- int vmwgfx_devices;
- int vmware_devices;
- int matched;
- char *driver_name;
- GDevPtr *gdevs;
- GDevPtr gdev;
- int i;
-
- vmware_devices = xf86MatchDevice(VMWARE_DRIVER_NAME, &gdevs);
- vmwgfx_devices = xf86MatchDevice(VMWGFX_DRIVER_NAME, NULL);
- vmwlegacy_devices = xf86MatchDevice(VMWLEGACY_DRIVER_NAME, NULL);
-
- if (vmware_check_vmwgfx_driver(vmwgfx_devices, opts) &&
- vmware_check_kernel_module()) {
- xf86DrvMsg(-1, X_INFO, "%s: Using %s X driver.\n",
- VMWARE_DRIVER_NAME, VMWGFX_DRIVER_NAME);
- driver_name = VMWGFX_DRIVER_NAME;
- matched = 1;
- } else {
- xf86DrvMsg(-1, X_INFO, "%s: Using %s driver everything is fine.\n",
- VMWARE_DRIVER_NAME, VMWLEGACY_DRIVER_NAME);
- driver_name = VMWLEGACY_DRIVER_NAME;
- matched = vmwlegacy_devices;
- }
-
- /* Xorg -configure returns 1 from xf86MatchDevice with NULL gdevs */
- for (i = 0; gdevs && i < vmware_devices; i++) {
- gdev = gdevs[i];
- gdev->driver = driver_name;
- }
-
- free(gdevs);
-
- if (!matched) {
- if (xf86LoadOneModule(driver_name, opts) == NULL) {
- xf86DrvMsg(-1, X_ERROR, "%s: Unexpected failure while "
- "loading the \"%s\" driver. Giving up.\n",
- VMWARE_DRIVER_NAME, driver_name);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-
-/*
- * Module info
- */
-
-static XF86ModuleVersionInfo vmware_version = {
- VMWARE_DRIVER_NAME,
- MODULEVENDORSTRING,
- MODINFOSTRING1,
- MODINFOSTRING2,
- XORG_VERSION_CURRENT,
- PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
- ABI_CLASS_VIDEODRV,
- ABI_VIDEODRV_VERSION,
- MOD_CLASS_VIDEODRV,
- {0, 0, 0, 0}
-};
-
-static pointer
-vmware_setup(pointer module, pointer opts, int *errmaj, int *errmin)
-{
- static Bool setupDone = 0;
-
- /* This module should be loaded only once, but check to be sure. */
- if (!setupDone) {
- setupDone = 1;
-
- /* Chain load the real driver */
- if (vmware_chain_module(opts))
- return (pointer) 1;
- else {
- if (errmaj)
- *errmaj = LDR_NOSUBENT;
- return NULL;
- }
- } else {
- if (errmaj)
- *errmaj = LDR_ONCEONLY;
- return NULL;
- }
-}