vmware.c revision 2e8abef9
1/* ********************************************************** 2 * Copyright (C) 1998-2001 VMware, Inc. 3 * All Rights Reserved 4 * **********************************************************/ 5#ifdef VMX86_DEVEL 6char rcsId_vmware[] = 7 "Id: vmware.c,v 1.11 2001/02/23 02:10:39 yoel Exp $"; 8#endif 9/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/vmware.c,v 1.18 2003/09/24 02:43:31 dawes Exp $ */ 10 11#ifdef HAVE_CONFIG_H 12#include "config.h" 13#endif 14 15/* 16 * TODO: support the vmware linux kernel fb driver (Option "UseFBDev"). 17 */ 18 19#include "xf86.h" 20#include "xf86_OSproc.h" 21#include "xf86Resources.h" 22 23#include "compiler.h" /* inb/outb */ 24 25#include "xf86PciInfo.h" /* pci vendor id */ 26#include "xf86Pci.h" /* pci */ 27 28#include "mipointer.h" /* sw cursor */ 29#include "mibstore.h" /* backing store */ 30#include "micmap.h" /* mi color map */ 31#include "vgaHW.h" /* VGA hardware */ 32#include "fb.h" 33#include "shadowfb.h" /* ShadowFB wrappers */ 34 35#include "xf86cmap.h" /* xf86HandleColormaps */ 36 37#include "vmware.h" 38#include "guest_os.h" 39#include "vm_device_version.h" 40#include "svga_modes.h" 41 42#ifdef HaveDriverFuncs 43#define VMWARE_DRIVER_FUNC HaveDriverFuncs 44#else 45#define VMWARE_DRIVER_FUNC 0 46#endif 47 48/* 49 * So that the file compiles unmodified when dropped in to a < 6.9 source tree. 50 */ 51#ifndef _X_EXPORT 52#define _X_EXPORT 53#endif 54/* 55 * So that the file compiles unmodified when dropped into an xfree source tree. 56 */ 57#ifndef XORG_VERSION_CURRENT 58#define XORG_VERSION_CURRENT XF86_VERSION_CURRENT 59#endif 60 61/* 62 * Sanity check that xf86PciInfo.h has the correct values (which come from 63 * the VMware source tree in vm_device_version.h. 64 */ 65#if PCI_CHIP_VMWARE0405 != PCI_DEVICE_ID_VMWARE_SVGA2 66#error "PCI_CHIP_VMWARE0405 is wrong, update it from vm_device_version.h" 67#endif 68#if PCI_CHIP_VMWARE0710 != PCI_DEVICE_ID_VMWARE_SVGA 69#error "PCI_CHIP_VMWARE0710 is wrong, update it from vm_device_version.h" 70#endif 71#if PCI_VENDOR_VMWARE != PCI_VENDOR_ID_VMWARE 72#error "PCI_VENDOR_VMWARE is wrong, update it from vm_device_version.h" 73#endif 74 75/* 76 * This is the only way I know to turn a #define of an integer constant into 77 * a constant string. 78 */ 79#define VMW_INNERSTRINGIFY(s) #s 80#define VMW_STRING(str) VMW_INNERSTRINGIFY(str) 81 82#define VMWARE_NAME "VMWARE" 83#define VMWARE_DRIVER_NAME "vmware" 84#define VMWARE_MAJOR_VERSION 10 85#define VMWARE_MINOR_VERSION 16 86#define VMWARE_PATCHLEVEL 7 87#define VMWARE_DRIVER_VERSION \ 88 (VMWARE_MAJOR_VERSION * 65536 + VMWARE_MINOR_VERSION * 256 + VMWARE_PATCHLEVEL) 89#define VMWARE_DRIVER_VERSION_STRING \ 90 VMW_STRING(VMWARE_MAJOR_VERSION) "." VMW_STRING(VMWARE_MINOR_VERSION) \ 91 "." VMW_STRING(VMWARE_PATCHLEVEL) 92 93static const char VMWAREBuildStr[] = "VMware Guest X Server " 94 VMWARE_DRIVER_VERSION_STRING " - build=$Name: $\n"; 95 96/* 97 * Standard four digit version string expected by VMware Tools installer. 98 * As the driver's version is only {major, minor, patchlevel}, simply append an 99 * extra zero for the fourth digit. 100 */ 101#ifdef __GNUC__ 102const char vm_svga_version[] __attribute__((section(".modinfo"),unused)) = 103 "version=" VMWARE_DRIVER_VERSION_STRING ".0"; 104#endif 105 106static SymTabRec VMWAREChipsets[] = { 107 { PCI_CHIP_VMWARE0405, "vmware0405" }, 108 { PCI_CHIP_VMWARE0710, "vmware0710" }, 109 { -1, NULL } 110}; 111 112static resRange vmwareLegacyRes[] = { 113 { ResExcIoBlock, SVGA_LEGACY_BASE_PORT, 114 SVGA_LEGACY_BASE_PORT + SVGA_NUM_PORTS*sizeof(uint32)}, 115 _VGA_EXCLUSIVE, _END 116}; 117 118#if XSERVER_LIBPCIACCESS 119 120#define VMWARE_DEVICE_MATCH(d, i) \ 121 {PCI_VENDOR_VMWARE, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) } 122 123static const struct pci_id_match VMwareDeviceMatch[] = { 124 VMWARE_DEVICE_MATCH (PCI_CHIP_VMWARE0405, 0 ), 125 VMWARE_DEVICE_MATCH (PCI_CHIP_VMWARE0710, 0 ), 126 { 0, 0, 0 }, 127}; 128#endif 129 130/* 131 * Currently, even the PCI obedient 0405 chip still only obeys IOSE and 132 * MEMSE for the SVGA resources. Thus, RES_EXCLUSIVE_VGA is required. 133 * 134 * The 0710 chip also uses hardcoded IO ports that aren't disablable. 135 */ 136 137static PciChipsets VMWAREPciChipsets[] = { 138 { PCI_CHIP_VMWARE0405, PCI_CHIP_VMWARE0405, RES_EXCLUSIVE_VGA }, 139 { PCI_CHIP_VMWARE0710, PCI_CHIP_VMWARE0710, vmwareLegacyRes }, 140 { -1, -1, RES_UNDEFINED } 141}; 142 143static const char *vgahwSymbols[] = { 144 "vgaHWGetHWRec", 145 "vgaHWGetIOBase", 146 "vgaHWGetIndex", 147 "vgaHWInit", 148 "vgaHWProtect", 149 "vgaHWRestore", 150 "vgaHWSave", 151 "vgaHWSaveScreen", 152 "vgaHWUnlock", 153 NULL 154}; 155 156static const char *fbSymbols[] = { 157 "fbCreateDefColormap", 158 "fbPictureInit", 159 "fbScreenInit", 160 NULL 161}; 162 163static const char *ramdacSymbols[] = { 164 "xf86CreateCursorInfoRec", 165 "xf86DestroyCursorInfoRec", 166 "xf86InitCursor", 167 NULL 168}; 169 170static const char *shadowfbSymbols[] = { 171 "ShadowFBInit2", 172 NULL 173}; 174 175#ifdef XFree86LOADER 176static XF86ModuleVersionInfo vmwareVersRec = { 177 "vmware", 178 MODULEVENDORSTRING, 179 MODINFOSTRING1, 180 MODINFOSTRING2, 181 XORG_VERSION_CURRENT, 182 VMWARE_MAJOR_VERSION, VMWARE_MINOR_VERSION, VMWARE_PATCHLEVEL, 183 ABI_CLASS_VIDEODRV, 184 ABI_VIDEODRV_VERSION, 185 MOD_CLASS_VIDEODRV, 186 { 0, 0, 0, 0} 187}; 188#endif /* XFree86LOADER */ 189 190typedef enum { 191 OPTION_HW_CURSOR, 192 OPTION_XINERAMA, 193 OPTION_STATIC_XINERAMA 194} VMWAREOpts; 195 196static const OptionInfoRec VMWAREOptions[] = { 197 { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 198 { OPTION_XINERAMA, "Xinerama", OPTV_BOOLEAN, {0}, FALSE }, 199 { OPTION_STATIC_XINERAMA, "StaticXinerama", OPTV_STRING, {0}, FALSE }, 200 { -1, NULL, OPTV_NONE, {0}, FALSE } 201}; 202 203/* Table of default modes to always add to the mode list. */ 204 205typedef struct { 206 int width; 207 int height; 208} VMWAREDefaultMode; 209 210#define SVGA_DEFAULT_MODE(width, height) { width, height, }, 211 212static const VMWAREDefaultMode VMWAREDefaultModes[] = { 213 SVGA_DEFAULT_MODES 214}; 215 216#undef SVGA_DEFAULT_MODE 217 218static void VMWAREStopFIFO(ScrnInfoPtr pScrn); 219static void VMWARESave(ScrnInfoPtr pScrn); 220 221static Bool 222VMWAREGetRec(ScrnInfoPtr pScrn) 223{ 224 if (pScrn->driverPrivate != NULL) { 225 return TRUE; 226 } 227 pScrn->driverPrivate = xnfcalloc(sizeof(VMWARERec), 1); 228 /* FIXME: Initialize driverPrivate... */ 229 return TRUE; 230} 231 232static void 233VMWAREFreeRec(ScrnInfoPtr pScrn) 234{ 235 if (pScrn->driverPrivate) { 236 xfree(pScrn->driverPrivate); 237 pScrn->driverPrivate = NULL; 238 } 239} 240 241CARD32 242vmwareReadReg(VMWAREPtr pVMWARE, int index) 243{ 244 /* 245 * Block SIGIO for the duration, so we don't get interrupted after the 246 * outl but before the inl by a mouse move (which write to our registers). 247 */ 248 int oldsigio, ret; 249 oldsigio = xf86BlockSIGIO(); 250 outl(pVMWARE->indexReg, index); 251 ret = inl(pVMWARE->valueReg); 252 xf86UnblockSIGIO(oldsigio); 253 return ret; 254} 255 256void 257vmwareWriteReg(VMWAREPtr pVMWARE, int index, CARD32 value) 258{ 259 /* 260 * Block SIGIO for the duration, so we don't get interrupted in between 261 * the outls by a mouse move (which write to our registers). 262 */ 263 int oldsigio; 264 oldsigio = xf86BlockSIGIO(); 265 outl(pVMWARE->indexReg, index); 266 outl(pVMWARE->valueReg, value); 267 xf86UnblockSIGIO(oldsigio); 268} 269 270void 271vmwareWriteWordToFIFO(VMWAREPtr pVMWARE, CARD32 value) 272{ 273 CARD32* vmwareFIFO = pVMWARE->vmwareFIFO; 274 275 /* Need to sync? */ 276 if ((vmwareFIFO[SVGA_FIFO_NEXT_CMD] + sizeof(CARD32) == vmwareFIFO[SVGA_FIFO_STOP]) 277 || (vmwareFIFO[SVGA_FIFO_NEXT_CMD] == vmwareFIFO[SVGA_FIFO_MAX] - sizeof(CARD32) && 278 vmwareFIFO[SVGA_FIFO_STOP] == vmwareFIFO[SVGA_FIFO_MIN])) { 279 VmwareLog(("Syncing because of full fifo\n")); 280 vmwareWaitForFB(pVMWARE); 281 } 282 283 vmwareFIFO[vmwareFIFO[SVGA_FIFO_NEXT_CMD] / sizeof(CARD32)] = value; 284 if(vmwareFIFO[SVGA_FIFO_NEXT_CMD] == vmwareFIFO[SVGA_FIFO_MAX] - 285 sizeof(CARD32)) { 286 vmwareFIFO[SVGA_FIFO_NEXT_CMD] = vmwareFIFO[SVGA_FIFO_MIN]; 287 } else { 288 vmwareFIFO[SVGA_FIFO_NEXT_CMD] += sizeof(CARD32); 289 } 290} 291 292void 293vmwareWaitForFB(VMWAREPtr pVMWARE) 294{ 295 vmwareWriteReg(pVMWARE, SVGA_REG_SYNC, 1); 296 while (vmwareReadReg(pVMWARE, SVGA_REG_BUSY)); 297} 298 299void 300vmwareSendSVGACmdUpdate(VMWAREPtr pVMWARE, BoxPtr pBB) 301{ 302 vmwareWriteWordToFIFO(pVMWARE, SVGA_CMD_UPDATE); 303 vmwareWriteWordToFIFO(pVMWARE, pBB->x1); 304 vmwareWriteWordToFIFO(pVMWARE, pBB->y1); 305 vmwareWriteWordToFIFO(pVMWARE, pBB->x2 - pBB->x1); 306 vmwareWriteWordToFIFO(pVMWARE, pBB->y2 - pBB->y1); 307} 308 309void 310vmwareSendSVGACmdUpdateFullScreen(VMWAREPtr pVMWARE) 311{ 312 BoxRec BB; 313 314 BB.x1 = 0; 315 BB.y1 = 0; 316 BB.x2 = pVMWARE->ModeReg.svga_reg_width; 317 BB.y2 = pVMWARE->ModeReg.svga_reg_height; 318 vmwareSendSVGACmdUpdate(pVMWARE, &BB); 319} 320 321static CARD32 322vmwareCalculateWeight(CARD32 mask) 323{ 324 CARD32 weight; 325 326 for (weight = 0; mask; mask >>= 1) { 327 if (mask & 1) { 328 weight++; 329 } 330 } 331 return weight; 332} 333 334/* 335 *----------------------------------------------------------------------------- 336 * 337 * VMXGetVMwareSvgaId -- 338 * 339 * Retrieve the SVGA_ID of the VMware SVGA adapter. 340 * This function should hide any backward compatibility mess. 341 * 342 * Results: 343 * The SVGA_ID_* of the present VMware adapter. 344 * 345 * Side effects: 346 * ins/outs 347 * 348 *----------------------------------------------------------------------------- 349 */ 350 351static uint32 352VMXGetVMwareSvgaId(VMWAREPtr pVMWARE) 353{ 354 uint32 vmware_svga_id; 355 356 /* Any version with any SVGA_ID_* support will initialize SVGA_REG_ID 357 * to SVGA_ID_0 to support versions of this driver with SVGA_ID_0. 358 * 359 * Versions of SVGA_ID_0 ignore writes to the SVGA_REG_ID register. 360 * 361 * Versions of SVGA_ID_1 will allow us to overwrite the content 362 * of the SVGA_REG_ID register only with the values SVGA_ID_0 or SVGA_ID_1. 363 * 364 * Versions of SVGA_ID_2 will allow us to overwrite the content 365 * of the SVGA_REG_ID register only with the values SVGA_ID_0 or SVGA_ID_1 366 * or SVGA_ID_2. 367 */ 368 369 vmwareWriteReg(pVMWARE, SVGA_REG_ID, SVGA_ID_2); 370 vmware_svga_id = vmwareReadReg(pVMWARE, SVGA_REG_ID); 371 if (vmware_svga_id == SVGA_ID_2) { 372 return SVGA_ID_2; 373 } 374 375 vmwareWriteReg(pVMWARE, SVGA_REG_ID, SVGA_ID_1); 376 vmware_svga_id = vmwareReadReg(pVMWARE, SVGA_REG_ID); 377 if (vmware_svga_id == SVGA_ID_1) { 378 return SVGA_ID_1; 379 } 380 381 if (vmware_svga_id == SVGA_ID_0) { 382 return SVGA_ID_0; 383 } 384 385 /* No supported VMware SVGA devices found */ 386 return SVGA_ID_INVALID; 387} 388 389#ifndef XSERVER_LIBPCIACCESS 390/* 391 *---------------------------------------------------------------------- 392 * 393 * RewriteTagString -- 394 * 395 * Rewrites the given string, removing the $Name: $, and 396 * replacing it with the contents. The output string must 397 * have enough room, or else. 398 * 399 * Results: 400 * 401 * Output string updated. 402 * 403 * Side effects: 404 * None. 405 * 406 *---------------------------------------------------------------------- 407 */ 408 409static void 410RewriteTagString(const char *istr, char *ostr, int osize) 411{ 412 int chr; 413 Bool inTag = FALSE; 414 char *op = ostr; 415 416 do { 417 chr = *istr++; 418 if (chr == '$') { 419 if (inTag) { 420 inTag = FALSE; 421 for (; op > ostr && op[-1] == ' '; op--) { 422 } 423 continue; 424 } 425 if (strncmp(istr, "Name:", 5) == 0) { 426 istr += 5; 427 istr += strspn(istr, " "); 428 inTag = TRUE; 429 continue; 430 } 431 } 432 *op++ = chr; 433 } while (chr); 434} 435#endif 436 437static void 438VMWAREIdentify(int flags) 439{ 440 xf86PrintChipsets(VMWARE_NAME, "driver for VMware SVGA", VMWAREChipsets); 441} 442 443static const OptionInfoRec * 444VMWAREAvailableOptions(int chipid, int busid) 445{ 446 return VMWAREOptions; 447} 448 449static int 450VMWAREParseTopologyElement(ScrnInfoPtr pScrn, 451 unsigned int output, 452 const char *elementName, 453 const char *element, 454 const char *expectedTerminators, 455 Bool needTerminator, 456 unsigned int *outValue) 457{ 458 char buf[10] = {0, }; 459 size_t i = 0; 460 int retVal = -1; 461 const char *str = element; 462 463 for (i = 0; str[i] >= '0' && str[i] <= '9'; i++); 464 if (i == 0) { 465 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: unable to parse %s.\n", 466 output, elementName); 467 goto exit; 468 } 469 470 strncpy(buf, str, i); 471 *outValue = atoi(buf); 472 473 if (*outValue > (unsigned short)-1) { 474 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: %s must be less than %hu.\n", 475 output, elementName, (unsigned short)-1); 476 goto exit; 477 } 478 479 str += i; 480 481 if (needTerminator || str[0] != '\0') { 482 Bool unexpected = TRUE; 483 484 for (i = 0; i < strlen(expectedTerminators); i++) { 485 if (str[0] == expectedTerminators[i]) { 486 unexpected = FALSE; 487 } 488 } 489 490 if (unexpected) { 491 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 492 "Output %u: unexpected character '%c' after %s.\n", 493 output, str[0], elementName); 494 goto exit; 495 } else { 496 str++; 497 } 498 } 499 500 retVal = str - element; 501 502 exit: 503 return retVal; 504} 505 506static xXineramaScreenInfo * 507VMWAREParseTopologyString(ScrnInfoPtr pScrn, 508 const char *topology, 509 unsigned int *retNumOutputs) 510{ 511 xXineramaScreenInfo *extents = NULL; 512 unsigned int numOutputs = 0; 513 const char *str = topology; 514 515 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing static Xinerama topology: Starting...\n"); 516 517 do { 518 unsigned int x, y, width, height; 519 int i; 520 521 i = VMWAREParseTopologyElement(pScrn, numOutputs, "width", str, "xX", TRUE, &width); 522 if (i == -1) { 523 goto error; 524 } 525 str += i; 526 527 i = VMWAREParseTopologyElement(pScrn, numOutputs, "height", str, "+", TRUE, &height); 528 if (i == -1) { 529 goto error; 530 } 531 str += i; 532 533 i= VMWAREParseTopologyElement(pScrn, numOutputs, "X offset", str, "+", TRUE, &x); 534 if (i == -1) { 535 goto error; 536 } 537 str += i; 538 539 i = VMWAREParseTopologyElement(pScrn, numOutputs, "Y offset", str, ";", FALSE, &y); 540 if (i == -1) { 541 goto error; 542 } 543 str += i; 544 545 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: %ux%u+%u+%u\n", 546 numOutputs, width, height, x, y); 547 548 numOutputs++; 549 extents = xrealloc(extents, numOutputs * sizeof (xXineramaScreenInfo)); 550 extents[numOutputs - 1].x_org = x; 551 extents[numOutputs - 1].y_org = y; 552 extents[numOutputs - 1].width = width; 553 extents[numOutputs - 1].height = height; 554 } while (*str != 0); 555 556 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing static Xinerama topology: Succeeded.\n"); 557 goto exit; 558 559 error: 560 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing static Xinerama topology: Failed.\n"); 561 562 xfree(extents); 563 extents = NULL; 564 numOutputs = 0; 565 566 exit: 567 *retNumOutputs = numOutputs; 568 return extents; 569} 570 571 572static Bool 573VMWAREPreInit(ScrnInfoPtr pScrn, int flags) 574{ 575 MessageType from; 576 VMWAREPtr pVMWARE; 577 OptionInfoPtr options; 578 int bpp24flags; 579 uint32 id; 580 int i; 581 ClockRange* clockRanges; 582 IOADDRESS domainIOBase = 0; 583 584#ifndef BUILD_FOR_420 585 domainIOBase = pScrn->domainIOBase; 586#endif 587 588 if (flags & PROBE_DETECT) { 589 return FALSE; 590 } 591 592 if (pScrn->numEntities != 1) { 593 return FALSE; 594 } 595 596 if (!VMWAREGetRec(pScrn)) { 597 return FALSE; 598 } 599 pVMWARE = VMWAREPTR(pScrn); 600 601 pVMWARE->pvtSema = &pScrn->vtSema; 602 603 pVMWARE->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 604 if (pVMWARE->pEnt->location.type != BUS_PCI) { 605 return FALSE; 606 } 607 pVMWARE->PciInfo = xf86GetPciInfoForEntity(pVMWARE->pEnt->index); 608 if (pVMWARE->PciInfo == NULL) { 609 return FALSE; 610 } 611 612 if (DEVICE_ID(pVMWARE->PciInfo) == PCI_CHIP_VMWARE0710) { 613 pVMWARE->indexReg = domainIOBase + 614 SVGA_LEGACY_BASE_PORT + SVGA_INDEX_PORT*sizeof(uint32); 615 pVMWARE->valueReg = domainIOBase + 616 SVGA_LEGACY_BASE_PORT + SVGA_VALUE_PORT*sizeof(uint32); 617 } else { 618 /* Note: This setting of valueReg causes unaligned I/O */ 619#if XSERVER_LIBPCIACCESS 620 pVMWARE->portIOBase = pVMWARE->PciInfo->regions[0].base_addr; 621#else 622 pVMWARE->portIOBase = pVMWARE->PciInfo->ioBase[0]; 623#endif 624 pVMWARE->indexReg = domainIOBase + 625 pVMWARE->portIOBase + SVGA_INDEX_PORT; 626 pVMWARE->valueReg = domainIOBase + 627 pVMWARE->portIOBase + SVGA_VALUE_PORT; 628 } 629 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 630 "VMware SVGA regs at (0x%04lx, 0x%04lx)\n", 631 pVMWARE->indexReg, pVMWARE->valueReg); 632 633 if (!xf86LoadSubModule(pScrn, "vgahw")) { 634 return FALSE; 635 } 636 637 xf86LoaderReqSymLists(vgahwSymbols, NULL); 638 639 if (!vgaHWGetHWRec(pScrn)) { 640 return FALSE; 641 } 642 643 /* 644 * Save the current video state. Do it here before VMXGetVMwareSvgaId 645 * writes to any registers. 646 */ 647 VMWARESave(pScrn); 648 649 id = VMXGetVMwareSvgaId(pVMWARE); 650 if (id == SVGA_ID_0 || id == SVGA_ID_INVALID) { 651 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 652 "No supported VMware SVGA found (read ID 0x%08x).\n", id); 653 return FALSE; 654 } 655 pVMWARE->suspensionSavedRegId = id; 656 657#if !XSERVER_LIBPCIACCESS 658 pVMWARE->PciTag = pciTag(pVMWARE->PciInfo->bus, pVMWARE->PciInfo->device, 659 pVMWARE->PciInfo->func); 660#endif 661 pVMWARE->Primary = xf86IsPrimaryPci(pVMWARE->PciInfo); 662 663 pScrn->monitor = pScrn->confScreen->monitor; 664 665#ifdef ACCELERATE_OPS 666 pVMWARE->vmwareCapability = vmwareReadReg(pVMWARE, SVGA_REG_CAPABILITIES); 667#else 668 pVMWARE->vmwareCapability = 0; 669#endif 670 671 pVMWARE->bitsPerPixel = vmwareReadReg(pVMWARE, 672 SVGA_REG_HOST_BITS_PER_PIXEL); 673 if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) { 674 vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL, pVMWARE->bitsPerPixel); 675 } 676 677 pVMWARE->depth = vmwareReadReg(pVMWARE, SVGA_REG_DEPTH); 678 pVMWARE->videoRam = vmwareReadReg(pVMWARE, SVGA_REG_VRAM_SIZE); 679 pVMWARE->memPhysBase = vmwareReadReg(pVMWARE, SVGA_REG_FB_START); 680 pVMWARE->maxWidth = vmwareReadReg(pVMWARE, SVGA_REG_MAX_WIDTH); 681 pVMWARE->maxHeight = vmwareReadReg(pVMWARE, SVGA_REG_MAX_HEIGHT); 682 pVMWARE->cursorDefined = FALSE; 683 pVMWARE->cursorShouldBeHidden = FALSE; 684 685 if (pVMWARE->vmwareCapability & SVGA_CAP_CURSOR_BYPASS_2) { 686 pVMWARE->cursorRemoveFromFB = SVGA_CURSOR_ON_REMOVE_FROM_FB; 687 pVMWARE->cursorRestoreToFB = SVGA_CURSOR_ON_RESTORE_TO_FB; 688 } else { 689 pVMWARE->cursorRemoveFromFB = SVGA_CURSOR_ON_HIDE; 690 pVMWARE->cursorRestoreToFB = SVGA_CURSOR_ON_SHOW; 691 } 692 693 xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "caps: 0x%08X\n", pVMWARE->vmwareCapability); 694 xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "depth: %d\n", pVMWARE->depth); 695 xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "bpp: %d\n", pVMWARE->bitsPerPixel); 696 697 xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "vram: %d\n", pVMWARE->videoRam); 698 xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "pbase: 0x%08lx\n", pVMWARE->memPhysBase); 699 xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "mwidt: %d\n", pVMWARE->maxWidth); 700 xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "mheig: %d\n", pVMWARE->maxHeight); 701 702 if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) { 703 bpp24flags = Support24bppFb | Support32bppFb; 704 } else { 705 switch (pVMWARE->depth) { 706 case 16: 707 /* 708 * In certain cases, the Windows host appears to 709 * report 16 bpp and 16 depth but 555 weight. Just 710 * silently convert it to depth of 15. 711 */ 712 if (pVMWARE->bitsPerPixel == 16 && 713 pVMWARE->weight.green == 5) 714 pVMWARE->depth = 15; 715 case 8: 716 case 15: 717 bpp24flags = NoDepth24Support; 718 break; 719 case 32: 720 /* 721 * There is no 32 bit depth, apparently it can get 722 * reported this way sometimes on the Windows host. 723 */ 724 if (pVMWARE->bitsPerPixel == 32) 725 pVMWARE->depth = 24; 726 case 24: 727 if (pVMWARE->bitsPerPixel == 24) 728 bpp24flags = Support24bppFb; 729 else 730 bpp24flags = Support32bppFb; 731 break; 732 default: 733 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 734 "Adapter is using an unsupported depth (%d).\n", 735 pVMWARE->depth); 736 return FALSE; 737 } 738 } 739 740 if (!xf86SetDepthBpp(pScrn, pVMWARE->depth, pVMWARE->bitsPerPixel, 741 pVMWARE->bitsPerPixel, bpp24flags)) { 742 return FALSE; 743 } 744 745 /* Check that the returned depth is one we support */ 746 switch (pScrn->depth) { 747 case 8: 748 case 15: 749 case 16: 750 case 24: 751 /* OK */ 752 break; 753 default: 754 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 755 "Given depth (%d) is not supported by this driver\n", 756 pScrn->depth); 757 return FALSE; 758 } 759 760 if (pScrn->bitsPerPixel != pVMWARE->bitsPerPixel) { 761 if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) { 762 vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL, 763 pScrn->bitsPerPixel); 764 pVMWARE->bitsPerPixel = 765 vmwareReadReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL); 766 pVMWARE->depth = vmwareReadReg(pVMWARE, SVGA_REG_DEPTH); 767 } else { 768 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 769 "Currently unavailable depth/bpp of %d/%d requested.\n" 770 "\tThe guest X server must run at the same depth and bpp as the host\n" 771 "\t(which are currently %d/%d). This is automatically detected. Please\n" 772 "\tdo not specify a depth on the command line or via the config file.\n", 773 pScrn->depth, pScrn->bitsPerPixel, 774 pVMWARE->depth, pVMWARE->bitsPerPixel); 775 return FALSE; 776 } 777 } 778 779 /* 780 * Defer reading the colour registers until here in case we changed 781 * bpp above. 782 */ 783 784 pVMWARE->weight.red = 785 vmwareCalculateWeight(vmwareReadReg(pVMWARE, SVGA_REG_RED_MASK)); 786 pVMWARE->weight.green = 787 vmwareCalculateWeight(vmwareReadReg(pVMWARE, SVGA_REG_GREEN_MASK)); 788 pVMWARE->weight.blue = 789 vmwareCalculateWeight(vmwareReadReg(pVMWARE, SVGA_REG_BLUE_MASK)); 790 pVMWARE->offset.blue = 0; 791 pVMWARE->offset.green = pVMWARE->weight.blue; 792 pVMWARE->offset.red = pVMWARE->weight.green + pVMWARE->offset.green; 793 pVMWARE->defaultVisual = vmwareReadReg(pVMWARE, SVGA_REG_PSEUDOCOLOR) ? 794 PseudoColor : TrueColor; 795 796 xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 797 2, "depth: %d\n", pVMWARE->depth); 798 xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 799 2, "bpp: %d\n", pVMWARE->bitsPerPixel); 800 xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 801 2, "w.red: %d\n", (int)pVMWARE->weight.red); 802 xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 803 2, "w.grn: %d\n", (int)pVMWARE->weight.green); 804 xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 805 2, "w.blu: %d\n", (int)pVMWARE->weight.blue); 806 xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 807 2, "vis: %d\n", pVMWARE->defaultVisual); 808 809 if (pScrn->depth != pVMWARE->depth) { 810 if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) { 811 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 812 "Currently unavailable depth of %d requested.\n" 813 "\tIf the guest X server's BPP matches the host's " 814 "BPP, then\n\tthe guest X server's depth must also " 815 "match the\n\thost's depth (currently %d).\n", 816 pScrn->depth, pVMWARE->depth); 817 } else { 818 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 819 "Currently unavailable depth of %d requested.\n" 820 "\tThe guest X server must run at the same depth as " 821 "the host (which\n\tis currently %d). This is " 822 "automatically detected. Please do not\n\tspecify " 823 "a depth on the command line or via the config file.\n", 824 pScrn->depth, pVMWARE->depth); 825 } 826 return FALSE; 827 } 828 xf86PrintDepthBpp(pScrn); 829 830#if 0 831 if (pScrn->depth == 24 && pix24bpp == 0) { 832 pix24bpp = xf86GetBppFromDepth(pScrn, 24); 833 } 834#endif 835 836 if (pScrn->depth > 8) { 837 rgb zeros = { 0, 0, 0 }; 838 839 if (!xf86SetWeight(pScrn, pVMWARE->weight, zeros)) { 840 return FALSE; 841 } 842 /* FIXME check returned weight */ 843 } 844 if (!xf86SetDefaultVisual(pScrn, pVMWARE->defaultVisual)) { 845 return FALSE; 846 } 847 if (pScrn->defaultVisual != pVMWARE->defaultVisual) { 848 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 849 "Given visual (%d) is not supported by this driver (%d is required)\n", 850 pScrn->defaultVisual, pVMWARE->defaultVisual); 851 return FALSE; 852 } 853#if 0 854 bytesPerPixel = pScrn->bitsPerPixel / 8; 855#endif 856 pScrn->progClock = TRUE; 857 858#if 0 /* MGA does not do this */ 859 if (pScrn->visual != 0) { /* FIXME */ 860 /* print error message */ 861 return FALSE; 862 } 863#endif 864 865 xf86CollectOptions(pScrn, NULL); 866 if (!(options = xalloc(sizeof(VMWAREOptions)))) 867 return FALSE; 868 memcpy(options, VMWAREOptions, sizeof(VMWAREOptions)); 869 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); 870 871 if (pScrn->depth <= 8) { 872 pScrn->rgbBits = 8; 873 } 874 875 from = X_PROBED; 876 pScrn->chipset = (char*)xf86TokenToString(VMWAREChipsets, DEVICE_ID(pVMWARE->PciInfo)); 877 878 if (!pScrn->chipset) { 879 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ChipID 0x%04x is not recognised\n", DEVICE_ID(pVMWARE->PciInfo)); 880 return FALSE; 881 } 882 883 from = X_DEFAULT; 884 pVMWARE->hwCursor = TRUE; 885 if (xf86GetOptValBool(options, OPTION_HW_CURSOR, &pVMWARE->hwCursor)) { 886 from = X_CONFIG; 887 } 888 if (pVMWARE->hwCursor && !(pVMWARE->vmwareCapability & SVGA_CAP_CURSOR)) { 889 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "HW cursor is not supported in this configuration\n"); 890 from = X_PROBED; 891 pVMWARE->hwCursor = FALSE; 892 } 893 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 894 pVMWARE->hwCursor ? "HW" : "SW"); 895 pScrn->videoRam = pVMWARE->videoRam / 1024; 896 pScrn->memPhysBase = pVMWARE->memPhysBase; 897 898 xfree(options); 899 900 { 901 Gamma zeros = { 0.0, 0.0, 0.0 }; 902 if (!xf86SetGamma(pScrn, zeros)) { 903 return FALSE; 904 } 905 } 906#if 0 907 if ((i = xf86GetPciInfoForScreen(pScrn->scrnIndex, &pciList, NULL)) != 1) { 908 /* print error message */ 909 VMWAREFreeRec(pScrn); 910 if (i > 0) { 911 xfree(pciList); 912 } 913 return FALSE; 914 } 915#endif 916 clockRanges = xnfcalloc(sizeof(ClockRange), 1); 917 clockRanges->next = NULL; 918 clockRanges->minClock = 1; 919 clockRanges->maxClock = 400000000; 920 clockRanges->clockIndex = -1; 921 clockRanges->interlaceAllowed = FALSE; 922 clockRanges->doubleScanAllowed = FALSE; 923 clockRanges->ClockMulFactor = 1; 924 clockRanges->ClockDivFactor = 1; 925 926 /* 927 * Get the default supported modelines 928 */ 929 vmwareGetSupportedModelines(&pScrn->monitor->Modes); 930 931 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes, 932 clockRanges, NULL, 256, pVMWARE->maxWidth, 32 * 32, 933 128, pVMWARE->maxHeight, 934 pScrn->display->virtualX, pScrn->display->virtualY, 935 pVMWARE->videoRam, 936 LOOKUP_BEST_REFRESH); 937 if (i == -1) { 938 VMWAREFreeRec(pScrn); 939 return FALSE; 940 } 941 xf86PruneDriverModes(pScrn); 942 if (i == 0 || pScrn->modes == NULL) { 943 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 944 VMWAREFreeRec(pScrn); 945 return FALSE; 946 } 947 xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); 948 pScrn->currentMode = pScrn->modes; 949 xf86PrintModes(pScrn); 950 xf86SetDpi(pScrn, 0, 0); 951 if (!xf86LoadSubModule(pScrn, "fb") || 952 !xf86LoadSubModule(pScrn, "shadowfb")) { 953 VMWAREFreeRec(pScrn); 954 return FALSE; 955 } 956 xf86LoaderReqSymLists(fbSymbols, shadowfbSymbols, NULL); 957 958 /* Need ramdac for hwcursor */ 959 if (pVMWARE->hwCursor) { 960 if (!xf86LoadSubModule(pScrn, "ramdac")) { 961 VMWAREFreeRec(pScrn); 962 return FALSE; 963 } 964 xf86LoaderReqSymLists(ramdacSymbols, NULL); 965 } 966 967 return TRUE; 968} 969 970static Bool 971VMWAREMapMem(ScrnInfoPtr pScrn) 972{ 973 VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 974#if XSERVER_LIBPCIACCESS 975 int err; 976 struct pci_device *const device = pVMWARE->PciInfo; 977#endif 978 979#if XSERVER_LIBPCIACCESS 980 err = pci_device_map_range(device, 981 pVMWARE->memPhysBase, 982 pVMWARE->videoRam, 983 PCI_DEV_MAP_FLAG_WRITABLE | 984 PCI_DEV_MAP_FLAG_WRITE_COMBINE, 985 (void **) &pVMWARE->FbBase); 986 if (err) { 987 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 988 "Unable to map frame buffer BAR. %s (%d)\n", 989 strerror (err), err); 990 return FALSE; 991 } 992 993#else 994 pVMWARE->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 995 pVMWARE->PciTag, 996 pVMWARE->memPhysBase, 997 pVMWARE->videoRam); 998#endif 999 if (!pVMWARE->FbBase) 1000 return FALSE; 1001 1002 VmwareLog(("FB Mapped: %p/%u -> %p/%u\n", 1003 pVMWARE->memPhysBase, pVMWARE->videoRam, 1004 pVMWARE->FbBase, pVMWARE->videoRam)); 1005 return TRUE; 1006} 1007 1008static Bool 1009VMWAREUnmapMem(ScrnInfoPtr pScrn) 1010{ 1011 VMWAREPtr pVMWARE; 1012 1013 pVMWARE = VMWAREPTR(pScrn); 1014 1015 VmwareLog(("Unmapped: %p/%u\n", pVMWARE->FbBase, pVMWARE->videoRam)); 1016 1017#if XSERVER_LIBPCIACCESS 1018 pci_device_unmap_range(pVMWARE->PciInfo, pVMWARE->FbBase, pVMWARE->videoRam); 1019#else 1020 xf86UnMapVidMem(pScrn->scrnIndex, pVMWARE->FbBase, pVMWARE->videoRam); 1021#endif 1022 pVMWARE->FbBase = NULL; 1023 return TRUE; 1024} 1025 1026static void 1027VMWARESave(ScrnInfoPtr pScrn) 1028{ 1029 vgaHWPtr hwp = VGAHWPTR(pScrn); 1030 vgaRegPtr vgaReg = &hwp->SavedReg; 1031 VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 1032 VMWARERegPtr vmwareReg = &pVMWARE->SavedReg; 1033 1034 vgaHWSave(pScrn, vgaReg, VGA_SR_ALL); 1035 1036 vmwareReg->svga_reg_enable = vmwareReadReg(pVMWARE, SVGA_REG_ENABLE); 1037 vmwareReg->svga_reg_width = vmwareReadReg(pVMWARE, SVGA_REG_WIDTH); 1038 vmwareReg->svga_reg_height = vmwareReadReg(pVMWARE, SVGA_REG_HEIGHT); 1039 vmwareReg->svga_reg_bits_per_pixel = 1040 vmwareReadReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL); 1041 vmwareReg->svga_reg_id = vmwareReadReg(pVMWARE, SVGA_REG_ID); 1042 1043 /* XXX this should be based on the cap bit, not hwCursor... */ 1044 if (pVMWARE->hwCursor) { 1045 vmwareReg->svga_reg_cursor_on = 1046 vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_ON); 1047 vmwareReg->svga_reg_cursor_x = 1048 vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_X); 1049 vmwareReg->svga_reg_cursor_y = 1050 vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_Y); 1051 vmwareReg->svga_reg_cursor_id = 1052 vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_ID); 1053 } 1054 1055 vmwareReg->svga_fifo_enabled = vmwareReadReg(pVMWARE, SVGA_REG_CONFIG_DONE); 1056} 1057 1058static void 1059VMWARERestoreRegs(ScrnInfoPtr pScrn, VMWARERegPtr vmwareReg) 1060{ 1061 VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 1062 VmwareLog(("VMWARERestoreRegs: W: %d, H: %d, BPP: %d, Enable: %d\n", 1063 vmwareReg->svga_reg_width, vmwareReg->svga_reg_height, 1064 vmwareReg->svga_reg_bits_per_pixel, vmwareReg->svga_reg_enable)); 1065 if (vmwareReg->svga_reg_enable) { 1066 vmwareWriteReg(pVMWARE, SVGA_REG_ID, vmwareReg->svga_reg_id); 1067 vmwareWriteReg(pVMWARE, SVGA_REG_WIDTH, vmwareReg->svga_reg_width); 1068 vmwareWriteReg(pVMWARE, SVGA_REG_HEIGHT, vmwareReg->svga_reg_height); 1069 vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL, 1070 vmwareReg->svga_reg_bits_per_pixel); 1071 vmwareWriteReg(pVMWARE, SVGA_REG_ENABLE, vmwareReg->svga_reg_enable); 1072 vmwareWriteReg(pVMWARE, SVGA_REG_GUEST_ID, GUEST_OS_LINUX); 1073 if (pVMWARE->hwCursor) { 1074 vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_ID, 1075 vmwareReg->svga_reg_cursor_id); 1076 vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_X, 1077 vmwareReg->svga_reg_cursor_x); 1078 vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_Y, 1079 vmwareReg->svga_reg_cursor_y); 1080 vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_ON, 1081 vmwareReg->svga_reg_cursor_on); 1082 } 1083 } else { 1084 vmwareWriteReg(pVMWARE, SVGA_REG_ENABLE, vmwareReg->svga_reg_enable); 1085 } 1086} 1087 1088static void 1089VMWARERestore(ScrnInfoPtr pScrn) 1090{ 1091 vgaHWPtr hwp = VGAHWPTR(pScrn); 1092 vgaRegPtr vgaReg = &hwp->SavedReg; 1093 VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 1094 VMWARERegPtr vmwareReg = &pVMWARE->SavedReg; 1095 1096 vmwareWaitForFB(pVMWARE); 1097 if (!vmwareReg->svga_fifo_enabled) { 1098 VMWAREStopFIFO(pScrn); 1099 } 1100 1101 vgaHWProtect(pScrn, TRUE); 1102 VMWARERestoreRegs(pScrn, vmwareReg); 1103 vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); 1104 vgaHWProtect(pScrn, FALSE); 1105} 1106 1107static Bool 1108VMWAREModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool rebuildPixmap) 1109{ 1110 vgaHWPtr hwp = VGAHWPTR(pScrn); 1111 vgaRegPtr vgaReg = &hwp->ModeReg; 1112 VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 1113 VMWARERegPtr vmwareReg = &pVMWARE->ModeReg; 1114 1115 vgaHWUnlock(hwp); 1116 if (!vgaHWInit(pScrn, mode)) 1117 return FALSE; 1118 pScrn->vtSema = TRUE; 1119 1120 vmwareReg->svga_reg_enable = 1; 1121 vmwareReg->svga_reg_width = max(mode->HDisplay, pScrn->virtualX); 1122 vmwareReg->svga_reg_height = max(mode->VDisplay, pScrn->virtualY); 1123 vmwareReg->svga_reg_bits_per_pixel = pVMWARE->bitsPerPixel; 1124 1125 vgaHWProtect(pScrn, TRUE); 1126 1127 vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); 1128 VMWARERestoreRegs(pScrn, vmwareReg); 1129 1130 if (pVMWARE->hwCursor) { 1131 vmwareCursorModeInit(pScrn, mode); 1132 } 1133 1134 VmwareLog(("Required mode: %ux%u\n", mode->HDisplay, mode->VDisplay)); 1135 VmwareLog(("Virtual: %ux%u\n", pScrn->virtualX, pScrn->virtualY)); 1136 VmwareLog(("dispWidth: %u\n", pScrn->displayWidth)); 1137 pVMWARE->fbOffset = vmwareReadReg(pVMWARE, SVGA_REG_FB_OFFSET); 1138 pVMWARE->fbPitch = vmwareReadReg(pVMWARE, SVGA_REG_BYTES_PER_LINE); 1139 pVMWARE->FbSize = vmwareReadReg(pVMWARE, SVGA_REG_FB_SIZE); 1140 1141 pScrn->displayWidth = (pVMWARE->fbPitch * 8) / ((pScrn->bitsPerPixel + 7) & ~7); 1142 VmwareLog(("fbOffset: %u\n", pVMWARE->fbOffset)); 1143 VmwareLog(("fbPitch: %u\n", pVMWARE->fbPitch)); 1144 VmwareLog(("fbSize: %u\n", pVMWARE->FbSize)); 1145 VmwareLog(("New dispWidth: %u\n", pScrn->displayWidth)); 1146 1147 vmwareCheckVideoSanity(pScrn); 1148 1149 if (rebuildPixmap) { 1150 pScrn->pScreen->ModifyPixmapHeader((*pScrn->pScreen->GetScreenPixmap)(pScrn->pScreen), 1151 pScrn->pScreen->width, 1152 pScrn->pScreen->height, 1153 pScrn->pScreen->rootDepth, 1154 pScrn->bitsPerPixel, 1155 PixmapBytePad(pScrn->displayWidth, 1156 pScrn->pScreen->rootDepth), 1157 (pointer)(pVMWARE->FbBase + pScrn->fbOffset)); 1158 1159 (*pScrn->EnableDisableFBAccess)(pScrn->pScreen->myNum, FALSE); 1160 (*pScrn->EnableDisableFBAccess)(pScrn->pScreen->myNum, TRUE); 1161 } 1162 1163 vgaHWProtect(pScrn, FALSE); 1164 1165 /* 1166 * Push the new Xinerama state to X clients and the hardware, 1167 * synchronously with the mode change. Note that this must happen 1168 * AFTER we write the new width and height to the hardware 1169 * registers, since updating the WIDTH and HEIGHT registers will 1170 * reset the device's multimon topology. 1171 */ 1172 vmwareNextXineramaState(pVMWARE); 1173 1174 return TRUE; 1175} 1176 1177void 1178vmwareNextXineramaState(VMWAREPtr pVMWARE) 1179{ 1180 VMWARERegPtr vmwareReg = &pVMWARE->ModeReg; 1181 1182 /* 1183 * Switch to the next Xinerama state (from pVMWARE->xineramaNextState). 1184 * 1185 * This new state will be available to X clients via the Xinerama 1186 * extension, and we push the new state to the virtual hardware, 1187 * in order to configure a number of virtual monitors within the 1188 * device's framebuffer. 1189 * 1190 * This function can be called at any time, but it should usually be 1191 * called just after a mode switch. This is for two reasons: 1192 * 1193 * 1) We don't want X clients to see a Xinerama topology and a video 1194 * mode that are inconsistent with each other, so we'd like to switch 1195 * both at the same time. 1196 * 1197 * 2) We must set the host's display topology registers after setting 1198 * the new video mode, since writes to WIDTH/HEIGHT will reset the 1199 * hardware display topology. 1200 */ 1201 1202 /* 1203 * Update Xinerama info appropriately. 1204 */ 1205 if (pVMWARE->xinerama && !pVMWARE->xineramaStatic) { 1206 if (pVMWARE->xineramaNextState) { 1207 xfree(pVMWARE->xineramaState); 1208 pVMWARE->xineramaState = pVMWARE->xineramaNextState; 1209 pVMWARE->xineramaNumOutputs = pVMWARE->xineramaNextNumOutputs; 1210 1211 pVMWARE->xineramaNextState = NULL; 1212 pVMWARE->xineramaNextNumOutputs = 0; 1213 1214 } else { 1215 /* 1216 * There is no next state pending. Switch back to 1217 * single-monitor mode. This is necessary for resetting the 1218 * Xinerama state if we get a mode change which doesn't 1219 * follow a VMwareCtrlDoSetTopology call. 1220 */ 1221 VMWAREXineramaPtr basicState = 1222 (VMWAREXineramaPtr)xcalloc(1, sizeof (VMWAREXineramaRec)); 1223 if (basicState) { 1224 basicState->x_org = 0; 1225 basicState->y_org = 0; 1226 basicState->width = vmwareReg->svga_reg_width; 1227 basicState->height = vmwareReg->svga_reg_height; 1228 1229 xfree(pVMWARE->xineramaState); 1230 pVMWARE->xineramaState = basicState; 1231 pVMWARE->xineramaNumOutputs = 1; 1232 } 1233 } 1234 } 1235 1236 /* 1237 * Update host's view of guest topology. This tells the device 1238 * how we're carving up its framebuffer into virtual screens. 1239 */ 1240 if (pVMWARE->vmwareCapability & SVGA_CAP_DISPLAY_TOPOLOGY) { 1241 if (pVMWARE->xinerama) { 1242 int i = 0; 1243 VMWAREXineramaPtr xineramaState = pVMWARE->xineramaState; 1244 vmwareWriteReg(pVMWARE, SVGA_REG_NUM_GUEST_DISPLAYS, 1245 pVMWARE->xineramaNumOutputs); 1246 1247 for (i = 0; i < pVMWARE->xineramaNumOutputs; i++) { 1248 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_ID, i); 1249 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_IS_PRIMARY, TRUE); 1250 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_X, 1251 xineramaState[i].x_org); 1252 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_Y, 1253 xineramaState[i].y_org); 1254 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_WIDTH, 1255 xineramaState[i].width); 1256 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_HEIGHT, 1257 xineramaState[i].height); 1258 } 1259 } else { 1260 vmwareWriteReg(pVMWARE, SVGA_REG_NUM_GUEST_DISPLAYS, 1); 1261 1262 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_ID, 0); 1263 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_IS_PRIMARY, TRUE); 1264 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_X, 0); 1265 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_Y, 0); 1266 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_WIDTH, vmwareReg->svga_reg_width); 1267 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_HEIGHT, vmwareReg->svga_reg_height); 1268 } 1269 1270 /* Done. */ 1271 vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_ID, SVGA_INVALID_DISPLAY_ID); 1272 } 1273} 1274 1275static void 1276VMWAREAdjustFrame(int scrnIndex, int x, int y, int flags) 1277{ 1278 /* FIXME */ 1279} 1280 1281static void 1282VMWAREInitFIFO(ScrnInfoPtr pScrn) 1283{ 1284 VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 1285#if XSERVER_LIBPCIACCESS 1286 struct pci_device *const device = pVMWARE->PciInfo; 1287 int err; 1288#endif 1289 CARD32* vmwareFIFO; 1290 Bool extendedFifo; 1291 int min; 1292 1293 TRACEPOINT 1294 1295 pVMWARE->mmioPhysBase = vmwareReadReg(pVMWARE, SVGA_REG_MEM_START); 1296 pVMWARE->mmioSize = vmwareReadReg(pVMWARE, SVGA_REG_MEM_SIZE) & ~3; 1297#if XSERVER_LIBPCIACCESS 1298 err = pci_device_map_range(device, pVMWARE->mmioPhysBase, 1299 pVMWARE->mmioSize, 1300 PCI_DEV_MAP_FLAG_WRITABLE, 1301 (void **) &pVMWARE->mmioVirtBase); 1302 if (err) { 1303 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1304 "Unable to map mmio BAR. %s (%d)\n", 1305 strerror (err), err); 1306 return; 1307 } 1308#else 1309 pVMWARE->mmioVirtBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, 1310 pVMWARE->PciTag, 1311 pVMWARE->mmioPhysBase, 1312 pVMWARE->mmioSize); 1313#endif 1314 vmwareFIFO = pVMWARE->vmwareFIFO = (CARD32*)pVMWARE->mmioVirtBase; 1315 1316 extendedFifo = pVMWARE->vmwareCapability & SVGA_CAP_EXTENDED_FIFO; 1317 min = extendedFifo ? vmwareReadReg(pVMWARE, SVGA_REG_MEM_REGS) : 4; 1318 1319 vmwareFIFO[SVGA_FIFO_MIN] = min * sizeof(CARD32); 1320 vmwareFIFO[SVGA_FIFO_MAX] = pVMWARE->mmioSize; 1321 vmwareFIFO[SVGA_FIFO_NEXT_CMD] = min * sizeof(CARD32); 1322 vmwareFIFO[SVGA_FIFO_STOP] = min * sizeof(CARD32); 1323 vmwareWriteReg(pVMWARE, SVGA_REG_CONFIG_DONE, 1); 1324} 1325 1326static void 1327VMWAREStopFIFO(ScrnInfoPtr pScrn) 1328{ 1329 VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 1330 1331 TRACEPOINT 1332 1333 vmwareWriteReg(pVMWARE, SVGA_REG_CONFIG_DONE, 0); 1334#if XSERVER_LIBPCIACCESS 1335 pci_device_unmap_range(pVMWARE->PciInfo, pVMWARE->mmioVirtBase, pVMWARE->mmioSize); 1336#else 1337 xf86UnMapVidMem(pScrn->scrnIndex, pVMWARE->mmioVirtBase, pVMWARE->mmioSize); 1338#endif 1339} 1340 1341static Bool 1342VMWARECloseScreen(int scrnIndex, ScreenPtr pScreen) 1343{ 1344 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1345 VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 1346 ScreenPtr save = &pVMWARE->ScrnFuncs; 1347 1348 VmwareLog(("cursorSema: %d\n", pVMWARE->cursorSema)); 1349 1350 if (*pVMWARE->pvtSema) { 1351 if (pVMWARE->videoStreams) { 1352 vmwareVideoEnd(pScreen); 1353 } 1354 1355 if (pVMWARE->CursorInfoRec) { 1356 vmwareCursorCloseScreen(pScreen); 1357 } 1358 1359 VMWARERestore(pScrn); 1360 VMWAREUnmapMem(pScrn); 1361 1362 pScrn->vtSema = FALSE; 1363 } 1364 1365 pScreen->CloseScreen = save->CloseScreen; 1366 pScreen->SaveScreen = save->SaveScreen; 1367 1368#if VMWARE_DRIVER_FUNC 1369 pScrn->DriverFunc = NULL; 1370#endif 1371 1372 return (*pScreen->CloseScreen)(scrnIndex, pScreen); 1373} 1374 1375static Bool 1376VMWARESaveScreen(ScreenPtr pScreen, int mode) 1377{ 1378 VmwareLog(("VMWareSaveScreen() mode = %d\n", mode)); 1379 1380 /* 1381 * This thoroughly fails to do anything useful to svga mode. I doubt 1382 * we care; who wants to idle-blank their VM's screen anyway? 1383 */ 1384 return vgaHWSaveScreen(pScreen, mode); 1385} 1386 1387/* disabled by default to reduce spew in DEBUG_LOGGING mode. */ 1388/*#define DEBUG_LOG_UPDATES*/ 1389 1390static void 1391VMWAREPreDirtyBBUpdate(ScrnInfoPtr pScrn, int nboxes, BoxPtr boxPtr) 1392{ 1393 VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 1394 1395#ifdef DEBUG_LOG_UPDATES 1396 { 1397 int i; 1398 for (i = 0; i < nboxes; i++) { 1399 VmwareLog(("PreUpdate #%d (%d, %d, w = %d, h = %d)\n", nboxes - i, 1400 boxPtr[i].x1, boxPtr[i].y1, 1401 boxPtr[i].x2 - boxPtr[i].x1, 1402 boxPtr[i].y2 - boxPtr[i].y1)); 1403 } 1404 } 1405#endif 1406 1407 /* 1408 * We only register this callback if we have a HW cursor. 1409 */ 1410 while (nboxes--) { 1411 if (BOX_INTERSECT(*boxPtr, pVMWARE->hwcur.box)) { 1412 if (!pVMWARE->cursorExcludedForUpdate) { 1413 PRE_OP_HIDE_CURSOR(); 1414 pVMWARE->cursorExcludedForUpdate = TRUE; 1415 } 1416 break; 1417 } 1418 boxPtr++; 1419 } 1420} 1421 1422static void 1423VMWAREPostDirtyBBUpdate(ScrnInfoPtr pScrn, int nboxes, BoxPtr boxPtr) 1424{ 1425 VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 1426 while (nboxes--) { 1427#ifdef DEBUG_LOG_UPDATES 1428 VmwareLog(("PostUpdate #%d (%d, %d, w = %d, h = %d)\n", nboxes, 1429 boxPtr->x1, boxPtr->y1, 1430 boxPtr->x2 - boxPtr->x1, boxPtr->y2 - boxPtr->y1)); 1431#endif 1432 1433 /* Clip off (y only) for offscreen memory */ 1434 if (boxPtr->y2 >= pVMWARE->ModeReg.svga_reg_height) 1435 boxPtr->y2 = pVMWARE->ModeReg.svga_reg_height; 1436 if (boxPtr->y1 >= pVMWARE->ModeReg.svga_reg_height) 1437 boxPtr->y1 = pVMWARE->ModeReg.svga_reg_height; 1438 if (boxPtr->y1 == boxPtr->y2) { 1439 boxPtr++; 1440 continue; 1441 } 1442 1443 vmwareSendSVGACmdUpdate(pVMWARE, boxPtr++); 1444 } 1445 1446 if (pVMWARE->hwCursor && pVMWARE->cursorExcludedForUpdate) { 1447 POST_OP_SHOW_CURSOR(); 1448 pVMWARE->cursorExcludedForUpdate = FALSE; 1449 } 1450} 1451 1452static void 1453VMWARELoadPalette(ScrnInfoPtr pScrn, int numColors, int* indices, 1454 LOCO* colors, VisualPtr pVisual) 1455{ 1456 VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 1457 int i; 1458 1459 for (i = 0; i < numColors; i++) { 1460 vmwareWriteReg(pVMWARE, SVGA_PALETTE_BASE + *indices * 3 + 0, colors[*indices].red); 1461 vmwareWriteReg(pVMWARE, SVGA_PALETTE_BASE + *indices * 3 + 1, colors[*indices].green); 1462 vmwareWriteReg(pVMWARE, SVGA_PALETTE_BASE + *indices * 3 + 2, colors[*indices].blue); 1463 indices++; 1464 } 1465 VmwareLog(("Palette loading done\n")); 1466} 1467 1468 1469DisplayModeRec * 1470VMWAREAddDisplayMode(ScrnInfoPtr pScrn, 1471 const char *name, 1472 int width, 1473 int height) 1474{ 1475 DisplayModeRec *mode; 1476 1477 mode = xalloc(sizeof(DisplayModeRec)); 1478 memset(mode, 0, sizeof *mode); 1479 1480 mode->name = xalloc(strlen(name) + 1); 1481 strcpy(mode->name, name); 1482 mode->status = MODE_OK; 1483 mode->type = M_T_DEFAULT; 1484 mode->HDisplay = width; 1485 mode->VDisplay = height; 1486 1487 mode->next = pScrn->modes; 1488 mode->prev = pScrn->modes->prev; 1489 pScrn->modes->prev->next = mode; 1490 pScrn->modes->prev = mode; 1491 1492 return mode; 1493} 1494 1495 1496/* 1497 *----------------------------------------------------------------------------- 1498 * 1499 * vmwareIsRegionEqual -- 1500 * 1501 * This function implements REGION_EQUAL because older versions of 1502 * regionstr.h don't define it. 1503 * It is a slightly modified version of miRegionEqual from $Xorg: miregion.c 1504 * 1505 * Results: 1506 * TRUE if regions are equal; FALSE otherwise 1507 * 1508 * Side effects: 1509 * None. 1510 * 1511 *----------------------------------------------------------------------------- 1512 */ 1513 1514Bool 1515vmwareIsRegionEqual(const RegionPtr reg1, 1516 const RegionPtr reg2) 1517{ 1518 int i, num; 1519 BoxPtr rects1, rects2; 1520 1521 if ((reg1->extents.x1 != reg2->extents.x1) || 1522 (reg1->extents.x2 != reg2->extents.x2) || 1523 (reg1->extents.y1 != reg2->extents.y1) || 1524 (reg1->extents.y2 != reg2->extents.y2)) { 1525 return FALSE; 1526 } 1527 1528 num = REGION_NUM_RECTS(reg1); 1529 if (num != REGION_NUM_RECTS(reg2)) { 1530 return FALSE; 1531 } 1532 1533 rects1 = REGION_RECTS(reg1); 1534 rects2 = REGION_RECTS(reg2); 1535 1536 for (i = 0; i < num; i++) { 1537 if ((rects1[i].x1 != rects2[i].x1) || 1538 (rects1[i].x2 != rects2[i].x2) || 1539 (rects1[i].y1 != rects2[i].y1) || 1540 (rects1[i].y2 != rects2[i].y2)) { 1541 return FALSE; 1542 } 1543 } 1544 1545 return TRUE; 1546} 1547 1548 1549#if VMWARE_DRIVER_FUNC 1550static Bool 1551VMWareDriverFunc(ScrnInfoPtr pScrn, 1552 xorgDriverFuncOp op, 1553 pointer data) 1554{ 1555 CARD32 *flag; 1556 xorgRRModeMM *modemm; 1557 1558 switch (op) { 1559 case GET_REQUIRED_HW_INTERFACES: 1560 flag = (CARD32 *)data; 1561 1562 if (flag) { 1563 *flag = HW_IO | HW_MMIO; 1564 } 1565 return TRUE; 1566 case RR_GET_MODE_MM: 1567 modemm = (xorgRRModeMM *)data; 1568 1569 /* 1570 * Because changing the resolution of the guest is usually changing the size 1571 * of a window on the host desktop, the real physical DPI will not change. To 1572 * keep the guest in sync, we scale the 'physical' screen dimensions to 1573 * keep the DPI constant. 1574 */ 1575 if (modemm && modemm->mode) { 1576 modemm->mmWidth *= modemm->mode->HDisplay / (double)(modemm->virtX); 1577 modemm->mmHeight *= modemm->mode->VDisplay / (double)(modemm->virtY); 1578 } 1579 return TRUE; 1580 default: 1581 return FALSE; 1582 } 1583} 1584#endif 1585 1586 1587static Bool 1588VMWAREScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 1589{ 1590 ScrnInfoPtr pScrn; 1591 vgaHWPtr hwp; 1592 VMWAREPtr pVMWARE; 1593 OptionInfoPtr options; 1594 Bool useXinerama = TRUE; 1595 1596 /* Get the ScrnInfoRec */ 1597 pScrn = xf86Screens[pScreen->myNum]; 1598 pVMWARE = VMWAREPTR(pScrn); 1599 1600 1601 xf86CollectOptions(pScrn, NULL); 1602 if (!(options = xalloc(sizeof(VMWAREOptions)))) 1603 return FALSE; 1604 memcpy(options, VMWAREOptions, sizeof(VMWAREOptions)); 1605 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); 1606 1607 /* 1608 * Init xinerama preferences. 1609 */ 1610 useXinerama = xf86ReturnOptValBool(options, OPTION_XINERAMA, 1611 pVMWARE->vmwareCapability & SVGA_CAP_MULTIMON); 1612 if (useXinerama && !(pVMWARE->vmwareCapability & SVGA_CAP_MULTIMON)) { 1613 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1614 "Xinerama is not safely supported by the current virtual hardware. " 1615 "Do not request resolutions that require > 16MB of framebuffer.\n"); 1616 } 1617 1618 1619 if (useXinerama && xf86IsOptionSet(options, OPTION_STATIC_XINERAMA)) { 1620 char *topology = xf86GetOptValString(options, OPTION_STATIC_XINERAMA); 1621 if (topology) { 1622 pVMWARE->xineramaState = 1623 VMWAREParseTopologyString(pScrn, topology, &pVMWARE->xineramaNumOutputs); 1624 1625 pVMWARE->xineramaStatic = pVMWARE->xineramaState != NULL; 1626 1627 xfree(topology); 1628 } 1629 } 1630 1631 xfree(options); 1632 1633 /* Initialise VMWARE_CTRL extension. */ 1634 VMwareCtrl_ExtInit(pScrn); 1635 1636 /* Initialise Xinerama extension. */ 1637 if (useXinerama) { 1638 VMwareXinerama_ExtInit(pScrn); 1639 } 1640 1641 if (pVMWARE->xinerama && pVMWARE->xineramaStatic) { 1642 xf86DrvMsg(pScrn->scrnIndex, X_INFO, pVMWARE->xineramaState ? 1643 "Using static Xinerama.\n" : 1644 "Failed to configure static Xinerama.\n"); 1645 } 1646 1647 /* 1648 * If using the vgahw module, its data structures and related 1649 * things are typically initialised/mapped here. 1650 */ 1651 hwp = VGAHWPTR(pScrn); 1652 vgaHWGetIOBase(hwp); 1653 1654 VMWAREInitFIFO(pScrn); 1655 1656 /* Initialise the first mode */ 1657 VMWAREModeInit(pScrn, pScrn->currentMode, FALSE); 1658 1659 /* Set the viewport if supported */ 1660 VMWAREAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 1661 1662 /* 1663 * Setup the screen's visuals, and initialise the framebuffer 1664 * code. 1665 */ 1666 VMWAREMapMem(pScrn); 1667 1668 /* 1669 * Clear the framebuffer (and any black-border mode areas). 1670 */ 1671 memset(pVMWARE->FbBase, 0, pVMWARE->FbSize); 1672 vmwareSendSVGACmdUpdateFullScreen(pVMWARE); 1673 1674 /* Reset the visual list */ 1675 miClearVisualTypes(); 1676 1677 /* 1678 * Setup the visuals supported. This driver only supports 1679 * TrueColor for bpp > 8, so the default set of visuals isn't 1680 * acceptable. To deal with this, call miSetVisualTypes with 1681 * the appropriate visual mask. 1682 */ 1683 if (pScrn->bitsPerPixel > 8) { 1684 if (!miSetVisualTypes(pScrn->depth, TrueColorMask, 1685 pScrn->rgbBits, pScrn->defaultVisual)) { 1686 return FALSE; 1687 } 1688 } else { 1689 if (!miSetVisualTypes(pScrn->depth, 1690 miGetDefaultVisualMask(pScrn->depth), 1691 pScrn->rgbBits, pScrn->defaultVisual)) { 1692 return FALSE; 1693 } 1694 } 1695 1696 miSetPixmapDepths(); 1697 1698 /* 1699 * Initialise the framebuffer. 1700 */ 1701 if (!fbScreenInit(pScreen, pVMWARE->FbBase + pVMWARE->fbOffset, 1702 pScrn->virtualX, pScrn->virtualY, 1703 pScrn->xDpi, pScrn->yDpi, 1704 pScrn->displayWidth, 1705 pScrn->bitsPerPixel)) { 1706 return FALSE; 1707 } 1708 1709 /* Override the default mask/offset settings */ 1710 if (pScrn->bitsPerPixel > 8) { 1711 int i; 1712 VisualPtr visual; 1713 1714 for (i = 0, visual = pScreen->visuals; 1715 i < pScreen->numVisuals; i++, visual++) { 1716 if ((visual->class | DynamicClass) == DirectColor) { 1717 visual->offsetRed = pScrn->offset.red; 1718 visual->offsetGreen = pScrn->offset.green; 1719 visual->offsetBlue = pScrn->offset.blue; 1720 visual->redMask = pScrn->mask.red; 1721 visual->greenMask = pScrn->mask.green; 1722 visual->blueMask = pScrn->mask.blue; 1723 } 1724 } 1725 } 1726 1727 /* must be after RGB ordering fixed */ 1728 fbPictureInit (pScreen, 0, 0); 1729 1730 /* 1731 * Save the old screen vector, then wrap CloseScreen and 1732 * set SaveScreen. 1733 */ 1734 pVMWARE->ScrnFuncs = *pScreen; 1735 pScreen->CloseScreen = VMWARECloseScreen; 1736 pScreen->SaveScreen = VMWARESaveScreen; 1737 1738 /* 1739 * Set initial black & white colourmap indices. 1740 */ 1741 xf86SetBlackWhitePixels(pScreen); 1742 1743 /* 1744 * Initialize shadowfb to notify us of dirty rectangles. We only 1745 * need preFB access callbacks if we're using the hw cursor. 1746 */ 1747 if (!ShadowFBInit2(pScreen, 1748 pVMWARE->hwCursor ? VMWAREPreDirtyBBUpdate : NULL, 1749 VMWAREPostDirtyBBUpdate)) { 1750 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1751 "ShadowFB initialization failed\n"); 1752 return FALSE; 1753 } 1754 1755 /* 1756 * If we have a hw cursor, we need to hook functions that might 1757 * read from the framebuffer. 1758 */ 1759 if (pVMWARE->hwCursor) { 1760 vmwareCursorHookWrappers(pScreen); 1761 } 1762 1763 /* 1764 * If backing store is to be supported (as is usually the case), 1765 * initialise it. 1766 */ 1767 miInitializeBackingStore(pScreen); 1768 xf86SetBackingStore(pScreen); 1769 xf86SetSilkenMouse(pScreen); 1770 1771 /* 1772 * Initialize software cursor. 1773 */ 1774 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 1775 1776 /* 1777 * Initialize hardware cursor. 1778 */ 1779 if (pVMWARE->hwCursor) { 1780 if (!vmwareCursorInit(pScreen)) { 1781 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1782 "Hardware cursor initialization failed\n"); 1783 pVMWARE->hwCursor = FALSE; 1784 } 1785 } 1786 1787 /* 1788 * Install colourmap functions. If using the vgahw module, 1789 * vgaHandleColormaps would usually be called here. 1790 */ 1791 if (!fbCreateDefColormap(pScreen)) 1792 return FALSE; 1793 1794 if (!xf86HandleColormaps(pScreen, 256, 8, 1795 VMWARELoadPalette, NULL, 1796 CMAP_PALETTED_TRUECOLOR | 1797 CMAP_RELOAD_ON_MODE_SWITCH)) { 1798 return FALSE; 1799 } 1800 1801 /* 1802 * We explictly add a set of default modes because the X server will 1803 * not include modes larger than the initial one. 1804 */ 1805 { 1806 unsigned int i; 1807 unsigned int numModes = sizeof (VMWAREDefaultModes) / sizeof *(VMWAREDefaultModes); 1808 char name[10]; 1809 for (i = 0; i < numModes; i++) { 1810 const VMWAREDefaultMode *mode = &VMWAREDefaultModes[i]; 1811 1812 /* Only modes that fit the hardware maximums should be added. */ 1813 if (mode->width <= pVMWARE->maxWidth && mode->height <= pVMWARE->maxHeight) { 1814 snprintf(name, 10, "%dx%d", mode->width, mode->height); 1815 VMWAREAddDisplayMode(pScrn, name, mode->width, mode->height); 1816 } 1817 } 1818 1819 /* Add the hardware maximums as a mode. */ 1820 snprintf(name, 10, "%dx%d", pVMWARE->maxWidth, pVMWARE->maxHeight); 1821 VMWAREAddDisplayMode(pScrn, name, pVMWARE->maxWidth, pVMWARE->maxHeight); 1822 } 1823 1824 /* 1825 * We will lazily add the dynamic modes as the are needed when new 1826 * modes are requested through the control extension. 1827 */ 1828 memset(&pVMWARE->dynModes, 0, sizeof pVMWARE->dynModes); 1829 1830#if VMWARE_DRIVER_FUNC 1831 pScrn->DriverFunc = VMWareDriverFunc; 1832#endif 1833 1834 /* Report any unused options (only for the first generation) */ 1835 if (serverGeneration == 1) { 1836 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 1837 } 1838 1839 /* Initialize Xv extension */ 1840 pVMWARE->videoStreams = NULL; 1841 if (vmwareVideoEnabled(pVMWARE)) { 1842 if (!vmwareVideoInit(pScreen)) { 1843 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Xv initialization failed\n"); 1844 } 1845 } 1846 1847 1848 /* Done */ 1849 return TRUE; 1850} 1851 1852static Bool 1853VMWARESwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 1854{ 1855 return VMWAREModeInit(xf86Screens[scrnIndex], mode, TRUE); 1856} 1857 1858static Bool 1859VMWAREEnterVT(int scrnIndex, int flags) 1860{ 1861 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1862 VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 1863 1864 /* 1865 * After system resumes from hiberation, EnterVT will be called and this 1866 * is a good place to restore the SVGA ID register. 1867 */ 1868 vmwareWriteReg(pVMWARE, SVGA_REG_ID, pVMWARE->suspensionSavedRegId); 1869 1870 if (!pVMWARE->SavedReg.svga_fifo_enabled) { 1871 VMWAREInitFIFO(pScrn); 1872 } 1873 1874 return VMWAREModeInit(pScrn, pScrn->currentMode, TRUE); 1875} 1876 1877static void 1878VMWARELeaveVT(int scrnIndex, int flags) 1879{ 1880 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1881 VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 1882 1883 /* 1884 * Before shutting down system for hibneration, LeaveVT will be called, 1885 * we save the ID register value here and later restore it in EnterVT. 1886 */ 1887 pVMWARE->suspensionSavedRegId = vmwareReadReg(pVMWARE, SVGA_REG_ID); 1888 1889 VMWARERestore(pScrn); 1890} 1891 1892static void 1893VMWAREFreeScreen(int scrnIndex, int flags) 1894{ 1895 /* 1896 * If the vgahw module is used vgaHWFreeHWRec() would be called 1897 * here. 1898 */ 1899 VMWAREFreeRec(xf86Screens[scrnIndex]); 1900} 1901 1902static ModeStatus 1903VMWAREValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 1904{ 1905 return MODE_OK; 1906} 1907 1908#if XSERVER_LIBPCIACCESS 1909static Bool 1910VMwarePciProbe (DriverPtr drv, 1911 int entity_num, 1912 struct pci_device *device, 1913 intptr_t match_data) 1914{ 1915 ScrnInfoPtr scrn = NULL; 1916 EntityInfoPtr entity; 1917 1918 scrn = xf86ConfigPciEntity(scrn, 0, entity_num, VMWAREPciChipsets, 1919 NULL, NULL, NULL, NULL, NULL); 1920 if (scrn != NULL) { 1921 scrn->driverVersion = VMWARE_DRIVER_VERSION; 1922 scrn->driverName = VMWARE_DRIVER_NAME; 1923 scrn->name = VMWARE_NAME; 1924 scrn->Probe = NULL; 1925 } 1926 1927 entity = xf86GetEntityInfo(entity_num); 1928 switch (DEVICE_ID(device)) { 1929 case PCI_CHIP_VMWARE0405: 1930 case PCI_CHIP_VMWARE0710: 1931 xf86MsgVerb(X_INFO, 4, "VMwarePciProbe: Valid device\n"); 1932 scrn->PreInit = VMWAREPreInit; 1933 scrn->ScreenInit = VMWAREScreenInit; 1934 scrn->SwitchMode = VMWARESwitchMode; 1935 scrn->EnterVT = VMWAREEnterVT; 1936 scrn->LeaveVT = VMWARELeaveVT; 1937 scrn->FreeScreen = VMWAREFreeScreen; 1938 scrn->ValidMode = VMWAREValidMode; 1939 break; 1940 default: 1941 xf86MsgVerb(X_INFO, 4, "VMwarePciProbe: Unknown device\n"); 1942 } 1943 return scrn != NULL; 1944} 1945#else 1946 1947static Bool 1948VMWAREProbe(DriverPtr drv, int flags) 1949{ 1950 int numDevSections, numUsed; 1951 GDevPtr *devSections; 1952 int *usedChips; 1953 int i; 1954 Bool foundScreen = FALSE; 1955 char buildString[sizeof(VMWAREBuildStr)]; 1956 1957 RewriteTagString(VMWAREBuildStr, buildString, sizeof(VMWAREBuildStr)); 1958 xf86MsgVerb(X_PROBED, 4, "%s", buildString); 1959 1960 numDevSections = xf86MatchDevice(VMWARE_DRIVER_NAME, &devSections); 1961 if (numDevSections <= 0) { 1962#ifdef DEBUG 1963 xf86MsgVerb(X_ERROR, 0, "No vmware driver section\n"); 1964#endif 1965 return FALSE; 1966 } 1967 if (xf86GetPciVideoInfo()) { 1968 VmwareLog(("Some PCI Video Info Exists\n")); 1969 numUsed = xf86MatchPciInstances(VMWARE_NAME, PCI_VENDOR_VMWARE, 1970 VMWAREChipsets, VMWAREPciChipsets, devSections, 1971 numDevSections, drv, &usedChips); 1972 xfree(devSections); 1973 if (numUsed <= 0) 1974 return FALSE; 1975 if (flags & PROBE_DETECT) 1976 foundScreen = TRUE; 1977 else 1978 for (i = 0; i < numUsed; i++) { 1979 ScrnInfoPtr pScrn = NULL; 1980 1981 VmwareLog(("Even some VMware SVGA PCI instances exists\n")); 1982 pScrn = xf86ConfigPciEntity(pScrn, flags, usedChips[i], 1983 VMWAREPciChipsets, NULL, NULL, NULL, 1984 NULL, NULL); 1985 if (pScrn) { 1986 VmwareLog(("And even configuration suceeded\n")); 1987 pScrn->driverVersion = VMWARE_DRIVER_VERSION; 1988 pScrn->driverName = VMWARE_DRIVER_NAME; 1989 pScrn->name = VMWARE_NAME; 1990 pScrn->Probe = VMWAREProbe; 1991 pScrn->PreInit = VMWAREPreInit; 1992 pScrn->ScreenInit = VMWAREScreenInit; 1993 pScrn->SwitchMode = VMWARESwitchMode; 1994 pScrn->AdjustFrame = VMWAREAdjustFrame; 1995 pScrn->EnterVT = VMWAREEnterVT; 1996 pScrn->LeaveVT = VMWARELeaveVT; 1997 pScrn->FreeScreen = VMWAREFreeScreen; 1998 pScrn->ValidMode = VMWAREValidMode; 1999 foundScreen = TRUE; 2000 } 2001 } 2002 xfree(usedChips); 2003 } 2004 return foundScreen; 2005} 2006#endif 2007 2008 2009_X_EXPORT DriverRec VMWARE = { 2010 VMWARE_DRIVER_VERSION, 2011 VMWARE_DRIVER_NAME, 2012 VMWAREIdentify, 2013#if XSERVER_LIBPCIACCESS 2014 NULL, 2015#else 2016 VMWAREProbe, 2017#endif 2018 VMWAREAvailableOptions, 2019 NULL, 2020 0, 2021#if VMWARE_DRIVER_FUNC 2022 VMWareDriverFunc, 2023#endif 2024#if XSERVER_LIBPCIACCESS 2025 VMwareDeviceMatch, 2026 VMwarePciProbe, 2027#endif 2028}; 2029 2030#ifdef XFree86LOADER 2031static MODULESETUPPROTO(vmwareSetup); 2032 2033_X_EXPORT XF86ModuleData vmwareModuleData = { 2034 &vmwareVersRec, 2035 vmwareSetup, 2036 NULL 2037}; 2038 2039static pointer 2040vmwareSetup(pointer module, pointer opts, int *errmaj, int *errmin) 2041{ 2042 static Bool setupDone = FALSE; 2043 2044 if (!setupDone) { 2045 setupDone = TRUE; 2046 xf86AddDriver(&VMWARE, module, VMWARE_DRIVER_FUNC); 2047 2048 LoaderRefSymLists(vgahwSymbols, fbSymbols, ramdacSymbols, 2049 shadowfbSymbols, NULL); 2050 2051 return (pointer)1; 2052 } 2053 if (errmaj) { 2054 *errmaj = LDR_ONCEONLY; 2055 } 2056 return NULL; 2057} 2058#endif /* XFree86LOADER */ 2059