13bfa90b6Smrg/*
23bfa90b6Smrg * Copyright 2011 VMWare, Inc.
33bfa90b6Smrg * All Rights Reserved.
43bfa90b6Smrg *
53bfa90b6Smrg * Permission is hereby granted, free of charge, to any person obtaining a
63bfa90b6Smrg * copy of this software and associated documentation files (the
73bfa90b6Smrg * "Software"), to deal in the Software without restriction, including
83bfa90b6Smrg * without limitation the rights to use, copy, modify, merge, publish,
93bfa90b6Smrg * distribute, sub license, and/or sell copies of the Software, and to
103bfa90b6Smrg * permit persons to whom the Software is furnished to do so, subject to
113bfa90b6Smrg * the following conditions:
123bfa90b6Smrg *
133bfa90b6Smrg * The above copyright notice and this permission notice (including the
143bfa90b6Smrg * next paragraph) shall be included in all copies or substantial portions
153bfa90b6Smrg * of the Software.
163bfa90b6Smrg *
173bfa90b6Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
183bfa90b6Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
193bfa90b6Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
203bfa90b6Smrg * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
213bfa90b6Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
223bfa90b6Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
233bfa90b6Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
243bfa90b6Smrg *
253bfa90b6Smrg * Author: Unknown at vmware
263bfa90b6Smrg * Author: Thomas Hellstrom <thellstrom@vmware.com>
273bfa90b6Smrg */
283bfa90b6Smrg#ifdef HAVE_CONFIG_H
293bfa90b6Smrg#include "config.h"
303bfa90b6Smrg#endif
313bfa90b6Smrg
323bfa90b6Smrg#include "xf86.h"
333bfa90b6Smrg#include "compiler.h"
343bfa90b6Smrg#include "xf86Pci.h"		/* pci */
353bfa90b6Smrg#include "vm_device_version.h"
363bfa90b6Smrg#include "vmware_bootstrap.h"
3722f7e8e5Smrg#include <stdint.h>
383bfa90b6Smrg
393bfa90b6Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
403bfa90b6Smrg#include "xf86Resources.h"
413bfa90b6Smrg#endif
423bfa90b6Smrg
433bfa90b6Smrg#ifndef XSERVER_LIBPCIACCESS
443bfa90b6Smrg#include "vm_basic_types.h"
453bfa90b6Smrg#include "svga_reg.h"
463bfa90b6Smrg#endif
473bfa90b6Smrg
483bfa90b6Smrg#ifndef HAVE_XORG_SERVER_1_5_0
493bfa90b6Smrg#include <xf86_ansic.h>
503bfa90b6Smrg#include <xf86_libc.h>
513bfa90b6Smrg#endif
523bfa90b6Smrg
53591e32d7Ssnj#ifdef XSERVER_PLATFORM_BUS
54591e32d7Ssnj#include "xf86platformBus.h"
55591e32d7Ssnj#endif
56591e32d7Ssnj
573bfa90b6Smrg#ifdef HaveDriverFuncs
583bfa90b6Smrg#define VMWARE_DRIVER_FUNC HaveDriverFuncs
593bfa90b6Smrg#else
603bfa90b6Smrg#define VMWARE_DRIVER_FUNC 0
613bfa90b6Smrg#endif
623bfa90b6Smrg
633bfa90b6Smrg/*
643bfa90b6Smrg * So that the file compiles unmodified when dropped in to a < 6.9 source tree.
653bfa90b6Smrg */
663bfa90b6Smrg#ifndef _X_EXPORT
673bfa90b6Smrg#define _X_EXPORT
683bfa90b6Smrg#endif
693bfa90b6Smrg/*
703bfa90b6Smrg * So that the file compiles unmodified when dropped into an xfree source tree.
713bfa90b6Smrg */
723bfa90b6Smrg#ifndef XORG_VERSION_CURRENT
733bfa90b6Smrg#define XORG_VERSION_CURRENT XF86_VERSION_CURRENT
743bfa90b6Smrg#endif
753bfa90b6Smrg
763bfa90b6Smrg/*
773bfa90b6Smrg * This is the only way I know to turn a #define of an integer constant into
783bfa90b6Smrg * a constant string.
793bfa90b6Smrg */
803bfa90b6Smrg#define VMW_INNERSTRINGIFY(s) #s
813bfa90b6Smrg#define VMW_STRING(str) VMW_INNERSTRINGIFY(str)
823bfa90b6Smrg
833bfa90b6Smrg#define VMWARE_DRIVER_NAME "vmware"
8425dbecb6Smrg#define VMWARE_NAME "vmware"
8525dbecb6Smrg
8625dbecb6Smrgstatic char vmware_driver_name[] = VMWARE_DRIVER_NAME;
8725dbecb6Smrg
883bfa90b6Smrg#define VMWARE_DRIVER_VERSION \
893bfa90b6Smrg   (PACKAGE_VERSION_MAJOR * 65536 + PACKAGE_VERSION_MINOR * 256 + PACKAGE_VERSION_PATCHLEVEL)
903bfa90b6Smrg#define VMWARE_DRIVER_VERSION_STRING \
913bfa90b6Smrg    VMW_STRING(PACKAGE_VERSION_MAJOR) "." VMW_STRING(PACKAGE_VERSION_MINOR) \
923bfa90b6Smrg    "." VMW_STRING(PACKAGE_VERSION_PATCHLEVEL)
933bfa90b6Smrg
9425dbecb6Smrg#if !XSERVER_LIBPCIACCESS
953bfa90b6Smrgstatic const char VMWAREBuildStr[] = "VMware Guest X Server "
963bfa90b6Smrg    VMWARE_DRIVER_VERSION_STRING " - build=$Name:  $\n";
9725dbecb6Smrg#else
9825dbecb6Smrgstatic char vmware_name[] = VMWARE_NAME;
9925dbecb6Smrg#endif
1003bfa90b6Smrg
1013bfa90b6Smrg/*
1023bfa90b6Smrg * Standard four digit version string expected by VMware Tools installer.
1033bfa90b6Smrg * As the driver's version is only  {major, minor, patchlevel},
1043bfa90b6Smrg * The fourth digit may describe the commit number relative to the
1053bfa90b6Smrg * last version tag as output from `git describe`
1063bfa90b6Smrg */
1073bfa90b6Smrg
1083bfa90b6Smrg#ifdef __GNUC__
1093bfa90b6Smrg#ifdef VMW_SUBPATCH
1103bfa90b6Smrgconst char vmware_drv_modinfo[]
1113bfa90b6Smrg__attribute__((section(".modinfo"),unused)) =
1123bfa90b6Smrg  "version=" VMWARE_DRIVER_VERSION_STRING "." VMW_STRING(VMW_SUBPATCH);
1133bfa90b6Smrg#else
1143bfa90b6Smrgconst char vmware_drv_modinfo[]
1153bfa90b6Smrg__attribute__((section(".modinfo"),unused)) =
1163bfa90b6Smrg  "version=" VMWARE_DRIVER_VERSION_STRING ".0";
1173bfa90b6Smrg#endif /*VMW_SUBPATCH*/
1183bfa90b6Smrg#endif
1193bfa90b6Smrg
1203bfa90b6Smrg#ifndef XSERVER_LIBPCIACCESS
1213bfa90b6Smrgstatic resRange vmwareLegacyRes[] = {
1223bfa90b6Smrg    { ResExcIoBlock, SVGA_LEGACY_BASE_PORT,
1233bfa90b6Smrg      SVGA_LEGACY_BASE_PORT + SVGA_NUM_PORTS*sizeof(uint32)},
1243bfa90b6Smrg    _VGA_EXCLUSIVE, _END
1253bfa90b6Smrg};
1263bfa90b6Smrg#else
1273bfa90b6Smrg#define vmwareLegacyRes NULL
1283bfa90b6Smrg#endif
1293bfa90b6Smrg
1303bfa90b6Smrg#if XSERVER_LIBPCIACCESS
1313bfa90b6Smrg#define VENDOR_ID(p)      (p)->vendor_id
1323bfa90b6Smrg#define DEVICE_ID(p)      (p)->device_id
1333bfa90b6Smrg#define SUBVENDOR_ID(p)   (p)->subvendor_id
1343bfa90b6Smrg#define SUBSYS_ID(p)      (p)->subdevice_id
1353bfa90b6Smrg#define CHIP_REVISION(p)  (p)->revision
1363bfa90b6Smrg#else
1373bfa90b6Smrg#define VENDOR_ID(p)      (p)->vendor
1383bfa90b6Smrg#define DEVICE_ID(p)      (p)->chipType
1393bfa90b6Smrg#define SUBVENDOR_ID(p)   (p)->subsysVendor
1403bfa90b6Smrg#define SUBSYS_ID(p)      (p)->subsysCard
1413bfa90b6Smrg#define CHIP_REVISION(p)  (p)->chipRev
1423bfa90b6Smrg#endif
1433bfa90b6Smrg
1443bfa90b6Smrg#if XSERVER_LIBPCIACCESS
1453bfa90b6Smrg
1463bfa90b6Smrg#define VMWARE_DEVICE_MATCH(d, i) \
1473bfa90b6Smrg    {PCI_VENDOR_ID_VMWARE, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
1483bfa90b6Smrg
1493bfa90b6Smrgstatic const struct pci_id_match VMwareDeviceMatch[] = {
1503bfa90b6Smrg    VMWARE_DEVICE_MATCH (PCI_DEVICE_ID_VMWARE_SVGA2, 0 ),
1513bfa90b6Smrg    VMWARE_DEVICE_MATCH (PCI_DEVICE_ID_VMWARE_SVGA, 0 ),
1523bfa90b6Smrg    { 0, 0, 0 },
1533bfa90b6Smrg};
1543bfa90b6Smrg#endif
1553bfa90b6Smrg
1563bfa90b6Smrg/*
1573bfa90b6Smrg * Currently, even the PCI obedient 0405 chip still only obeys IOSE and
1583bfa90b6Smrg * MEMSE for the SVGA resources.  Thus, RES_EXCLUSIVE_VGA is required.
1593bfa90b6Smrg *
1603bfa90b6Smrg * The 0710 chip also uses hardcoded IO ports that aren't disablable.
1613bfa90b6Smrg */
1623bfa90b6Smrg
1633bfa90b6Smrgstatic PciChipsets VMWAREPciChipsets[] = {
1643bfa90b6Smrg    { PCI_DEVICE_ID_VMWARE_SVGA2, PCI_DEVICE_ID_VMWARE_SVGA2, RES_EXCLUSIVE_VGA },
1653bfa90b6Smrg    { PCI_DEVICE_ID_VMWARE_SVGA, PCI_DEVICE_ID_VMWARE_SVGA, vmwareLegacyRes },
1663bfa90b6Smrg    { -1,		       -1,		    RES_UNDEFINED }
1673bfa90b6Smrg};
1683bfa90b6Smrg
1693bfa90b6Smrgstatic SymTabRec VMWAREChipsets[] = {
1703bfa90b6Smrg    { PCI_DEVICE_ID_VMWARE_SVGA2, "vmware0405" },
1713bfa90b6Smrg    { PCI_DEVICE_ID_VMWARE_SVGA, "vmware0710" },
1723bfa90b6Smrg    { -1,                  NULL }
1733bfa90b6Smrg};
1743bfa90b6Smrg
1753bfa90b6Smrg#ifdef XFree86LOADER
1763bfa90b6Smrgstatic XF86ModuleVersionInfo vmwareVersRec = {
1773bfa90b6Smrg    VMWARE_DRIVER_NAME,
1783bfa90b6Smrg    MODULEVENDORSTRING,
1793bfa90b6Smrg    MODINFOSTRING1,
1803bfa90b6Smrg    MODINFOSTRING2,
1813bfa90b6Smrg    XORG_VERSION_CURRENT,
1823bfa90b6Smrg    PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
1833bfa90b6Smrg    ABI_CLASS_VIDEODRV,
1843bfa90b6Smrg    ABI_VIDEODRV_VERSION,
1853bfa90b6Smrg    MOD_CLASS_VIDEODRV,
1863bfa90b6Smrg    { 0, 0, 0, 0}
1873bfa90b6Smrg};
1883bfa90b6Smrg#endif	/* XFree86LOADER */
1893bfa90b6Smrg
1903bfa90b6Smrgstatic const OptionInfoRec VMWAREOptions[] = {
1913bfa90b6Smrg    { OPTION_HW_CURSOR, "HWcursor",     OPTV_BOOLEAN,   {0},    FALSE },
1923bfa90b6Smrg    { OPTION_XINERAMA,  "Xinerama",     OPTV_BOOLEAN,   {0},    FALSE },
1933bfa90b6Smrg    { OPTION_STATIC_XINERAMA, "StaticXinerama", OPTV_STRING, {0}, FALSE },
1943bfa90b6Smrg    { OPTION_GUI_LAYOUT, "GuiLayout", OPTV_STRING, {0}, FALSE },
1953bfa90b6Smrg    { OPTION_DEFAULT_MODE, "AddDefaultMode", OPTV_BOOLEAN,   {0},    FALSE },
1963bfa90b6Smrg    { OPTION_RENDER_ACCEL, "RenderAccel", OPTV_BOOLEAN, {0}, FALSE},
1973bfa90b6Smrg    { OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE},
1983bfa90b6Smrg    { OPTION_DIRECT_PRESENTS, "DirectPresents", OPTV_BOOLEAN, {0}, FALSE},
1993bfa90b6Smrg    { OPTION_HW_PRESENTS, "HWPresents", OPTV_BOOLEAN, {0}, FALSE},
2003bfa90b6Smrg    { OPTION_RENDERCHECK, "RenderCheck", OPTV_BOOLEAN, {0}, FALSE},
2013bfa90b6Smrg    { -1,               NULL,           OPTV_NONE,      {0},    FALSE }
2023bfa90b6Smrg};
2033bfa90b6Smrg
2043bfa90b6SmrgOptionInfoPtr VMWARECopyOptions(void)
2053bfa90b6Smrg{
2063bfa90b6Smrg    OptionInfoPtr options;
2073bfa90b6Smrg    if (!(options = malloc(sizeof(VMWAREOptions))))
2083bfa90b6Smrg        return NULL;
2093bfa90b6Smrg
2103bfa90b6Smrg    memcpy(options, VMWAREOptions, sizeof(VMWAREOptions));
2113bfa90b6Smrg    return options;
2123bfa90b6Smrg}
2133bfa90b6Smrg
21422f7e8e5Smrg/*
21522f7e8e5Smrg * Also in vmwgfx_hosted.h, which we don't include.
21622f7e8e5Smrg */
21722f7e8e5Smrgvoid *
21822f7e8e5Smrgvmwgfx_hosted_detect(void);
21922f7e8e5Smrg
2203bfa90b6Smrgstatic Bool
2213bfa90b6SmrgVMwarePreinitStub(ScrnInfoPtr pScrn, int flags)
2223bfa90b6Smrg{
2233bfa90b6Smrg#if XSERVER_LIBPCIACCESS
2243bfa90b6Smrg    struct pci_device *pciInfo;
2253bfa90b6Smrg#else
2263bfa90b6Smrg    pciVideoPtr pciInfo;
2273bfa90b6Smrg#endif /* XSERVER_LIBPCIACCESS */
2283bfa90b6Smrg    EntityInfoPtr pEnt;
2293bfa90b6Smrg
2303bfa90b6Smrg    pScrn->PreInit = pScrn->driverPrivate;
2313bfa90b6Smrg
2323bfa90b6Smrg#ifdef BUILD_VMWGFX
2333bfa90b6Smrg    pScrn->driverPrivate = NULL;
2343bfa90b6Smrg
2353bfa90b6Smrg    /*
2363bfa90b6Smrg     * Try vmwgfx path.
2373bfa90b6Smrg     */
2383bfa90b6Smrg    if ((*pScrn->PreInit)(pScrn, flags))
2393bfa90b6Smrg	return TRUE;
2403bfa90b6Smrg
24122f7e8e5Smrg    /*
24222f7e8e5Smrg     * Can't run legacy hosted
24322f7e8e5Smrg     */
24422f7e8e5Smrg    if (vmwgfx_hosted_detect())
24522f7e8e5Smrg	return FALSE;
2463bfa90b6Smrg#else
2473bfa90b6Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2483bfa90b6Smrg	       "Driver was compiled without KMS- and 3D support.\n");
2493bfa90b6Smrg#endif /* defined(BUILD_VMWGFX) */
2503bfa90b6Smrg    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2513bfa90b6Smrg	       "Disabling 3D support.\n");
2523bfa90b6Smrg    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2533bfa90b6Smrg	       "Disabling Render Acceleration.\n");
2543bfa90b6Smrg    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2553bfa90b6Smrg	       "Disabling RandR12+ support.\n");
2563bfa90b6Smrg
2573bfa90b6Smrg    pScrn->driverPrivate = NULL;
2583bfa90b6Smrg    vmwlegacy_hookup(pScrn);
2593bfa90b6Smrg
2603bfa90b6Smrg    pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
2613bfa90b6Smrg    pciInfo = xf86GetPciInfoForEntity(pEnt->index);
2623bfa90b6Smrg    if (pciInfo == NULL)
2633bfa90b6Smrg        return FALSE;
2643bfa90b6Smrg
26525dbecb6Smrg    pScrn->chipset = xstrdup(xf86TokenToString(VMWAREChipsets,
26625dbecb6Smrg					       DEVICE_ID(pciInfo)));
26725dbecb6Smrg    if (pScrn->chipset == NULL)
26825dbecb6Smrg	return FALSE;
2693bfa90b6Smrg
2703bfa90b6Smrg    return (*pScrn->PreInit)(pScrn, flags);
2713bfa90b6Smrg};
2723bfa90b6Smrg
2733bfa90b6Smrg#if XSERVER_LIBPCIACCESS
2743bfa90b6Smrgstatic Bool
2753bfa90b6SmrgVMwarePciProbe (DriverPtr           drv,
2763bfa90b6Smrg                int                 entity_num,
2773bfa90b6Smrg                struct pci_device   *device,
2783bfa90b6Smrg                intptr_t            match_data)
2793bfa90b6Smrg{
2803bfa90b6Smrg    ScrnInfoPtr     scrn = NULL;
2813bfa90b6Smrg
2823bfa90b6Smrg    scrn = xf86ConfigPciEntity(scrn, 0, entity_num, VMWAREPciChipsets,
2833bfa90b6Smrg                               NULL, NULL, NULL, NULL, NULL);
2843bfa90b6Smrg    if (scrn != NULL) {
2853bfa90b6Smrg        scrn->driverVersion = VMWARE_DRIVER_VERSION;
28625dbecb6Smrg        scrn->driverName = vmware_driver_name;
28725dbecb6Smrg        scrn->name = vmware_name;
2883bfa90b6Smrg        scrn->Probe = NULL;
2893bfa90b6Smrg    }
2903bfa90b6Smrg
2913bfa90b6Smrg    switch (DEVICE_ID(device)) {
2923bfa90b6Smrg    case PCI_DEVICE_ID_VMWARE_SVGA2:
2933bfa90b6Smrg    case PCI_DEVICE_ID_VMWARE_SVGA:
2943bfa90b6Smrg        xf86MsgVerb(X_INFO, 4, "VMwarePciProbe: Valid device\n");
2953bfa90b6Smrg
2963bfa90b6Smrg#ifdef BUILD_VMWGFX
2973bfa90b6Smrg	vmwgfx_hookup(scrn);
2983bfa90b6Smrg#else
2993bfa90b6Smrg	vmwlegacy_hookup(scrn);
3003bfa90b6Smrg#endif /* defined(BUILD_VMWGFX) */
3013bfa90b6Smrg
3023bfa90b6Smrg	scrn->driverPrivate = scrn->PreInit;
3033bfa90b6Smrg	scrn->PreInit = VMwarePreinitStub;
3043bfa90b6Smrg        break;
3053bfa90b6Smrg    default:
3063bfa90b6Smrg        xf86MsgVerb(X_INFO, 4, "VMwarePciProbe: Unknown device\n");
3073bfa90b6Smrg    }
3083bfa90b6Smrg    return scrn != NULL;
3093bfa90b6Smrg}
3103bfa90b6Smrg#else
3113bfa90b6Smrg
3123bfa90b6Smrg/*
3133bfa90b6Smrg *----------------------------------------------------------------------
3143bfa90b6Smrg *
3153bfa90b6Smrg *  RewriteTagString --
3163bfa90b6Smrg *
3173bfa90b6Smrg *      Rewrites the given string, removing the $Name:  $, and
3183bfa90b6Smrg *      replacing it with the contents.  The output string must
3193bfa90b6Smrg *      have enough room, or else.
3203bfa90b6Smrg *
3213bfa90b6Smrg * Results:
3223bfa90b6Smrg *
3233bfa90b6Smrg *      Output string updated.
3243bfa90b6Smrg *
3253bfa90b6Smrg * Side effects:
3263bfa90b6Smrg *      None.
3273bfa90b6Smrg *
3283bfa90b6Smrg *----------------------------------------------------------------------
3293bfa90b6Smrg */
3303bfa90b6Smrg
3313bfa90b6Smrgstatic void
3323bfa90b6SmrgRewriteTagString(const char *istr, char *ostr, int osize)
3333bfa90b6Smrg{
3343bfa90b6Smrg    int chr;
3353bfa90b6Smrg    Bool inTag = FALSE;
3363bfa90b6Smrg    char *op = ostr;
3373bfa90b6Smrg
3383bfa90b6Smrg    do {
3393bfa90b6Smrg	chr = *istr++;
3403bfa90b6Smrg	if (chr == '$') {
3413bfa90b6Smrg	    if (inTag) {
3423bfa90b6Smrg		inTag = FALSE;
3433bfa90b6Smrg		for (; op > ostr && op[-1] == ' '; op--) {
3443bfa90b6Smrg		}
3453bfa90b6Smrg		continue;
3463bfa90b6Smrg	    }
3473bfa90b6Smrg	    if (strncmp(istr, "Name:", 5) == 0) {
3483bfa90b6Smrg		istr += 5;
3493bfa90b6Smrg		istr += strspn(istr, " ");
3503bfa90b6Smrg		inTag = TRUE;
3513bfa90b6Smrg		continue;
3523bfa90b6Smrg	    }
3533bfa90b6Smrg	}
3543bfa90b6Smrg	*op++ = chr;
3553bfa90b6Smrg    } while (chr);
3563bfa90b6Smrg}
3573bfa90b6Smrg
3583bfa90b6Smrgstatic Bool
3593bfa90b6SmrgVMWAREProbe(DriverPtr drv, int flags)
3603bfa90b6Smrg{
3613bfa90b6Smrg    int numDevSections, numUsed;
3623bfa90b6Smrg    GDevPtr *devSections;
3633bfa90b6Smrg    int *usedChips;
3643bfa90b6Smrg    int i;
3653bfa90b6Smrg    Bool foundScreen = FALSE;
3663bfa90b6Smrg    char buildString[sizeof(VMWAREBuildStr)];
3673bfa90b6Smrg
3683bfa90b6Smrg    RewriteTagString(VMWAREBuildStr, buildString, sizeof(VMWAREBuildStr));
3693bfa90b6Smrg    xf86MsgVerb(X_PROBED, 4, "%s", buildString);
3703bfa90b6Smrg
3713bfa90b6Smrg    numDevSections = xf86MatchDevice(VMWARE_DRIVER_NAME, &devSections);
3723bfa90b6Smrg    if (numDevSections <= 0) {
3733bfa90b6Smrg#ifdef DEBUG
3743bfa90b6Smrg        xf86MsgVerb(X_ERROR, 0, "No vmware driver section\n");
3753bfa90b6Smrg#endif
3763bfa90b6Smrg        return FALSE;
3773bfa90b6Smrg    }
3783bfa90b6Smrg    if (xf86GetPciVideoInfo()) {
3793bfa90b6Smrg        VmwareLog(("Some PCI Video Info Exists\n"));
3803bfa90b6Smrg        numUsed = xf86MatchPciInstances(VMWARE_NAME, PCI_VENDOR_ID_VMWARE,
3813bfa90b6Smrg                                        VMWAREChipsets, VMWAREPciChipsets, devSections,
3823bfa90b6Smrg                                        numDevSections, drv, &usedChips);
3833bfa90b6Smrg        free(devSections);
3843bfa90b6Smrg        if (numUsed <= 0)
3853bfa90b6Smrg            return FALSE;
3863bfa90b6Smrg        if (flags & PROBE_DETECT)
3873bfa90b6Smrg            foundScreen = TRUE;
3883bfa90b6Smrg        else
3893bfa90b6Smrg            for (i = 0; i < numUsed; i++) {
3903bfa90b6Smrg                ScrnInfoPtr pScrn = NULL;
3913bfa90b6Smrg
3923bfa90b6Smrg                VmwareLog(("Even some VMware SVGA PCI instances exists\n"));
3933bfa90b6Smrg                pScrn = xf86ConfigPciEntity(pScrn, flags, usedChips[i],
3943bfa90b6Smrg                                            VMWAREPciChipsets, NULL, NULL, NULL,
3953bfa90b6Smrg                                            NULL, NULL);
3963bfa90b6Smrg                if (pScrn) {
39725dbecb6Smrg                    VmwareLog(("And even configuration succeeded\n"));
3983bfa90b6Smrg                    pScrn->driverVersion = VMWARE_DRIVER_VERSION;
3993bfa90b6Smrg                    pScrn->driverName = VMWARE_DRIVER_NAME;
4003bfa90b6Smrg                    pScrn->name = VMWARE_NAME;
4013bfa90b6Smrg                    pScrn->Probe = VMWAREProbe;
4023bfa90b6Smrg
4033bfa90b6Smrg#ifdef BUILD_VMWGFX
4043bfa90b6Smrg		    vmwgfx_hookup(pScrn);
4053bfa90b6Smrg#else
4063bfa90b6Smrg		    vmwlegacy_hookup(pScrn);
4073bfa90b6Smrg#endif /* defined(BUILD_VMWGFX) */
4083bfa90b6Smrg
4093bfa90b6Smrg		    pScrn->driverPrivate = pScrn->PreInit;
4103bfa90b6Smrg		    pScrn->PreInit = VMwarePreinitStub;
4113bfa90b6Smrg                    foundScreen = TRUE;
4123bfa90b6Smrg                }
4133bfa90b6Smrg            }
4143bfa90b6Smrg        free(usedChips);
4153bfa90b6Smrg    }
4163bfa90b6Smrg    return foundScreen;
4173bfa90b6Smrg}
4183bfa90b6Smrg#endif
4193bfa90b6Smrg
420591e32d7Ssnj#ifdef XSERVER_PLATFORM_BUS
421591e32d7Ssnjstatic Bool
422591e32d7SsnjVMwarePlatformProbe(DriverPtr drv, int entity, int flags,
423591e32d7Ssnj                    struct xf86_platform_device *dev, intptr_t match_data)
424591e32d7Ssnj{
425591e32d7Ssnj    ScrnInfoPtr pScrn;
426591e32d7Ssnj    int scrnFlag = 0;
427591e32d7Ssnj
428591e32d7Ssnj    if (!dev->pdev)
429591e32d7Ssnj        return FALSE;
430591e32d7Ssnj
431591e32d7Ssnj    if (flags & PLATFORM_PROBE_GPU_SCREEN)
432591e32d7Ssnj        scrnFlag = XF86_ALLOCATE_GPU_SCREEN;
433591e32d7Ssnj
434591e32d7Ssnj    pScrn = xf86AllocateScreen(drv, scrnFlag);
435591e32d7Ssnj    if (!pScrn)
436591e32d7Ssnj        return FALSE;
437591e32d7Ssnj
438591e32d7Ssnj    if (xf86IsEntitySharable(entity))
439591e32d7Ssnj        xf86SetEntityShared(entity);
440591e32d7Ssnj
441591e32d7Ssnj    xf86AddEntityToScreen(pScrn, entity);
442591e32d7Ssnj
443591e32d7Ssnj    pScrn->driverVersion = VMWARE_DRIVER_VERSION;
444591e32d7Ssnj    pScrn->driverName = VMWARE_DRIVER_NAME;
445591e32d7Ssnj    pScrn->name = VMWARE_NAME;
446591e32d7Ssnj    pScrn->Probe = NULL;
447591e32d7Ssnj#ifdef BUILD_VMWGFX
448591e32d7Ssnj    vmwgfx_hookup(pScrn);
449591e32d7Ssnj#else
450591e32d7Ssnj    vmwlegacy_hookup(pScrn);
451591e32d7Ssnj#endif
452591e32d7Ssnj    pScrn->driverPrivate = pScrn->PreInit;
453591e32d7Ssnj    pScrn->PreInit = VMwarePreinitStub;
454591e32d7Ssnj
455591e32d7Ssnj    return TRUE;
456591e32d7Ssnj}
457591e32d7Ssnj#endif
458591e32d7Ssnj
4593bfa90b6Smrgstatic void
4603bfa90b6SmrgVMWAREIdentify(int flags)
4613bfa90b6Smrg{
4623bfa90b6Smrg    xf86PrintChipsets(VMWARE_NAME, "driver for VMware SVGA", VMWAREChipsets);
4633bfa90b6Smrg}
4643bfa90b6Smrg
4653bfa90b6Smrgstatic const OptionInfoRec *
4663bfa90b6SmrgVMWAREAvailableOptions(int chipid, int busid)
4673bfa90b6Smrg{
4683bfa90b6Smrg    return VMWAREOptions;
4693bfa90b6Smrg}
4703bfa90b6Smrg
4713bfa90b6Smrg#if VMWARE_DRIVER_FUNC
4723bfa90b6Smrgstatic Bool
4733bfa90b6SmrgVMWareDriverFunc(ScrnInfoPtr pScrn,
4743bfa90b6Smrg                 xorgDriverFuncOp op,
4753bfa90b6Smrg                 pointer data)
4763bfa90b6Smrg{
47722f7e8e5Smrg   uint32_t *flag;
4783bfa90b6Smrg   xorgRRModeMM *modemm;
4793bfa90b6Smrg
4803bfa90b6Smrg   switch (op) {
4813bfa90b6Smrg   case GET_REQUIRED_HW_INTERFACES:
48222f7e8e5Smrg      flag = (uint32_t *)data;
4833bfa90b6Smrg
4843bfa90b6Smrg      if (flag) {
48522f7e8e5Smrg#ifdef BUILD_VMWGFX
48622f7e8e5Smrg	  vmwgfx_modify_flags(flag);
48722f7e8e5Smrg#else
4883bfa90b6Smrg         *flag = HW_IO | HW_MMIO;
48922f7e8e5Smrg#endif
4903bfa90b6Smrg      }
4913bfa90b6Smrg      return TRUE;
4923bfa90b6Smrg   case RR_GET_MODE_MM:
4933bfa90b6Smrg      modemm = (xorgRRModeMM *)data;
4943bfa90b6Smrg
4953bfa90b6Smrg      /*
4963bfa90b6Smrg       * Because changing the resolution of the guest is usually changing the size
4973bfa90b6Smrg       * of a window on the host desktop, the real physical DPI will not change. To
4983bfa90b6Smrg       * keep the guest in sync, we scale the 'physical' screen dimensions to
4993bfa90b6Smrg       * keep the DPI constant.
5003bfa90b6Smrg       */
5013bfa90b6Smrg      if (modemm && modemm->mode) {
5023bfa90b6Smrg	  modemm->mmWidth = (modemm->mode->HDisplay * VMWARE_INCHTOMM +
5033bfa90b6Smrg			     pScrn->xDpi / 2)  / pScrn->xDpi;
5043bfa90b6Smrg	  modemm->mmHeight = (modemm->mode->VDisplay * VMWARE_INCHTOMM +
5053bfa90b6Smrg			      pScrn->yDpi / 2) / pScrn->yDpi;
5063bfa90b6Smrg      }
5073bfa90b6Smrg      return TRUE;
508591e32d7Ssnj#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 18
509591e32d7Ssnj   case SUPPORTS_SERVER_FDS:
510591e32d7Ssnj      return TRUE;
511591e32d7Ssnj#endif
5123bfa90b6Smrg   default:
5133bfa90b6Smrg      return FALSE;
5143bfa90b6Smrg   }
5153bfa90b6Smrg}
5163bfa90b6Smrg#endif
5173bfa90b6Smrg
5183bfa90b6Smrg
5193bfa90b6Smrg_X_EXPORT DriverRec vmware = {
5203bfa90b6Smrg    VMWARE_DRIVER_VERSION,
52125dbecb6Smrg    vmware_driver_name,
5223bfa90b6Smrg    VMWAREIdentify,
5233bfa90b6Smrg#if XSERVER_LIBPCIACCESS
5243bfa90b6Smrg    NULL,
5253bfa90b6Smrg#else
5263bfa90b6Smrg    VMWAREProbe,
5273bfa90b6Smrg#endif
5283bfa90b6Smrg    VMWAREAvailableOptions,
5293bfa90b6Smrg    NULL,
5303bfa90b6Smrg    0,
5313bfa90b6Smrg#if VMWARE_DRIVER_FUNC
5323bfa90b6Smrg    VMWareDriverFunc,
5333bfa90b6Smrg#endif
534591e32d7Ssnj#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 4
5353bfa90b6Smrg#if XSERVER_LIBPCIACCESS
5363bfa90b6Smrg    VMwareDeviceMatch,
5373bfa90b6Smrg    VMwarePciProbe,
538591e32d7Ssnj#else
539591e32d7Ssnj    NULL,
540591e32d7Ssnj    NULL,
541591e32d7Ssnj#endif
542591e32d7Ssnj#endif
543591e32d7Ssnj#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 13
544591e32d7Ssnj#ifdef XSERVER_PLATFORM_BUS
545591e32d7Ssnj    VMwarePlatformProbe,
546591e32d7Ssnj#else
547591e32d7Ssnj    NULL,
548591e32d7Ssnj#endif
5493bfa90b6Smrg#endif
5503bfa90b6Smrg};
5513bfa90b6Smrg
5523bfa90b6Smrg
5533bfa90b6Smrg#ifdef XFree86LOADER
5543bfa90b6Smrgstatic MODULESETUPPROTO(vmwareSetup);
5553bfa90b6Smrg
5563bfa90b6Smrg_X_EXPORT XF86ModuleData vmwareModuleData = {
5573bfa90b6Smrg    &vmwareVersRec,
5583bfa90b6Smrg    vmwareSetup,
5593bfa90b6Smrg    NULL
5603bfa90b6Smrg};
5613bfa90b6Smrg
5623bfa90b6Smrgstatic pointer
5633bfa90b6SmrgvmwareSetup(pointer module, pointer opts, int *errmaj, int *errmin)
5643bfa90b6Smrg{
5653bfa90b6Smrg    static Bool setupDone = FALSE;
5663bfa90b6Smrg
5673bfa90b6Smrg    if (!setupDone) {
5683bfa90b6Smrg        setupDone = TRUE;
5693bfa90b6Smrg
5703bfa90b6Smrg        xf86AddDriver(&vmware, module, VMWARE_DRIVER_FUNC);
5713bfa90b6Smrg
5723bfa90b6Smrg        VMWARERefSymLists();
5733bfa90b6Smrg
5743bfa90b6Smrg        return (pointer)1;
5753bfa90b6Smrg    }
5763bfa90b6Smrg    if (errmaj) {
5773bfa90b6Smrg        *errmaj = LDR_ONCEONLY;
5783bfa90b6Smrg    }
5793bfa90b6Smrg    return NULL;
5803bfa90b6Smrg}
5813bfa90b6Smrg#endif	/* XFree86LOADER */
582