|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1990-1992 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: xga.c ! 8: ! 9: Abstract: ! 10: ! 11: This module contains the code that implements the XGA miniport driver. ! 12: ! 13: Environment: ! 14: ! 15: Kernel mode ! 16: ! 17: Revision History: ! 18: ! 19: --*/ ! 20: ! 21: #include "dderror.h" ! 22: #include "devioctl.h" ! 23: #include "miniport.h" ! 24: ! 25: #include "ntddvdeo.h" ! 26: #include "video.h" ! 27: #include "xga.h" ! 28: #include "xgaioctl.h" ! 29: ! 30: #include "xgaloger.h" ! 31: ! 32: ! 33: // ! 34: // Function Prototypes ! 35: // ! 36: // Functions that start with 'Xga' are entry points for the OS port driver. ! 37: // ! 38: ! 39: VP_STATUS ! 40: XgaFindAdapter( ! 41: PVOID HwDeviceExtension, ! 42: PVOID HwContext, ! 43: PWSTR ArgumentString, ! 44: PVIDEO_PORT_CONFIG_INFO ConfigInfo, ! 45: PUCHAR Again ! 46: ); ! 47: ! 48: BOOLEAN ! 49: XgaInitialize( ! 50: PVOID HwDeviceExtension ! 51: ); ! 52: ! 53: BOOLEAN ! 54: XgaStartIO( ! 55: PVOID HwDeviceExtension, ! 56: PVIDEO_REQUEST_PACKET RequestPacket ! 57: ); ! 58: ! 59: // ! 60: // Define device driver procedure prototypes. ! 61: // ! 62: ! 63: VP_STATUS ! 64: XgaGetPosData( ! 65: PVOID HwDeviceExtension, ! 66: PVOID Context, ! 67: VIDEO_DEVICE_DATA_TYPE DeviceDataType, ! 68: PVOID Identifier, ! 69: ULONG IdentifierLength, ! 70: PVOID ConfigurationData, ! 71: ULONG ConfigurationDataLength, ! 72: PVOID ComponentInformation, ! 73: ULONG ComponentInformationLength ! 74: ); ! 75: ! 76: ULONG ! 77: XgaFindXga( ! 78: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 79: PCM_MCA_POS_DATA PosData ! 80: ); ! 81: ! 82: VP_STATUS ! 83: XgaSetMode( ! 84: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 85: ULONG ModeNum ! 86: ); ! 87: ! 88: VP_STATUS ! 89: XgaGetRegistryParamaterCallback( ! 90: PVOID HwDeviceExtension, ! 91: PVOID Context, ! 92: PWSTR ValueName, ! 93: PVOID ValueData, ! 94: ULONG ValueLength ! 95: ); ! 96: ! 97: // ! 98: // Last slot at which an adapter was found. ! 99: // ! 100: ! 101: ULONG XgaSlot; ! 102: LONG BusNumber = -1; ! 103: ! 104: ! 105: ULONG ! 106: DriverEntry ( ! 107: PVOID Context1, ! 108: PVOID Context2 ! 109: ) ! 110: ! 111: /*++ ! 112: ! 113: Routine Description: ! 114: ! 115: Installable driver initialization entry point. ! 116: This entry point is called directly by the I/O system. ! 117: ! 118: Arguments: ! 119: ! 120: Context1 - First context value passed by the operating system. This is ! 121: the value with which the miniport driver calls VideoPortInitialize(). ! 122: ! 123: Context2 - Second context value passed by the operating system. This is ! 124: the value with which the miniport driver calls VideoPortInitialize(). ! 125: ! 126: Return Value: ! 127: ! 128: Status from VideoPortInitialize() ! 129: ! 130: --*/ ! 131: ! 132: { ! 133: ! 134: VIDEO_HW_INITIALIZATION_DATA hwInitData; ! 135: ! 136: // ! 137: // Zero out structure. ! 138: // ! 139: ! 140: VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA)) ; ! 141: ! 142: // ! 143: // Specify sizes of structure and extension. ! 144: // ! 145: ! 146: hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA); ! 147: ! 148: // ! 149: // Set entry points. ! 150: // ! 151: ! 152: hwInitData.HwFindAdapter = XgaFindAdapter; ! 153: hwInitData.HwInitialize = XgaInitialize; ! 154: hwInitData.HwInterrupt = NULL; ! 155: hwInitData.HwStartIO = XgaStartIO; ! 156: ! 157: // ! 158: // Determine the size we require for the device extension. ! 159: // ! 160: ! 161: hwInitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION); ! 162: ! 163: // ! 164: // Always start with parameters for device0 in this case. ! 165: // ! 166: ! 167: // hwInitData.StartingDeviceNumber = 0; ! 168: ! 169: // ! 170: // This device only supports the internal bus type. So return the status ! 171: // value directly to the operating system. ! 172: // ! 173: ! 174: hwInitData.AdapterInterfaceType = MicroChannel; ! 175: ! 176: return VideoPortInitialize(Context1, ! 177: Context2, ! 178: &hwInitData, ! 179: NULL); ! 180: ! 181: } // end DriverEntry() ! 182: ! 183: VP_STATUS ! 184: XgaFindAdapter( ! 185: PVOID HwDeviceExtension, ! 186: PVOID HwContext, ! 187: PWSTR ArgumentString, ! 188: PVIDEO_PORT_CONFIG_INFO ConfigInfo, ! 189: PUCHAR Again ! 190: ) ! 191: ! 192: /*++ ! 193: ! 194: Routine Description: ! 195: ! 196: This routine is called to determine if the adapter for this driver ! 197: is present in the system. ! 198: If it is present, the function fills out some information describing ! 199: the adapter. ! 200: ! 201: Arguments: ! 202: ! 203: HwDeviceExtension - Supplies the miniport driver's adapter storage. This ! 204: storage is initialized to zero before this call. ! 205: ! 206: HwContext - Supplies the context value which was passed to ! 207: VideoPortInitialize(). ! 208: ! 209: ArgumentString - Suuplies a NULL terminated ASCII string. This string ! 210: originates from the user. ! 211: ! 212: ConfigInfo - Returns the configuration information structure which is ! 213: filled by the miniport driver. This structure is initialized with ! 214: any knwon configuration information (such as SystemIoBusNumber) by ! 215: the port driver. Where possible, drivers should have one set of ! 216: defaults which do not require any supplied configuration information. ! 217: ! 218: Again - Indicates if the miniport driver wants the port driver to call ! 219: its VIDEO_HW_FIND_ADAPTER function again with a new device extension ! 220: and the same config info. This is used by the miniport drivers which ! 221: can search for several adapters on a bus. ! 222: ! 223: Return Value: ! 224: ! 225: This routine must return: ! 226: ! 227: NO_ERROR - Indicates a host adapter was found and the ! 228: configuration information was successfully determined. ! 229: ! 230: ERROR_INVALID_PARAMETER - Indicates an adapter was found but there was an ! 231: error obtaining the configuration information. If possible an error ! 232: should be logged. ! 233: ! 234: ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the ! 235: supplied configuration information. ! 236: ! 237: --*/ ! 238: ! 239: { ! 240: ! 241: // ! 242: // Number of entries in the access range structure passed to the port driver. ! 243: // ! 244: ! 245: #define NUM_XGA_ACCESS_RANGES 6 ! 246: ! 247: PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension; ! 248: CM_MCA_POS_DATA posData; ! 249: ULONG ioAddress; ! 250: VP_STATUS status; ! 251: VIDEO_ACCESS_RANGE accessRange[NUM_XGA_ACCESS_RANGES]; ! 252: PHYSICAL_ADDRESS A0000PhysicalAddress; ! 253: PHYSICAL_ADDRESS passThroughPort; ! 254: ! 255: A0000PhysicalAddress.LowPart = 0x000A0000; ! 256: A0000PhysicalAddress.HighPart = 0x00000000; ! 257: ! 258: passThroughPort.LowPart = 0x000003C3; ! 259: passThroughPort.HighPart = 0x00000000; ! 260: ! 261: // ! 262: // Indicate we do not wish to be called over ! 263: // ! 264: ! 265: *Again = 0; ! 266: ! 267: // ! 268: // Make sure the size of the structure is at least as large as what we ! 269: // are expecting (check version of the config info structure). ! 270: // ! 271: ! 272: if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) { ! 273: ! 274: return ERROR_INVALID_PARAMETER; ! 275: ! 276: } ! 277: ! 278: // ! 279: // Reset the Slot number being examined to zero if we are processing ! 280: // a new bus number. ! 281: // ! 282: ! 283: if (BusNumber != (LONG)ConfigInfo->SystemIoBusNumber) { ! 284: ! 285: BusNumber = ConfigInfo->SystemIoBusNumber; ! 286: XgaSlot = 0; ! 287: ! 288: } ! 289: ! 290: // ! 291: // This picks up the POS registers. ! 292: // ! 293: ! 294: if (NO_ERROR != VideoPortGetDeviceData(hwDeviceExtension, ! 295: VpBusData, ! 296: XgaGetPosData, ! 297: &posData)) { ! 298: ! 299: VideoDebugPrint((2, "Xga: GetDeviceData returned error - probably no XGAs\n")); ! 300: ! 301: return ERROR_DEV_NOT_EXIST; ! 302: } ! 303: ! 304: // ! 305: // Since we got the data properly, make sure we get called again to find ! 306: // the next XGA adapter. ! 307: // ! 308: ! 309: *Again = 1; ! 310: ! 311: // ! 312: // Determine the XGA registers by munging the POS register data. ! 313: // ! 314: ! 315: ioAddress = (posData.PosData1 &0x0E) >> 1; ! 316: ! 317: hwDeviceExtension->PhysicalRomBaseAddress.LowPart = ! 318: (((posData.PosData1 & 0xF0) >> 4) * 0x2000) + 0xC0000 ; ! 319: hwDeviceExtension->PhysicalRomBaseAddress.HighPart = 0x00000000 ; ! 320: ! 321: hwDeviceExtension->PhysicalIoRegBaseAddress.LowPart = 0x2100 + ! 322: (ioAddress << 4) ; ! 323: hwDeviceExtension->PhysicalIoRegBaseAddress.HighPart = 0x00000000; ! 324: ! 325: // ! 326: // Choose a size of 1 MEG for video memory as a default ! 327: // ! 328: ! 329: hwDeviceExtension->PhysicalVideoMemoryLength = 0x00100000; ! 330: ! 331: // ! 332: // Find the virtual address of the frame buffer. Get the 4Meg aperture ! 333: // if it is available, otherwise take the 1MEG. ! 334: // ! 335: ! 336: if (posData.PosData3 & 0x01) { ! 337: ! 338: VideoDebugPrint((1, "Xga: using the 4 MEG Aperture\n")); ! 339: ! 340: hwDeviceExtension->PhysicalVideoMemoryAddress.LowPart = ! 341: ((posData.PosData3 &0xFE) << 24) | (ioAddress << 22) ; ! 342: hwDeviceExtension->PhysicalVideoMemoryAddress.HighPart = ! 343: 0x00000000 ; ! 344: ! 345: } else { ! 346: ! 347: VideoDebugPrint((1, "Xga: trying the 1 MEG aperture\n")); ! 348: ! 349: hwDeviceExtension->PhysicalVideoMemoryAddress.LowPart = ! 350: (posData.PosData4 &0x0F) << 20 ; ! 351: hwDeviceExtension->PhysicalVideoMemoryAddress.HighPart = 0x00000000 ; ! 352: ! 353: } ! 354: ! 355: // ! 356: // If none of these apertures are open, (64K aperture) then fail. ! 357: // 1 MEG aperture is disabled if the base is 0 ! 358: // ! 359: ! 360: if (!hwDeviceExtension->PhysicalVideoMemoryAddress.LowPart) { ! 361: ! 362: VideoDebugPrint((1, "Xga: 64K aperture\n")); ! 363: ! 364: VideoPortLogError(hwDeviceExtension, ! 365: NULL, ! 366: XGA_WRONG_APERTURE, ! 367: __LINE__); ! 368: ! 369: return ERROR_INVALID_PARAMETER; ! 370: ! 371: } ! 372: ! 373: // ! 374: // Get the address of the Co processor registers. ! 375: // ! 376: ! 377: hwDeviceExtension->PhysicalCoProcessorAddress.LowPart = 0x80 * ioAddress ! 378: + 0x1C00 + hwDeviceExtension->PhysicalRomBaseAddress.LowPart; ! 379: hwDeviceExtension->PhysicalCoProcessorAddress.HighPart = 0x00000000 ; ! 380: ! 381: // ! 382: // Save the data for access ranges ! 383: // ! 384: ! 385: // ! 386: // Io Ports ! 387: // ! 388: ! 389: accessRange[0].RangeStart = hwDeviceExtension->PhysicalIoRegBaseAddress; ! 390: accessRange[0].RangeLength = XGA_IO_REGS_SIZE; ! 391: accessRange[0].RangeInIoSpace = TRUE; ! 392: accessRange[0].RangeVisible = TRUE; ! 393: accessRange[0].RangeShareable = FALSE; ! 394: ! 395: // ! 396: // Video Memory ! 397: // ! 398: ! 399: accessRange[1].RangeStart = hwDeviceExtension->PhysicalVideoMemoryAddress; ! 400: accessRange[1].RangeLength = hwDeviceExtension->PhysicalVideoMemoryLength; ! 401: accessRange[1].RangeInIoSpace = FALSE; ! 402: accessRange[1].RangeVisible = TRUE; ! 403: accessRange[1].RangeShareable = FALSE; ! 404: ! 405: // ! 406: // ROM Location ! 407: // ! 408: ! 409: accessRange[2].RangeStart = hwDeviceExtension->PhysicalRomBaseAddress; ! 410: accessRange[2].RangeLength = XGA_ROM_SIZE; ! 411: accessRange[2].RangeInIoSpace = FALSE; ! 412: accessRange[2].RangeVisible = TRUE; ! 413: accessRange[2].RangeShareable = FALSE; ! 414: ! 415: // ! 416: // Co-Processor Location ! 417: // ! 418: ! 419: accessRange[3].RangeStart = hwDeviceExtension->PhysicalCoProcessorAddress; ! 420: accessRange[3].RangeLength = XGA_CO_PROCESSOR_REGS_SIZE; ! 421: accessRange[3].RangeInIoSpace = FALSE; ! 422: accessRange[3].RangeVisible = TRUE; ! 423: accessRange[3].RangeShareable = FALSE; ! 424: ! 425: // ! 426: // Resources shared with the VGA ! 427: // ! 428: ! 429: // ! 430: // Io Ports ! 431: // ! 432: ! 433: accessRange[4].RangeStart = passThroughPort; ! 434: accessRange[4].RangeLength = 0x00000001; ! 435: accessRange[4].RangeInIoSpace = TRUE; ! 436: accessRange[4].RangeVisible = FALSE; ! 437: accessRange[4].RangeShareable = TRUE; ! 438: ! 439: // ! 440: // Video Memory ! 441: // ! 442: ! 443: accessRange[5].RangeStart = A0000PhysicalAddress; ! 444: accessRange[5].RangeLength = 0x00010000; ! 445: accessRange[5].RangeInIoSpace = FALSE; ! 446: accessRange[5].RangeVisible = FALSE; ! 447: accessRange[5].RangeShareable = TRUE; ! 448: ! 449: // ! 450: // Check to see if there is a hardware resource conflict. ! 451: // ! 452: ! 453: status = VideoPortVerifyAccessRanges(HwDeviceExtension, ! 454: NUM_XGA_ACCESS_RANGES, ! 455: accessRange); ! 456: ! 457: if (status != NO_ERROR) { ! 458: ! 459: return status; ! 460: ! 461: } ! 462: ! 463: // ! 464: // Clear out the Emulator entries and the state size since this driver ! 465: // does not support them. ! 466: // ! 467: ! 468: ConfigInfo->NumEmulatorAccessEntries = 0; ! 469: ConfigInfo->EmulatorAccessEntries = NULL; ! 470: ConfigInfo->EmulatorAccessEntriesContext = 0; ! 471: ! 472: ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = 0x00000000; ! 473: ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0x00000000; ! 474: ConfigInfo->VdmPhysicalVideoMemoryLength = 0x00000000; ! 475: ! 476: ConfigInfo->HardwareStateSize = 0; ! 477: ! 478: // ! 479: // Map the video memory into the system virtual address space so we can ! 480: // clear it out. ! 481: // ! 482: ! 483: if ( (hwDeviceExtension->FrameAddress = ! 484: VideoPortGetDeviceBase(hwDeviceExtension, ! 485: hwDeviceExtension->PhysicalVideoMemoryAddress, ! 486: hwDeviceExtension->PhysicalVideoMemoryLength, ! 487: FALSE)) == NULL) { ! 488: ! 489: return ERROR_INVALID_PARAMETER; ! 490: ! 491: } ! 492: ! 493: // ! 494: // Map in the memory at A0000 so we can test the card for the amount of ! 495: // memory afterwards. ! 496: // ! 497: ! 498: if ( ( hwDeviceExtension->A0000MemoryAddress = ! 499: VideoPortGetDeviceBase(hwDeviceExtension, ! 500: A0000PhysicalAddress, ! 501: 0x00010000, ! 502: FALSE)) == NULL) { ! 503: ! 504: VideoDebugPrint((2, "XgaFindAdapter - Fail to get A0000 aperture address\n")); ! 505: ! 506: return ERROR_INVALID_PARAMETER; ! 507: ! 508: } ! 509: ! 510: // ! 511: // Map in the IO registers so we can access them. ! 512: // ! 513: ! 514: if ( ( hwDeviceExtension->IoRegBaseAddress = (ULONG) ! 515: VideoPortGetDeviceBase(hwDeviceExtension, ! 516: hwDeviceExtension->PhysicalIoRegBaseAddress, ! 517: XGA_IO_REGS_SIZE, ! 518: TRUE)) == 0) { ! 519: ! 520: VideoDebugPrint((2, "XgaFindAdapter - Fail to get io register addresses\n")); ! 521: ! 522: return ERROR_INVALID_PARAMETER; ! 523: ! 524: } ! 525: ! 526: // ! 527: // Map in the pass-throught port. ! 528: // ! 529: ! 530: if ( ( hwDeviceExtension->PassThroughPort = ! 531: VideoPortGetDeviceBase(hwDeviceExtension, ! 532: passThroughPort, ! 533: 1, ! 534: TRUE)) == 0) { ! 535: ! 536: VideoDebugPrint((2, "XgaFindAdapter - Fail to get io register addresses\n")); ! 537: ! 538: return ERROR_INVALID_PARAMETER; ! 539: ! 540: } ! 541: ! 542: // ! 543: // Indicate a successful completion status. ! 544: // ! 545: ! 546: return NO_ERROR; ! 547: ! 548: } // end XgaFindAdapter() ! 549: ! 550: ! 551: VP_STATUS ! 552: XgaGetPosData( ! 553: PVOID HwDeviceExtension, ! 554: PVOID Context, ! 555: VIDEO_DEVICE_DATA_TYPE DeviceDataType, ! 556: PVOID Identifier, ! 557: ULONG IdentifierLength, ! 558: PVOID ConfigurationData, ! 559: ULONG ConfigurationDataLength, ! 560: PVOID ComponentInformation, ! 561: ULONG ComponentInformationLength ! 562: ) ! 563: ! 564: /*++ ! 565: ! 566: Routine Description: ! 567: ! 568: Callback for the GetDeviceData function. ! 569: This routine will scan for an XGA adapter, and if it finds one, will ! 570: save the POS information in the device extension so it can be further ! 571: processed in the FindAdapter() routine. ! 572: ! 573: Arguments: ! 574: ! 575: HwDeviceExtension - Pointer to the miniport drivers device extension. ! 576: ! 577: Context - Context value passed to the VideoPortGetDeviceData function. ! 578: ! 579: DeviceDataType - The type of data that was requested in ! 580: VideoPortGetDeviceData. ! 581: ! 582: Identifier - Pointer to a string that contains the name of the device, ! 583: as setup by the ROM or ntdetect. ! 584: ! 585: IdentifierLength - Length of the Identifier string. ! 586: ! 587: ConfigurationData - Pointer to the configuration data for the device or ! 588: BUS. ! 589: ! 590: ConfigurationDataLength - Length of the data in the configurationData ! 591: field. ! 592: ! 593: ComponentInformation - Undefined. ! 594: ! 595: ComponentInformationLength - Undefined. ! 596: ! 597: Return Value: ! 598: ! 599: Returns NO_ERROR if the function completed properly. ! 600: Returns ERROR_DEV_NOT_EXIST if we did not find the device. ! 601: Returns ERROR_INVALID_PARAMETER otherwise. ! 602: ! 603: --*/ ! 604: ! 605: { ! 606: PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension; ! 607: USHORT adapterId; ! 608: BOOLEAN found = FALSE; ! 609: PCM_MCA_POS_DATA posData = Context; ! 610: ! 611: // ! 612: // Find the XGA. ! 613: // Loop through all the POS data in the PosData array ! 614: // ! 615: ! 616: while ((XgaSlot + 1) * sizeof(CM_MCA_POS_DATA) <= ConfigurationDataLength) { ! 617: ! 618: adapterId = *((PUSHORT)((PCM_MCA_POS_DATA)ConfigurationData + XgaSlot)); ! 619: ! 620: VideoDebugPrint((3, "PosAdapterId for slot %d is %x \n", XgaSlot, ! 621: adapterId)); ! 622: ! 623: switch ( adapterId ) { ! 624: ! 625: case 0x8FDB: ! 626: ! 627: hwDeviceExtension->BoardType = XGA_TYPE_1; ! 628: ! 629: found = TRUE; ! 630: break; ! 631: ! 632: case 0x8FDA: ! 633: ! 634: hwDeviceExtension->BoardType = XGA_TYPE_2; ! 635: ! 636: found = TRUE; ! 637: break; ! 638: ! 639: default: ! 640: break; ! 641: ! 642: } ! 643: ! 644: // ! 645: // Go to the next slot. ! 646: // ! 647: ! 648: XgaSlot++; ! 649: ! 650: // ! 651: // We have found an XGA adapter. Save the data in the device extension ! 652: // so we can process it further. ! 653: // ! 654: ! 655: if (found) { ! 656: ! 657: *posData = *((PCM_MCA_POS_DATA)ConfigurationData + XgaSlot - 1); ! 658: ! 659: return NO_ERROR; ! 660: } ! 661: } ! 662: ! 663: return ERROR_DEV_NOT_EXIST; ! 664: ! 665: } ! 666: ! 667: BOOLEAN ! 668: XgaInitialize( ! 669: PVOID HwDeviceExtension ! 670: ) ! 671: ! 672: /*++ ! 673: ! 674: Routine Description: ! 675: ! 676: This routine does one time initialization of the device. ! 677: ! 678: Arguments: ! 679: ! 680: HwDeviceExtension - Supplies a pointer to the miniport's device extension. ! 681: ! 682: Return Value: ! 683: ! 684: ! 685: Always returns TRUE since this routine can never fail. ! 686: ! 687: --*/ ! 688: ! 689: { ! 690: PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension; ! 691: volatile PUCHAR videoMemory; ! 692: UCHAR testValue = 0xA5; ! 693: ULONG i; ! 694: ULONG color; ! 695: ! 696: videoMemory = hwDeviceExtension->A0000MemoryAddress; ! 697: ! 698: // ! 699: // Disable interrupts on the card since they will not be used ! 700: // ! 701: ! 702: VideoPortWritePortUchar( ! 703: (PUCHAR) (hwDeviceExtension->IoRegBaseAddress | INT_ENABLE_REG), 0x00); ! 704: ! 705: // ! 706: // Blank the palette so we get a black screen. ! 707: // ! 708: ! 709: VideoPortWritePortUchar( ! 710: (PUCHAR) (hwDeviceExtension->IoRegBaseAddress | INDEX_REG), 0x64); ! 711: ! 712: VideoPortWritePortUchar( ! 713: (PUCHAR) (hwDeviceExtension->IoRegBaseAddress | DATA_IN_REG), 0x00); ! 714: ! 715: // ! 716: // Put the adapter in a temporary Extended Graphics Mode, set up video ! 717: // memory at A0000, put the aperture at 768 K higher and try to access ! 718: // it to determine how much memory is present. ! 719: // ! 720: ! 721: VideoPortWritePortUchar( ! 722: (PUCHAR) (hwDeviceExtension->IoRegBaseAddress | OP_MODE_REG), 0x04); ! 723: ! 724: VideoPortWritePortUchar( ! 725: (PUCHAR) (hwDeviceExtension->IoRegBaseAddress | APP_CTL_REG), 0x01); ! 726: ! 727: VideoPortWritePortUchar( ! 728: (PUCHAR) (hwDeviceExtension->IoRegBaseAddress | APP_INDEX_REG), 0x0C); ! 729: ! 730: // ! 731: // To test if memory is present, use a test value (make sure the same ! 732: // value is not currently stored in video memory, otherwise change it), ! 733: // store it in video memory, and read it back. If the value is identical ! 734: // to the value we stored then there must be memory present at that ! 735: // location (which, in this case, means we have 1 MEG of Video RAM). ! 736: // ! 737: ! 738: if (*videoMemory == testValue) { ! 739: ! 740: testValue >>= 1; ! 741: ! 742: } ! 743: ! 744: *videoMemory = testValue; ! 745: ! 746: if (*videoMemory == testValue) { ! 747: ! 748: hwDeviceExtension->PhysicalVideoMemoryLength = 0x00100000; ! 749: ! 750: } else { ! 751: ! 752: hwDeviceExtension->PhysicalVideoMemoryLength = 0x00080000; ! 753: ! 754: } ! 755: ! 756: VideoDebugPrint((2, "XgaInitialize\n The amount of memory on the card is %d K\n", ! 757: hwDeviceExtension->PhysicalVideoMemoryLength >> 10)); ! 758: ! 759: // ! 760: // For now, we only support color devices ! 761: // ! 762: ! 763: hwDeviceExtension->Color = TRUE; ! 764: ! 765: // ! 766: // Now compute the number of available modes based on the infromation ! 767: // we found out. ! 768: // ! 769: ! 770: hwDeviceExtension->NumAvailableModes = 0; ! 771: ! 772: for (i = 0; i < XGA_NUM_MODES; i++) { ! 773: ! 774: // ! 775: // If the right amount of memory and the right board type is present ... ! 776: // ! 777: ! 778: if (XgaModes[i].minimumRequiredMemory <= ! 779: hwDeviceExtension->PhysicalVideoMemoryLength) { ! 780: ! 781: // ! 782: // Check we have the right type of board. ! 783: // ! 784: ! 785: if ( (XgaModes[i].Xga1Mode && ! 786: (hwDeviceExtension->BoardType & XGA_TYPE_1)) || ! 787: (XgaModes[i].Xga2Mode && ! 788: (hwDeviceExtension->BoardType & XGA_TYPE_2)) ) { ! 789: ! 790: color = XgaModes[i].modeInformation.AttributeFlags & ! 791: VIDEO_MODE_COLOR; ! 792: ! 793: // ! 794: // check that both the mode and what we support is the same ! 795: // in terms of color. ! 796: // ! 797: ! 798: if ( (color && (ULONG)hwDeviceExtension->Color) || // color ! 799: (color == (ULONG)hwDeviceExtension->Color) ) { // monochrome ! 800: ! 801: hwDeviceExtension->Valid[i] = TRUE; ! 802: hwDeviceExtension->NumAvailableModes++; ! 803: ! 804: } ! 805: } ! 806: } ! 807: } ! 808: ! 809: VideoPortGetRegistryParameters(hwDeviceExtension, ! 810: L"Monitor", ! 811: TRUE, ! 812: XgaGetRegistryParamaterCallback, ! 813: NULL); ! 814: ! 815: return TRUE; ! 816: ! 817: } // end XgaInitialize() ! 818: ! 819: ! 820: VP_STATUS ! 821: XgaGetRegistryParamaterCallback( ! 822: PVOID HwDeviceExtension, ! 823: PVOID Context, ! 824: PWSTR ValueName, ! 825: PVOID ValueData, ! 826: ULONG ValueLength ! 827: ) ! 828: ! 829: /*++ ! 830: ! 831: Routine Description: ! 832: ! 833: Callback routine to process the information coming back from the registry. ! 834: ! 835: Arguments: ! 836: ! 837: HwDeviceExtension - Pointer to the miniport driver's device extension. ! 838: ! 839: Context - Context parameter passed to the callback routine. ! 840: ! 841: ValueName - Pointer to the name of the requested data field. ! 842: ! 843: ValueData - Pointer to a buffer containing the information. ! 844: ! 845: ValueLength - Size of the data. ! 846: ! 847: Return Value: ! 848: ! 849: ! 850: Environment: ! 851: ! 852: Can only be called During initialization. ! 853: ! 854: --*/ ! 855: ! 856: { ! 857: ! 858: VideoDebugPrint((3, "In the GetRegistryParameters callback routine\n")); ! 859: ! 860: return NO_ERROR; ! 861: ! 862: } ! 863: ! 864: ! 865: BOOLEAN ! 866: XgaStartIO( ! 867: PVOID HwDeviceExtension, ! 868: PVIDEO_REQUEST_PACKET RequestPacket ! 869: ) ! 870: ! 871: /*++ ! 872: ! 873: Routine Description: ! 874: ! 875: This routine is the main execution routine for the miniport driver. It ! 876: acceptss a Video Request Packet, performs the request, and then returns ! 877: with the appropriate status. ! 878: ! 879: Arguments: ! 880: ! 881: HwDeviceExtension - Supplies a pointer to the miniport's device extension. ! 882: ! 883: RequestPacket - Pointer to the video request packet. This structure ! 884: contains all the parameters passed to the VideoIoControl function. ! 885: ! 886: Return Value: ! 887: ! 888: ! 889: --*/ ! 890: ! 891: { ! 892: VP_STATUS status; ! 893: PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension; ! 894: ! 895: PVIDEO_MEMORY_INFORMATION memoryInformation; ! 896: PVIDEO_MODE_INFORMATION modeInformation; ! 897: ULONG inIoSpace; ! 898: ! 899: PVIDEO_CLUT clutBuffer; ! 900: PVIDEO_CLUTDATA pClutData; ! 901: ! 902: USHORT i; ! 903: ULONG length; ! 904: PHYSICAL_ADDRESS physicalAddress; ! 905: ULONG offset; ! 906: ! 907: ! 908: // ! 909: // Switch on the IoContolCode in the RequestPacket. It indicates which ! 910: // function must be performed by the driver. ! 911: // ! 912: ! 913: switch (RequestPacket->IoControlCode) { ! 914: ! 915: ! 916: case IOCTL_VIDEO_MAP_VIDEO_MEMORY: ! 917: ! 918: VideoDebugPrint((2, "XgaStartIO - MapVideoMemory\n")); ! 919: ! 920: if ( (RequestPacket->OutputBufferLength < ! 921: (RequestPacket->StatusBlock->Information = ! 922: sizeof(VIDEO_MEMORY_INFORMATION))) || ! 923: (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) ) { ! 924: ! 925: status = ERROR_INSUFFICIENT_BUFFER; ! 926: } ! 927: ! 928: memoryInformation = RequestPacket->OutputBuffer; ! 929: ! 930: memoryInformation->VideoRamBase = ((PVIDEO_MEMORY) ! 931: (RequestPacket->InputBuffer))->RequestedVirtualAddress; ! 932: ! 933: memoryInformation->VideoRamLength = ! 934: hwDeviceExtension->PhysicalVideoMemoryLength; ! 935: ! 936: inIoSpace = 0; ! 937: ! 938: status = VideoPortMapMemory(hwDeviceExtension, ! 939: hwDeviceExtension->PhysicalVideoMemoryAddress, ! 940: &(memoryInformation->VideoRamLength), ! 941: &inIoSpace, ! 942: &(memoryInformation->VideoRamBase)); ! 943: ! 944: // ! 945: // The frame buffer and virtual memory and equivalent in this ! 946: // case. ! 947: // ! 948: ! 949: memoryInformation->FrameBufferBase = ! 950: memoryInformation->VideoRamBase; ! 951: ! 952: memoryInformation->FrameBufferLength = ! 953: XgaModes[hwDeviceExtension->CurrentMode].modeInformation.VisScreenHeight * ! 954: XgaModes[hwDeviceExtension->CurrentMode].modeInformation.ScreenStride; ! 955: ! 956: VideoDebugPrint((3, "Xga IOCLT_MAP_MEMORY\n physical = %x\n \ ! 957: virtual = %x\n length = %x\n framebase = %x\n frameLength = %x\n", ! 958: hwDeviceExtension->PhysicalVideoMemoryAddress.LowPart, ! 959: memoryInformation->VideoRamBase, ! 960: memoryInformation->VideoRamLength, ! 961: memoryInformation->FrameBufferBase, ! 962: memoryInformation->FrameBufferLength)); ! 963: ! 964: break; ! 965: ! 966: ! 967: case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY: ! 968: ! 969: VideoDebugPrint((2, "XgaStartIO - UnMapVideoMemory\n")); ! 970: ! 971: if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) { ! 972: ! 973: status = ERROR_INSUFFICIENT_BUFFER; ! 974: } ! 975: ! 976: status = VideoPortUnmapMemory(hwDeviceExtension, ! 977: ((PVIDEO_MEMORY) ! 978: (RequestPacket->InputBuffer))-> ! 979: RequestedVirtualAddress, ! 980: 0); ! 981: break; ! 982: ! 983: ! 984: case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES: ! 985: ! 986: VideoDebugPrint((2, "XgaStartIO - QueryNumberAvaialbleModes\n")); ! 987: ! 988: if (RequestPacket->OutputBufferLength < ! 989: (RequestPacket->StatusBlock->Information = ! 990: sizeof(VIDEO_NUM_MODES)) ) { ! 991: ! 992: status = ERROR_INSUFFICIENT_BUFFER; ! 993: ! 994: } else { ! 995: ! 996: ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->NumModes = ! 997: hwDeviceExtension->NumAvailableModes; ! 998: ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->ModeInformationLength = ! 999: sizeof(VIDEO_MODE_INFORMATION); ! 1000: ! 1001: status = NO_ERROR; ! 1002: } ! 1003: ! 1004: break; ! 1005: ! 1006: ! 1007: case IOCTL_VIDEO_QUERY_AVAIL_MODES: ! 1008: ! 1009: VideoDebugPrint((2, "XgaStartIO - QueryAvailableModes\n")); ! 1010: ! 1011: if (RequestPacket->OutputBufferLength < ! 1012: (RequestPacket->StatusBlock->Information = ! 1013: hwDeviceExtension->NumAvailableModes * ! 1014: sizeof(VIDEO_MODE_INFORMATION)) ) { ! 1015: ! 1016: status = ERROR_INSUFFICIENT_BUFFER; ! 1017: ! 1018: } else { ! 1019: ! 1020: modeInformation = RequestPacket->OutputBuffer; ! 1021: ! 1022: for (i = 0; i < XGA_NUM_MODES; i++) { ! 1023: ! 1024: if (hwDeviceExtension->Valid[i]) { ! 1025: ! 1026: *modeInformation = XgaModes[i].modeInformation; ! 1027: modeInformation++; ! 1028: ! 1029: } ! 1030: } ! 1031: ! 1032: status = NO_ERROR; ! 1033: } ! 1034: ! 1035: break; ! 1036: ! 1037: ! 1038: case IOCTL_VIDEO_QUERY_CURRENT_MODE: ! 1039: ! 1040: VideoDebugPrint((2, "XgaStartIO - QueryCurrentMode\n")); ! 1041: ! 1042: if (RequestPacket->OutputBufferLength < ! 1043: (RequestPacket->StatusBlock->Information = ! 1044: sizeof(VIDEO_MODE_INFORMATION)) ) { ! 1045: ! 1046: status = ERROR_INSUFFICIENT_BUFFER; ! 1047: ! 1048: } else { ! 1049: ! 1050: *((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer) = ! 1051: XgaModes[hwDeviceExtension->CurrentMode].modeInformation; ! 1052: ! 1053: status = NO_ERROR; ! 1054: ! 1055: } ! 1056: ! 1057: break; ! 1058: ! 1059: ! 1060: ! 1061: ! 1062: ! 1063: ! 1064: case IOCTL_VIDEO_SET_CURRENT_MODE: ! 1065: ! 1066: VideoDebugPrint((2, "XgaStartIO - SetCurrentMode\n")); ! 1067: ! 1068: if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE)) { ! 1069: ! 1070: status = ERROR_INSUFFICIENT_BUFFER; ! 1071: ! 1072: } else { ! 1073: ! 1074: status = XgaSetMode(hwDeviceExtension, ! 1075: ((PVIDEO_MODE)RequestPacket->InputBuffer)-> ! 1076: RequestedMode); ! 1077: ! 1078: } ! 1079: ! 1080: break; ! 1081: ! 1082: ! 1083: case IOCTL_VIDEO_SET_COLOR_REGISTERS: ! 1084: ! 1085: VideoDebugPrint((2, "XgaStartIO - SetColorRegs\n")); ! 1086: ! 1087: clutBuffer = RequestPacket->InputBuffer; ! 1088: ! 1089: /* Load simple 16 entry palette */ ! 1090: ! 1091: XGAIDXOUT(INDEX_REG, 0x66, 0x0) ; ! 1092: ! 1093: /* Start at beginning of palette */ ! 1094: ! 1095: XGAIDXOUT(INDEX_REG, 0x60, clutBuffer->FirstEntry) ; ! 1096: XGAIDXOUT(INDEX_REG, 0x61, 0x0) ; ! 1097: ! 1098: ! 1099: for ( i = 0 ; i < clutBuffer->NumEntries; i++ ) { ! 1100: ! 1101: pClutData = &clutBuffer->LookupTable[i].RgbArray ; ! 1102: ! 1103: XGAOUT(INDEX_REG, 0x65) ; ! 1104: XGAOUT(0x0B, pClutData->Red) ; ! 1105: ! 1106: XGAOUT(INDEX_REG, 0x65) ; ! 1107: XGAOUT(0x0B, pClutData->Green) ; ! 1108: ! 1109: XGAOUT(INDEX_REG, 0x65) ; ! 1110: XGAOUT(0x0B, pClutData->Blue) ; ! 1111: } ! 1112: ! 1113: status = NO_ERROR; ! 1114: ! 1115: break; ! 1116: ! 1117: case IOCTL_VIDEO_XGA_MAP_COPROCESSOR: ! 1118: ! 1119: if (RequestPacket->OutputBufferLength < ! 1120: (RequestPacket->StatusBlock->Information = ! 1121: sizeof(VIDEO_XGA_COPROCESSOR_INFORMATION)) ) { ! 1122: ! 1123: status = ERROR_INSUFFICIENT_BUFFER; ! 1124: break; ! 1125: ! 1126: } ! 1127: ! 1128: length = XGA_CO_PROCESSOR_REGS_SIZE; ! 1129: ! 1130: // Map in at the page ganularity, then add in the page offset ! 1131: // to the linear address. ! 1132: ! 1133: offset = hwDeviceExtension->PhysicalCoProcessorAddress.LowPart & 0x00000FFF ; ! 1134: ! 1135: physicalAddress.LowPart = ! 1136: hwDeviceExtension->PhysicalCoProcessorAddress.LowPart & 0xFFFFF000 ; ! 1137: ! 1138: physicalAddress.HighPart = 0x00000000; ! 1139: ! 1140: ((PVIDEO_XGA_COPROCESSOR_INFORMATION)RequestPacket->OutputBuffer)-> ! 1141: CoProcessorVirtualAddress = 0; ! 1142: ! 1143: inIoSpace = 0; ! 1144: ! 1145: status = VideoPortMapMemory(hwDeviceExtension, ! 1146: physicalAddress, ! 1147: &length, ! 1148: &inIoSpace, ! 1149: &((PVIDEO_XGA_COPROCESSOR_INFORMATION)RequestPacket-> ! 1150: OutputBuffer)->CoProcessorVirtualAddress); ! 1151: ! 1152: (PCHAR) ((PVIDEO_XGA_COPROCESSOR_INFORMATION) ! 1153: RequestPacket->OutputBuffer)->CoProcessorVirtualAddress += offset; ! 1154: ! 1155: // ! 1156: // Also return the physical address of the video memory so the ! 1157: // co-processor can access it. ! 1158: // ! 1159: ! 1160: ! 1161: (ULONG) ((PVIDEO_XGA_COPROCESSOR_INFORMATION) ! 1162: RequestPacket->OutputBuffer)->PhysicalVideoMemoryAddress = ! 1163: hwDeviceExtension->PhysicalVideoMemoryAddress.LowPart; ! 1164: ! 1165: // ! 1166: // Also return the XGA IO Register Base Address. ! 1167: // ! 1168: ! 1169: (ULONG) ((PVIDEO_XGA_COPROCESSOR_INFORMATION) ! 1170: RequestPacket->OutputBuffer)->XgaIoRegisterBaseAddress = ! 1171: hwDeviceExtension->PhysicalIoRegBaseAddress.LowPart; ! 1172: ! 1173: ! 1174: VideoDebugPrint((3, "Xga IOCLT_MAP_CO_PROCESSOR\n physicalco = %x\n virtualco = %x\n physicalmem = %x\n", ! 1175: hwDeviceExtension->PhysicalCoProcessorAddress.LowPart, ! 1176: ((PVIDEO_XGA_COPROCESSOR_INFORMATION) ! 1177: RequestPacket->OutputBuffer)->CoProcessorVirtualAddress, ! 1178: hwDeviceExtension->PhysicalVideoMemoryAddress.LowPart)); ! 1179: ! 1180: break ; ! 1181: ! 1182: ! 1183: case IOCTL_VIDEO_RESET_DEVICE: ! 1184: ! 1185: XGAOUT(APP_CTL_REG, 0x00) ; ! 1186: ! 1187: XGAOUT(INT_ENABLE_REG, 0x00) ; ! 1188: ! 1189: XGAOUT(INT_STATUS_REG, 0xff) ; ! 1190: ! 1191: // Now init all the index registers. ! 1192: ! 1193: for (i = 0 ; XgaResetToVga[i].PortIndex != 0xff ; i++) { ! 1194: ! 1195: XGAIDXOUT(0x0A, ! 1196: XgaResetToVga[i].PortIndex, ! 1197: XgaResetToVga[i].Data) ; ! 1198: } ! 1199: ! 1200: XGAOUT(OP_MODE_REG, 0x1) ; ! 1201: ! 1202: VideoPortWritePortUchar(hwDeviceExtension->PassThroughPort, 0x01); ! 1203: ! 1204: status = NO_ERROR; ! 1205: ! 1206: break ; ! 1207: ! 1208: // ! 1209: // if we get here, an invalid IoControlCode was specified. ! 1210: // ! 1211: ! 1212: default: ! 1213: ! 1214: VideoDebugPrint((1, "Fell through Xga startIO routine - invalid command\n")); ! 1215: ! 1216: status = ERROR_INVALID_FUNCTION ; ! 1217: ! 1218: break; ! 1219: ! 1220: } ! 1221: ! 1222: RequestPacket->StatusBlock->Status = status; ! 1223: ! 1224: return TRUE; ! 1225: ! 1226: } // end XgaStartIO() ! 1227: ! 1228: ! 1229: VP_STATUS ! 1230: XgaSetMode( ! 1231: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 1232: ULONG ModeNum ! 1233: ) ! 1234: ! 1235: /*++ ! 1236: ! 1237: Routine Description: ! 1238: ! 1239: This routine is the main execution routine for the miniport driver. It ! 1240: acceptss a Video Request Packet, performs the request, and then returns ! 1241: with the appropriate status. ! 1242: ! 1243: Arguments: ! 1244: ! 1245: HwDeviceExtension - Supplies a pointer to the miniport's device extension. ! 1246: ! 1247: ModeNum - Index of the mode in which the adapter must be programmed. ! 1248: ! 1249: Return Value: ! 1250: ! 1251: NO_ERROR if the function completed successfully ! 1252: ERROR_INVALID_PARAMETER if the requested mode is invalid for the device. ! 1253: ! 1254: --*/ ! 1255: ! 1256: { ! 1257: PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension; ! 1258: PUCHAR indexRegister = (PUCHAR) (hwDeviceExtension->IoRegBaseAddress + INDEX_REG); ! 1259: PMODE_REGISTER_DATA_TABLE modeTable; ! 1260: UCHAR input; ! 1261: ! 1262: VideoDebugPrint((1, "XgaSetMode: the mode being set is %d\n", ModeNum)); ! 1263: ! 1264: // ! 1265: // Get the right mode table ! 1266: // ! 1267: ! 1268: if (hwDeviceExtension->BoardType & XGA_TYPE_1) { ! 1269: ! 1270: modeTable = XgaModes[ModeNum].Xga1Mode; ! 1271: ! 1272: } else { ! 1273: ! 1274: if (hwDeviceExtension->BoardType & XGA_TYPE_2) { ! 1275: ! 1276: modeTable = XgaModes[ModeNum].Xga2Mode; ! 1277: ! 1278: } else { ! 1279: ! 1280: VideoDebugPrint((0, "XGA: Internal mode flags are invalid")); ! 1281: return ERROR_INVALID_PARAMETER; ! 1282: ! 1283: } ! 1284: } ! 1285: ! 1286: // ! 1287: // Program the registers. ! 1288: // ! 1289: ! 1290: while (modeTable->Port != END_OF_SWITCH) { ! 1291: ! 1292: switch (modeTable->Port) { ! 1293: ! 1294: case INDEX_REG: ! 1295: ! 1296: VideoPortWritePortUchar(indexRegister, ! 1297: modeTable->IndexPort); ! 1298: ! 1299: VideoPortWritePortUchar(indexRegister + 1, ! 1300: modeTable->Data); ! 1301: ! 1302: break; ! 1303: ! 1304: case INDEX_OR_REG: ! 1305: ! 1306: VideoPortWritePortUchar(indexRegister, ! 1307: modeTable->IndexPort); ! 1308: ! 1309: input = VideoPortReadPortUchar((PUCHAR) hwDeviceExtension->IoRegBaseAddress + ! 1310: DATA_IN_REG); ! 1311: ! 1312: input |= modeTable->Data; ! 1313: ! 1314: VideoPortWritePortUchar(indexRegister + 1, input); ! 1315: ! 1316: break; ! 1317: ! 1318: default: ! 1319: ! 1320: VideoPortWritePortUchar((PUCHAR) hwDeviceExtension->IoRegBaseAddress + ! 1321: modeTable->Port, ! 1322: modeTable->Data); ! 1323: ! 1324: } ! 1325: ! 1326: modeTable++; ! 1327: ! 1328: } ! 1329: ! 1330: // ! 1331: // Save the current mode for future reference. ! 1332: // ! 1333: ! 1334: hwDeviceExtension->CurrentMode = (UCHAR) ModeNum; ! 1335: ! 1336: return NO_ERROR; ! 1337: ! 1338: } // end XgaSetMode();
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.