Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2650 lines
69 KiB

  1. /*++
  2. Copyright (c) 1993 Weitek Corporation
  3. Module Name:
  4. p9.c
  5. Abstract:
  6. This module contains the code that implements the Weitek P9 miniport
  7. device driver.
  8. Environment:
  9. Kernel mode
  10. Revision History may be found at the end of this file.
  11. --*/
  12. #include "p9.h"
  13. #include "p9gbl.h"
  14. #include "vga.h"
  15. #include "string.h"
  16. #include "p91regs.h"
  17. #include "p9errlog.h"
  18. //
  19. // This global is used as an error flag to error out quickly on the multiple
  20. // calls to P9FindAdapter when a board is not supported.
  21. //
  22. extern VP_STATUS vpP91AdapterStatus;
  23. extern BOOLEAN bFoundPCI;
  24. extern ULONG P91_Bt485_DAC_Regs[];
  25. BOOLEAN gMadeAdjustments=FALSE;
  26. extern BOOLEAN
  27. bIntergraphBoard(
  28. PHW_DEVICE_EXTENSION HwDeviceExtension
  29. );
  30. extern VOID SetVgaMode3(
  31. PHW_DEVICE_EXTENSION HwDeviceExtension
  32. );
  33. extern VOID
  34. WriteP9ConfigRegister(
  35. PHW_DEVICE_EXTENSION HwDeviceExtension,
  36. UCHAR regnum,
  37. UCHAR jValue
  38. );
  39. extern VOID
  40. InitP9100(
  41. PHW_DEVICE_EXTENSION HwDeviceExtension
  42. );
  43. extern VOID
  44. P91_SysConf(
  45. PHW_DEVICE_EXTENSION HwDeviceExtension
  46. );
  47. extern VOID
  48. P91_WriteTiming(
  49. PHW_DEVICE_EXTENSION HwDeviceExtension
  50. );
  51. extern VOID vDumpPCIConfig(PHW_DEVICE_EXTENSION HwDeviceExtension,
  52. PUCHAR psz);
  53. extern
  54. VOID
  55. P91RestoreVGAregs(
  56. PHW_DEVICE_EXTENSION HwDeviceExtension,
  57. VGA_REGS * SaveVGARegisters);
  58. extern
  59. VOID
  60. P91SaveVGARegs(
  61. PHW_DEVICE_EXTENSION HwDeviceExtension,
  62. VGA_REGS * SaveVGARegisters);
  63. //
  64. // Local function Prototypes
  65. //
  66. // Functions that start with 'P9' are entry points for the OS port driver.
  67. //
  68. VP_STATUS
  69. GetCPUIdCallback(
  70. PVOID HwDeviceExtension,
  71. PVOID Context,
  72. VIDEO_DEVICE_DATA_TYPE DeviceDataType,
  73. PVOID Identifier,
  74. ULONG IdentifierLength,
  75. PVOID ConfigurationData,
  76. ULONG ConfigurationDataLength,
  77. PVOID ComponentInformation,
  78. ULONG ComponentInformationLength
  79. );
  80. VP_STATUS
  81. GetDeviceDataCallback(
  82. PVOID HwDeviceExtension,
  83. PVOID Context,
  84. VIDEO_DEVICE_DATA_TYPE DeviceDataType,
  85. PVOID Identifier,
  86. ULONG IdentifierLength,
  87. PVOID ConfigurationData,
  88. ULONG ConfigurationDataLength,
  89. PVOID ComponentInformation,
  90. ULONG ComponentInformationLength
  91. );
  92. VOID
  93. DevSetRegistryParams(
  94. PHW_DEVICE_EXTENSION hwDeviceExtension
  95. );
  96. VP_STATUS
  97. FindAdapter(
  98. PHW_DEVICE_EXTENSION HwDeviceExtension,
  99. PVOID HwContext,
  100. PWSTR ArgumentString,
  101. PVIDEO_PORT_CONFIG_INFO ConfigInfo,
  102. PP9ADAPTER pCurAdapter
  103. );
  104. VP_STATUS
  105. P9FindAdapter(
  106. PHW_DEVICE_EXTENSION HwDeviceExtension,
  107. PVOID HwContext,
  108. PWSTR ArgumentString,
  109. PVIDEO_PORT_CONFIG_INFO ConfigInfo,
  110. PUCHAR Again
  111. );
  112. BOOLEAN
  113. P9Initialize(
  114. PHW_DEVICE_EXTENSION HwDeviceExtension
  115. );
  116. BOOLEAN
  117. P9StartIO(
  118. PHW_DEVICE_EXTENSION HwDeviceExtension,
  119. PVIDEO_REQUEST_PACKET RequestPacket
  120. );
  121. VOID
  122. DevInitP9(
  123. PHW_DEVICE_EXTENSION HwDeviceExtension
  124. );
  125. VOID
  126. DevDisableP9(
  127. PHW_DEVICE_EXTENSION HwDeviceExtension,
  128. BOOLEAN BugCheck
  129. );
  130. VP_STATUS
  131. P9QueryNamedValueCallback(
  132. PVOID HwDeviceExtension,
  133. PVOID Context,
  134. PWSTR ValueName,
  135. PVOID ValueData,
  136. ULONG ValueLength
  137. );
  138. BOOLEAN
  139. P9ResetVideo(
  140. IN PVOID HwDeviceExtension,
  141. IN ULONG Columns,
  142. IN ULONG Rows
  143. );
  144. VOID
  145. InitializeModes(
  146. PHW_DEVICE_EXTENSION HwDeviceExtension
  147. );
  148. //
  149. // New entry points added for NT 5.0.
  150. //
  151. #if (_WIN32_WINNT >= 500)
  152. //
  153. // Routine to set a desired DPMS power management state.
  154. //
  155. VP_STATUS
  156. WP9SetPower50(
  157. PHW_DEVICE_EXTENSION phwDeviceExtension,
  158. ULONG HwDeviceId,
  159. PVIDEO_POWER_MANAGEMENT pVideoPowerMgmt
  160. );
  161. //
  162. // Routine to retrieve possible DPMS power management states.
  163. //
  164. VP_STATUS
  165. WP9GetPower50(
  166. PHW_DEVICE_EXTENSION phwDeviceExtension,
  167. ULONG HwDeviceId,
  168. PVIDEO_POWER_MANAGEMENT pVideoPowerMgmt
  169. );
  170. //
  171. // Routine to retrieve the Enhanced Display ID structure via DDC
  172. //
  173. ULONG
  174. WP9GetVideoChildDescriptor(
  175. PVOID HwDeviceExtension,
  176. PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
  177. PVIDEO_CHILD_TYPE pChildType,
  178. PVOID pvChildDescriptor,
  179. PULONG pHwId,
  180. PULONG pUnused
  181. );
  182. #endif // _WIN32_WINNT >= 500
  183. #if defined(ALLOC_PRAGMA)
  184. #pragma alloc_text(PAGE,DriverEntry)
  185. #pragma alloc_text(PAGE,GetCPUIdCallback)
  186. #pragma alloc_text(PAGE,GetDeviceDataCallback)
  187. #pragma alloc_text(PAGE,DevSetRegistryParams)
  188. #pragma alloc_text(PAGE,P9FindAdapter)
  189. #pragma alloc_text(PAGE,FindAdapter)
  190. #pragma alloc_text(PAGE,P9Initialize)
  191. #pragma alloc_text(PAGE,P9StartIO)
  192. #if (_WIN32_WINNT >= 500)
  193. #pragma alloc_text(PAGE_COM, WP9SetPower50)
  194. #pragma alloc_text(PAGE_COM, WP9GetPower50)
  195. #pragma alloc_text(PAGE_COM, WP9GetVideoChildDescriptor)
  196. #endif // _WIN32_WINNT >= 500
  197. /*****************************************************************************
  198. *
  199. * IMPORTANT:
  200. *
  201. * Some routines, like DevDisable, can not be paged since they are called
  202. * when the system is bugchecking
  203. *
  204. ****************************************************************************/
  205. // #pragma alloc_text(PAGE, DevDisableP9)
  206. #endif
  207. ULONG
  208. DriverEntry (
  209. PVOID Context1,
  210. PVOID Context2
  211. )
  212. /*++
  213. Routine Description:
  214. Installable driver initialization entry point.
  215. This entry point is called directly by the I/O system.
  216. Arguments:
  217. Context1 - First context value passed by the operating system. This is
  218. the value with which the miniport driver calls VideoPortInitialize().
  219. Context2 - Second context value passed by the operating system. This is
  220. the value with which the miniport driver calls VideoPortInitialize().
  221. Return Value:
  222. Status from VideoPortInitialize()
  223. --*/
  224. {
  225. VIDEO_HW_INITIALIZATION_DATA hwInitData;
  226. ULONG status = ERROR_DEV_NOT_EXIST;
  227. VideoDebugPrint((2, "DriverEntry ----------\n"));
  228. //
  229. // Zero out structure.
  230. //
  231. VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
  232. //
  233. // Specify sizes of structure and extension.
  234. //
  235. hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
  236. //
  237. // Set entry points.
  238. //
  239. hwInitData.HwFindAdapter = P9FindAdapter;
  240. hwInitData.HwInitialize = P9Initialize;
  241. hwInitData.HwInterrupt = NULL;
  242. hwInitData.HwStartIO = P9StartIO;
  243. hwInitData.HwResetHw = P9ResetVideo;
  244. #if (_WIN32_WINNT >= 500)
  245. //
  246. // Set new entry points added for NT 5.0.
  247. //
  248. hwInitData.HwSetPowerState = WP9SetPower50;
  249. hwInitData.HwGetPowerState = WP9GetPower50;
  250. hwInitData.HwGetVideoChildDescriptor = WP9GetVideoChildDescriptor;
  251. #endif // _WIN32_WINNT >= 500
  252. //
  253. // Determine the size we require for the device extension.
  254. //
  255. //
  256. // Compute the size of the device extension by adding in the
  257. // number of DAC Registers.
  258. //
  259. hwInitData.HwDeviceExtensionSize =
  260. sizeof(HW_DEVICE_EXTENSION) +
  261. (17) * sizeof(PVOID);
  262. //
  263. // This driver accesses one range of memory one range of control
  264. // register and a last range for cursor control.
  265. //
  266. // hwInitData.NumberOfAccessRanges = 0;
  267. //
  268. // There is no support for the V86 emulator in this driver so this field
  269. // is ignored.
  270. //
  271. // hwInitData.NumEmulatorAccessEntries = 0;
  272. //
  273. // This device supports many bus types.
  274. //
  275. // SNI has implemented machines with both VL and PCI versions of the
  276. // weitek chipset. Don't bother with the other buses since the
  277. // detection code may actually crash some MIPS boxes.
  278. //
  279. hwInitData.AdapterInterfaceType = PCIBus;
  280. status = VideoPortInitialize(Context1,
  281. Context2,
  282. &hwInitData,
  283. NULL);
  284. if (status == NO_ERROR)
  285. {
  286. VideoDebugPrint((2, "DriverEntry SUCCESS for PCI\n"));
  287. bFoundPCI = TRUE;
  288. return(status);
  289. }
  290. //
  291. // As of NT5, we won't support weitek PCI with any other weitek on
  292. // the same machine.
  293. //
  294. if (bFoundPCI)
  295. return ERROR_DEV_NOT_EXIST;
  296. hwInitData.AdapterInterfaceType = Isa;
  297. status = VideoPortInitialize(Context1,
  298. Context2,
  299. &hwInitData,
  300. NULL);
  301. if ((status == NO_ERROR))
  302. {
  303. VideoDebugPrint((2, "DriverEntry SUCCESS for ISA\n"));
  304. return(status);
  305. }
  306. hwInitData.AdapterInterfaceType = Eisa;
  307. status = VideoPortInitialize(Context1,
  308. Context2,
  309. &hwInitData,
  310. NULL);
  311. if ((status == NO_ERROR))
  312. {
  313. VideoDebugPrint((2, "DriverEntry SUCCESS for EISA\n"));
  314. return(status);
  315. }
  316. hwInitData.AdapterInterfaceType = Internal;
  317. status = VideoPortInitialize(Context1,
  318. Context2,
  319. &hwInitData,
  320. NULL);
  321. if ((status == NO_ERROR))
  322. {
  323. VideoDebugPrint((2, "DriverEntry SUCCESS at for Internal\n"));
  324. return(status);
  325. }
  326. return(status);
  327. } // end DriverEntry()
  328. VP_STATUS
  329. P9FindAdapter (
  330. PHW_DEVICE_EXTENSION HwDeviceExtension,
  331. PVOID HwContext,
  332. PWSTR ArgumentString,
  333. PVIDEO_PORT_CONFIG_INFO ConfigInfo,
  334. PUCHAR Again
  335. )
  336. /*++
  337. Routine Description:
  338. Arguments:
  339. Return Value:
  340. Status from FindAdapter()
  341. --*/
  342. {
  343. ULONG status;
  344. UCHAR i;
  345. *Again = TRUE;
  346. VideoDebugPrint((2, "P9FindAdapter entry\n"));
  347. //
  348. // Loop through the table of types of cards. DriverEntry() loops through
  349. // the bus types.
  350. //
  351. for (i = 0; i < NUM_OEM_ADAPTERS; i++)
  352. {
  353. VideoDebugPrint((2, "Loop %d in P9FindAdapter\n", i));
  354. status = FindAdapter(HwDeviceExtension,
  355. HwContext,
  356. ArgumentString,
  357. ConfigInfo,
  358. &(OEMAdapter[i]));
  359. if (status == NO_ERROR)
  360. {
  361. VideoDebugPrint((2, "P9FindAdapter SUCCESS at loop %d\n", i));
  362. //
  363. // Indicate we do not wish to be called over
  364. //
  365. *Again = FALSE;
  366. break;
  367. }
  368. }
  369. //
  370. // If we've exhausted the table, request to not be recalled.
  371. //
  372. if ( i == NUM_OEM_ADAPTERS)
  373. {
  374. VideoDebugPrint((1, "P9FindAdapter FAILED\n", i));
  375. *Again = FALSE;
  376. }
  377. return(status);
  378. } // end P9FindAdapter()
  379. VP_STATUS
  380. pVlCardDetect(
  381. PVOID HwDeviceExtension,
  382. PVOID Context,
  383. PWSTR ValueName,
  384. PVOID ValueData,
  385. ULONG ValueLength
  386. )
  387. /*++
  388. Routine Description:
  389. This routine determines if the driver is the ForceVga.
  390. Arguments:
  391. Return Value:
  392. return STATUS_SUCCESS if we are in DEADMAN_KEY state
  393. return failiure otherwise.
  394. --*/
  395. {
  396. #ifdef _X86_
  397. if (ValueData &&
  398. ValueLength &&
  399. (*((PULONG)ValueData) == 1)) {
  400. VideoDebugPrint((2, "doing VL card detection\n"));
  401. return NO_ERROR;
  402. } else {
  403. return ERROR_INVALID_PARAMETER;
  404. }
  405. #else
  406. //
  407. // we never have a VL bus on non-x86 systems
  408. //
  409. return ERROR_INVALID_PARAMETER;
  410. #endif
  411. }
  412. VP_STATUS
  413. GetCPUIdCallback(
  414. PVOID HwDeviceExtension,
  415. PVOID Context,
  416. VIDEO_DEVICE_DATA_TYPE DeviceDataType,
  417. PVOID Identifier,
  418. ULONG IdentifierLength,
  419. PVOID ConfigurationData,
  420. ULONG ConfigurationDataLength,
  421. PVOID ComponentInformation,
  422. ULONG ComponentInformationLength
  423. )
  424. {
  425. VideoDebugPrint((2, "Weitek: Check the SNI CPU ID\n"));
  426. //
  427. // We do not want to try to detect the weitekp9 if there isn't one present.
  428. // (Kind of a paradox?)
  429. //
  430. if (Identifier) {
  431. if (VideoPortCompareMemory(Context,
  432. Identifier,
  433. IdentifierLength) == IdentifierLength)
  434. {
  435. return NO_ERROR;
  436. }
  437. }
  438. return ERROR_DEV_NOT_EXIST;
  439. } //end GetCPUIdCallback()
  440. VP_STATUS
  441. GetDeviceDataCallback(
  442. PVOID HwDeviceExtension,
  443. PVOID Context,
  444. VIDEO_DEVICE_DATA_TYPE DeviceDataType,
  445. PVOID Identifier,
  446. ULONG IdentifierLength,
  447. PVOID ConfigurationData,
  448. ULONG ConfigurationDataLength,
  449. PVOID ComponentInformation,
  450. ULONG ComponentInformationLength
  451. )
  452. {
  453. PVIDEO_HARDWARE_CONFIGURATION_DATA configData = ConfigurationData;
  454. PHW_DEVICE_EXTENSION hwDeviceExtension;
  455. ULONG i;
  456. hwDeviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
  457. VideoDebugPrint((2, "Weitek: controller information is present\n"));
  458. //
  459. // We do not want to try to detect the weitekp9 if there isn't one present.
  460. // (Kind of a paradox?)
  461. //
  462. if (Identifier) {
  463. if (VideoPortCompareMemory(L"DIAMOND P9000 VLBUS",
  464. Identifier,
  465. sizeof(L"DIAMOND P9000 VLBUS")) ==
  466. sizeof(L"DIAMOND P9000 VLBUS"))
  467. {
  468. hwDeviceExtension->MachineType = SIEMENS;
  469. }
  470. else if (VideoPortCompareMemory(L"DIAMOND P9100 VLBUS",
  471. Identifier,
  472. sizeof(L"DIAMOND P9100 VLBUS")) ==
  473. sizeof(L"DIAMOND P9100 VLBUS"))
  474. {
  475. hwDeviceExtension->MachineType = SIEMENS_P9100_VLB;
  476. }
  477. else
  478. {
  479. return ERROR_DEV_NOT_EXIST;
  480. }
  481. VideoDebugPrint((1, "Siemens Nixdorf RM400 VL with Weitek P9%d00\n",
  482. hwDeviceExtension->MachineType == SIEMENS ? 0:1));
  483. hwDeviceExtension->P9PhysAddr.LowPart = 0x1D000000;
  484. //
  485. // adjust DriverAccessRanges for Siemens box
  486. //
  487. // This routine may be called several times, but we
  488. // only want to do this once!
  489. //
  490. if (!gMadeAdjustments)
  491. {
  492. ULONG adjust;
  493. if ((hwDeviceExtension->MachineType == SIEMENS_P9100_VLB) &&
  494. (VideoPortIsCpu(L"RM400-MT") || VideoPortIsCpu(L"RM400-T")
  495. ||VideoPortIsCpu(L"RM400-T MP")))
  496. {
  497. //
  498. // If we have a P9100 VLB and it's *not* on a RM200
  499. // then use the new address.
  500. //
  501. // Otherwise, use the old address.
  502. //
  503. adjust = 0x1E000000;
  504. }
  505. else if (hwDeviceExtension->MachineType == SIEMENS
  506. || VideoPortIsCpu(L"RM200"))
  507. {
  508. adjust = 0x14000000;
  509. }
  510. else return ERROR_DEV_NOT_EXIST;
  511. DriverAccessRanges[1].RangeStart.LowPart += adjust;
  512. for(i=0; i<0x10; i++)
  513. {
  514. VLDefDACRegRange[i].RangeStart.LowPart += adjust;
  515. }
  516. gMadeAdjustments = TRUE;
  517. }
  518. }
  519. return NO_ERROR;
  520. } //end GetDeviceDataCallback()
  521. VP_STATUS
  522. P9QueryNamedValueCallback(
  523. PVOID HwDeviceExtension,
  524. PVOID Context,
  525. PWSTR ValueName,
  526. PVOID ValueData,
  527. ULONG ValueLength
  528. )
  529. {
  530. if (ValueLength == 4)
  531. {
  532. *((PULONG) Context) = *((PULONG)ValueData);
  533. return(NO_ERROR);
  534. }
  535. else
  536. {
  537. return(ERROR_INVALID_PARAMETER);
  538. }
  539. }
  540. VOID
  541. WeitekP91NapTime(
  542. VOID
  543. )
  544. {
  545. ULONG count;
  546. for (count=0; count<100; count) {
  547. VideoPortStallExecution(1000);
  548. ++count;
  549. }
  550. }
  551. VP_STATUS
  552. FindAdapter(
  553. PHW_DEVICE_EXTENSION HwDeviceExtension,
  554. PVOID HwContext,
  555. PWSTR ArgumentString,
  556. PVIDEO_PORT_CONFIG_INFO ConfigInfo,
  557. PP9ADAPTER pCurAdapter
  558. )
  559. /*++
  560. Routine Description:
  561. This routine is called to determine if the adapter for this driver
  562. is present in the system.
  563. If it is present, the function fills out some information describing
  564. the adapter.
  565. Arguments:
  566. HwDeviceExtension - Supplies the miniport driver's adapter storage. This
  567. storage is initialized to zero before this call.
  568. HwContext - Supplies the context value which was passed to
  569. VideoPortInitialize(). Must be NULL for PnP drivers.
  570. ArgumentString - Suuplies a NULL terminated ASCII string. This string
  571. originates from the user.
  572. ConfigInfo - Returns the configuration information structure which is
  573. filled by the miniport driver. This structure is initialized with
  574. any knwon configuration information (such as SystemIoBusNumber) by
  575. the port driver. Where possible, drivers should have one set of
  576. defaults which do not require any supplied configuration information.
  577. Again - Indicates if the miniport driver wants the port driver to call
  578. its VIDEO_HW_FIND_ADAPTER function again with a new
  579. and the same config info. This is used by the miniport drivers which
  580. can search for several adapters on a bus.
  581. NO_ERROR - Indicates a host adapter was found and the
  582. configuration information was successfully determined.
  583. ERROR_INVALID_PARAMETER - Indicates an adapter was found but there was an
  584. error obtaining the configuration information. If possible an error
  585. should be logged.
  586. ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the
  587. supplied configuration information.
  588. --*/
  589. {
  590. PULONG pVirtAddr;
  591. SHORT i;
  592. ULONG TotalRanges;
  593. ULONG CoProcId;
  594. VP_STATUS vpCurrStatus = NO_ERROR;
  595. VGA_REGS VGAregs;
  596. BOOLEAN bRetryP9100 = TRUE;
  597. VideoDebugPrint((2, "FindAdapter: enter\n"));
  598. //
  599. // NOTE:
  600. // Important workaround for detection:
  601. //
  602. // We can not always autodetect Weitek VL designs because many machines
  603. // will NMI if we try to access the high memory locations at which the
  604. // card is present.
  605. //
  606. // We will only "detect" the Weitek VL cards if the user specifically
  607. // installed the weitek driver using the video applet.
  608. //
  609. // We will only autodetect the PCI and Viper VL designs. The bAutoDetect
  610. // field in the adapter info structure indicates if a design can be
  611. // autodetected.
  612. //
  613. if ((!pCurAdapter->pAdapterDesc->bAutoDetect) &&
  614. !bFoundPCI &&
  615. VideoPortGetRegistryParameters(HwDeviceExtension,
  616. L"DetectVLCards",
  617. FALSE,
  618. pVlCardDetect,
  619. NULL) != NO_ERROR)
  620. {
  621. VideoDebugPrint((1, "FindAdapter: failed to autodetect\n"));
  622. return(ERROR_DEV_NOT_EXIST);
  623. }
  624. //
  625. // If the bus type in pCurAdapter->pAdapterDesc is PCI, but
  626. // the AdapterInterfaceType in ConfigInfo is not PCI, return
  627. // ERROR_DEV_NOT_EXIST.
  628. //
  629. if ((ConfigInfo->AdapterInterfaceType == PCIBus) &&
  630. (!pCurAdapter->pAdapterDesc->bPCIAdapter))
  631. return ERROR_DEV_NOT_EXIST;
  632. HwDeviceExtension->P9PhysAddr.HighPart = 0;
  633. HwDeviceExtension->P9PhysAddr.LowPart = 0;
  634. VideoPortGetRegistryParameters((PVOID) HwDeviceExtension,
  635. L"Membase",
  636. FALSE,
  637. P9QueryNamedValueCallback,
  638. (PVOID) &(HwDeviceExtension->P9PhysAddr.LowPart));
  639. // SNI is shipping MIPS machine with Internal and PCI versions of the
  640. // weitek chips. For other buses, don't try to load
  641. // For MIPS machine with an Internal Bus, check the ID
  642. // for PPC, we just go through normal detection
  643. //
  644. #if defined(_MIPS_)
  645. if (ConfigInfo->AdapterInterfaceType == Internal)
  646. {
  647. //
  648. // Let get the hardware information from the hardware description
  649. // part of the registry.
  650. //
  651. // Check if there is a video adapter on the internal bus.
  652. // Exit right away if there is not.
  653. //
  654. if (NO_ERROR != VideoPortGetDeviceData(HwDeviceExtension,
  655. VpControllerData,
  656. &GetDeviceDataCallback,
  657. pCurAdapter))
  658. {
  659. VideoDebugPrint((1, "Weitek: VideoPort get controller info failed\n"));
  660. return ERROR_INVALID_PARAMETER;
  661. }
  662. }
  663. else if(ConfigInfo->AdapterInterfaceType != PCIBus)
  664. return ERROR_INVALID_PARAMETER;
  665. #endif
  666. //
  667. // Move the various Hw component structures for this board into the
  668. // device extension.
  669. //
  670. VideoPortMoveMemory(&HwDeviceExtension->P9CoprocInfo,
  671. pCurAdapter->pCoprocInfo,
  672. sizeof(P9_COPROC));
  673. VideoPortMoveMemory(&HwDeviceExtension->AdapterDesc,
  674. pCurAdapter->pAdapterDesc,
  675. sizeof(ADAPTER_DESC));
  676. VideoPortMoveMemory(&HwDeviceExtension->Dac,
  677. pCurAdapter->pDac,
  678. sizeof(DAC));
  679. //
  680. // Set up the array of register ptrs in the device extension:
  681. // the OEMGetBaseAddr routine will need them if a board is found.
  682. // The arrays are kept at the very end of the device extension and
  683. // are order dependent.
  684. //
  685. (PUCHAR) HwDeviceExtension->pDACRegs = (PUCHAR) HwDeviceExtension +
  686. sizeof(HW_DEVICE_EXTENSION);
  687. //
  688. // Call the OEMGetBaseAddr routine to determine if the board is
  689. // installed.
  690. //
  691. VideoDebugPrint((2, "AdapterInterfaceType:%d\n", ConfigInfo->AdapterInterfaceType));
  692. if (!pCurAdapter->pAdapterDesc->OEMGetBaseAddr(HwDeviceExtension))
  693. {
  694. VideoDebugPrint((1, "FindAdapter, GetBaseAddr Failed, line %d\n", __LINE__));
  695. return(ERROR_DEV_NOT_EXIST);
  696. }
  697. //
  698. // We found an adapter, pickup a local for the chip type.
  699. //
  700. CoProcId = pCurAdapter->pCoprocInfo->CoprocId;
  701. //
  702. // Make sure the size of the structure is at least as large as what we
  703. // are expecting (check version of the config info structure).
  704. //
  705. if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO))
  706. {
  707. VideoDebugPrint((1, "FindAdapter Failed, wrong version, line %d\n", __LINE__));
  708. return ERROR_INVALID_PARAMETER;
  709. }
  710. //
  711. // Clear out the Emulator entries and the state size since this driver
  712. // does not support them.
  713. //
  714. ConfigInfo->NumEmulatorAccessEntries = 0;
  715. ConfigInfo->EmulatorAccessEntries = NULL;
  716. ConfigInfo->EmulatorAccessEntriesContext = 0;
  717. ConfigInfo->HardwareStateSize = 0;
  718. if ((CoProcId == P9000_ID) && !(pCurAdapter->pAdapterDesc->bPCIAdapter))
  719. {
  720. ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = 0L;
  721. ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0L;
  722. ConfigInfo->VdmPhysicalVideoMemoryLength = 0L;
  723. }
  724. else
  725. {
  726. ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = MEM_VGA_ADDR;
  727. ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0L;
  728. ConfigInfo->VdmPhysicalVideoMemoryLength = MEM_VGA_SIZE;
  729. if(HwDeviceExtension->MachineType == SIEMENS_P9100_PCi)
  730. ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart |= 0x10000000;
  731. }
  732. //
  733. // The OEMGetBaseAddr routine should have initialized the following
  734. // data structures:
  735. //
  736. // 1) The DAC access ranges in DriverAccessRanges.
  737. // 2) The P9PhysAddr field in the device extension.
  738. //
  739. //
  740. // Initialize the physical address for the registers and frame buffer.
  741. //
  742. HwDeviceExtension->CoprocPhyAddr = HwDeviceExtension->P9PhysAddr;
  743. HwDeviceExtension->CoprocPhyAddr.LowPart +=
  744. HwDeviceExtension->P9CoprocInfo.CoprocRegOffset;
  745. HwDeviceExtension->PhysicalFrameAddr = HwDeviceExtension->P9PhysAddr;
  746. HwDeviceExtension->PhysicalFrameAddr.LowPart +=
  747. HwDeviceExtension->P9CoprocInfo.FrameBufOffset;
  748. //
  749. // Initialize the access range structure with the base address values
  750. // so the driver can register its memory usage.
  751. //
  752. DriverAccessRanges[0].RangeStart =
  753. HwDeviceExtension->P9PhysAddr;
  754. DriverAccessRanges[0].RangeLength =
  755. HwDeviceExtension->P9CoprocInfo.AddrSpace;
  756. if (CoProcId == P9000_ID)
  757. {
  758. //
  759. // Init the total number of standard access ranges.
  760. //
  761. TotalRanges = NUM_DRIVER_ACCESS_RANGES + NUM_DAC_ACCESS_RANGES + 1;
  762. }
  763. else
  764. {
  765. TotalRanges = NUM_DRIVER_ACCESS_RANGES;
  766. }
  767. //
  768. // Check to see if another miniport driver has allocated any of the
  769. // coprocessor's memory space.
  770. //
  771. if (VideoPortVerifyAccessRanges(HwDeviceExtension,
  772. TotalRanges,
  773. DriverAccessRanges) != NO_ERROR)
  774. {
  775. if (HwDeviceExtension->AdapterDesc.bRequiresIORanges)
  776. {
  777. //
  778. // If we need more then just the coproc ranges, and couldn't get
  779. // then we need to fail.
  780. //
  781. VideoDebugPrint((1, "FindAdapter : (ERROR) VideoPortVerifyAccessRanges - Failed 1\n"));
  782. return ERROR_INVALID_PARAMETER;
  783. }
  784. else
  785. {
  786. //
  787. // We couldn't claim all of the access ranges. However, this is a
  788. // card which really only needs the coproc and frame buffer range.
  789. //
  790. if (DriverAccessRanges[0].RangeStart.LowPart &&
  791. VideoPortVerifyAccessRanges(HwDeviceExtension,
  792. 1,
  793. DriverAccessRanges) != NO_ERROR)
  794. {
  795. //
  796. // This access range we can't do without
  797. //
  798. VideoDebugPrint((1, "FindAdapter : (ERROR) VideoPortVerifyAccessRanges - Failed 2\n"));
  799. return ERROR_INVALID_PARAMETER;
  800. }
  801. }
  802. }
  803. else
  804. {
  805. //
  806. // If we get here, then we must have successfully claimed
  807. // the VGA access ranges. Lets map them in.
  808. //
  809. HwDeviceExtension->Vga =
  810. VideoPortGetDeviceBase(HwDeviceExtension,
  811. DriverAccessRanges[1].RangeStart,
  812. DriverAccessRanges[1].RangeLength,
  813. DriverAccessRanges[1].RangeInIoSpace);
  814. }
  815. //
  816. // map coproc, frame buffer, and vga ports
  817. //
  818. {
  819. PHYSICAL_ADDRESS Base;
  820. Base = DriverAccessRanges[0].RangeStart;
  821. Base.QuadPart += HwDeviceExtension->P9CoprocInfo.CoprocRegOffset;
  822. HwDeviceExtension->Coproc =
  823. VideoPortGetDeviceBase(HwDeviceExtension,
  824. Base,
  825. 0x100000,
  826. DriverAccessRanges[0].RangeInIoSpace);
  827. Base = DriverAccessRanges[0].RangeStart;
  828. Base.QuadPart += HwDeviceExtension->P9CoprocInfo.FrameBufOffset;
  829. HwDeviceExtension->FrameAddress =
  830. VideoPortGetDeviceBase(HwDeviceExtension,
  831. Base,
  832. HwDeviceExtension->P9CoprocInfo.AddrSpace -
  833. HwDeviceExtension->P9CoprocInfo.FrameBufOffset,
  834. DriverAccessRanges[0].RangeInIoSpace);
  835. }
  836. if( HwDeviceExtension->Coproc == NULL ||
  837. HwDeviceExtension->FrameAddress == NULL ||
  838. (HwDeviceExtension->Vga == NULL &&
  839. HwDeviceExtension->AdapterDesc.bRequiresIORanges))
  840. {
  841. VideoDebugPrint((1, "weitekp9: VideoPortGetDeviceBase failed.\n"));
  842. return ERROR_INVALID_PARAMETER;
  843. }
  844. if (CoProcId == P9000_ID)
  845. {
  846. //
  847. // Map all of the DAC registers into system virtual address space.
  848. // These registers are mapped seperately from the coprocessor and DAC
  849. // registers since their virtual addresses must be kept in an array
  850. // at the end of the device extension.
  851. //
  852. for (i = 0; i < NUM_DAC_ACCESS_RANGES; i++)
  853. {
  854. if ( (HwDeviceExtension->pDACRegs[i] =
  855. (ULONG)(ULONG_PTR) VideoPortGetDeviceBase(HwDeviceExtension,
  856. DriverAccessRanges[i + NUM_DRIVER_ACCESS_RANGES].RangeStart,
  857. DriverAccessRanges[i + NUM_DRIVER_ACCESS_RANGES].RangeLength,
  858. DriverAccessRanges[i + NUM_DRIVER_ACCESS_RANGES].RangeInIoSpace)) == 0)
  859. {
  860. return ERROR_INVALID_PARAMETER;
  861. }
  862. }
  863. }
  864. else
  865. {
  866. for (i = 0; i < NUM_DAC_ACCESS_RANGES; i++)
  867. {
  868. HwDeviceExtension->pDACRegs[i] = P91_Bt485_DAC_Regs[i];
  869. }
  870. }
  871. // NOTE: !!! jn 1294
  872. // On the P9100 we will always allocate the a full 12 meg
  873. // of address space...
  874. if (CoProcId == P9000_ID)
  875. {
  876. //
  877. // Enable the video memory so it can be sized.
  878. //
  879. if (HwDeviceExtension->AdapterDesc.P9EnableMem)
  880. {
  881. if (!HwDeviceExtension->AdapterDesc.P9EnableMem(HwDeviceExtension))
  882. {
  883. return(FALSE);
  884. }
  885. }
  886. //
  887. // Determine the amount of video memory installed.
  888. //
  889. HwDeviceExtension->P9CoprocInfo.SizeMem(HwDeviceExtension);
  890. }
  891. //
  892. // Detect the DAC type.
  893. // !!!
  894. // On the X86, This requires switching into native mode, so the screen
  895. // will be dark for the remainder of boot.
  896. //
  897. if (CoProcId == P9100_ID)
  898. {
  899. ULONG ulPuConfig;
  900. /*
  901. ** SNI-Od: Save all VGA registers before we switch
  902. ** to native mode
  903. */
  904. VideoDebugPrint((2, "Before save\n"));
  905. P91SaveVGARegs(HwDeviceExtension,&VGAregs);
  906. VideoDebugPrint((2, "After save\n"));
  907. WeitekP91NapTime();
  908. // If we have found a serious error, don't go any further. We have already
  909. // logged the error if the status is set in HwDeviceExtension
  910. if ( vpP91AdapterStatus != NO_ERROR )
  911. {
  912. P91RestoreVGAregs(HwDeviceExtension,&VGAregs);
  913. return (ERROR_DEV_NOT_EXIST);
  914. }
  915. // Get into Native mode
  916. if (HwDeviceExtension->usBusType == VESA)
  917. {
  918. WriteP9ConfigRegister(HwDeviceExtension, P91_CONFIG_CONFIGURATION, 3);
  919. VideoDebugPrint((2, "WroteConfig 1\n"));
  920. }
  921. WriteP9ConfigRegister(HwDeviceExtension, P91_CONFIG_MODE, 0);
  922. VideoDebugPrint((2, "WroteConfig 2\n"));
  923. WeitekP91NapTime();
  924. HwDeviceExtension->p91State.ulPuConfig = P9_RD_REG(P91_PU_CONFIG);
  925. // Look to see if it is an Intergraph board - if so, we want to error out
  926. if ( bIntergraphBoard(HwDeviceExtension) == TRUE )
  927. {
  928. vpCurrStatus = P9_INTERGRAPH_FOUND;
  929. goto error1;
  930. }
  931. // Determine the VRAM type:
  932. HwDeviceExtension->p91State.bVram256 =
  933. (HwDeviceExtension->p91State.ulPuConfig & P91_PUC_MEMORY_DEPTH)
  934. ? FALSE : TRUE;
  935. // Size the memory
  936. P91SizeVideoMemory(HwDeviceExtension);
  937. VideoDebugPrint((2, "Sized mem\n"));
  938. WeitekP91NapTime();
  939. // Setup the Hardware Device Extension.
  940. // So the mode counter will work.
  941. HwDeviceExtension->FrameLength = HwDeviceExtension->p91State.ulFrameBufferSize;
  942. // Make sure we are supporting the correct DAC.
  943. ulPuConfig = HwDeviceExtension->p91State.ulPuConfig;
  944. if ((ulPuConfig & P91_PUC_RAMDAC_TYPE) == P91_PUC_DAC_IBM525)
  945. {
  946. if (HwDeviceExtension->Dac.ulDacId != DAC_ID_IBM525)
  947. {
  948. VideoDebugPrint((1, "WEITEKP9! WARNING - Detected an IBM525 DAC, Expected a Bt485 DAC\n"));
  949. goto error1;
  950. }
  951. }
  952. else if ((ulPuConfig & P91_PUC_RAMDAC_TYPE) == P91_PUC_DAC_BT485)
  953. {
  954. if (HwDeviceExtension->Dac.ulDacId != DAC_ID_BT485)
  955. {
  956. VideoDebugPrint((1, "WEITEKP9! WARNING - Detected an BT485 DAC, Expected an IBM525 DAC\n"));
  957. goto error1;
  958. }
  959. }
  960. else if ((ulPuConfig & P91_PUC_RAMDAC_TYPE) == P91_PUC_DAC_BT489)
  961. {
  962. if (HwDeviceExtension->Dac.ulDacId != DAC_ID_BT489)
  963. {
  964. VideoDebugPrint((1, "WEITEKP9! WARNING - Detected an BT489 DAC, Expected an IBM525 DAC\n"));
  965. goto error1;
  966. }
  967. }
  968. else
  969. {
  970. vpCurrStatus = P9_UNSUPPORTED_DAC;
  971. VideoDebugPrint((1, "WEITEKP9! ERROR - Found P9100, detected an unsupported DAC\n"));
  972. goto error1;
  973. }
  974. /*
  975. ** SNI-Od: Restore all VGA registers
  976. ** after we switch back to VGA mode
  977. */
  978. VideoDebugPrint((2, "Before 1st write config"));
  979. WeitekP91NapTime();
  980. WriteP9ConfigRegister(HwDeviceExtension,P91_CONFIG_MODE,0x2);
  981. VideoDebugPrint((2, "After wrote config\n"));
  982. VideoDebugPrint((2, "Before restore\n"));
  983. WeitekP91NapTime();
  984. P91RestoreVGAregs(HwDeviceExtension,&VGAregs);
  985. VideoDebugPrint((2, "After restore\n"));
  986. WeitekP91NapTime();
  987. }
  988. //
  989. // Set the Chip, Adapter, DAC, and Memory information in the registry.
  990. //
  991. DevSetRegistryParams(HwDeviceExtension);
  992. //
  993. // Initialize the monitor parameters.
  994. //
  995. HwDeviceExtension->CurrentModeNumber = 0;
  996. //
  997. // Initialize the pointer state flags.
  998. //
  999. HwDeviceExtension->flPtrState = 0;
  1000. //
  1001. // NOTE:
  1002. // Should we free up all the address map we allocated to ourselves ?
  1003. // Do we use them after initialization ???
  1004. //
  1005. // VideoPortFreeDeviceBase(HwDeviceExtension, HwDeviceExtension->Coproc);
  1006. // VideoPortFreeDeviceBase(HwDeviceExtension, HwDeviceExtension->Vga);
  1007. //
  1008. // Indicate a successful completion status.
  1009. //
  1010. VideoDebugPrint((2, "FindAdapter: succeeded\n"));
  1011. if_Not_SIEMENS_P9100_VLB()
  1012. VideoPortFreeDeviceBase(HwDeviceExtension, HwDeviceExtension->FrameAddress);
  1013. InitializeModes(HwDeviceExtension);
  1014. WeitekP91NapTime();
  1015. VideoDebugPrint((2, "return\n"));
  1016. return(NO_ERROR);
  1017. //
  1018. // We get here if we really detected a problem, not a mismatch of configuration
  1019. //
  1020. error1:
  1021. if (CoProcId == P9100_ID)
  1022. {
  1023. P91RestoreVGAregs(HwDeviceExtension,&VGAregs);
  1024. VideoDebugPrint((2, "restored vga\n"));
  1025. WeitekP91NapTime();
  1026. }
  1027. if ( vpCurrStatus != NO_ERROR && vpCurrStatus != vpP91AdapterStatus )
  1028. {
  1029. vpP91AdapterStatus = vpCurrStatus;
  1030. VideoPortLogError(HwDeviceExtension,
  1031. NULL,
  1032. vpCurrStatus,
  1033. __LINE__);
  1034. }
  1035. #if defined(i386)
  1036. // Switch back to VGA emulation mode
  1037. //
  1038. // We need to do this so that the VGA miniport can start up.
  1039. //
  1040. WriteP9ConfigRegister(HwDeviceExtension, P91_CONFIG_MODE, 0x2);
  1041. #endif
  1042. VideoDebugPrint((1, "returning ERROR_DEV_NOT_EXIST\n"));
  1043. return (ERROR_DEV_NOT_EXIST);
  1044. } // end FindAdapter()
  1045. VOID
  1046. DevSetRegistryParams(PHW_DEVICE_EXTENSION hwDeviceExtension)
  1047. {
  1048. PUSHORT pwszChip,
  1049. pwszDAC,
  1050. pwszAdapterString;
  1051. ULONG cbChip,
  1052. cbDAC,
  1053. cbAdapterString,
  1054. AdapterMemorySize;
  1055. //
  1056. // First set the string for the chip type, and set the
  1057. // memory configuration if available.
  1058. //
  1059. if (hwDeviceExtension->P9CoprocInfo.CoprocId == P9000_ID)
  1060. {
  1061. pwszChip = L"Weitek P9000";
  1062. cbChip = sizeof (L"Weitek P9000");
  1063. }
  1064. else
  1065. {
  1066. pwszChip = L"Weitek P9100";
  1067. cbChip = sizeof (L"Weitek P9100");
  1068. }
  1069. //
  1070. // Set the memory size
  1071. //
  1072. AdapterMemorySize = hwDeviceExtension->FrameLength;
  1073. //
  1074. // Now, set the string for the DAC type.
  1075. //
  1076. if (hwDeviceExtension->Dac.ulDacId == DAC_ID_BT485)
  1077. {
  1078. pwszDAC = L"Brooktree Bt485";
  1079. cbDAC = sizeof (L"Brooktree Bt485");
  1080. }
  1081. else if (hwDeviceExtension->Dac.ulDacId == DAC_ID_BT489)
  1082. {
  1083. pwszDAC = L"Brooktree Bt489";
  1084. cbDAC = sizeof (L"Brooktree Bt489");
  1085. }
  1086. else
  1087. {
  1088. pwszDAC = L"IBM IBM525";
  1089. cbDAC = sizeof (L"IBM IBM525");
  1090. }
  1091. //
  1092. // Now just pickup the adapter information from the adapter description.
  1093. //
  1094. //
  1095. // Use the length of the longest string !
  1096. //
  1097. pwszAdapterString = hwDeviceExtension->AdapterDesc.ausAdapterIDString;
  1098. cbAdapterString = sizeof(L"Generic Weitek P9000 VL Adapter");
  1099. //
  1100. // We now have a complete hardware description of the hardware.
  1101. // Save the information to the registry so it can be used by
  1102. // configuration programs - such as the display applet
  1103. //
  1104. VideoPortSetRegistryParameters(hwDeviceExtension,
  1105. L"HardwareInformation.ChipType",
  1106. pwszChip,
  1107. cbChip);
  1108. VideoPortSetRegistryParameters(hwDeviceExtension,
  1109. L"HardwareInformation.DacType",
  1110. pwszDAC,
  1111. cbDAC);
  1112. VideoPortSetRegistryParameters(hwDeviceExtension,
  1113. L"HardwareInformation.MemorySize",
  1114. &AdapterMemorySize,
  1115. sizeof(ULONG));
  1116. VideoPortSetRegistryParameters(hwDeviceExtension,
  1117. L"HardwareInformation.AdapterString",
  1118. pwszAdapterString,
  1119. cbAdapterString);
  1120. }
  1121. BOOLEAN
  1122. P9Initialize(
  1123. PHW_DEVICE_EXTENSION HwDeviceExtension
  1124. )
  1125. /*++
  1126. Routine Description:
  1127. This routine does one time initialization of the device.
  1128. Arguments:
  1129. HwDeviceExtension - Supplies a pointer to the miniport's device extension.
  1130. Return Value:
  1131. Always returns TRUE since this routine can never fail.
  1132. --*/
  1133. {
  1134. VideoDebugPrint((2, "P9Initialize ----------\n"));
  1135. return(TRUE);
  1136. } // end P9Initialize()
  1137. BOOLEAN
  1138. P9StartIO(
  1139. PHW_DEVICE_EXTENSION HwDeviceExtension,
  1140. PVIDEO_REQUEST_PACKET RequestPacket
  1141. )
  1142. /*++
  1143. Routine Description:
  1144. This routine is the main execution routine for the miniport driver. It
  1145. acceptss a Video Request Packet, performs the request, and then returns
  1146. with the appropriate status.
  1147. Arguments:
  1148. HwDeviceExtension - Supplies a pointer to the miniport's device extension.
  1149. RequestPacket - Pointer to the video request packet. This structure
  1150. contains all the parameters passed to the VideoIoControl function.
  1151. Return Value:
  1152. --*/
  1153. {
  1154. VP_STATUS status;
  1155. PVIDEO_MODE_INFORMATION modeInformation;
  1156. PVIDEO_MEMORY_INFORMATION memoryInformation;
  1157. ULONG inIoSpace;
  1158. PVIDEO_CLUT clutBuffer;
  1159. PVOID virtualAddr;
  1160. UCHAR i;
  1161. ULONG numValidModes;
  1162. ULONG ulMemoryUsage;
  1163. // VideoDebugPrint((2, "StartIO ----------\n"));
  1164. //
  1165. // Switch on the IoContolCode in the RequestPacket. It indicates which
  1166. // function must be performed by the driver.
  1167. //
  1168. switch (RequestPacket->IoControlCode)
  1169. {
  1170. case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES:
  1171. VideoDebugPrint((2, "P9StartIO - IOCTL_QUERY_PUBLIC_ACCESS_RANGES\n"));
  1172. if (RequestPacket->OutputBufferLength <
  1173. (RequestPacket->StatusBlock->Information =
  1174. sizeof(VIDEO_PUBLIC_ACCESS_RANGES)) )
  1175. {
  1176. status = ERROR_INSUFFICIENT_BUFFER;
  1177. break;
  1178. }
  1179. #if 0
  1180. vDumpPCIConfig(HwDeviceExtension,
  1181. "P9StartIo - IOCTL_QUERY_PUBLIC_ACCESS_RANGES");
  1182. #endif
  1183. // map the coproc to a virtual address
  1184. //
  1185. // Note that on the Alpha we have to map this in sparse-space
  1186. // because dense-space requires all reads to be 64 bits, which
  1187. // would give us unintended side effects using the Weitek
  1188. // registers.
  1189. //
  1190. {
  1191. PVIDEO_PUBLIC_ACCESS_RANGES portAccess;
  1192. ULONG CoprocSize = 0x100000;
  1193. portAccess = RequestPacket->OutputBuffer;
  1194. portAccess->InIoSpace = FALSE;
  1195. portAccess->MappedInIoSpace = portAccess->InIoSpace;
  1196. portAccess->VirtualAddress = NULL;
  1197. status = VideoPortMapMemory(HwDeviceExtension,
  1198. HwDeviceExtension->CoprocPhyAddr,
  1199. &CoprocSize,
  1200. &(portAccess->MappedInIoSpace),
  1201. &(portAccess->VirtualAddress));
  1202. HwDeviceExtension->CoprocVirtAddr = portAccess->VirtualAddress;
  1203. }
  1204. status = NO_ERROR;
  1205. break;
  1206. case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES:
  1207. VideoDebugPrint((2, "P9StartIO - FreePublicAccessRanges\n"));
  1208. {
  1209. PVIDEO_MEMORY mappedMemory;
  1210. if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) {
  1211. status = ERROR_INSUFFICIENT_BUFFER;
  1212. break;
  1213. }
  1214. mappedMemory = RequestPacket->InputBuffer;
  1215. status = NO_ERROR;
  1216. if (mappedMemory->RequestedVirtualAddress != NULL)
  1217. {
  1218. status = VideoPortUnmapMemory(HwDeviceExtension,
  1219. mappedMemory->
  1220. RequestedVirtualAddress,
  1221. 0);
  1222. }
  1223. }
  1224. break;
  1225. case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
  1226. VideoDebugPrint((2, "P9StartIO - MapVideoMemory\n"));
  1227. if ( (RequestPacket->OutputBufferLength <
  1228. (RequestPacket->StatusBlock->Information =
  1229. sizeof(VIDEO_MEMORY_INFORMATION))) ||
  1230. (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) )
  1231. {
  1232. status = ERROR_INSUFFICIENT_BUFFER;
  1233. }
  1234. memoryInformation = RequestPacket->OutputBuffer;
  1235. memoryInformation->VideoRamBase = ((PVIDEO_MEMORY)
  1236. (RequestPacket->InputBuffer))->RequestedVirtualAddress;
  1237. memoryInformation->VideoRamLength = HwDeviceExtension->FrameLength;
  1238. #ifdef ALPHA
  1239. //
  1240. // On the Alpha, we map the frame buffer in dense-space so that
  1241. // we can have GDI draw directly on the surface when we need it
  1242. // to.
  1243. //
  1244. inIoSpace = 4;
  1245. #else
  1246. inIoSpace = 0;
  1247. #endif
  1248. status = VideoPortMapMemory(HwDeviceExtension,
  1249. HwDeviceExtension->PhysicalFrameAddr,
  1250. &(memoryInformation->VideoRamLength),
  1251. &inIoSpace,
  1252. &(memoryInformation->VideoRamBase));
  1253. //
  1254. // The frame buffer and virtual memory and equivalent in this
  1255. // case.
  1256. //
  1257. memoryInformation->FrameBufferBase =
  1258. memoryInformation->VideoRamBase;
  1259. memoryInformation->FrameBufferLength =
  1260. memoryInformation->VideoRamLength;
  1261. break;
  1262. case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
  1263. VideoDebugPrint((2, "P9StartIO - UnMapVideoMemory\n"));
  1264. if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
  1265. {
  1266. status = ERROR_INSUFFICIENT_BUFFER;
  1267. }
  1268. status = VideoPortUnmapMemory(HwDeviceExtension,
  1269. ((PVIDEO_MEMORY)
  1270. (RequestPacket->InputBuffer))->
  1271. RequestedVirtualAddress,
  1272. 0);
  1273. break;
  1274. case IOCTL_VIDEO_QUERY_CURRENT_MODE:
  1275. VideoDebugPrint((2, "P9StartIO - QueryCurrentModes\n"));
  1276. modeInformation = RequestPacket->OutputBuffer;
  1277. if (RequestPacket->OutputBufferLength <
  1278. (RequestPacket->StatusBlock->Information =
  1279. sizeof(VIDEO_MODE_INFORMATION)) )
  1280. {
  1281. status = ERROR_INSUFFICIENT_BUFFER;
  1282. }
  1283. else
  1284. {
  1285. *((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer) =
  1286. P9Modes[HwDeviceExtension->CurrentModeNumber].modeInformation;
  1287. ((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer)->Frequency =
  1288. HwDeviceExtension->VideoData.vlr;
  1289. if (HwDeviceExtension->P9CoprocInfo.CoprocId == P9000_ID)
  1290. {
  1291. ((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer)->DriverSpecificAttributeFlags =
  1292. CAPS_WEITEK_CHIPTYPE_IS_P9000;
  1293. }
  1294. else
  1295. {
  1296. ((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer)->DriverSpecificAttributeFlags =
  1297. 0;
  1298. }
  1299. status = NO_ERROR;
  1300. }
  1301. break;
  1302. case IOCTL_VIDEO_QUERY_AVAIL_MODES:
  1303. VideoDebugPrint((2, "P9StartIO - QueryAvailableModes\n"));
  1304. numValidModes = HwDeviceExtension->ulNumAvailModes;
  1305. if (RequestPacket->OutputBufferLength <
  1306. (RequestPacket->StatusBlock->Information =
  1307. numValidModes * sizeof(VIDEO_MODE_INFORMATION)) )
  1308. {
  1309. status = ERROR_INSUFFICIENT_BUFFER;
  1310. }
  1311. else
  1312. {
  1313. ULONG Flags=0;
  1314. if (HwDeviceExtension->P9CoprocInfo.CoprocId == P9000_ID)
  1315. {
  1316. Flags = CAPS_WEITEK_CHIPTYPE_IS_P9000;
  1317. }
  1318. modeInformation = RequestPacket->OutputBuffer;
  1319. for (i = 0; i < mP9ModeCount; i++)
  1320. {
  1321. if (P9Modes[i].valid == TRUE)
  1322. {
  1323. *modeInformation = P9Modes[i].modeInformation;
  1324. modeInformation->DriverSpecificAttributeFlags = Flags;
  1325. modeInformation++;
  1326. }
  1327. }
  1328. status = NO_ERROR;
  1329. }
  1330. break;
  1331. case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
  1332. VideoDebugPrint((2, "P9StartIO - QueryNumAvailableModes\n"));
  1333. //
  1334. // Find out the size of the data to be put in the the buffer and
  1335. // return that in the status information (whether or not the
  1336. // information is there). If the buffer passed in is not large
  1337. // enough return an appropriate error code.
  1338. //
  1339. // !!! This must be changed to take into account which monitor
  1340. // is present on the machine.
  1341. //
  1342. if (RequestPacket->OutputBufferLength <
  1343. (RequestPacket->StatusBlock->Information =
  1344. sizeof(VIDEO_NUM_MODES)) )
  1345. {
  1346. status = ERROR_INSUFFICIENT_BUFFER;
  1347. }
  1348. else
  1349. {
  1350. ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->NumModes =
  1351. HwDeviceExtension->ulNumAvailModes;
  1352. ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->ModeInformationLength =
  1353. sizeof(VIDEO_MODE_INFORMATION);
  1354. status = NO_ERROR;
  1355. }
  1356. break;
  1357. case IOCTL_VIDEO_SET_CURRENT_MODE:
  1358. VideoDebugPrint((2, "P9StartIO - SetCurrentMode\n"));
  1359. //
  1360. // verify data
  1361. // !!! Make sure it is one of the valid modes on the list
  1362. // calculated using the monitor information.
  1363. //
  1364. if (((PVIDEO_MODE)(RequestPacket->InputBuffer))->RequestedMode
  1365. >= mP9ModeCount)
  1366. {
  1367. status = ERROR_INVALID_PARAMETER;
  1368. break;
  1369. }
  1370. HwDeviceExtension->CurrentModeNumber =
  1371. *(ULONG *)(RequestPacket->InputBuffer);
  1372. DevInitP9(HwDeviceExtension);
  1373. #if 0
  1374. vDumpPCIConfig(HwDeviceExtension,
  1375. "P9StartIo - IOCTL_VIDEO_SET_CURRENT_MODE");
  1376. #endif
  1377. status = NO_ERROR;
  1378. break;
  1379. case IOCTL_VIDEO_SET_COLOR_REGISTERS:
  1380. VideoDebugPrint((2, "P9StartIO - SetColorRegs\n"));
  1381. clutBuffer = RequestPacket->InputBuffer;
  1382. //
  1383. // Check if the size of the data in the input buffer is large enough.
  1384. //
  1385. if ( (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) -
  1386. sizeof(ULONG)) ||
  1387. (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) +
  1388. (sizeof(ULONG) * (clutBuffer->NumEntries - 1)) ) )
  1389. {
  1390. status = ERROR_INSUFFICIENT_BUFFER;
  1391. break;
  1392. }
  1393. if (P9Modes[HwDeviceExtension->CurrentModeNumber].
  1394. modeInformation.BitsPerPlane == 8)
  1395. {
  1396. HwDeviceExtension->Dac.DACSetPalette(HwDeviceExtension,
  1397. (PULONG)clutBuffer->LookupTable,
  1398. clutBuffer->FirstEntry,
  1399. clutBuffer->NumEntries);
  1400. status = NO_ERROR;
  1401. }
  1402. break;
  1403. case IOCTL_VIDEO_ENABLE_POINTER:
  1404. {
  1405. ULONG iCount = (CURSOR_WIDTH * CURSOR_HEIGHT * 2) / 8;
  1406. ULONG xInitPos, yInitPos;
  1407. VideoDebugPrint((2, "P9StartIO - EnablePointer\n"));
  1408. xInitPos = P9Modes[HwDeviceExtension->CurrentModeNumber].
  1409. modeInformation.VisScreenWidth / 2;
  1410. yInitPos = P9Modes[HwDeviceExtension->CurrentModeNumber].
  1411. modeInformation.VisScreenHeight / 2;
  1412. HwDeviceExtension->Dac.HwPointerSetPos(HwDeviceExtension, xInitPos, yInitPos);
  1413. HwDeviceExtension->Dac.HwPointerOn(HwDeviceExtension);
  1414. status = NO_ERROR;
  1415. break;
  1416. case IOCTL_VIDEO_DISABLE_POINTER:
  1417. VideoDebugPrint((2, "P9StartIO - DisablePointer\n"));
  1418. HwDeviceExtension->Dac.HwPointerOff(HwDeviceExtension);
  1419. status = NO_ERROR;
  1420. break;
  1421. }
  1422. case IOCTL_VIDEO_SET_POINTER_POSITION:
  1423. {
  1424. PVIDEO_POINTER_POSITION pointerPosition;
  1425. pointerPosition = RequestPacket->InputBuffer;
  1426. //
  1427. // Check if the size of the data in the input buffer is large enough.
  1428. //
  1429. if (RequestPacket->InputBufferLength < sizeof(VIDEO_POINTER_POSITION))
  1430. {
  1431. status = ERROR_INSUFFICIENT_BUFFER;
  1432. }
  1433. else
  1434. {
  1435. HwDeviceExtension->ulPointerX = (ULONG)pointerPosition->Row;
  1436. HwDeviceExtension->ulPointerY = (ULONG)pointerPosition->Column;
  1437. HwDeviceExtension->Dac.HwPointerSetPos(HwDeviceExtension,
  1438. (ULONG)pointerPosition->Column,
  1439. (ULONG)pointerPosition->Row);
  1440. status = NO_ERROR;
  1441. }
  1442. break;
  1443. }
  1444. case IOCTL_VIDEO_QUERY_POINTER_POSITION:
  1445. {
  1446. PVIDEO_POINTER_POSITION pPointerPosition = RequestPacket->OutputBuffer;
  1447. VideoDebugPrint((2, "P9StartIO - QuerypointerPostion\n"));
  1448. //
  1449. // Make sure the output buffer is big enough.
  1450. //
  1451. if (RequestPacket->OutputBufferLength < sizeof(VIDEO_POINTER_POSITION))
  1452. {
  1453. RequestPacket->StatusBlock->Information = 0;
  1454. return ERROR_INSUFFICIENT_BUFFER;
  1455. }
  1456. //
  1457. // Return the pointer position
  1458. //
  1459. pPointerPosition->Row = (SHORT)HwDeviceExtension->ulPointerX;
  1460. pPointerPosition->Column = (SHORT)HwDeviceExtension->ulPointerY;
  1461. RequestPacket->StatusBlock->Information =
  1462. sizeof(VIDEO_POINTER_POSITION);
  1463. status = NO_ERROR;
  1464. break;
  1465. }
  1466. case IOCTL_VIDEO_SET_POINTER_ATTR: // Set pointer shape
  1467. {
  1468. PVIDEO_POINTER_ATTRIBUTES pointerAttributes;
  1469. UCHAR *pHWCursorShape; // Temp Buffer
  1470. VideoDebugPrint((2, "P9StartIO - SetPointerAttributes\n"));
  1471. pointerAttributes = RequestPacket->InputBuffer;
  1472. //
  1473. // Check if the size of the data in the input buffer is large enough.
  1474. //
  1475. if (RequestPacket->InputBufferLength <
  1476. (sizeof(VIDEO_POINTER_ATTRIBUTES) + ((sizeof(UCHAR) *
  1477. (CURSOR_WIDTH/8) * CURSOR_HEIGHT) * 2)))
  1478. {
  1479. status = ERROR_INSUFFICIENT_BUFFER;
  1480. }
  1481. //
  1482. // If the specified cursor width or height is not valid, then
  1483. // return an invalid parameter error.
  1484. //
  1485. else if ((pointerAttributes->Width > CURSOR_WIDTH) ||
  1486. (pointerAttributes->Height > CURSOR_HEIGHT))
  1487. {
  1488. status = ERROR_INVALID_PARAMETER;
  1489. }
  1490. else if (pointerAttributes->Flags & VIDEO_MODE_MONO_POINTER)
  1491. {
  1492. pHWCursorShape = (PUCHAR) &pointerAttributes->Pixels[0];
  1493. //
  1494. // If this is an animated pointer, don't turn the hw
  1495. // pointer off. This will eliminate cursor blinking.
  1496. // Since GDI currently doesn't pass the ANIMATE_START
  1497. // flag, also check to see if the state of the
  1498. // ANIMATE_UPDATE flag has changed from the last call.
  1499. // If it has, turn the pointer off to eliminate ptr
  1500. // "jumping" when the ptr shape is changed.
  1501. //
  1502. if (!(pointerAttributes->Flags & VIDEO_MODE_ANIMATE_UPDATE) ||
  1503. ((HwDeviceExtension->flPtrState ^
  1504. pointerAttributes->Flags) & VIDEO_MODE_ANIMATE_UPDATE))
  1505. {
  1506. HwDeviceExtension->Dac.HwPointerOff(HwDeviceExtension);
  1507. }
  1508. //
  1509. // Update the cursor state flags in the Device Extension.
  1510. //
  1511. HwDeviceExtension->flPtrState = pointerAttributes->Flags;
  1512. HwDeviceExtension->Dac.HwPointerSetShape(HwDeviceExtension,
  1513. pHWCursorShape);
  1514. HwDeviceExtension->Dac.HwPointerSetPos(HwDeviceExtension,
  1515. (ULONG)pointerAttributes->Column,
  1516. (ULONG)pointerAttributes->Row);
  1517. HwDeviceExtension->Dac.HwPointerOn(HwDeviceExtension);
  1518. status = NO_ERROR;
  1519. break;
  1520. }
  1521. else
  1522. {
  1523. //
  1524. // This cursor is unsupported. Return an error.
  1525. //
  1526. status = ERROR_INVALID_PARAMETER;
  1527. }
  1528. //
  1529. // Couldn't set the new cursor shape. Ensure that any existing HW
  1530. // cursor is disabled.
  1531. //
  1532. HwDeviceExtension->Dac.HwPointerOff(HwDeviceExtension);
  1533. break;
  1534. }
  1535. case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES:
  1536. {
  1537. PVIDEO_POINTER_CAPABILITIES pointerCaps = RequestPacket->OutputBuffer;
  1538. VideoDebugPrint((2, "P9StartIO - QueryPointerCapabilities\n"));
  1539. if (RequestPacket->OutputBufferLength < sizeof(VIDEO_POINTER_CAPABILITIES))
  1540. {
  1541. RequestPacket->StatusBlock->Information = 0;
  1542. status = ERROR_INSUFFICIENT_BUFFER;
  1543. }
  1544. pointerCaps->Flags = VIDEO_MODE_MONO_POINTER;
  1545. pointerCaps->MaxWidth = CURSOR_WIDTH;
  1546. pointerCaps->MaxHeight = CURSOR_HEIGHT;
  1547. pointerCaps->HWPtrBitmapStart = 0; // No VRAM storage for pointer
  1548. pointerCaps->HWPtrBitmapEnd = 0;
  1549. //
  1550. // Number of bytes we're returning.
  1551. //
  1552. RequestPacket->StatusBlock->Information = sizeof(VIDEO_POINTER_CAPABILITIES);
  1553. status = NO_ERROR;
  1554. break;
  1555. }
  1556. case IOCTL_VIDEO_RESET_DEVICE:
  1557. VideoDebugPrint((2, "P9StartIO - RESET_DEVICE\n"));
  1558. DevDisableP9(HwDeviceExtension, FALSE);
  1559. status = NO_ERROR;
  1560. break;
  1561. case IOCTL_VIDEO_SHARE_VIDEO_MEMORY:
  1562. {
  1563. PVIDEO_SHARE_MEMORY pShareMemory;
  1564. PVIDEO_SHARE_MEMORY_INFORMATION pShareMemoryInformation;
  1565. PHYSICAL_ADDRESS shareAddress;
  1566. PVOID virtualAddress;
  1567. ULONG sharedViewSize;
  1568. VideoDebugPrint((2, "P9StartIo - ShareVideoMemory\n"));
  1569. if ( (RequestPacket->OutputBufferLength < sizeof(VIDEO_SHARE_MEMORY_INFORMATION)) ||
  1570. (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) ) {
  1571. VideoDebugPrint((1, "IOCTL_VIDEO_SHARE_VIDEO_MEMORY - ERROR_INSUFFICIENT_BUFFER\n"));
  1572. status = ERROR_INSUFFICIENT_BUFFER;
  1573. break;
  1574. }
  1575. pShareMemory = RequestPacket->InputBuffer;
  1576. if ( (pShareMemory->ViewOffset > HwDeviceExtension->FrameLength) ||
  1577. ((pShareMemory->ViewOffset + pShareMemory->ViewSize) >
  1578. HwDeviceExtension->FrameLength) ) {
  1579. VideoDebugPrint((1, "IOCTL_VIDEO_SHARE_VIDEO_MEMORY - ERROR_INVALID_PARAMETER\n"));
  1580. status = ERROR_INVALID_PARAMETER;
  1581. break;
  1582. }
  1583. RequestPacket->StatusBlock->Information =
  1584. sizeof(VIDEO_SHARE_MEMORY_INFORMATION);
  1585. //
  1586. // Beware: the input buffer and the output buffer are the same
  1587. // buffer, and therefore data should not be copied from one to the
  1588. // other
  1589. //
  1590. virtualAddress = pShareMemory->ProcessHandle;
  1591. sharedViewSize = pShareMemory->ViewSize;
  1592. #ifdef ALPHA
  1593. //
  1594. // On the Alpha, we map the frame buffer in dense-space so that
  1595. // we can have GDI draw directly on the surface when we need it
  1596. // to.
  1597. //
  1598. inIoSpace = 4;
  1599. #else
  1600. inIoSpace = 0;
  1601. #endif
  1602. //
  1603. // NOTE: we are ignoring ViewOffset
  1604. //
  1605. shareAddress.QuadPart =
  1606. HwDeviceExtension->PhysicalFrameAddr.QuadPart;
  1607. //
  1608. // The frame buffer is always mapped linearly.
  1609. //
  1610. status = VideoPortMapMemory(HwDeviceExtension,
  1611. shareAddress,
  1612. &sharedViewSize,
  1613. &inIoSpace,
  1614. &virtualAddress);
  1615. pShareMemoryInformation = RequestPacket->OutputBuffer;
  1616. pShareMemoryInformation->SharedViewOffset = pShareMemory->ViewOffset;
  1617. pShareMemoryInformation->VirtualAddress = virtualAddress;
  1618. pShareMemoryInformation->SharedViewSize = sharedViewSize;
  1619. break;
  1620. }
  1621. case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY:
  1622. {
  1623. PVIDEO_SHARE_MEMORY pShareMemory;
  1624. VideoDebugPrint((2, "P9StartIo - UnshareVideoMemory\n"));
  1625. if (RequestPacket->InputBufferLength < sizeof(VIDEO_SHARE_MEMORY)) {
  1626. status = ERROR_INSUFFICIENT_BUFFER;
  1627. break;
  1628. }
  1629. pShareMemory = RequestPacket->InputBuffer;
  1630. status = VideoPortUnmapMemory(HwDeviceExtension,
  1631. pShareMemory->RequestedVirtualAddress,
  1632. pShareMemory->ProcessHandle);
  1633. break;
  1634. }
  1635. //
  1636. // if we get here, an invalid IoControlCode was specified.
  1637. //
  1638. default:
  1639. VideoDebugPrint((1, "Fell through P9 startIO routine - invalid command\n"));
  1640. status = ERROR_INVALID_FUNCTION;
  1641. break;
  1642. }
  1643. RequestPacket->StatusBlock->Status = status;
  1644. return(TRUE);
  1645. } // end P9StartIO()
  1646. VOID
  1647. DevInitP9(
  1648. PHW_DEVICE_EXTENSION HwDeviceExtension
  1649. )
  1650. /*++
  1651. Routine Description:
  1652. Sets the video mode described in the device extension.
  1653. Arguments:
  1654. HwDeviceExtension - Pointer to the miniport driver's device extension.
  1655. Return Value:
  1656. --*/
  1657. {
  1658. VideoDebugPrint((2, "DevInitP9 ----------\n"));
  1659. //
  1660. // Copy the default parameters for this resolution mode into the
  1661. // device extension.
  1662. //
  1663. VideoPortMoveMemory((PVOID) &(HwDeviceExtension->VideoData),
  1664. (PVOID) P9Modes[HwDeviceExtension->CurrentModeNumber].pvData,
  1665. sizeof(VDATA));
  1666. //
  1667. // Store the requested Bits/Pixel value in the video parms structure
  1668. // in the Device Extension.
  1669. //
  1670. HwDeviceExtension->usBitsPixel =
  1671. P9Modes[HwDeviceExtension->CurrentModeNumber].modeInformation.BitsPerPlane *
  1672. P9Modes[HwDeviceExtension->CurrentModeNumber].modeInformation.NumberOfPlanes;
  1673. HwDeviceExtension->AdapterDesc.OEMSetMode(HwDeviceExtension);
  1674. if (HwDeviceExtension->P9CoprocInfo.CoprocId == P9000_ID)
  1675. {
  1676. Init8720(HwDeviceExtension);
  1677. //
  1678. // Initialize the P9000 system configuration register.
  1679. //
  1680. SysConf(HwDeviceExtension);
  1681. //
  1682. // Set the P9000 Crtc timing registers.
  1683. //
  1684. WriteTiming(HwDeviceExtension);
  1685. }
  1686. else
  1687. {
  1688. InitP9100(HwDeviceExtension);
  1689. P91_SysConf(HwDeviceExtension);
  1690. P91_WriteTiming(HwDeviceExtension);
  1691. }
  1692. VideoDebugPrint((2, "DevInitP9 ---done---\n"));
  1693. }
  1694. BOOLEAN
  1695. P9ResetVideo(
  1696. IN PVOID HwDeviceExtension,
  1697. IN ULONG Columns,
  1698. IN ULONG Rows
  1699. )
  1700. /*++
  1701. routine description:
  1702. disables the P9 and turns on vga pass-thru.
  1703. This function is exported as the HwResetHw entry point so that it may be
  1704. called by the Video Port driver
  1705. at bugcheck time so that VGA video may be enabled.
  1706. arguments:
  1707. hwdeviceextension - pointer to the miniport driver's device extension.
  1708. Columns - Number of columns for text mode (not used).
  1709. Rows - Number of rows for text mode (not used).
  1710. return value:
  1711. Always returns FALSE so that the Video Port driver will call Int 10 to
  1712. set the desired video mode.
  1713. --*/
  1714. {
  1715. DevDisableP9(HwDeviceExtension, TRUE);
  1716. //
  1717. // Tell the Video Port driver to do an Int 10 mode set.
  1718. //
  1719. return(FALSE);
  1720. }
  1721. VOID
  1722. DevDisableP9(
  1723. PHW_DEVICE_EXTENSION HwDeviceExtension,
  1724. BOOLEAN BugCheck
  1725. )
  1726. {
  1727. PHYSICAL_ADDRESS Base;
  1728. BOOLEAN bResetComplete;
  1729. //
  1730. // Clean up the DAC.
  1731. //
  1732. HwDeviceExtension->Dac.DACRestore(HwDeviceExtension);
  1733. //
  1734. // If we are not about to "bugcheck", then clear out
  1735. // video memory.
  1736. //
  1737. // NOTE: On the alpha, the attempt to clear video memory causes
  1738. // the machine to hang. So, we just won't clear the memory
  1739. // on the alpha.
  1740. //
  1741. #if !defined(_ALPHA_)
  1742. if (BugCheck == FALSE)
  1743. {
  1744. Base = DriverAccessRanges[0].RangeStart;
  1745. Base.QuadPart += HwDeviceExtension->P9CoprocInfo.FrameBufOffset;
  1746. HwDeviceExtension->FrameAddress =
  1747. VideoPortGetDeviceBase(HwDeviceExtension,
  1748. Base,
  1749. HwDeviceExtension->P9CoprocInfo.AddrSpace -
  1750. HwDeviceExtension->P9CoprocInfo.FrameBufOffset,
  1751. DriverAccessRanges[0].RangeInIoSpace);
  1752. if (HwDeviceExtension->FrameAddress != NULL)
  1753. {
  1754. VideoDebugPrint((2, "Weitekp9: Clearing video memory.\n"));
  1755. VideoPortZeroMemory(HwDeviceExtension->FrameAddress,
  1756. HwDeviceExtension->FrameLength);
  1757. VideoPortFreeDeviceBase(HwDeviceExtension, HwDeviceExtension->FrameAddress);
  1758. }
  1759. }
  1760. #endif
  1761. // NOTE: On the P9100 we must take care of the DAC before
  1762. // we change the mode to emulation.
  1763. // !!! This must be tested on the P9000
  1764. bResetComplete = HwDeviceExtension->AdapterDesc.P9DisableVideo(HwDeviceExtension);
  1765. //
  1766. // We only want to call int10 if the reset function needs some help and
  1767. // we are not in bugcheck mode, because int10 does not work in bugcheck
  1768. // mode.
  1769. //
  1770. if ((bResetComplete == FALSE) &&
  1771. (BugCheck == FALSE))
  1772. {
  1773. #ifndef PPC
  1774. VIDEO_X86_BIOS_ARGUMENTS biosArguments;
  1775. //
  1776. // Now simply do an int10 and switch to mode 3. The video BIOS
  1777. // will do the work.
  1778. //
  1779. VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  1780. biosArguments.Eax = 0x0003;
  1781. VideoPortInt10(HwDeviceExtension, &biosArguments);
  1782. #endif
  1783. }
  1784. }
  1785. VOID
  1786. InitializeModes(
  1787. PHW_DEVICE_EXTENSION HwDeviceExtension
  1788. )
  1789. /*++
  1790. Routine Description:
  1791. This routine walks through the list of modes, and determines which
  1792. modes will work with our hardware. It sets a flag for each mode
  1793. which will work, and places the number of valid modes in the
  1794. HwDeviceExtension.
  1795. Arguments:
  1796. HwDeviceExtension - pointer to the miniport driver's device extension.
  1797. Columns - Number of columns for text mode (not used).
  1798. Rows - Number of rows for text mode (not used).
  1799. Return Value:
  1800. none
  1801. --*/
  1802. {
  1803. int i;
  1804. ULONG numValidModes=0;
  1805. for(i=0; i<mP9ModeCount; i++)
  1806. {
  1807. if ((HwDeviceExtension->FrameLength >=
  1808. P9Modes[i].modeInformation.ScreenStride *
  1809. P9Modes[i].modeInformation.VisScreenHeight) &&
  1810. (HwDeviceExtension->P9CoprocInfo.CoprocId &
  1811. P9Modes[i].ulChips) &&
  1812. ((P9Modes[i].modeInformation.BitsPerPlane != 24) ||
  1813. (HwDeviceExtension->Dac.bRamdac24BPP)) )
  1814. {
  1815. if_SIEMENS_VLB()
  1816. {
  1817. P9Modes[i].modeInformation.AttributeFlags |=
  1818. VIDEO_MODE_NO_64_BIT_ACCESS;
  1819. }
  1820. P9Modes[i].valid = TRUE;
  1821. numValidModes++;
  1822. }
  1823. }
  1824. //
  1825. // store the number of valid modes in the HwDeviceExtension
  1826. // so we can quickly look it up later when we need it.
  1827. //
  1828. HwDeviceExtension->ulNumAvailModes = numValidModes;
  1829. }
  1830. //
  1831. // Global Functions.
  1832. //
  1833. long mul32(
  1834. short op1,
  1835. short op2
  1836. )
  1837. {
  1838. return ( ((long) op1) * ((long) op2));
  1839. }
  1840. int div32(
  1841. long op1,
  1842. short op2
  1843. )
  1844. {
  1845. return ( (int) (op1 / (long) op2));
  1846. }
  1847. #if (_WIN32_WINNT >= 500)
  1848. //
  1849. // Routine to set a desired DPMS power management state.
  1850. //
  1851. VP_STATUS
  1852. WP9SetPower50(
  1853. PHW_DEVICE_EXTENSION phwDeviceExtension,
  1854. ULONG HwDeviceId,
  1855. PVIDEO_POWER_MANAGEMENT pVideoPowerMgmt
  1856. )
  1857. {
  1858. if ((pVideoPowerMgmt->PowerState == VideoPowerOn) ||
  1859. (pVideoPowerMgmt->PowerState == VideoPowerHibernate) ||
  1860. (pVideoPowerMgmt->PowerState == VideoPowerStandBy)
  1861. ) {
  1862. return NO_ERROR;
  1863. } else {
  1864. return ERROR_INVALID_FUNCTION;
  1865. }
  1866. }
  1867. //
  1868. // Routine to retrieve possible DPMS power management states.
  1869. //
  1870. VP_STATUS
  1871. WP9GetPower50(
  1872. PHW_DEVICE_EXTENSION phwDeviceExtension,
  1873. ULONG HwDeviceId,
  1874. PVIDEO_POWER_MANAGEMENT pVideoPowerMgmt
  1875. )
  1876. {
  1877. if ((pVideoPowerMgmt->PowerState == VideoPowerOn) ||
  1878. (pVideoPowerMgmt->PowerState == VideoPowerHibernate)) {
  1879. return NO_ERROR;
  1880. } else {
  1881. return ERROR_INVALID_FUNCTION;
  1882. }
  1883. }
  1884. //
  1885. // Routine to retrieve the Enhanced Display ID structure via DDC
  1886. //
  1887. ULONG
  1888. WP9GetVideoChildDescriptor(
  1889. PVOID HwDeviceExtension,
  1890. PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
  1891. PVIDEO_CHILD_TYPE pChildType,
  1892. PVOID pvChildDescriptor,
  1893. PULONG pHwId,
  1894. PULONG pUnused
  1895. )
  1896. {
  1897. PHW_DEVICE_EXTENSION pHwDeviceExtension = HwDeviceExtension;
  1898. ULONG Status;
  1899. ASSERT(pHwDeviceExtension != NULL && pMoreChildren != NULL);
  1900. VideoDebugPrint((2, "weitekp9 GetVideoChildDescriptor: *** Entry point ***\n"));
  1901. //
  1902. // Determine if the graphics adapter in the system supports
  1903. // DDC2 (our miniport only supports DDC2, not DDC1). This has
  1904. // the side effect (assuming both monitor and card support
  1905. // DDC2) of switching the monitor from DDC1 mode (repeated
  1906. // "blind" broadcast of EDID clocked by the vertical sync
  1907. // signal) to DDC2 mode (query/response not using any of the
  1908. // normal video lines - can transfer information rapidly
  1909. // without first disrupting the screen by switching into
  1910. // a pseudo-mode with a high vertical sync frequency).
  1911. //
  1912. // Since we must support hot-plugging of monitors, and our
  1913. // routine to obtain the EDID structure via DDC2 assumes that
  1914. // the monitor is in DDC2 mode, we must make this test each
  1915. // time this entry point is called.
  1916. //
  1917. switch (ChildEnumInfo->ChildIndex) {
  1918. case 0:
  1919. //
  1920. // Case 0 is used to enumerate devices found by the ACPI firmware.
  1921. //
  1922. // Since we do not support ACPI devices yet, we must return failure.
  1923. //
  1924. Status = ERROR_NO_MORE_DEVICES;
  1925. break;
  1926. case 1:
  1927. //
  1928. // We do not support monitor enumeration
  1929. //
  1930. Status = ERROR_NO_MORE_DEVICES;
  1931. break;
  1932. case DISPLAY_ADAPTER_HW_ID:
  1933. {
  1934. PUSHORT pPnpDeviceDescription = NULL;
  1935. ULONG stringSize = sizeof(L"*PNPXXXX");
  1936. //
  1937. // Special ID to handle return legacy PnP IDs for root enumerated
  1938. // devices.
  1939. //
  1940. *pChildType = VideoChip;
  1941. *pHwId = DISPLAY_ADAPTER_HW_ID;
  1942. //
  1943. // Figure out which card type and set pPnpDeviceDescription at
  1944. // associated string.
  1945. //
  1946. // WTK_9100_ID 0x0002
  1947. if (pHwDeviceExtension->P9CoprocInfo.CoprocId == P9100_ID)
  1948. pPnpDeviceDescription = L"*PNP0002";
  1949. // WTK_9002_ID 0x9002
  1950. else if (pHwDeviceExtension->P9CoprocInfo.CoprocId == P9000_ID )
  1951. pPnpDeviceDescription = L"*PNP9002";
  1952. else {
  1953. VideoDebugPrint((1, "weitekp9.sys coprocId:%x\n",
  1954. pHwDeviceExtension->P9CoprocInfo.CoprocId));
  1955. }
  1956. //
  1957. // Now just copy the string into memory provided.
  1958. //
  1959. if (pPnpDeviceDescription)
  1960. memcpy(pvChildDescriptor, pPnpDeviceDescription, stringSize);
  1961. Status = ERROR_MORE_DATA;
  1962. break;
  1963. }
  1964. default:
  1965. Status = ERROR_NO_MORE_DEVICES;
  1966. break;
  1967. }
  1968. return Status;
  1969. }
  1970. #endif // _WIN32_WINNT >= 500