vmware_bootstrap.c revision 22f7e8e5
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
533bfa90b6Smrg#ifdef HaveDriverFuncs
543bfa90b6Smrg#define VMWARE_DRIVER_FUNC HaveDriverFuncs
553bfa90b6Smrg#else
563bfa90b6Smrg#define VMWARE_DRIVER_FUNC 0
573bfa90b6Smrg#endif
583bfa90b6Smrg
593bfa90b6Smrg/*
603bfa90b6Smrg * So that the file compiles unmodified when dropped in to a < 6.9 source tree.
613bfa90b6Smrg */
623bfa90b6Smrg#ifndef _X_EXPORT
633bfa90b6Smrg#define _X_EXPORT
643bfa90b6Smrg#endif
653bfa90b6Smrg/*
663bfa90b6Smrg * So that the file compiles unmodified when dropped into an xfree source tree.
673bfa90b6Smrg */
683bfa90b6Smrg#ifndef XORG_VERSION_CURRENT
693bfa90b6Smrg#define XORG_VERSION_CURRENT XF86_VERSION_CURRENT
703bfa90b6Smrg#endif
713bfa90b6Smrg
723bfa90b6Smrg/*
733bfa90b6Smrg * This is the only way I know to turn a #define of an integer constant into
743bfa90b6Smrg * a constant string.
753bfa90b6Smrg */
763bfa90b6Smrg#define VMW_INNERSTRINGIFY(s) #s
773bfa90b6Smrg#define VMW_STRING(str) VMW_INNERSTRINGIFY(str)
783bfa90b6Smrg
793bfa90b6Smrg#define VMWARE_NAME "vmware"
803bfa90b6Smrg#define VMWARE_DRIVER_NAME "vmware"
813bfa90b6Smrg#define VMWARE_DRIVER_VERSION \
823bfa90b6Smrg   (PACKAGE_VERSION_MAJOR * 65536 + PACKAGE_VERSION_MINOR * 256 + PACKAGE_VERSION_PATCHLEVEL)
833bfa90b6Smrg#define VMWARE_DRIVER_VERSION_STRING \
843bfa90b6Smrg    VMW_STRING(PACKAGE_VERSION_MAJOR) "." VMW_STRING(PACKAGE_VERSION_MINOR) \
853bfa90b6Smrg    "." VMW_STRING(PACKAGE_VERSION_PATCHLEVEL)
863bfa90b6Smrg
873bfa90b6Smrgstatic const char VMWAREBuildStr[] = "VMware Guest X Server "
883bfa90b6Smrg    VMWARE_DRIVER_VERSION_STRING " - build=$Name:  $\n";
893bfa90b6Smrg
903bfa90b6Smrg/*
913bfa90b6Smrg * Standard four digit version string expected by VMware Tools installer.
923bfa90b6Smrg * As the driver's version is only  {major, minor, patchlevel},
933bfa90b6Smrg * The fourth digit may describe the commit number relative to the
943bfa90b6Smrg * last version tag as output from `git describe`
953bfa90b6Smrg */
963bfa90b6Smrg
973bfa90b6Smrg#ifdef __GNUC__
983bfa90b6Smrg#ifdef VMW_SUBPATCH
993bfa90b6Smrgconst char vmware_drv_modinfo[]
1003bfa90b6Smrg__attribute__((section(".modinfo"),unused)) =
1013bfa90b6Smrg  "version=" VMWARE_DRIVER_VERSION_STRING "." VMW_STRING(VMW_SUBPATCH);
1023bfa90b6Smrg#else
1033bfa90b6Smrgconst char vmware_drv_modinfo[]
1043bfa90b6Smrg__attribute__((section(".modinfo"),unused)) =
1053bfa90b6Smrg  "version=" VMWARE_DRIVER_VERSION_STRING ".0";
1063bfa90b6Smrg#endif /*VMW_SUBPATCH*/
1073bfa90b6Smrg#endif
1083bfa90b6Smrg
1093bfa90b6Smrg#ifndef XSERVER_LIBPCIACCESS
1103bfa90b6Smrgstatic resRange vmwareLegacyRes[] = {
1113bfa90b6Smrg    { ResExcIoBlock, SVGA_LEGACY_BASE_PORT,
1123bfa90b6Smrg      SVGA_LEGACY_BASE_PORT + SVGA_NUM_PORTS*sizeof(uint32)},
1133bfa90b6Smrg    _VGA_EXCLUSIVE, _END
1143bfa90b6Smrg};
1153bfa90b6Smrg#else
1163bfa90b6Smrg#define vmwareLegacyRes NULL
1173bfa90b6Smrg#endif
1183bfa90b6Smrg
1193bfa90b6Smrg#if XSERVER_LIBPCIACCESS
1203bfa90b6Smrg#define VENDOR_ID(p)      (p)->vendor_id
1213bfa90b6Smrg#define DEVICE_ID(p)      (p)->device_id
1223bfa90b6Smrg#define SUBVENDOR_ID(p)   (p)->subvendor_id
1233bfa90b6Smrg#define SUBSYS_ID(p)      (p)->subdevice_id
1243bfa90b6Smrg#define CHIP_REVISION(p)  (p)->revision
1253bfa90b6Smrg#else
1263bfa90b6Smrg#define VENDOR_ID(p)      (p)->vendor
1273bfa90b6Smrg#define DEVICE_ID(p)      (p)->chipType
1283bfa90b6Smrg#define SUBVENDOR_ID(p)   (p)->subsysVendor
1293bfa90b6Smrg#define SUBSYS_ID(p)      (p)->subsysCard
1303bfa90b6Smrg#define CHIP_REVISION(p)  (p)->chipRev
1313bfa90b6Smrg#endif
1323bfa90b6Smrg
1333bfa90b6Smrg#if XSERVER_LIBPCIACCESS
1343bfa90b6Smrg
1353bfa90b6Smrg#define VMWARE_DEVICE_MATCH(d, i) \
1363bfa90b6Smrg    {PCI_VENDOR_ID_VMWARE, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
1373bfa90b6Smrg
1383bfa90b6Smrgstatic const struct pci_id_match VMwareDeviceMatch[] = {
1393bfa90b6Smrg    VMWARE_DEVICE_MATCH (PCI_DEVICE_ID_VMWARE_SVGA2, 0 ),
1403bfa90b6Smrg    VMWARE_DEVICE_MATCH (PCI_DEVICE_ID_VMWARE_SVGA, 0 ),
1413bfa90b6Smrg    { 0, 0, 0 },
1423bfa90b6Smrg};
1433bfa90b6Smrg#endif
1443bfa90b6Smrg
1453bfa90b6Smrg/*
1463bfa90b6Smrg * Currently, even the PCI obedient 0405 chip still only obeys IOSE and
1473bfa90b6Smrg * MEMSE for the SVGA resources.  Thus, RES_EXCLUSIVE_VGA is required.
1483bfa90b6Smrg *
1493bfa90b6Smrg * The 0710 chip also uses hardcoded IO ports that aren't disablable.
1503bfa90b6Smrg */
1513bfa90b6Smrg
1523bfa90b6Smrgstatic PciChipsets VMWAREPciChipsets[] = {
1533bfa90b6Smrg    { PCI_DEVICE_ID_VMWARE_SVGA2, PCI_DEVICE_ID_VMWARE_SVGA2, RES_EXCLUSIVE_VGA },
1543bfa90b6Smrg    { PCI_DEVICE_ID_VMWARE_SVGA, PCI_DEVICE_ID_VMWARE_SVGA, vmwareLegacyRes },
1553bfa90b6Smrg    { -1,		       -1,		    RES_UNDEFINED }
1563bfa90b6Smrg};
1573bfa90b6Smrg
1583bfa90b6Smrgstatic SymTabRec VMWAREChipsets[] = {
1593bfa90b6Smrg    { PCI_DEVICE_ID_VMWARE_SVGA2, "vmware0405" },
1603bfa90b6Smrg    { PCI_DEVICE_ID_VMWARE_SVGA, "vmware0710" },
1613bfa90b6Smrg    { -1,                  NULL }
1623bfa90b6Smrg};
1633bfa90b6Smrg
1643bfa90b6Smrg#ifdef XFree86LOADER
1653bfa90b6Smrgstatic XF86ModuleVersionInfo vmwareVersRec = {
1663bfa90b6Smrg    VMWARE_DRIVER_NAME,
1673bfa90b6Smrg    MODULEVENDORSTRING,
1683bfa90b6Smrg    MODINFOSTRING1,
1693bfa90b6Smrg    MODINFOSTRING2,
1703bfa90b6Smrg    XORG_VERSION_CURRENT,
1713bfa90b6Smrg    PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
1723bfa90b6Smrg    ABI_CLASS_VIDEODRV,
1733bfa90b6Smrg    ABI_VIDEODRV_VERSION,
1743bfa90b6Smrg    MOD_CLASS_VIDEODRV,
1753bfa90b6Smrg    { 0, 0, 0, 0}
1763bfa90b6Smrg};
1773bfa90b6Smrg#endif	/* XFree86LOADER */
1783bfa90b6Smrg
1793bfa90b6Smrgstatic const OptionInfoRec VMWAREOptions[] = {
1803bfa90b6Smrg    { OPTION_HW_CURSOR, "HWcursor",     OPTV_BOOLEAN,   {0},    FALSE },
1813bfa90b6Smrg    { OPTION_XINERAMA,  "Xinerama",     OPTV_BOOLEAN,   {0},    FALSE },
1823bfa90b6Smrg    { OPTION_STATIC_XINERAMA, "StaticXinerama", OPTV_STRING, {0}, FALSE },
1833bfa90b6Smrg    { OPTION_GUI_LAYOUT, "GuiLayout", OPTV_STRING, {0}, FALSE },
1843bfa90b6Smrg    { OPTION_DEFAULT_MODE, "AddDefaultMode", OPTV_BOOLEAN,   {0},    FALSE },
1853bfa90b6Smrg    { OPTION_RENDER_ACCEL, "RenderAccel", OPTV_BOOLEAN, {0}, FALSE},
1863bfa90b6Smrg    { OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE},
1873bfa90b6Smrg    { OPTION_DIRECT_PRESENTS, "DirectPresents", OPTV_BOOLEAN, {0}, FALSE},
1883bfa90b6Smrg    { OPTION_HW_PRESENTS, "HWPresents", OPTV_BOOLEAN, {0}, FALSE},
1893bfa90b6Smrg    { OPTION_RENDERCHECK, "RenderCheck", OPTV_BOOLEAN, {0}, FALSE},
1903bfa90b6Smrg    { -1,               NULL,           OPTV_NONE,      {0},    FALSE }
1913bfa90b6Smrg};
1923bfa90b6Smrg
1933bfa90b6SmrgOptionInfoPtr VMWARECopyOptions(void)
1943bfa90b6Smrg{
1953bfa90b6Smrg    OptionInfoPtr options;
1963bfa90b6Smrg    if (!(options = malloc(sizeof(VMWAREOptions))))
1973bfa90b6Smrg        return NULL;
1983bfa90b6Smrg
1993bfa90b6Smrg    memcpy(options, VMWAREOptions, sizeof(VMWAREOptions));
2003bfa90b6Smrg    return options;
2013bfa90b6Smrg}
2023bfa90b6Smrg
20322f7e8e5Smrg/*
20422f7e8e5Smrg * Also in vmwgfx_hosted.h, which we don't include.
20522f7e8e5Smrg */
20622f7e8e5Smrgvoid *
20722f7e8e5Smrgvmwgfx_hosted_detect(void);
20822f7e8e5Smrg
2093bfa90b6Smrgstatic Bool
2103bfa90b6SmrgVMwarePreinitStub(ScrnInfoPtr pScrn, int flags)
2113bfa90b6Smrg{
2123bfa90b6Smrg#if XSERVER_LIBPCIACCESS
2133bfa90b6Smrg    struct pci_device *pciInfo;
2143bfa90b6Smrg#else
2153bfa90b6Smrg    pciVideoPtr pciInfo;
2163bfa90b6Smrg#endif /* XSERVER_LIBPCIACCESS */
2173bfa90b6Smrg    EntityInfoPtr pEnt;
2183bfa90b6Smrg
2193bfa90b6Smrg    pScrn->PreInit = pScrn->driverPrivate;
2203bfa90b6Smrg
2213bfa90b6Smrg#ifdef BUILD_VMWGFX
2223bfa90b6Smrg    pScrn->driverPrivate = NULL;
2233bfa90b6Smrg
2243bfa90b6Smrg    /*
2253bfa90b6Smrg     * Try vmwgfx path.
2263bfa90b6Smrg     */
2273bfa90b6Smrg    if ((*pScrn->PreInit)(pScrn, flags))
2283bfa90b6Smrg	return TRUE;
2293bfa90b6Smrg
23022f7e8e5Smrg    /*
23122f7e8e5Smrg     * Can't run legacy hosted
23222f7e8e5Smrg     */
23322f7e8e5Smrg    if (vmwgfx_hosted_detect())
23422f7e8e5Smrg	return FALSE;
2353bfa90b6Smrg#else
2363bfa90b6Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2373bfa90b6Smrg	       "Driver was compiled without KMS- and 3D support.\n");
2383bfa90b6Smrg#endif /* defined(BUILD_VMWGFX) */
2393bfa90b6Smrg    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2403bfa90b6Smrg	       "Disabling 3D support.\n");
2413bfa90b6Smrg    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2423bfa90b6Smrg	       "Disabling Render Acceleration.\n");
2433bfa90b6Smrg    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2443bfa90b6Smrg	       "Disabling RandR12+ support.\n");
2453bfa90b6Smrg
2463bfa90b6Smrg    pScrn->driverPrivate = NULL;
2473bfa90b6Smrg    vmwlegacy_hookup(pScrn);
2483bfa90b6Smrg
2493bfa90b6Smrg    pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
2503bfa90b6Smrg    if (pEnt->location.type != BUS_PCI)
2513bfa90b6Smrg        return FALSE;
2523bfa90b6Smrg
2533bfa90b6Smrg    pciInfo = xf86GetPciInfoForEntity(pEnt->index);
2543bfa90b6Smrg    if (pciInfo == NULL)
2553bfa90b6Smrg        return FALSE;
2563bfa90b6Smrg
2573bfa90b6Smrg    pScrn->chipset = (char*)xf86TokenToString(VMWAREChipsets,
2583bfa90b6Smrg					      DEVICE_ID(pciInfo));
2593bfa90b6Smrg
2603bfa90b6Smrg    return (*pScrn->PreInit)(pScrn, flags);
2613bfa90b6Smrg};
2623bfa90b6Smrg
2633bfa90b6Smrg#if XSERVER_LIBPCIACCESS
2643bfa90b6Smrgstatic Bool
2653bfa90b6SmrgVMwarePciProbe (DriverPtr           drv,
2663bfa90b6Smrg                int                 entity_num,
2673bfa90b6Smrg                struct pci_device   *device,
2683bfa90b6Smrg                intptr_t            match_data)
2693bfa90b6Smrg{
2703bfa90b6Smrg    ScrnInfoPtr     scrn = NULL;
2713bfa90b6Smrg
2723bfa90b6Smrg    scrn = xf86ConfigPciEntity(scrn, 0, entity_num, VMWAREPciChipsets,
2733bfa90b6Smrg                               NULL, NULL, NULL, NULL, NULL);
2743bfa90b6Smrg    if (scrn != NULL) {
2753bfa90b6Smrg        scrn->driverVersion = VMWARE_DRIVER_VERSION;
2763bfa90b6Smrg        scrn->driverName = VMWARE_DRIVER_NAME;
2773bfa90b6Smrg        scrn->name = VMWARE_NAME;
2783bfa90b6Smrg        scrn->Probe = NULL;
2793bfa90b6Smrg    }
2803bfa90b6Smrg
2813bfa90b6Smrg    switch (DEVICE_ID(device)) {
2823bfa90b6Smrg    case PCI_DEVICE_ID_VMWARE_SVGA2:
2833bfa90b6Smrg    case PCI_DEVICE_ID_VMWARE_SVGA:
2843bfa90b6Smrg        xf86MsgVerb(X_INFO, 4, "VMwarePciProbe: Valid device\n");
2853bfa90b6Smrg
2863bfa90b6Smrg#ifdef BUILD_VMWGFX
2873bfa90b6Smrg	vmwgfx_hookup(scrn);
2883bfa90b6Smrg#else
2893bfa90b6Smrg	vmwlegacy_hookup(scrn);
2903bfa90b6Smrg#endif /* defined(BUILD_VMWGFX) */
2913bfa90b6Smrg
2923bfa90b6Smrg	scrn->driverPrivate = scrn->PreInit;
2933bfa90b6Smrg	scrn->PreInit = VMwarePreinitStub;
2943bfa90b6Smrg        break;
2953bfa90b6Smrg    default:
2963bfa90b6Smrg        xf86MsgVerb(X_INFO, 4, "VMwarePciProbe: Unknown device\n");
2973bfa90b6Smrg    }
2983bfa90b6Smrg    return scrn != NULL;
2993bfa90b6Smrg}
3003bfa90b6Smrg#else
3013bfa90b6Smrg
3023bfa90b6Smrg/*
3033bfa90b6Smrg *----------------------------------------------------------------------
3043bfa90b6Smrg *
3053bfa90b6Smrg *  RewriteTagString --
3063bfa90b6Smrg *
3073bfa90b6Smrg *      Rewrites the given string, removing the $Name:  $, and
3083bfa90b6Smrg *      replacing it with the contents.  The output string must
3093bfa90b6Smrg *      have enough room, or else.
3103bfa90b6Smrg *
3113bfa90b6Smrg * Results:
3123bfa90b6Smrg *
3133bfa90b6Smrg *      Output string updated.
3143bfa90b6Smrg *
3153bfa90b6Smrg * Side effects:
3163bfa90b6Smrg *      None.
3173bfa90b6Smrg *
3183bfa90b6Smrg *----------------------------------------------------------------------
3193bfa90b6Smrg */
3203bfa90b6Smrg
3213bfa90b6Smrgstatic void
3223bfa90b6SmrgRewriteTagString(const char *istr, char *ostr, int osize)
3233bfa90b6Smrg{
3243bfa90b6Smrg    int chr;
3253bfa90b6Smrg    Bool inTag = FALSE;
3263bfa90b6Smrg    char *op = ostr;
3273bfa90b6Smrg
3283bfa90b6Smrg    do {
3293bfa90b6Smrg	chr = *istr++;
3303bfa90b6Smrg	if (chr == '$') {
3313bfa90b6Smrg	    if (inTag) {
3323bfa90b6Smrg		inTag = FALSE;
3333bfa90b6Smrg		for (; op > ostr && op[-1] == ' '; op--) {
3343bfa90b6Smrg		}
3353bfa90b6Smrg		continue;
3363bfa90b6Smrg	    }
3373bfa90b6Smrg	    if (strncmp(istr, "Name:", 5) == 0) {
3383bfa90b6Smrg		istr += 5;
3393bfa90b6Smrg		istr += strspn(istr, " ");
3403bfa90b6Smrg		inTag = TRUE;
3413bfa90b6Smrg		continue;
3423bfa90b6Smrg	    }
3433bfa90b6Smrg	}
3443bfa90b6Smrg	*op++ = chr;
3453bfa90b6Smrg    } while (chr);
3463bfa90b6Smrg}
3473bfa90b6Smrg
3483bfa90b6Smrgstatic Bool
3493bfa90b6SmrgVMWAREProbe(DriverPtr drv, int flags)
3503bfa90b6Smrg{
3513bfa90b6Smrg    int numDevSections, numUsed;
3523bfa90b6Smrg    GDevPtr *devSections;
3533bfa90b6Smrg    int *usedChips;
3543bfa90b6Smrg    int i;
3553bfa90b6Smrg    Bool foundScreen = FALSE;
3563bfa90b6Smrg    char buildString[sizeof(VMWAREBuildStr)];
3573bfa90b6Smrg
3583bfa90b6Smrg    RewriteTagString(VMWAREBuildStr, buildString, sizeof(VMWAREBuildStr));
3593bfa90b6Smrg    xf86MsgVerb(X_PROBED, 4, "%s", buildString);
3603bfa90b6Smrg
3613bfa90b6Smrg    numDevSections = xf86MatchDevice(VMWARE_DRIVER_NAME, &devSections);
3623bfa90b6Smrg    if (numDevSections <= 0) {
3633bfa90b6Smrg#ifdef DEBUG
3643bfa90b6Smrg        xf86MsgVerb(X_ERROR, 0, "No vmware driver section\n");
3653bfa90b6Smrg#endif
3663bfa90b6Smrg        return FALSE;
3673bfa90b6Smrg    }
3683bfa90b6Smrg    if (xf86GetPciVideoInfo()) {
3693bfa90b6Smrg        VmwareLog(("Some PCI Video Info Exists\n"));
3703bfa90b6Smrg        numUsed = xf86MatchPciInstances(VMWARE_NAME, PCI_VENDOR_ID_VMWARE,
3713bfa90b6Smrg                                        VMWAREChipsets, VMWAREPciChipsets, devSections,
3723bfa90b6Smrg                                        numDevSections, drv, &usedChips);
3733bfa90b6Smrg        free(devSections);
3743bfa90b6Smrg        if (numUsed <= 0)
3753bfa90b6Smrg            return FALSE;
3763bfa90b6Smrg        if (flags & PROBE_DETECT)
3773bfa90b6Smrg            foundScreen = TRUE;
3783bfa90b6Smrg        else
3793bfa90b6Smrg            for (i = 0; i < numUsed; i++) {
3803bfa90b6Smrg                ScrnInfoPtr pScrn = NULL;
3813bfa90b6Smrg
3823bfa90b6Smrg                VmwareLog(("Even some VMware SVGA PCI instances exists\n"));
3833bfa90b6Smrg                pScrn = xf86ConfigPciEntity(pScrn, flags, usedChips[i],
3843bfa90b6Smrg                                            VMWAREPciChipsets, NULL, NULL, NULL,
3853bfa90b6Smrg                                            NULL, NULL);
3863bfa90b6Smrg                if (pScrn) {
3873bfa90b6Smrg                    VmwareLog(("And even configuration suceeded\n"));
3883bfa90b6Smrg                    pScrn->driverVersion = VMWARE_DRIVER_VERSION;
3893bfa90b6Smrg                    pScrn->driverName = VMWARE_DRIVER_NAME;
3903bfa90b6Smrg                    pScrn->name = VMWARE_NAME;
3913bfa90b6Smrg                    pScrn->Probe = VMWAREProbe;
3923bfa90b6Smrg
3933bfa90b6Smrg#ifdef BUILD_VMWGFX
3943bfa90b6Smrg		    vmwgfx_hookup(pScrn);
3953bfa90b6Smrg#else
3963bfa90b6Smrg		    vmwlegacy_hookup(pScrn);
3973bfa90b6Smrg#endif /* defined(BUILD_VMWGFX) */
3983bfa90b6Smrg
3993bfa90b6Smrg		    pScrn->driverPrivate = pScrn->PreInit;
4003bfa90b6Smrg		    pScrn->PreInit = VMwarePreinitStub;
4013bfa90b6Smrg                    foundScreen = TRUE;
4023bfa90b6Smrg                }
4033bfa90b6Smrg            }
4043bfa90b6Smrg        free(usedChips);
4053bfa90b6Smrg    }
4063bfa90b6Smrg    return foundScreen;
4073bfa90b6Smrg}
4083bfa90b6Smrg#endif
4093bfa90b6Smrg
4103bfa90b6Smrgstatic void
4113bfa90b6SmrgVMWAREIdentify(int flags)
4123bfa90b6Smrg{
4133bfa90b6Smrg    xf86PrintChipsets(VMWARE_NAME, "driver for VMware SVGA", VMWAREChipsets);
4143bfa90b6Smrg}
4153bfa90b6Smrg
4163bfa90b6Smrgstatic const OptionInfoRec *
4173bfa90b6SmrgVMWAREAvailableOptions(int chipid, int busid)
4183bfa90b6Smrg{
4193bfa90b6Smrg    return VMWAREOptions;
4203bfa90b6Smrg}
4213bfa90b6Smrg
4223bfa90b6Smrg#if VMWARE_DRIVER_FUNC
4233bfa90b6Smrgstatic Bool
4243bfa90b6SmrgVMWareDriverFunc(ScrnInfoPtr pScrn,
4253bfa90b6Smrg                 xorgDriverFuncOp op,
4263bfa90b6Smrg                 pointer data)
4273bfa90b6Smrg{
42822f7e8e5Smrg   uint32_t *flag;
4293bfa90b6Smrg   xorgRRModeMM *modemm;
4303bfa90b6Smrg
4313bfa90b6Smrg   switch (op) {
4323bfa90b6Smrg   case GET_REQUIRED_HW_INTERFACES:
43322f7e8e5Smrg      flag = (uint32_t *)data;
4343bfa90b6Smrg
4353bfa90b6Smrg      if (flag) {
43622f7e8e5Smrg#ifdef BUILD_VMWGFX
43722f7e8e5Smrg	  vmwgfx_modify_flags(flag);
43822f7e8e5Smrg#else
4393bfa90b6Smrg         *flag = HW_IO | HW_MMIO;
44022f7e8e5Smrg#endif
4413bfa90b6Smrg      }
4423bfa90b6Smrg      return TRUE;
4433bfa90b6Smrg   case RR_GET_MODE_MM:
4443bfa90b6Smrg      modemm = (xorgRRModeMM *)data;
4453bfa90b6Smrg
4463bfa90b6Smrg      /*
4473bfa90b6Smrg       * Because changing the resolution of the guest is usually changing the size
4483bfa90b6Smrg       * of a window on the host desktop, the real physical DPI will not change. To
4493bfa90b6Smrg       * keep the guest in sync, we scale the 'physical' screen dimensions to
4503bfa90b6Smrg       * keep the DPI constant.
4513bfa90b6Smrg       */
4523bfa90b6Smrg      if (modemm && modemm->mode) {
4533bfa90b6Smrg	  modemm->mmWidth = (modemm->mode->HDisplay * VMWARE_INCHTOMM +
4543bfa90b6Smrg			     pScrn->xDpi / 2)  / pScrn->xDpi;
4553bfa90b6Smrg	  modemm->mmHeight = (modemm->mode->VDisplay * VMWARE_INCHTOMM +
4563bfa90b6Smrg			      pScrn->yDpi / 2) / pScrn->yDpi;
4573bfa90b6Smrg      }
4583bfa90b6Smrg      return TRUE;
4593bfa90b6Smrg   default:
4603bfa90b6Smrg      return FALSE;
4613bfa90b6Smrg   }
4623bfa90b6Smrg}
4633bfa90b6Smrg#endif
4643bfa90b6Smrg
4653bfa90b6Smrg
4663bfa90b6Smrg_X_EXPORT DriverRec vmware = {
4673bfa90b6Smrg    VMWARE_DRIVER_VERSION,
4683bfa90b6Smrg    VMWARE_DRIVER_NAME,
4693bfa90b6Smrg    VMWAREIdentify,
4703bfa90b6Smrg#if XSERVER_LIBPCIACCESS
4713bfa90b6Smrg    NULL,
4723bfa90b6Smrg#else
4733bfa90b6Smrg    VMWAREProbe,
4743bfa90b6Smrg#endif
4753bfa90b6Smrg    VMWAREAvailableOptions,
4763bfa90b6Smrg    NULL,
4773bfa90b6Smrg    0,
4783bfa90b6Smrg#if VMWARE_DRIVER_FUNC
4793bfa90b6Smrg    VMWareDriverFunc,
4803bfa90b6Smrg#endif
4813bfa90b6Smrg#if XSERVER_LIBPCIACCESS
4823bfa90b6Smrg    VMwareDeviceMatch,
4833bfa90b6Smrg    VMwarePciProbe,
4843bfa90b6Smrg#endif
4853bfa90b6Smrg};
4863bfa90b6Smrg
4873bfa90b6Smrg
4883bfa90b6Smrg#ifdef XFree86LOADER
4893bfa90b6Smrgstatic MODULESETUPPROTO(vmwareSetup);
4903bfa90b6Smrg
4913bfa90b6Smrg_X_EXPORT XF86ModuleData vmwareModuleData = {
4923bfa90b6Smrg    &vmwareVersRec,
4933bfa90b6Smrg    vmwareSetup,
4943bfa90b6Smrg    NULL
4953bfa90b6Smrg};
4963bfa90b6Smrg
4973bfa90b6Smrgstatic pointer
4983bfa90b6SmrgvmwareSetup(pointer module, pointer opts, int *errmaj, int *errmin)
4993bfa90b6Smrg{
5003bfa90b6Smrg    static Bool setupDone = FALSE;
5013bfa90b6Smrg
5023bfa90b6Smrg    if (!setupDone) {
5033bfa90b6Smrg        setupDone = TRUE;
5043bfa90b6Smrg
5053bfa90b6Smrg        xf86AddDriver(&vmware, module, VMWARE_DRIVER_FUNC);
5063bfa90b6Smrg
5073bfa90b6Smrg        VMWARERefSymLists();
5083bfa90b6Smrg
5093bfa90b6Smrg        return (pointer)1;
5103bfa90b6Smrg    }
5113bfa90b6Smrg    if (errmaj) {
5123bfa90b6Smrg        *errmaj = LDR_ONCEONLY;
5133bfa90b6Smrg    }
5143bfa90b6Smrg    return NULL;
5153bfa90b6Smrg}
5163bfa90b6Smrg#endif	/* XFree86LOADER */
517