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