1 /* **********************************************************
2  * Copyright (C) 1998-2001 VMware, Inc.
3  * All Rights Reserved
4  * **********************************************************/
5 #ifdef VMX86_DEVEL
6 char rcsId_vmware[] =
7     "Id: vmware.c,v 1.11 2001/02/23 02:10:39 yoel Exp $";
8 #endif
9 
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13 
14 /*
15  * TODO: support the vmware linux kernel fb driver (Option "UseFBDev").
16  */
17 
18 #include "xf86.h"
19 #include "xf86_OSproc.h"
20 
21 #include "compiler.h"	/* inb/outb */
22 
23 #include "xf86Pci.h"		/* pci */
24 
25 #include "mipointer.h"		/* sw cursor */
26 #include "micmap.h"		/* mi color map */
27 #include "vgaHW.h"		/* VGA hardware */
28 #include "fb.h"
29 #include "shadowfb.h"           /* ShadowFB wrappers */
30 
31 #include "xf86cmap.h"		/* xf86HandleColormaps */
32 
33 #include "vmware.h"
34 #include "guest_os.h"
35 #include "vm_device_version.h"
36 #include "svga_modes.h"
37 #include "vmware_bootstrap.h"
38 #include "vmware_common.h"
39 #include "common_compat.h"
40 
41 #ifndef HAVE_XORG_SERVER_1_5_0
42 #include <xf86_ansic.h>
43 #include <xf86_libc.h>
44 #endif
45 
46 #if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5)
47 
48 #define xf86LoaderReqSymLists(...) do {} while (0)
49 #define LoaderRefSymLists(...) do {} while (0)
50 
51 #else
52 
53 const char *vgahwSymbols[] = {
54     "vgaHWGetHWRec",
55     "vgaHWGetIOBase",
56     "vgaHWGetIndex",
57     "vgaHWInit",
58     "vgaHWProtect",
59     "vgaHWRestore",
60     "vgaHWSave",
61     "vgaHWSaveScreen",
62     "vgaHWUnlock",
63     NULL
64 };
65 
66 static const char *fbSymbols[] = {
67     "fbCreateDefColormap",
68     "fbPictureInit",
69     "fbScreenInit",
70     NULL
71 };
72 
73 static const char *ramdacSymbols[] = {
74     "xf86CreateCursorInfoRec",
75     "xf86DestroyCursorInfoRec",
76     "xf86InitCursor",
77     NULL
78 };
79 
80 static const char *shadowfbSymbols[] = {
81     "ShadowFBInit2",
82     NULL
83 };
84 #endif
85 
86 /* Table of default modes to always add to the mode list. */
87 
88 typedef struct {
89    int width;
90    int height;
91 } VMWAREDefaultMode;
92 
93 #define VMW_MIN_INITIAL_WIDTH 800
94 #define VMW_MIN_INITIAL_HEIGHT 600
95 
96 #define SVGA_DEFAULT_MODE(width, height) { width, height, },
97 
98 static const VMWAREDefaultMode VMWAREDefaultModes[] = {
99    SVGA_DEFAULT_MODES
100 };
101 
102 #undef SVGA_DEFAULT_MODE
103 
104 static void VMWAREStopFIFO(ScrnInfoPtr pScrn);
105 static void VMWARESave(ScrnInfoPtr pScrn);
106 
107 static Bool
VMWAREGetRec(ScrnInfoPtr pScrn)108 VMWAREGetRec(ScrnInfoPtr pScrn)
109 {
110     if (pScrn->driverPrivate != NULL) {
111         return TRUE;
112     }
113     pScrn->driverPrivate = xnfcalloc(sizeof(VMWARERec), 1);
114     /* FIXME: Initialize driverPrivate... */
115     return TRUE;
116 }
117 
118 static void
VMWAREFreeRec(ScrnInfoPtr pScrn)119 VMWAREFreeRec(ScrnInfoPtr pScrn)
120 {
121     if (pScrn->driverPrivate) {
122         free(pScrn->driverPrivate);
123         pScrn->driverPrivate = NULL;
124     }
125 }
126 
127 CARD32
vmwareReadReg(VMWAREPtr pVMWARE,int rIndex)128 vmwareReadReg(VMWAREPtr pVMWARE, int rIndex)
129 {
130     /*
131      * Block SIGIO for the duration, so we don't get interrupted after the
132      * outl but before the inl by a mouse move (which write to our registers).
133      */
134     int ret;
135 #if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 22)
136     int oldsigio;
137 
138     oldsigio = xf86BlockSIGIO();
139 #else
140     input_lock();
141 #endif
142     outl(pVMWARE->indexReg, rIndex);
143     ret = inl(pVMWARE->valueReg);
144 #if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 22)
145     xf86UnblockSIGIO(oldsigio);
146 #else
147     input_unlock();
148 #endif
149     return ret;
150 }
151 
152 void
vmwareWriteReg(VMWAREPtr pVMWARE,int wIndex,CARD32 value)153 vmwareWriteReg(VMWAREPtr pVMWARE, int wIndex, CARD32 value)
154 {
155     /*
156      * Block SIGIO for the duration, so we don't get interrupted in between
157      * the outls by a mouse move (which write to our registers).
158      */
159 #if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 22)
160     int oldsigio;
161     oldsigio = xf86BlockSIGIO();
162 #else
163     input_lock();
164 #endif
165     outl(pVMWARE->indexReg, wIndex);
166     outl(pVMWARE->valueReg, value);
167 #if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 22)
168     xf86UnblockSIGIO(oldsigio);
169 #else
170     input_unlock();
171 #endif
172 }
173 
174 void
vmwareWriteWordToFIFO(VMWAREPtr pVMWARE,CARD32 value)175 vmwareWriteWordToFIFO(VMWAREPtr pVMWARE, CARD32 value)
176 {
177     volatile CARD32* vmwareFIFO = pVMWARE->vmwareFIFO;
178 
179     /* Need to sync? */
180     if ((vmwareFIFO[SVGA_FIFO_NEXT_CMD] + sizeof(CARD32) == vmwareFIFO[SVGA_FIFO_STOP])
181      || (vmwareFIFO[SVGA_FIFO_NEXT_CMD] == vmwareFIFO[SVGA_FIFO_MAX] - sizeof(CARD32) &&
182 	 vmwareFIFO[SVGA_FIFO_STOP] == vmwareFIFO[SVGA_FIFO_MIN])) {
183         VmwareLog(("Syncing because of full fifo\n"));
184         vmwareWaitForFB(pVMWARE);
185     }
186 
187     vmwareFIFO[vmwareFIFO[SVGA_FIFO_NEXT_CMD] / sizeof(CARD32)] = value;
188 
189     write_mem_barrier();
190 
191     if(vmwareFIFO[SVGA_FIFO_NEXT_CMD] == vmwareFIFO[SVGA_FIFO_MAX] -
192        sizeof(CARD32)) {
193         vmwareFIFO[SVGA_FIFO_NEXT_CMD] = vmwareFIFO[SVGA_FIFO_MIN];
194     } else {
195         vmwareFIFO[SVGA_FIFO_NEXT_CMD] += sizeof(CARD32);
196     }
197 }
198 
199 void
vmwareWaitForFB(VMWAREPtr pVMWARE)200 vmwareWaitForFB(VMWAREPtr pVMWARE)
201 {
202     vmwareWriteReg(pVMWARE, SVGA_REG_SYNC, 1);
203     while (vmwareReadReg(pVMWARE, SVGA_REG_BUSY));
204 }
205 
206 void
vmwareSendSVGACmdUpdate(VMWAREPtr pVMWARE,BoxPtr pBB)207 vmwareSendSVGACmdUpdate(VMWAREPtr pVMWARE, BoxPtr pBB)
208 {
209     vmwareWriteWordToFIFO(pVMWARE, SVGA_CMD_UPDATE);
210     vmwareWriteWordToFIFO(pVMWARE, pBB->x1);
211     vmwareWriteWordToFIFO(pVMWARE, pBB->y1);
212     vmwareWriteWordToFIFO(pVMWARE, pBB->x2 - pBB->x1);
213     vmwareWriteWordToFIFO(pVMWARE, pBB->y2 - pBB->y1);
214 }
215 
216 void
vmwareSendSVGACmdUpdateFullScreen(VMWAREPtr pVMWARE)217 vmwareSendSVGACmdUpdateFullScreen(VMWAREPtr pVMWARE)
218 {
219     BoxRec BB;
220 
221     BB.x1 = 0;
222     BB.y1 = 0;
223     BB.x2 = pVMWARE->ModeReg.svga_reg_width;
224     BB.y2 = pVMWARE->ModeReg.svga_reg_height;
225     vmwareSendSVGACmdUpdate(pVMWARE, &BB);
226 }
227 
228 static CARD32
vmwareCalculateWeight(CARD32 mask)229 vmwareCalculateWeight(CARD32 mask)
230 {
231     CARD32 weight;
232 
233     for (weight = 0; mask; mask >>= 1) {
234         if (mask & 1) {
235             weight++;
236         }
237     }
238     return weight;
239 }
240 
241 /*
242  *-----------------------------------------------------------------------------
243  *
244  * VMXGetVMwareSvgaId --
245  *
246  *    Retrieve the SVGA_ID of the VMware SVGA adapter.
247  *    This function should hide any backward compatibility mess.
248  *
249  * Results:
250  *    The SVGA_ID_* of the present VMware adapter.
251  *
252  * Side effects:
253  *    ins/outs
254  *
255  *-----------------------------------------------------------------------------
256  */
257 
258 static uint32
VMXGetVMwareSvgaId(VMWAREPtr pVMWARE)259 VMXGetVMwareSvgaId(VMWAREPtr pVMWARE)
260 {
261     uint32 vmware_svga_id;
262 
263     /* Any version with any SVGA_ID_* support will initialize SVGA_REG_ID
264      * to SVGA_ID_0 to support versions of this driver with SVGA_ID_0.
265      *
266      * Versions of SVGA_ID_0 ignore writes to the SVGA_REG_ID register.
267      *
268      * Versions of SVGA_ID_1 will allow us to overwrite the content
269      * of the SVGA_REG_ID register only with the values SVGA_ID_0 or SVGA_ID_1.
270      *
271      * Versions of SVGA_ID_2 will allow us to overwrite the content
272      * of the SVGA_REG_ID register only with the values SVGA_ID_0 or SVGA_ID_1
273      * or SVGA_ID_2.
274      */
275 
276     vmwareWriteReg(pVMWARE, SVGA_REG_ID, SVGA_ID_2);
277     vmware_svga_id = vmwareReadReg(pVMWARE, SVGA_REG_ID);
278     if (vmware_svga_id == SVGA_ID_2) {
279         return SVGA_ID_2;
280     }
281 
282     vmwareWriteReg(pVMWARE, SVGA_REG_ID, SVGA_ID_1);
283     vmware_svga_id = vmwareReadReg(pVMWARE, SVGA_REG_ID);
284     if (vmware_svga_id == SVGA_ID_1) {
285         return SVGA_ID_1;
286     }
287 
288     if (vmware_svga_id == SVGA_ID_0) {
289         return SVGA_ID_0;
290     }
291 
292     /* No supported VMware SVGA devices found */
293     return SVGA_ID_INVALID;
294 }
295 
296 static Bool
VMWAREPreInit(ScrnInfoPtr pScrn,int flags)297 VMWAREPreInit(ScrnInfoPtr pScrn, int flags)
298 {
299     MessageType from;
300     VMWAREPtr pVMWARE;
301     OptionInfoPtr options;
302     int bpp24flags;
303     uint32 id;
304     int i;
305     ClockRange* clockRanges;
306     unsigned long domainIOBase = 0;
307     uint32 width = 0, height = 0;
308     Bool defaultMode;
309 
310 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
311 #ifndef BUILD_FOR_420
312     domainIOBase = pScrn->domainIOBase;
313 #endif
314 #endif
315 
316     if (flags & PROBE_DETECT) {
317         return FALSE;
318     }
319 
320     if (pScrn->numEntities != 1) {
321         return FALSE;
322     }
323 
324     if (!VMWAREGetRec(pScrn)) {
325         return FALSE;
326     }
327     pVMWARE = VMWAREPTR(pScrn);
328 
329     pVMWARE->pvtSema = &pScrn->vtSema;
330 
331     pVMWARE->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
332     pVMWARE->PciInfo = xf86GetPciInfoForEntity(pVMWARE->pEnt->index);
333     if (pVMWARE->PciInfo == NULL) {
334         return FALSE;
335     }
336 
337     if (DEVICE_ID(pVMWARE->PciInfo) == PCI_DEVICE_ID_VMWARE_SVGA) {
338         pVMWARE->indexReg = domainIOBase +
339            SVGA_LEGACY_BASE_PORT + SVGA_INDEX_PORT*sizeof(uint32);
340         pVMWARE->valueReg = domainIOBase +
341            SVGA_LEGACY_BASE_PORT + SVGA_VALUE_PORT*sizeof(uint32);
342     } else {
343         /* Note:  This setting of valueReg causes unaligned I/O */
344 #if XSERVER_LIBPCIACCESS
345         pVMWARE->portIOBase = pVMWARE->PciInfo->regions[0].base_addr;
346 #else
347         pVMWARE->portIOBase = pVMWARE->PciInfo->ioBase[0];
348 #endif
349         pVMWARE->indexReg = domainIOBase +
350            pVMWARE->portIOBase + SVGA_INDEX_PORT;
351         pVMWARE->valueReg = domainIOBase +
352            pVMWARE->portIOBase + SVGA_VALUE_PORT;
353     }
354     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
355                "VMware SVGA regs at (0x%04lx, 0x%04lx)\n",
356                pVMWARE->indexReg, pVMWARE->valueReg);
357 
358     if (!xf86LoadSubModule(pScrn, "vgahw")) {
359         return FALSE;
360     }
361 
362     xf86LoaderReqSymLists(vgahwSymbols, NULL);
363 
364     if (!vgaHWGetHWRec(pScrn)) {
365         return FALSE;
366     }
367 
368 #ifdef HAVE_XORG_SERVER_1_12_0
369     vgaHWSetStdFuncs(VGAHWPTR(pScrn));
370 #endif
371 
372     /*
373      * Save the current video state.  Do it here before VMXGetVMwareSvgaId
374      * writes to any registers.
375      */
376     VMWARESave(pScrn);
377 
378     id = VMXGetVMwareSvgaId(pVMWARE);
379     if (id == SVGA_ID_0 || id == SVGA_ID_INVALID) {
380         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
381                    "No supported VMware SVGA found (read ID 0x%08x).\n", id);
382         return FALSE;
383     }
384     pVMWARE->SavedReg.svga_reg_id = id;
385 
386 #if !XSERVER_LIBPCIACCESS
387     pVMWARE->PciTag = pciTag(pVMWARE->PciInfo->bus, pVMWARE->PciInfo->device,
388                              pVMWARE->PciInfo->func);
389 #endif
390     pVMWARE->Primary = xf86IsPrimaryPci(pVMWARE->PciInfo);
391 
392     pScrn->monitor = pScrn->confScreen->monitor;
393 
394 #ifdef ACCELERATE_OPS
395     pVMWARE->vmwareCapability = vmwareReadReg(pVMWARE, SVGA_REG_CAPABILITIES);
396 #else
397     pVMWARE->vmwareCapability = vmwareReadReg(pVMWARE, SVGA_REG_CAPABILITIES) &
398 	SVGA_CAP_PITCHLOCK;
399 #endif
400 
401     pVMWARE->bitsPerPixel = vmwareReadReg(pVMWARE,
402                                           SVGA_REG_HOST_BITS_PER_PIXEL);
403     if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) {
404        vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL, pVMWARE->bitsPerPixel);
405     }
406 
407     pVMWARE->depth = vmwareReadReg(pVMWARE, SVGA_REG_DEPTH);
408     pVMWARE->videoRam = vmwareReadReg(pVMWARE, SVGA_REG_VRAM_SIZE);
409     pVMWARE->memPhysBase = vmwareReadReg(pVMWARE, SVGA_REG_FB_START);
410     pVMWARE->maxWidth = vmwareReadReg(pVMWARE, SVGA_REG_MAX_WIDTH);
411     pVMWARE->maxHeight = vmwareReadReg(pVMWARE, SVGA_REG_MAX_HEIGHT);
412     pVMWARE->cursorDefined = FALSE;
413     pVMWARE->cursorShouldBeHidden = FALSE;
414 
415     if (pVMWARE->vmwareCapability & SVGA_CAP_CURSOR_BYPASS_2) {
416         pVMWARE->cursorRemoveFromFB = SVGA_CURSOR_ON_REMOVE_FROM_FB;
417         pVMWARE->cursorRestoreToFB = SVGA_CURSOR_ON_RESTORE_TO_FB;
418     } else {
419         pVMWARE->cursorRemoveFromFB = SVGA_CURSOR_ON_HIDE;
420         pVMWARE->cursorRestoreToFB = SVGA_CURSOR_ON_SHOW;
421     }
422 
423     xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "caps:  0x%08X\n", pVMWARE->vmwareCapability);
424     xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "depth: %d\n", pVMWARE->depth);
425     xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "bpp:   %d\n", pVMWARE->bitsPerPixel);
426 
427     xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "vram:  %d\n", pVMWARE->videoRam);
428     xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "pbase: 0x%08lx\n", pVMWARE->memPhysBase);
429     xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "mwidt: %d\n", pVMWARE->maxWidth);
430     xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "mheig: %d\n", pVMWARE->maxHeight);
431 
432     if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) {
433         bpp24flags = Support24bppFb | Support32bppFb;
434     } else {
435         switch (pVMWARE->depth) {
436         case 16:
437             /*
438              * In certain cases, the Windows host appears to
439              * report 16 bpp and 16 depth but 555 weight.  Just
440              * silently convert it to depth of 15.
441              */
442             if (pVMWARE->bitsPerPixel == 16 &&
443                 pVMWARE->weight.green == 5)
444                 pVMWARE->depth = 15;
445         case 8:
446         case 15:
447             bpp24flags = NoDepth24Support;
448          break;
449         case 32:
450             /*
451              * There is no 32 bit depth, apparently it can get
452              * reported this way sometimes on the Windows host.
453              */
454             if (pVMWARE->bitsPerPixel == 32)
455                 pVMWARE->depth = 24;
456         case 24:
457             if (pVMWARE->bitsPerPixel == 24)
458                 bpp24flags = Support24bppFb;
459             else
460                 bpp24flags = Support32bppFb;
461             break;
462        default:
463             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
464                        "Adapter is using an unsupported depth (%d).\n",
465                        pVMWARE->depth);
466             return FALSE;
467        }
468     }
469 
470     if (!xf86SetDepthBpp(pScrn, pVMWARE->depth, pVMWARE->bitsPerPixel,
471                          pVMWARE->bitsPerPixel, bpp24flags)) {
472         return FALSE;
473     }
474 
475     /* Check that the returned depth is one we support */
476     switch (pScrn->depth) {
477     case 8:
478     case 15:
479     case 16:
480     case 24:
481         /* OK */
482         break;
483     default:
484         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
485                    "Given depth (%d) is not supported by this driver\n",
486                    pScrn->depth);
487         return FALSE;
488     }
489 
490     if (pScrn->bitsPerPixel != pVMWARE->bitsPerPixel) {
491         if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) {
492             vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL,
493                            pScrn->bitsPerPixel);
494             pVMWARE->bitsPerPixel =
495                vmwareReadReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL);
496             pVMWARE->depth = vmwareReadReg(pVMWARE, SVGA_REG_DEPTH);
497         } else {
498             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
499                        "Currently unavailable depth/bpp of %d/%d requested.\n"
500                        "\tThe guest X server must run at the same depth and bpp as the host\n"
501                        "\t(which are currently %d/%d).  This is automatically detected.  Please\n"
502                        "\tdo not specify a depth on the command line or via the config file.\n",
503                        pScrn->depth, pScrn->bitsPerPixel,
504                        pVMWARE->depth, pVMWARE->bitsPerPixel);
505             return FALSE;
506         }
507     }
508 
509     /*
510      * Defer reading the colour registers until here in case we changed
511      * bpp above.
512      */
513 
514     pVMWARE->weight.red =
515        vmwareCalculateWeight(vmwareReadReg(pVMWARE, SVGA_REG_RED_MASK));
516     pVMWARE->weight.green =
517        vmwareCalculateWeight(vmwareReadReg(pVMWARE, SVGA_REG_GREEN_MASK));
518     pVMWARE->weight.blue =
519        vmwareCalculateWeight(vmwareReadReg(pVMWARE, SVGA_REG_BLUE_MASK));
520     pVMWARE->offset.blue = 0;
521     pVMWARE->offset.green = pVMWARE->weight.blue;
522     pVMWARE->offset.red = pVMWARE->weight.green + pVMWARE->offset.green;
523     pVMWARE->defaultVisual = vmwareReadReg(pVMWARE, SVGA_REG_PSEUDOCOLOR) ?
524        PseudoColor : TrueColor;
525 
526     xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
527                    2, "depth: %d\n", pVMWARE->depth);
528     xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
529                    2, "bpp:   %d\n", pVMWARE->bitsPerPixel);
530     xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
531                    2, "w.red: %d\n", (int)pVMWARE->weight.red);
532     xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
533                    2, "w.grn: %d\n", (int)pVMWARE->weight.green);
534     xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
535                    2, "w.blu: %d\n", (int)pVMWARE->weight.blue);
536     xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
537                    2, "vis:   %d\n", pVMWARE->defaultVisual);
538 
539     if (pScrn->depth != pVMWARE->depth) {
540         if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) {
541             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
542                        "Currently unavailable depth of %d requested.\n"
543                        "\tIf the guest X server's BPP matches the host's "
544                        "BPP, then\n\tthe guest X server's depth must also "
545                        "match the\n\thost's depth (currently %d).\n",
546                        pScrn->depth, pVMWARE->depth);
547         } else {
548             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
549                        "Currently unavailable depth of %d requested.\n"
550                        "\tThe guest X server must run at the same depth as "
551                        "the host (which\n\tis currently %d).  This is "
552                        "automatically detected.  Please do not\n\tspecify "
553                        "a depth on the command line or via the config file.\n",
554                        pScrn->depth, pVMWARE->depth);
555         }
556            return FALSE;
557     }
558     xf86PrintDepthBpp(pScrn);
559 
560 #if 0
561     if (pScrn->depth == 24 && pix24bpp == 0) {
562         pix24bpp = xf86GetBppFromDepth(pScrn, 24);
563     }
564 #endif
565 
566     if (pScrn->depth > 8) {
567         rgb zeros = { 0, 0, 0 };
568 
569         if (!xf86SetWeight(pScrn, pVMWARE->weight, zeros)) {
570             return FALSE;
571         }
572         /* FIXME check returned weight */
573     }
574     if (!xf86SetDefaultVisual(pScrn, pVMWARE->defaultVisual)) {
575         return FALSE;
576     }
577     if (pScrn->defaultVisual != pVMWARE->defaultVisual) {
578         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
579                    "Given visual (%d) is not supported by this driver (%d is required)\n",
580                    pScrn->defaultVisual, pVMWARE->defaultVisual);
581         return FALSE;
582     }
583 #if 0
584     bytesPerPixel = pScrn->bitsPerPixel / 8;
585 #endif
586     pScrn->progClock = TRUE;
587 
588 #if 0 /* MGA does not do this */
589     if (pScrn->visual != 0) {	/* FIXME */
590         /* print error message */
591         return FALSE;
592     }
593 #endif
594 
595     xf86CollectOptions(pScrn, NULL);
596     if (!(options = VMWARECopyOptions()))
597         return FALSE;
598     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
599 
600     if (pScrn->depth <= 8) {
601         pScrn->rgbBits = 8;
602     }
603 
604     if (!pScrn->chipset) {
605         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ChipID 0x%04x is not recognised\n", DEVICE_ID(pVMWARE->PciInfo));
606         return FALSE;
607     }
608 
609     from = X_DEFAULT;
610     pVMWARE->hwCursor = TRUE;
611     if (xf86GetOptValBool(options, OPTION_HW_CURSOR, &pVMWARE->hwCursor)) {
612         from = X_CONFIG;
613     }
614     if (pVMWARE->hwCursor && !(pVMWARE->vmwareCapability & SVGA_CAP_CURSOR)) {
615         xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "HW cursor is not supported in this configuration\n");
616         from = X_PROBED;
617         pVMWARE->hwCursor = FALSE;
618     }
619     xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
620                pVMWARE->hwCursor ? "HW" : "SW");
621     pScrn->videoRam = pVMWARE->videoRam / 1024;
622     pScrn->memPhysBase = pVMWARE->memPhysBase;
623 
624     from = X_DEFAULT;
625     defaultMode = TRUE;
626     if (xf86GetOptValBool(options, OPTION_DEFAULT_MODE, &defaultMode)) {
627         from = X_CONFIG;
628     }
629 
630     width = vmwareReadReg(pVMWARE, SVGA_REG_WIDTH);
631     height = vmwareReadReg(pVMWARE, SVGA_REG_HEIGHT);
632     width = MAX(width, VMW_MIN_INITIAL_WIDTH);
633     height = MAX(height, VMW_MIN_INITIAL_HEIGHT);
634 
635     if (width > pVMWARE->maxWidth || height > pVMWARE->maxHeight) {
636 	/*
637 	 * This is an error condition and shouldn't happen.
638 	 * revert to MIN_INITIAL_ values
639 	 */
640 	width = VMW_MIN_INITIAL_WIDTH;
641 	height = VMW_MIN_INITIAL_HEIGHT;
642     }
643 
644     xf86DrvMsg(pScrn->scrnIndex, from,
645 	       "Will %sset up a driver mode with dimensions %dx%d.\n",
646 	       defaultMode ? "" : "not ", width, height);
647 
648     free(options);
649 
650     {
651         Gamma zeros = { 0.0, 0.0, 0.0 };
652         if (!xf86SetGamma(pScrn, zeros)) {
653             return FALSE;
654         }
655     }
656 #if 0
657     if ((i = xf86GetPciInfoForScreen(pScrn->scrnIndex, &pciList, NULL)) != 1) {
658         /* print error message */
659         VMWAREFreeRec(pScrn);
660         if (i > 0) {
661             free(pciList);
662         }
663         return FALSE;
664     }
665 #endif
666     clockRanges = xnfcalloc(sizeof(ClockRange), 1);
667     clockRanges->next = NULL;
668     clockRanges->minClock = 1;
669     clockRanges->maxClock = 400000000;
670     clockRanges->clockIndex = -1;
671     clockRanges->interlaceAllowed = FALSE;
672     clockRanges->doubleScanAllowed = FALSE;
673     clockRanges->ClockMulFactor = 1;
674     clockRanges->ClockDivFactor = 1;
675 
676     if (defaultMode) {
677 	vmwareAddDefaultMode(pScrn, width, height);
678     }
679 
680     i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes,
681                           clockRanges, NULL, 256, pVMWARE->maxWidth,
682                           pVMWARE->bitsPerPixel * 1,
683                           128, pVMWARE->maxHeight,
684                           pScrn->display->virtualX, pScrn->display->virtualY,
685                           pVMWARE->videoRam,
686                           LOOKUP_BEST_REFRESH | LOOKUP_OPTIONAL_TOLERANCES);
687 
688     if (i == -1) {
689         VMWAREFreeRec(pScrn);
690         return FALSE;
691     }
692     xf86PruneDriverModes(pScrn);
693     if (i == 0 || pScrn->modes == NULL) {
694         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
695         VMWAREFreeRec(pScrn);
696         return FALSE;
697     }
698 
699     pScrn->currentMode = pScrn->modes;
700     pScrn->virtualX = pScrn->modes->HDisplay;
701     pScrn->virtualY = pScrn->modes->VDisplay;
702 
703     xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
704 
705     xf86PrintModes(pScrn);
706     xf86SetDpi(pScrn, 0, 0);
707     if (!xf86LoadSubModule(pScrn, "fb") ||
708         !xf86LoadSubModule(pScrn, "shadowfb")) {
709         VMWAREFreeRec(pScrn);
710         return FALSE;
711     }
712     xf86LoaderReqSymLists(fbSymbols, shadowfbSymbols, NULL);
713 
714     /* Need ramdac for hwcursor */
715     if (pVMWARE->hwCursor) {
716         if (!xf86LoadSubModule(pScrn, "ramdac")) {
717             VMWAREFreeRec(pScrn);
718             return FALSE;
719         }
720         xf86LoaderReqSymLists(ramdacSymbols, NULL);
721     }
722 
723     return TRUE;
724 }
725 
726 static Bool
VMWAREMapMem(ScrnInfoPtr pScrn)727 VMWAREMapMem(ScrnInfoPtr pScrn)
728 {
729     VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
730 #if XSERVER_LIBPCIACCESS
731     int err;
732     struct pci_device *const device = pVMWARE->PciInfo;
733     void *fbBase;
734 #endif
735 
736 #if XSERVER_LIBPCIACCESS
737    err = pci_device_map_range(device,
738                               pVMWARE->memPhysBase,
739                               pVMWARE->videoRam,
740                               PCI_DEV_MAP_FLAG_WRITABLE,
741 			      &fbBase);
742    if (err) {
743        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
744                   "Unable to map frame buffer BAR. %s (%d)\n",
745                   strerror (err), err);
746        return FALSE;
747    }
748    pVMWARE->FbBase = fbBase;
749 #else
750     pVMWARE->FbBase = xf86MapPciMem(pScrn->scrnIndex, 0,
751                                     pVMWARE->PciTag,
752                                     pVMWARE->memPhysBase,
753                                     pVMWARE->videoRam);
754 #endif
755     if (!pVMWARE->FbBase)
756         return FALSE;
757 
758     VmwareLog(("FB Mapped: %p/%u -> %p/%u\n",
759                pVMWARE->memPhysBase, pVMWARE->videoRam,
760                pVMWARE->FbBase, pVMWARE->videoRam));
761     return TRUE;
762 }
763 
764 static Bool
VMWAREUnmapMem(ScrnInfoPtr pScrn)765 VMWAREUnmapMem(ScrnInfoPtr pScrn)
766 {
767     VMWAREPtr pVMWARE;
768 
769     pVMWARE = VMWAREPTR(pScrn);
770 
771     VmwareLog(("Unmapped: %p/%u\n", pVMWARE->FbBase, pVMWARE->videoRam));
772 
773 #if XSERVER_LIBPCIACCESS
774     pci_device_unmap_range(pVMWARE->PciInfo, pVMWARE->FbBase, pVMWARE->videoRam);
775 #else
776     xf86UnMapVidMem(pScrn->scrnIndex, pVMWARE->FbBase, pVMWARE->videoRam);
777 #endif
778     pVMWARE->FbBase = NULL;
779     return TRUE;
780 }
781 
782 static void
VMWARESave(ScrnInfoPtr pScrn)783 VMWARESave(ScrnInfoPtr pScrn)
784 {
785     vgaHWPtr hwp = VGAHWPTR(pScrn);
786     vgaRegPtr vgaReg = &hwp->SavedReg;
787     VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
788     VMWARERegPtr vmwareReg = &pVMWARE->SavedReg;
789 
790     vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
791 
792     vmwareReg->svga_reg_enable = vmwareReadReg(pVMWARE, SVGA_REG_ENABLE);
793     vmwareReg->svga_reg_width = vmwareReadReg(pVMWARE, SVGA_REG_WIDTH);
794     vmwareReg->svga_reg_height = vmwareReadReg(pVMWARE, SVGA_REG_HEIGHT);
795     vmwareReg->svga_reg_bits_per_pixel =
796        vmwareReadReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL);
797     vmwareReg->svga_reg_id = vmwareReadReg(pVMWARE, SVGA_REG_ID);
798 
799     /* XXX this should be based on the cap bit, not hwCursor... */
800     if (pVMWARE->hwCursor) {
801        vmwareReg->svga_reg_cursor_on =
802           vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_ON);
803        vmwareReg->svga_reg_cursor_x =
804           vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_X);
805        vmwareReg->svga_reg_cursor_y =
806           vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_Y);
807        vmwareReg->svga_reg_cursor_id =
808           vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_ID);
809     }
810 
811     vmwareReg->svga_fifo_enabled = vmwareReadReg(pVMWARE, SVGA_REG_CONFIG_DONE);
812 }
813 
814 static void
VMWARERestoreRegs(ScrnInfoPtr pScrn,VMWARERegPtr vmwareReg)815 VMWARERestoreRegs(ScrnInfoPtr pScrn, VMWARERegPtr vmwareReg)
816 {
817     VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
818     VmwareLog(("VMWARERestoreRegs: W: %d, H: %d, BPP: %d, Enable: %d\n",
819 	       vmwareReg->svga_reg_width, vmwareReg->svga_reg_height,
820 	       vmwareReg->svga_reg_bits_per_pixel, vmwareReg->svga_reg_enable));
821     if (vmwareReg->svga_reg_enable) {
822         vmwareWriteReg(pVMWARE, SVGA_REG_ID, vmwareReg->svga_reg_id);
823         vmwareWriteReg(pVMWARE, SVGA_REG_WIDTH, vmwareReg->svga_reg_width);
824         vmwareWriteReg(pVMWARE, SVGA_REG_HEIGHT, vmwareReg->svga_reg_height);
825         vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL,
826                        vmwareReg->svga_reg_bits_per_pixel);
827         vmwareWriteReg(pVMWARE, SVGA_REG_ENABLE, vmwareReg->svga_reg_enable);
828         vmwareWriteReg(pVMWARE, SVGA_REG_GUEST_ID, GUEST_OS_LINUX);
829         if (pVMWARE->hwCursor) {
830             vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_ID,
831                            vmwareReg->svga_reg_cursor_id);
832             vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_X,
833                            vmwareReg->svga_reg_cursor_x);
834             vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_Y,
835                            vmwareReg->svga_reg_cursor_y);
836             vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_ON,
837                            vmwareReg->svga_reg_cursor_on);
838         }
839     } else {
840         vmwareWriteReg(pVMWARE, SVGA_REG_ID, vmwareReg->svga_reg_id);
841         vmwareWriteReg(pVMWARE, SVGA_REG_WIDTH, vmwareReg->svga_reg_width);
842         vmwareWriteReg(pVMWARE, SVGA_REG_HEIGHT, vmwareReg->svga_reg_height);
843         vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL,
844                        vmwareReg->svga_reg_bits_per_pixel);
845 	vmwareWriteReg(pVMWARE, SVGA_REG_ENABLE, vmwareReg->svga_reg_enable);
846     }
847 }
848 
849 static void
VMWARERestore(ScrnInfoPtr pScrn)850 VMWARERestore(ScrnInfoPtr pScrn)
851 {
852     vgaHWPtr hwp = VGAHWPTR(pScrn);
853     vgaRegPtr vgaReg = &hwp->SavedReg;
854     VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
855     VMWARERegPtr vmwareReg = &pVMWARE->SavedReg;
856 
857     vmwareWaitForFB(pVMWARE);
858     if (!vmwareReg->svga_fifo_enabled) {
859         VMWAREStopFIFO(pScrn);
860     }
861 
862     vgaHWProtect(pScrn, TRUE);
863     VMWARERestoreRegs(pScrn, vmwareReg);
864     vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
865     vgaHWProtect(pScrn, FALSE);
866 }
867 
868 static Bool
VMWAREModeInit(ScrnInfoPtr pScrn,DisplayModePtr mode,Bool rebuildPixmap)869 VMWAREModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool rebuildPixmap)
870 {
871     vgaHWPtr hwp = VGAHWPTR(pScrn);
872     vgaRegPtr vgaReg = &hwp->ModeReg;
873     VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
874     VMWARERegPtr vmwareReg = &pVMWARE->ModeReg;
875 
876     vgaHWUnlock(hwp);
877     if (!vgaHWInit(pScrn, mode))
878         return FALSE;
879     pScrn->vtSema = TRUE;
880 
881     if (pVMWARE->vmwareCapability & SVGA_CAP_PITCHLOCK)
882 	vmwareWriteReg(pVMWARE, SVGA_REG_PITCHLOCK, 0);
883     vmwareReg->svga_reg_enable = 1;
884     vmwareReg->svga_reg_width = max(mode->HDisplay, pScrn->virtualX);
885     vmwareReg->svga_reg_height = max(mode->VDisplay, pScrn->virtualY);
886     vmwareReg->svga_reg_bits_per_pixel = pVMWARE->bitsPerPixel;
887 
888     vgaHWProtect(pScrn, TRUE);
889 
890     vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
891     VMWARERestoreRegs(pScrn, vmwareReg);
892 
893     if (pVMWARE->hwCursor) {
894         vmwareCursorModeInit(pScrn, mode);
895     }
896 
897     VmwareLog(("Required mode: %ux%u\n", mode->HDisplay, mode->VDisplay));
898     VmwareLog(("Virtual:       %ux%u\n", pScrn->virtualX, pScrn->virtualY));
899     VmwareLog(("dispWidth:     %u\n", pScrn->displayWidth));
900     pVMWARE->fbOffset = vmwareReadReg(pVMWARE, SVGA_REG_FB_OFFSET);
901     pVMWARE->fbPitch = vmwareReadReg(pVMWARE, SVGA_REG_BYTES_PER_LINE);
902     pVMWARE->FbSize = vmwareReadReg(pVMWARE, SVGA_REG_FB_SIZE);
903 
904     pScrn->displayWidth = (pVMWARE->fbPitch * 8) / ((pScrn->bitsPerPixel + 7) & ~7);
905     VmwareLog(("fbOffset:      %u\n", pVMWARE->fbOffset));
906     VmwareLog(("fbPitch:       %u\n", pVMWARE->fbPitch));
907     VmwareLog(("fbSize:        %u\n", pVMWARE->FbSize));
908     VmwareLog(("New dispWidth: %u\n", pScrn->displayWidth));
909 
910     vmwareCheckVideoSanity(pScrn);
911 
912     if (rebuildPixmap) {
913         pScrn->pScreen->ModifyPixmapHeader((*pScrn->pScreen->GetScreenPixmap)(pScrn->pScreen),
914                                            pScrn->pScreen->width,
915                                            pScrn->pScreen->height,
916                                            pScrn->pScreen->rootDepth,
917                                            pScrn->bitsPerPixel,
918                                            PixmapBytePad(pScrn->displayWidth,
919                                                          pScrn->pScreen->rootDepth),
920                                            (pointer)(pVMWARE->FbBase + pScrn->fbOffset));
921 
922         (*pScrn->EnableDisableFBAccess)(XF86_SCRN_ARG(pScrn), FALSE);
923         (*pScrn->EnableDisableFBAccess)(XF86_SCRN_ARG(pScrn), TRUE);
924     }
925 
926     vgaHWProtect(pScrn, FALSE);
927 
928     /*
929      * Push the new Xinerama state to X clients and the hardware,
930      * synchronously with the mode change. Note that this must happen
931      * AFTER we write the new width and height to the hardware
932      * registers, since updating the WIDTH and HEIGHT registers will
933      * reset the device's multimon topology.
934      */
935     vmwareNextXineramaState(pVMWARE);
936 
937     return TRUE;
938 }
939 
940 void
vmwareNextXineramaState(VMWAREPtr pVMWARE)941 vmwareNextXineramaState(VMWAREPtr pVMWARE)
942 {
943     VMWARERegPtr vmwareReg = &pVMWARE->ModeReg;
944 
945     /*
946      * Switch to the next Xinerama state (from pVMWARE->xineramaNextState).
947      *
948      * This new state will be available to X clients via the Xinerama
949      * extension, and we push the new state to the virtual hardware,
950      * in order to configure a number of virtual monitors within the
951      * device's framebuffer.
952      *
953      * This function can be called at any time, but it should usually be
954      * called just after a mode switch. This is for two reasons:
955      *
956      *   1) We don't want X clients to see a Xinerama topology and a video
957      *      mode that are inconsistent with each other, so we'd like to switch
958      *      both at the same time.
959      *
960      *   2) We must set the host's display topology registers after setting
961      *      the new video mode, since writes to WIDTH/HEIGHT will reset the
962      *      hardware display topology.
963      */
964 
965     /*
966      * Update Xinerama info appropriately.
967      */
968     if (pVMWARE->xinerama && !pVMWARE->xineramaStatic) {
969        if (pVMWARE->xineramaNextState) {
970           free(pVMWARE->xineramaState);
971           pVMWARE->xineramaState = pVMWARE->xineramaNextState;
972           pVMWARE->xineramaNumOutputs = pVMWARE->xineramaNextNumOutputs;
973 
974           pVMWARE->xineramaNextState = NULL;
975           pVMWARE->xineramaNextNumOutputs = 0;
976 
977        } else {
978           /*
979            * There is no next state pending. Switch back to
980            * single-monitor mode. This is necessary for resetting the
981            * Xinerama state if we get a mode change which doesn't
982            * follow a VMwareCtrlDoSetTopology call.
983            */
984           VMWAREXineramaPtr basicState =
985              (VMWAREXineramaPtr)calloc(1, sizeof (VMWAREXineramaRec));
986           if (basicState) {
987              basicState->x_org = 0;
988              basicState->y_org = 0;
989              basicState->width = vmwareReg->svga_reg_width;
990              basicState->height = vmwareReg->svga_reg_height;
991 
992              free(pVMWARE->xineramaState);
993              pVMWARE->xineramaState = basicState;
994              pVMWARE->xineramaNumOutputs = 1;
995           }
996        }
997     }
998 
999     /*
1000      * Update host's view of guest topology. This tells the device
1001      * how we're carving up its framebuffer into virtual screens.
1002      */
1003     if (pVMWARE->vmwareCapability & SVGA_CAP_DISPLAY_TOPOLOGY) {
1004         if (pVMWARE->xinerama) {
1005             int i = 0;
1006             VMWAREXineramaPtr xineramaState = pVMWARE->xineramaState;
1007             vmwareWriteReg(pVMWARE, SVGA_REG_NUM_GUEST_DISPLAYS,
1008                            pVMWARE->xineramaNumOutputs);
1009 
1010             for (i = 0; i < pVMWARE->xineramaNumOutputs; i++) {
1011                 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_ID, i);
1012                 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_IS_PRIMARY, i == 0);
1013                 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_X,
1014                                xineramaState[i].x_org);
1015                 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_Y,
1016                                xineramaState[i].y_org);
1017                 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_WIDTH,
1018                                xineramaState[i].width);
1019                 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_HEIGHT,
1020                                xineramaState[i].height);
1021             }
1022         } else {
1023             vmwareWriteReg(pVMWARE, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
1024 
1025             vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_ID, 0);
1026             vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_IS_PRIMARY, TRUE);
1027             vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_X, 0);
1028             vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_Y, 0);
1029             vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_WIDTH, vmwareReg->svga_reg_width);
1030             vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_HEIGHT, vmwareReg->svga_reg_height);
1031         }
1032 
1033         /* Done. */
1034         vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_ID, SVGA_INVALID_DISPLAY_ID);
1035     }
1036 }
1037 
1038 static void
VMWAREAdjustFrame(ADJUST_FRAME_ARGS_DECL)1039 VMWAREAdjustFrame(ADJUST_FRAME_ARGS_DECL)
1040 {
1041     /* FIXME */
1042 }
1043 
1044 static void
VMWAREInitFIFO(ScrnInfoPtr pScrn)1045 VMWAREInitFIFO(ScrnInfoPtr pScrn)
1046 {
1047     VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
1048 #if XSERVER_LIBPCIACCESS
1049     struct pci_device *const device = pVMWARE->PciInfo;
1050     int err;
1051     void *mmioVirtBase;
1052 #endif
1053     volatile CARD32* vmwareFIFO;
1054     Bool extendedFifo;
1055     int min;
1056 
1057     TRACEPOINT
1058 
1059     pVMWARE->mmioPhysBase = vmwareReadReg(pVMWARE, SVGA_REG_MEM_START);
1060     pVMWARE->mmioSize = vmwareReadReg(pVMWARE, SVGA_REG_MEM_SIZE) & ~3;
1061 #if XSERVER_LIBPCIACCESS
1062     err = pci_device_map_range(device, pVMWARE->mmioPhysBase,
1063                                pVMWARE->mmioSize,
1064                                PCI_DEV_MAP_FLAG_WRITABLE,
1065                                &mmioVirtBase);
1066     if (err) {
1067         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1068                    "Unable to map mmio BAR. %s (%d)\n",
1069                    strerror (err), err);
1070         return;
1071     }
1072     pVMWARE->mmioVirtBase = mmioVirtBase;
1073 #else
1074     pVMWARE->mmioVirtBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
1075                                           pVMWARE->PciTag,
1076                                           pVMWARE->mmioPhysBase,
1077                                           pVMWARE->mmioSize);
1078 #endif
1079     vmwareFIFO = pVMWARE->vmwareFIFO = (CARD32*)pVMWARE->mmioVirtBase;
1080 
1081     extendedFifo = pVMWARE->vmwareCapability & SVGA_CAP_EXTENDED_FIFO;
1082     min = extendedFifo ? vmwareReadReg(pVMWARE, SVGA_REG_MEM_REGS) : 4;
1083 
1084     vmwareWaitForFB(pVMWARE);
1085     vmwareWriteReg(pVMWARE, SVGA_REG_CONFIG_DONE, 0);
1086 
1087     vmwareFIFO[SVGA_FIFO_MIN] = min * sizeof(CARD32);
1088     vmwareFIFO[SVGA_FIFO_MAX] = pVMWARE->mmioSize;
1089     vmwareFIFO[SVGA_FIFO_NEXT_CMD] = min * sizeof(CARD32);
1090     vmwareFIFO[SVGA_FIFO_STOP] = min * sizeof(CARD32);
1091     vmwareWriteReg(pVMWARE, SVGA_REG_CONFIG_DONE, 1);
1092 }
1093 
1094 static void
VMWAREStopFIFO(ScrnInfoPtr pScrn)1095 VMWAREStopFIFO(ScrnInfoPtr pScrn)
1096 {
1097     VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
1098 
1099     TRACEPOINT
1100 
1101     vmwareWriteReg(pVMWARE, SVGA_REG_CONFIG_DONE, 0);
1102 #if XSERVER_LIBPCIACCESS
1103     pci_device_unmap_range(pVMWARE->PciInfo, pVMWARE->mmioVirtBase, pVMWARE->mmioSize);
1104 #else
1105     xf86UnMapVidMem(pScrn->scrnIndex, pVMWARE->mmioVirtBase, pVMWARE->mmioSize);
1106 #endif
1107 }
1108 
1109 static Bool
VMWARECloseScreen(CLOSE_SCREEN_ARGS_DECL)1110 VMWARECloseScreen(CLOSE_SCREEN_ARGS_DECL)
1111 {
1112     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1113     VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
1114     ScreenPtr save = &pVMWARE->ScrnFuncs;
1115 
1116     VmwareLog(("cursorSema: %d\n", pVMWARE->cursorSema));
1117 
1118     if (*pVMWARE->pvtSema) {
1119         if (pVMWARE->videoStreams) {
1120             vmwareVideoEnd(pScreen);
1121         }
1122 
1123         if (pVMWARE->CursorInfoRec) {
1124             vmwareCursorCloseScreen(pScreen);
1125         }
1126 
1127         VMWARERestore(pScrn);
1128         VMWAREUnmapMem(pScrn);
1129 
1130         pScrn->vtSema = FALSE;
1131     }
1132 
1133     pScreen->CloseScreen = save->CloseScreen;
1134     pScreen->SaveScreen = save->SaveScreen;
1135 
1136 #if VMWARE_DRIVER_FUNC
1137     pScrn->DriverFunc = NULL;
1138 #endif
1139 
1140     return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
1141 }
1142 
1143 static Bool
VMWARESaveScreen(ScreenPtr pScreen,int mode)1144 VMWARESaveScreen(ScreenPtr pScreen, int mode)
1145 {
1146     VmwareLog(("VMWareSaveScreen() mode = %d\n", mode));
1147 
1148     /*
1149      * This thoroughly fails to do anything useful to svga mode.  I doubt
1150      * we care; who wants to idle-blank their VM's screen anyway?
1151      */
1152     return vgaHWSaveScreen(pScreen, mode);
1153 }
1154 
1155 /* disabled by default to reduce spew in DEBUG_LOGGING mode. */
1156 /*#define DEBUG_LOG_UPDATES*/
1157 
1158 static void
VMWAREPreDirtyBBUpdate(ScrnInfoPtr pScrn,int nboxes,BoxPtr boxPtr)1159 VMWAREPreDirtyBBUpdate(ScrnInfoPtr pScrn, int nboxes, BoxPtr boxPtr)
1160 {
1161     VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
1162 
1163 #ifdef DEBUG_LOG_UPDATES
1164     {
1165         int i;
1166         for (i = 0; i < nboxes; i++) {
1167             VmwareLog(("PreUpdate #%d (%d, %d, w = %d, h = %d)\n", nboxes - i,
1168                        boxPtr[i].x1, boxPtr[i].y1,
1169                        boxPtr[i].x2 - boxPtr[i].x1,
1170                        boxPtr[i].y2 - boxPtr[i].y1));
1171         }
1172     }
1173 #endif
1174 
1175     /*
1176      * We only register this callback if we have a HW cursor.
1177      */
1178     while (nboxes--) {
1179         if (BOX_INTERSECT(*boxPtr, pVMWARE->hwcur.box)) {
1180             if (!pVMWARE->cursorExcludedForUpdate) {
1181                 PRE_OP_HIDE_CURSOR();
1182                 pVMWARE->cursorExcludedForUpdate = TRUE;
1183             }
1184 	    break;
1185         }
1186         boxPtr++;
1187     }
1188 }
1189 
1190 static void
VMWAREPostDirtyBBUpdate(ScrnInfoPtr pScrn,int nboxes,BoxPtr boxPtr)1191 VMWAREPostDirtyBBUpdate(ScrnInfoPtr pScrn, int nboxes, BoxPtr boxPtr)
1192 {
1193     VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
1194     while (nboxes--) {
1195 #ifdef DEBUG_LOG_UPDATES
1196         VmwareLog(("PostUpdate #%d (%d, %d, w = %d, h = %d)\n", nboxes,
1197                    boxPtr->x1, boxPtr->y1,
1198                    boxPtr->x2 - boxPtr->x1, boxPtr->y2 - boxPtr->y1));
1199 #endif
1200 
1201         /* Clip off (y only) for offscreen memory */
1202         if (boxPtr->y2 >= pVMWARE->ModeReg.svga_reg_height)
1203             boxPtr->y2 = pVMWARE->ModeReg.svga_reg_height;
1204         if (boxPtr->y1 >= pVMWARE->ModeReg.svga_reg_height)
1205             boxPtr->y1 = pVMWARE->ModeReg.svga_reg_height;
1206         if (boxPtr->y1 == boxPtr->y2) {
1207             boxPtr++;
1208             continue;
1209         }
1210 
1211         vmwareSendSVGACmdUpdate(pVMWARE, boxPtr++);
1212     }
1213 
1214     if (pVMWARE->hwCursor && pVMWARE->cursorExcludedForUpdate) {
1215         POST_OP_SHOW_CURSOR();
1216         pVMWARE->cursorExcludedForUpdate = FALSE;
1217     }
1218 }
1219 
1220 static void
VMWARELoadPalette(ScrnInfoPtr pScrn,int numColors,int * indices,LOCO * colors,VisualPtr pVisual)1221 VMWARELoadPalette(ScrnInfoPtr pScrn, int numColors, int* indices,
1222                   LOCO* colors, VisualPtr pVisual)
1223 {
1224     VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
1225     int i;
1226 
1227     for (i = 0; i < numColors; i++) {
1228         vmwareWriteReg(pVMWARE, SVGA_PALETTE_BASE + *indices * 3 + 0, colors[*indices].red);
1229         vmwareWriteReg(pVMWARE, SVGA_PALETTE_BASE + *indices * 3 + 1, colors[*indices].green);
1230         vmwareWriteReg(pVMWARE, SVGA_PALETTE_BASE + *indices * 3 + 2, colors[*indices].blue);
1231         indices++;
1232     }
1233     VmwareLog(("Palette loading done\n"));
1234 }
1235 
1236 
1237 DisplayModeRec *
VMWAREAddDisplayMode(ScrnInfoPtr pScrn,const char * name,int width,int height)1238 VMWAREAddDisplayMode(ScrnInfoPtr pScrn,
1239                      const char *name,
1240                      int width,
1241                      int height)
1242 {
1243    DisplayModeRec *mode;
1244    char * modeName;
1245 
1246    mode = malloc(sizeof(DisplayModeRec));
1247    memset(mode, 0, sizeof *mode);
1248 
1249    modeName = malloc(strlen(name) + 1);
1250    strcpy(modeName, name);
1251    mode->name = modeName;
1252    mode->status = MODE_OK;
1253    mode->type = M_T_DEFAULT;
1254    mode->HDisplay = width;
1255    mode->VDisplay = height;
1256 
1257    mode->next = pScrn->modes;
1258    mode->prev = pScrn->modes->prev;
1259    pScrn->modes->prev->next = mode;
1260    pScrn->modes->prev = mode;
1261 
1262    return mode;
1263 }
1264 
1265 
1266 /*
1267  *-----------------------------------------------------------------------------
1268  *
1269  * vmwareIsRegionEqual --
1270  *
1271  *    This function implements REGION_EQUAL because older versions of
1272  *    regionstr.h don't define it.
1273  *    It is a slightly modified version of miRegionEqual from $Xorg: miregion.c
1274  *
1275  * Results:
1276  *    TRUE if regions are equal; FALSE otherwise
1277  *
1278  * Side effects:
1279  *    None.
1280  *
1281  *-----------------------------------------------------------------------------
1282  */
1283 
1284 Bool
vmwareIsRegionEqual(const RegionPtr reg1,const RegionPtr reg2)1285 vmwareIsRegionEqual(const RegionPtr reg1,
1286                     const RegionPtr reg2)
1287 {
1288     int i, num;
1289     BoxPtr rects1, rects2;
1290 
1291     if ((reg1->extents.x1 != reg2->extents.x1) ||
1292         (reg1->extents.x2 != reg2->extents.x2) ||
1293         (reg1->extents.y1 != reg2->extents.y1) ||
1294         (reg1->extents.y2 != reg2->extents.y2)) {
1295         return FALSE;
1296     }
1297 
1298     num = REGION_NUM_RECTS(reg1);
1299     if (num != REGION_NUM_RECTS(reg2)) {
1300         return FALSE;
1301     }
1302 
1303     rects1 = REGION_RECTS(reg1);
1304     rects2 = REGION_RECTS(reg2);
1305 
1306     for (i = 0; i < num; i++) {
1307         if ((rects1[i].x1 != rects2[i].x1) ||
1308             (rects1[i].x2 != rects2[i].x2) ||
1309             (rects1[i].y1 != rects2[i].y1) ||
1310             (rects1[i].y2 != rects2[i].y2)) {
1311             return FALSE;
1312         }
1313     }
1314 
1315     return TRUE;
1316 }
1317 
1318 static Bool
VMWAREScreenInit(SCREEN_INIT_ARGS_DECL)1319 VMWAREScreenInit(SCREEN_INIT_ARGS_DECL)
1320 {
1321     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1322     vgaHWPtr hwp;
1323     VMWAREPtr pVMWARE;
1324     OptionInfoPtr options;
1325     Bool useXinerama = TRUE;
1326 
1327     pVMWARE = VMWAREPTR(pScrn);
1328 
1329 
1330     xf86CollectOptions(pScrn, NULL);
1331     if (!(options = VMWARECopyOptions()))
1332         return FALSE;
1333     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
1334 
1335     /*
1336      * Init xinerama preferences.
1337      */
1338     useXinerama = xf86ReturnOptValBool(options, OPTION_XINERAMA,
1339                                        pVMWARE->vmwareCapability & SVGA_CAP_MULTIMON);
1340     if (useXinerama && !(pVMWARE->vmwareCapability & SVGA_CAP_MULTIMON)) {
1341        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1342                   "Xinerama is not safely supported by the current virtual hardware. "
1343                   "Do not request resolutions that require > 16MB of framebuffer.\n");
1344     }
1345 
1346 
1347     if (useXinerama && xf86IsOptionSet(options, OPTION_GUI_LAYOUT)) {
1348        CONST_ABI_18_0 char *topology = xf86GetOptValString(options, OPTION_GUI_LAYOUT);
1349        if (topology) {
1350           pVMWARE->xineramaState =
1351              VMWAREParseTopologyString(pScrn, topology,
1352 				       &pVMWARE->xineramaNumOutputs, "gui");
1353 
1354          pVMWARE->xineramaStatic = pVMWARE->xineramaState != NULL;
1355 
1356          free((void *)topology);
1357        }
1358     } else if (useXinerama &&
1359 	       xf86IsOptionSet(options, OPTION_STATIC_XINERAMA)) {
1360        CONST_ABI_18_0 char *topology = xf86GetOptValString(options, OPTION_STATIC_XINERAMA);
1361        if (topology) {
1362           pVMWARE->xineramaState =
1363              VMWAREParseTopologyString(pScrn, topology,
1364 				       &pVMWARE->xineramaNumOutputs,
1365 				       "static Xinerama");
1366 
1367          pVMWARE->xineramaStatic = pVMWARE->xineramaState != NULL;
1368 
1369          free((void *)topology);
1370        }
1371     }
1372 
1373     free(options);
1374 
1375     /* Initialise VMWARE_CTRL extension. */
1376     VMwareCtrl_ExtInit(pScrn);
1377 
1378     /* Initialise Xinerama extension. */
1379     if (useXinerama) {
1380        VMwareXinerama_ExtInit(pScrn);
1381     }
1382 
1383     if (pVMWARE->xinerama && pVMWARE->xineramaStatic) {
1384        xf86DrvMsg(pScrn->scrnIndex, X_INFO, pVMWARE->xineramaState ?
1385                                             "Using static Xinerama.\n" :
1386                                             "Failed to configure static Xinerama.\n");
1387     }
1388 
1389     /*
1390      * If using the vgahw module, its data structures and related
1391      * things are typically initialised/mapped here.
1392      */
1393     hwp = VGAHWPTR(pScrn);
1394     vgaHWGetIOBase(hwp);
1395 
1396     VMWAREInitFIFO(pScrn);
1397 
1398     /* Initialise the first mode */
1399     VMWAREModeInit(pScrn, pScrn->currentMode, FALSE);
1400 
1401     /* Set the viewport if supported */
1402     VMWAREAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
1403 
1404     /*
1405      * Setup the screen's visuals, and initialise the framebuffer
1406      * code.
1407      */
1408     VMWAREMapMem(pScrn);
1409 
1410     /*
1411      * Clear the framebuffer (and any black-border mode areas).
1412      */
1413     memset(pVMWARE->FbBase, 0, pVMWARE->FbSize);
1414     vmwareSendSVGACmdUpdateFullScreen(pVMWARE);
1415 
1416     /* Reset the visual list */
1417     miClearVisualTypes();
1418 
1419     /*
1420      * Setup the visuals supported.  This driver only supports
1421      * TrueColor for bpp > 8, so the default set of visuals isn't
1422      * acceptable.  To deal with this, call miSetVisualTypes with
1423      * the appropriate visual mask.
1424      */
1425     if (pScrn->bitsPerPixel > 8) {
1426         if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
1427                               pScrn->rgbBits, pScrn->defaultVisual)) {
1428             return FALSE;
1429         }
1430     } else {
1431         if (!miSetVisualTypes(pScrn->depth,
1432                               miGetDefaultVisualMask(pScrn->depth),
1433                               pScrn->rgbBits, pScrn->defaultVisual)) {
1434             return FALSE;
1435         }
1436     }
1437 
1438     miSetPixmapDepths();
1439 
1440     /*
1441      * Initialise the framebuffer.
1442      */
1443     if (!fbScreenInit(pScreen, pVMWARE->FbBase + pVMWARE->fbOffset,
1444                       pScrn->virtualX, pScrn->virtualY,
1445                       pScrn->xDpi, pScrn->yDpi,
1446                       pScrn->displayWidth,
1447                       pScrn->bitsPerPixel)) {
1448         return FALSE;
1449     }
1450 
1451     /* Override the default mask/offset settings */
1452     if (pScrn->bitsPerPixel > 8) {
1453         int i;
1454         VisualPtr visual;
1455 
1456         for (i = 0, visual = pScreen->visuals;
1457              i < pScreen->numVisuals; i++, visual++) {
1458             if ((visual->class | DynamicClass) == DirectColor) {
1459                 visual->offsetRed = pScrn->offset.red;
1460                 visual->offsetGreen = pScrn->offset.green;
1461                 visual->offsetBlue = pScrn->offset.blue;
1462                 visual->redMask = pScrn->mask.red;
1463                 visual->greenMask = pScrn->mask.green;
1464                 visual->blueMask = pScrn->mask.blue;
1465             }
1466         }
1467     }
1468 
1469     /* must be after RGB ordering fixed */
1470     fbPictureInit (pScreen, 0, 0);
1471 
1472     /*
1473      * Save the old screen vector.
1474      */
1475     pVMWARE->ScrnFuncs = *pScreen;
1476 
1477     /*
1478      * Set initial black & white colourmap indices.
1479      */
1480     xf86SetBlackWhitePixels(pScreen);
1481 
1482     /*
1483      * Initialize shadowfb to notify us of dirty rectangles.  We only
1484      * need preFB access callbacks if we're using the hw cursor.
1485      */
1486     if (!ShadowFBInit2(pScreen,
1487                        pVMWARE->hwCursor ? VMWAREPreDirtyBBUpdate : NULL,
1488                        VMWAREPostDirtyBBUpdate)) {
1489         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1490                    "ShadowFB initialization failed\n");
1491         return FALSE;
1492     }
1493 
1494     /*
1495      * If we have a hw cursor, we need to hook functions that might
1496      * read from the framebuffer.
1497      */
1498     if (pVMWARE->hwCursor) {
1499         vmwareCursorHookWrappers(pScreen);
1500     }
1501 
1502     /*
1503      * If backing store is to be supported (as is usually the case),
1504      * initialise it.
1505      */
1506     xf86SetBackingStore(pScreen);
1507     xf86SetSilkenMouse(pScreen);
1508 
1509     /*
1510      * Initialize software cursor.
1511      */
1512     miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
1513 
1514     /*
1515      * Initialize hardware cursor.
1516      */
1517     if (pVMWARE->hwCursor) {
1518         if (!vmwareCursorInit(pScreen)) {
1519             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1520                        "Hardware cursor initialization failed\n");
1521             pVMWARE->hwCursor = FALSE;
1522         }
1523     }
1524 
1525     /*
1526      * Install colourmap functions.  If using the vgahw module,
1527      * vgaHandleColormaps would usually be called here.
1528      */
1529     if (!fbCreateDefColormap(pScreen))
1530         return FALSE;
1531 
1532     if (!xf86HandleColormaps(pScreen, 256, 8,
1533                              VMWARELoadPalette, NULL,
1534                              CMAP_PALETTED_TRUECOLOR |
1535                              CMAP_RELOAD_ON_MODE_SWITCH)) {
1536         return FALSE;
1537     }
1538 
1539     /*
1540      * We explictly add a set of default modes because the X server will
1541      * not include modes larger than the initial one.
1542      */
1543    {
1544       unsigned int i;
1545       unsigned int numModes = sizeof (VMWAREDefaultModes) / sizeof *(VMWAREDefaultModes);
1546       char name[10];
1547       for (i = 0; i < numModes; i++) {
1548          const VMWAREDefaultMode *mode = &VMWAREDefaultModes[i];
1549 
1550          /* Only modes that fit the hardware maximums should be added. */
1551          if (mode->width <= pVMWARE->maxWidth && mode->height <= pVMWARE->maxHeight) {
1552             snprintf(name, 10, "%dx%d", mode->width, mode->height);
1553             VMWAREAddDisplayMode(pScrn, name, mode->width, mode->height);
1554          }
1555       }
1556 
1557       /* Add the hardware maximums as a mode. */
1558       snprintf(name, 10, "%dx%d", pVMWARE->maxWidth, pVMWARE->maxHeight);
1559       VMWAREAddDisplayMode(pScrn, name, pVMWARE->maxWidth, pVMWARE->maxHeight);
1560    }
1561 
1562     /*
1563      * We will lazily add the dynamic modes as the are needed when new
1564      * modes are requested through the control extension.
1565      */
1566     memset(&pVMWARE->dynModes, 0, sizeof pVMWARE->dynModes);
1567 
1568 #if VMWARE_DRIVER_FUNC
1569     pScrn->DriverFunc = VMWareDriverFunc;
1570 #endif
1571 
1572     /* Report any unused options (only for the first generation) */
1573     if (serverGeneration == 1) {
1574         xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
1575     }
1576 
1577     /* Initialize Xv extension */
1578     pVMWARE->videoStreams = NULL;
1579     if (vmwareVideoEnabled(pVMWARE)) {
1580         if (!vmwareVideoInit(pScreen)) {
1581             xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Xv initialization failed\n");
1582         }
1583     }
1584 
1585     /**
1586      * Wrap CloseScreen and SaveScreen. Do this late since we
1587      * want to be first in the callchain, to avoid using resources
1588      * already taken down in CloseScreen.
1589      */
1590 
1591     pVMWARE->ScrnFuncs.CloseScreen = pScreen->CloseScreen;
1592     pVMWARE->ScrnFuncs.SaveScreen = pScreen->SaveScreen;
1593 
1594     pScreen->CloseScreen = VMWARECloseScreen;
1595     pScreen->SaveScreen = VMWARESaveScreen;
1596 
1597     /* Done */
1598     return TRUE;
1599 }
1600 
1601 static Bool
VMWARESwitchMode(SWITCH_MODE_ARGS_DECL)1602 VMWARESwitchMode(SWITCH_MODE_ARGS_DECL)
1603 {
1604     SCRN_INFO_PTR(arg);
1605     ScreenPtr pScreen = pScrn->pScreen;
1606 
1607     pScreen->mmWidth = (pScreen->width * VMWARE_INCHTOMM +
1608 			pScrn->xDpi / 2) / pScrn->xDpi;
1609     pScreen->mmHeight = (pScreen->height * VMWARE_INCHTOMM +
1610 			 pScrn->yDpi / 2) / pScrn->yDpi;
1611 
1612     return VMWAREModeInit(pScrn, mode, TRUE);
1613 }
1614 
1615 static Bool
VMWAREEnterVT(VT_FUNC_ARGS_DECL)1616 VMWAREEnterVT(VT_FUNC_ARGS_DECL)
1617 {
1618     SCRN_INFO_PTR(arg);
1619     VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
1620 
1621     /*
1622      * After system resumes from hiberation, EnterVT will be called and this
1623      * is a good place to restore the SVGA ID register.
1624      */
1625     vmwareWriteReg(pVMWARE, SVGA_REG_ID, pVMWARE->suspensionSavedRegId);
1626 
1627     if (!pVMWARE->SavedReg.svga_fifo_enabled) {
1628         VMWAREInitFIFO(pScrn);
1629     }
1630 
1631     return VMWAREModeInit(pScrn, pScrn->currentMode, TRUE);
1632 }
1633 
1634 static void
VMWARELeaveVT(VT_FUNC_ARGS_DECL)1635 VMWARELeaveVT(VT_FUNC_ARGS_DECL)
1636 {
1637     SCRN_INFO_PTR(arg);
1638     VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
1639 
1640     /*
1641      * Before shutting down system for hibneration, LeaveVT will be called,
1642      * we save the ID register value here and later restore it in EnterVT.
1643      */
1644     pVMWARE->suspensionSavedRegId = vmwareReadReg(pVMWARE, SVGA_REG_ID);
1645 
1646     VMWARERestore(pScrn);
1647 }
1648 
1649 static void
VMWAREFreeScreen(FREE_SCREEN_ARGS_DECL)1650 VMWAREFreeScreen(FREE_SCREEN_ARGS_DECL)
1651 {
1652     SCRN_INFO_PTR(arg);
1653     /*
1654      * If the vgahw module is used vgaHWFreeHWRec() would be called
1655      * here.
1656      */
1657    VMWAREFreeRec(pScrn);
1658 }
1659 
1660 static ModeStatus
VMWAREValidMode(SCRN_ARG_TYPE arg,DisplayModePtr mode,Bool verbose,int flags)1661 VMWAREValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
1662 {
1663     return MODE_OK;
1664 }
1665 
1666 void
vmwlegacy_hookup(ScrnInfoPtr pScrn)1667 vmwlegacy_hookup(ScrnInfoPtr pScrn)
1668 {
1669     pScrn->PreInit = VMWAREPreInit;
1670     pScrn->ScreenInit = VMWAREScreenInit;
1671     pScrn->SwitchMode = VMWARESwitchMode;
1672     pScrn->EnterVT = VMWAREEnterVT;
1673     pScrn->LeaveVT = VMWARELeaveVT;
1674     pScrn->FreeScreen = VMWAREFreeScreen;
1675     pScrn->ValidMode = VMWAREValidMode;
1676 }
1677 
1678 #ifdef XFree86LOADER
1679 void
VMWARERefSymLists(void)1680 VMWARERefSymLists(void)
1681 {
1682     LoaderRefSymLists(vgahwSymbols, fbSymbols, ramdacSymbols,
1683 		      shadowfbSymbols, NULL);
1684 }
1685 #endif	/* XFree86LOADER */
1686