Edit

IABSD.fr/xenocara/driver/xf86-video-vmware/src/vmware_bootstrap.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2022-06-28 10:09:44
    Hash : eaba5413
    Message : Update to xf86-video-vmware 13.3.0

  • driver/xf86-video-vmware/src/vmware_bootstrap.c
  • /*
     * 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 "xf86Pci.h"		/* pci */
    #include "vm_device_version.h"
    #include "vmware_bootstrap.h"
    #include <stdint.h>
    
    #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
    #include "xf86Resources.h"
    #endif
    
    #ifndef XSERVER_LIBPCIACCESS
    #include "vm_basic_types.h"
    #include "svga_reg.h"
    #endif
    
    #ifndef HAVE_XORG_SERVER_1_5_0
    #include <xf86_ansic.h>
    #include <xf86_libc.h>
    #endif
    
    #ifdef XSERVER_PLATFORM_BUS
    #include "xf86platformBus.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
    
    /*
     * 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_DRIVER_NAME "vmware"
    #define VMWARE_NAME "vmware"
    
    static char vmware_driver_name[] = VMWARE_DRIVER_NAME;
    
    #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)
    
    #if !XSERVER_LIBPCIACCESS
    static const char VMWAREBuildStr[] = "VMware Guest X Server "
        VMWARE_DRIVER_VERSION_STRING " - build=$Name:  $\n";
    #else
    static char vmware_name[] = VMWARE_NAME;
    #endif
    
    /*
     * 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_ID_VMWARE, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
    
    static const struct pci_id_match VMwareDeviceMatch[] = {
        VMWARE_DEVICE_MATCH (PCI_DEVICE_ID_VMWARE_SVGA2, 0 ),
        VMWARE_DEVICE_MATCH (PCI_DEVICE_ID_VMWARE_SVGA, 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_DEVICE_ID_VMWARE_SVGA2, PCI_DEVICE_ID_VMWARE_SVGA2, RES_EXCLUSIVE_VGA },
        { PCI_DEVICE_ID_VMWARE_SVGA, PCI_DEVICE_ID_VMWARE_SVGA, vmwareLegacyRes },
        { -1,		       -1,		    RES_UNDEFINED }
    };
    
    static SymTabRec VMWAREChipsets[] = {
        { PCI_DEVICE_ID_VMWARE_SVGA2, "vmware0405" },
        { PCI_DEVICE_ID_VMWARE_SVGA, "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;
    }
    
    /*
     * Also in vmwgfx_hosted.h, which we don't include.
     */
    void *
    vmwgfx_hosted_detect(void);
    
    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;
    
        /*
         * Can't run legacy hosted
         */
        if (vmwgfx_hosted_detect())
    	return FALSE;
    #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]);
        pciInfo = xf86GetPciInfoForEntity(pEnt->index);
        if (pciInfo == NULL)
            return FALSE;
    
        pScrn->chipset = xstrdup(xf86TokenToString(VMWAREChipsets,
    					       DEVICE_ID(pciInfo)));
        if (pScrn->chipset == NULL)
    	return FALSE;
    
        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;
    
        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;
        }
    
        switch (DEVICE_ID(device)) {
        case PCI_DEVICE_ID_VMWARE_SVGA2:
        case PCI_DEVICE_ID_VMWARE_SVGA:
            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
    
    /*
     *----------------------------------------------------------------------
     *
     *  RewriteTagString --
     *
     *      Rewrites the given string, removing the $Name:  $, and
     *      replacing it with the contents.  The output string must
     *      have enough room, or else.
     *
     * Results:
     *
     *      Output string updated.
     *
     * Side effects:
     *      None.
     *
     *----------------------------------------------------------------------
     */
    
    static void
    RewriteTagString(const char *istr, char *ostr, int osize)
    {
        int chr;
        Bool inTag = FALSE;
        char *op = ostr;
    
        do {
    	chr = *istr++;
    	if (chr == '$') {
    	    if (inTag) {
    		inTag = FALSE;
    		for (; op > ostr && op[-1] == ' '; op--) {
    		}
    		continue;
    	    }
    	    if (strncmp(istr, "Name:", 5) == 0) {
    		istr += 5;
    		istr += strspn(istr, " ");
    		inTag = TRUE;
    		continue;
    	    }
    	}
    	*op++ = chr;
        } while (chr);
    }
    
    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_ID_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;
    
    #ifdef BUILD_VMWGFX
    		    vmwgfx_hookup(pScrn);
    #else
    		    vmwlegacy_hookup(pScrn);
    #endif /* defined(BUILD_VMWGFX) */
    
    		    pScrn->driverPrivate = pScrn->PreInit;
    		    pScrn->PreInit = VMwarePreinitStub;
                        foundScreen = TRUE;
                    }
                }
            free(usedChips);
        }
        return foundScreen;
    }
    #endif
    
    #ifdef XSERVER_PLATFORM_BUS
    static Bool
    VMwarePlatformProbe(DriverPtr drv, int entity, int flags,
                        struct xf86_platform_device *dev, intptr_t match_data)
    {
        ScrnInfoPtr pScrn;
        int scrnFlag = 0;
    
        if (!dev->pdev)
            return FALSE;
    
        if (flags & PLATFORM_PROBE_GPU_SCREEN)
            scrnFlag = XF86_ALLOCATE_GPU_SCREEN;
    
        pScrn = xf86AllocateScreen(drv, scrnFlag);
        if (!pScrn)
            return FALSE;
    
        if (xf86IsEntitySharable(entity))
            xf86SetEntityShared(entity);
    
        xf86AddEntityToScreen(pScrn, entity);
    
        pScrn->driverVersion = VMWARE_DRIVER_VERSION;
        pScrn->driverName = VMWARE_DRIVER_NAME;
        pScrn->name = VMWARE_NAME;
        pScrn->Probe = NULL;
    #ifdef BUILD_VMWGFX
        vmwgfx_hookup(pScrn);
    #else
        vmwlegacy_hookup(pScrn);
    #endif
        pScrn->driverPrivate = pScrn->PreInit;
        pScrn->PreInit = VMwarePreinitStub;
    
        return TRUE;
    }
    #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)
    {
       uint32_t *flag;
       xorgRRModeMM *modemm;
    
       switch (op) {
       case GET_REQUIRED_HW_INTERFACES:
          flag = (uint32_t *)data;
    
          if (flag) {
    #ifdef BUILD_VMWGFX
    	  vmwgfx_modify_flags(flag);
    #else
             *flag = HW_IO | HW_MMIO;
    #endif
          }
          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;
    #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 18
       case SUPPORTS_SERVER_FDS:
          return TRUE;
    #endif
       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 GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 4
    #if XSERVER_LIBPCIACCESS
        VMwareDeviceMatch,
        VMwarePciProbe,
    #else
        NULL,
        NULL,
    #endif
    #endif
    #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 13
    #ifdef XSERVER_PLATFORM_BUS
        VMwarePlatformProbe,
    #else
        NULL,
    #endif
    #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);
    
            VMWARERefSymLists();
    
            return (pointer)1;
        }
        if (errmaj) {
            *errmaj = LDR_ONCEONLY;
        }
        return NULL;
    }
    #endif	/* XFree86LOADER */