Leaked source code of windows server 2003
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.

1412 lines
46 KiB

  1. /************************************************************************/
  2. /* */
  3. /* INIT_M.C */
  4. /* */
  5. /* Sep 27 1993 (c) 1993, ATI Technologies Incorporated. */
  6. /************************************************************************/
  7. /********************** PolyTron RCS Utilities
  8. $Revision: 1.16 $
  9. $Date: 15 May 1996 16:35:42 $
  10. $Author: RWolff $
  11. $Log: S:/source/wnt/ms11/miniport/archive/init_m.c_v $
  12. *
  13. * Rev 1.16 15 May 1996 16:35:42 RWolff
  14. * Waits for idle after setting accelerator mode.
  15. *
  16. * Rev 1.15 17 Apr 1996 13:09:26 RWolff
  17. * Backed out Alpha LFB mapping as dense.
  18. *
  19. * Rev 1.14 11 Apr 1996 15:12:40 RWolff
  20. * Now maps framebuffer as dense on DEC Alpha with PCI graphics card.
  21. *
  22. * Rev 1.13 31 Mar 1995 11:53:46 RWOLFF
  23. * Changed from all-or-nothing debug print statements to thresholds
  24. * depending on importance of the message.
  25. *
  26. * Rev 1.12 14 Feb 1995 15:41:20 RWOLFF
  27. * Changed conditional compile that uses or fakes failure of
  28. * VideoPortMapBankedMemory() to look for IOCTL_VIDEO_SHARE_VIDEO_MEMORY
  29. * instead of the routine itself. Looking for the routine always failed,
  30. * and since the routine is supplied in order to allow DCI to be used
  31. * on systems without a linear framebuffer, it should be available on
  32. * any DDK version that supports the IOCTL. If it isn't, a compile-time
  33. * error will be generated (unresolved external reference).
  34. *
  35. * Rev 1.11 03 Feb 1995 15:17:00 RWOLFF
  36. * Added support for DCI, removed dead code.
  37. *
  38. * Rev 1.10 23 Dec 1994 10:47:18 ASHANMUG
  39. * ALPHA/Chrontel-DAC
  40. *
  41. * Rev 1.9 22 Jul 1994 17:48:50 RWOLFF
  42. * Merged with Richard's non-x86 code stream.
  43. *
  44. * Rev 1.8 27 Jun 1994 16:30:12 RWOLFF
  45. * Now reports all hardware default mode tables as noninterlaced to
  46. * avoid confusing the display applet.
  47. *
  48. * Rev 1.7 15 Jun 1994 11:07:08 RWOLFF
  49. * Now uses VideoPortZeroDeviceMemory() to clear 24BPP screens on NT builds
  50. * where this function is available.
  51. *
  52. * Rev 1.6 12 May 1994 11:05:32 RWOLFF
  53. * Reports the refresh rate from the mode table, rather than always
  54. * reporting "Use hardware default".
  55. *
  56. * Rev 1.5 31 Mar 1994 15:02:00 RWOLFF
  57. * Added SetPowerManagement_m() function to implement DPMS handling.
  58. *
  59. * Rev 1.4 14 Mar 1994 16:31:36 RWOLFF
  60. * XMillimeter field of mode information structure now set properly.
  61. *
  62. * Rev 1.3 03 Mar 1994 12:37:54 ASHANMUG
  63. * Pageable
  64. *
  65. * Rev 1.1 31 Jan 1994 16:27:06 RWOLFF
  66. * Now fills in Frequency and VideoMemoryBitmap[Width|Height] fields of
  67. * mode information structure. Sets Number[Red|Green|Blue]Bits fields
  68. * for palette modes to 6 (assumes VGA-compatible DAC) instead of 0
  69. * to allow Windows NT to set the palette colours to the best match
  70. * for the colours to be displayed.
  71. *
  72. * Rev 1.0 31 Jan 1994 11:10:40 RWOLFF
  73. * Initial revision.
  74. *
  75. * Rev 1.6 24 Jan 1994 18:04:28 RWOLFF
  76. * Now puts DAC in known state before setting video mode. This is to
  77. * accomodate the Graphics Wonder (1M DRAM Mach 32 with BT48x DAC).
  78. *
  79. * Rev 1.5 14 Jan 1994 15:21:22 RWOLFF
  80. * SetCurrentMode_m() and (new routine) ResetDevice_m() now initialize
  81. * and deinitialize the bank manager.
  82. *
  83. * Rev 1.4 15 Dec 1993 15:26:48 RWOLFF
  84. * Added note to clean up before sending to Microsoft.
  85. *
  86. * Rev 1.3 30 Nov 1993 18:16:34 RWOLFF
  87. * MapVideoMemory_m() now sets memoryInformation->FrameBufferLength to
  88. * aperture size rather than amount of video memory present.
  89. *
  90. * Rev 1.2 05 Nov 1993 13:25:24 RWOLFF
  91. * Switched to defined values for memory type, 1280x1024 DAC initialization is
  92. * now done in the same manner as for other resolutions.
  93. *
  94. * Rev 1.0 08 Oct 1993 11:20:34 RWOLFF
  95. * Initial revision.
  96. End of PolyTron RCS section *****************/
  97. #ifdef DOC
  98. INIT_M.C - Highest-level card-dependent routines for miniport.
  99. DESCRIPTION
  100. This file contains initialization and packet handling routines
  101. for 8514/A-compatible ATI accelerators. Routines in this module
  102. are called only by routines in ATIMP.C, which is card-independent.
  103. OTHER FILES
  104. #endif
  105. #include "dderror.h"
  106. #include "miniport.h"
  107. #include "ntddvdeo.h"
  108. #include "video.h"
  109. #include "stdtyp.h"
  110. #include "amach.h"
  111. #include "amach1.h"
  112. #include "atimp.h"
  113. #include "atint.h"
  114. #define INCLUDE_INIT_M
  115. #include "init_m.h"
  116. #include "modes_m.h"
  117. #include "services.h"
  118. #include "setup_m.h"
  119. /*
  120. * Prototypes for static functions.
  121. */
  122. static void QuerySingleMode_m(PVIDEO_MODE_INFORMATION ModeInformation, struct query_structure *QueryPtr, ULONG ModeIndex);
  123. /*
  124. * Allow miniport to be swapped out when not needed.
  125. */
  126. #if defined (ALLOC_PRAGMA)
  127. #pragma alloc_text(PAGE_M, AlphaInit_m)
  128. #pragma alloc_text(PAGE_M, Initialize_m)
  129. #pragma alloc_text(PAGE_M, MapVideoMemory_m)
  130. #pragma alloc_text(PAGE_M, QueryPublicAccessRanges_m)
  131. #pragma alloc_text(PAGE_M, QueryCurrentMode_m)
  132. #pragma alloc_text(PAGE_M, QueryAvailModes_m)
  133. #pragma alloc_text(PAGE_M, QuerySingleMode_m)
  134. #pragma alloc_text(PAGE_M, SetCurrentMode_m)
  135. #pragma alloc_text(PAGE_M, ResetDevice_m)
  136. #pragma alloc_text(PAGE_M, SetPowerManagement_m)
  137. #pragma alloc_text(PAGE_M, ShareVideoMemory_m)
  138. /* BankMap_m() can't be made pageable */
  139. #endif
  140. /***************************************************************************
  141. *
  142. * void AlphaInit_m(void);
  143. *
  144. * DESCRIPTION:
  145. * Perform the initialization that would normally be done by the ROM
  146. * BIOS on x86 machines.
  147. *
  148. * GLOBALS CHANGED:
  149. * none
  150. *
  151. * CALLED BY:
  152. * ATIMPFindAdapter()
  153. *
  154. * AUTHOR:
  155. * Robert Wolff
  156. *
  157. * CHANGE HISTORY:
  158. *
  159. * TEST HISTORY:
  160. *
  161. ***************************************************************************/
  162. void AlphaInit_m(void)
  163. {
  164. OUTPW(MEM_CFG, 0);
  165. DEC_DELAY
  166. OUTPW(MISC_OPTIONS, 0xb0a9);
  167. DEC_DELAY
  168. OUTPW(MEM_BNDRY, 0);
  169. DEC_DELAY
  170. #if 0
  171. OUTPW(CONFIG_STATUS_1, 0x1410);
  172. DEC_DELAY
  173. OUTPW(SCRATCH_PAD_1, 0);
  174. DEC_DELAY
  175. OUTPW(SCRATCH_PAD_0, 0);
  176. DEC_DELAY
  177. #endif
  178. OUTPW(CLOCK_SEL, 0x250);
  179. DEC_DELAY
  180. OUTPW(DAC_W_INDEX, 0x40);
  181. DEC_DELAY
  182. OUTPW(MISC_CNTL, 0xC00);
  183. DEC_DELAY
  184. OUTPW(LOCAL_CONTROL, 0x1402);
  185. #if defined (MIPS) || defined (_MIPS_)
  186. DEC_DELAY
  187. OUTPW(OVERSCAN_COLOR_8, 0); //RKE: to eliminate left overscan on MIPS
  188. #endif
  189. DEC_DELAY
  190. return;
  191. } /* AlphaInit_m() */
  192. /***************************************************************************
  193. *
  194. * void Initialize_m(void);
  195. *
  196. * DESCRIPTION:
  197. * This routine is the 8514/A-compatible hardware initialization routine
  198. * for the miniport driver. It is called once an adapter has been found
  199. * and all the required data structures for it have been created.
  200. *
  201. * GLOBALS CHANGED:
  202. * none
  203. *
  204. * CALLED BY:
  205. * ATIMPInitialize()
  206. *
  207. * AUTHOR:
  208. * Robert Wolff
  209. *
  210. * CHANGE HISTORY:
  211. *
  212. * TEST HISTORY:
  213. *
  214. ***************************************************************************/
  215. void Initialize_m(void)
  216. {
  217. /*
  218. * Make sure we have enough available FIFO entries
  219. * to initialize the card.
  220. */
  221. CheckFIFOSpace_m(SIXTEEN_WORDS);
  222. /*
  223. * On the 68800, set the memory boundary to shared VGA memory.
  224. * On all cards, set the screen and drawing engine to start
  225. * at the beginning of accelerator memory and MEM_CNTL
  226. * to linear.
  227. */
  228. if (phwDeviceExtension->ModelNumber == MACH32_ULTRA)
  229. OUTP (MEM_BNDRY,0);
  230. OUTPW(CRT_OFFSET_LO, 0);
  231. OUTPW(GE_OFFSET_LO, 0);
  232. OUTPW(CRT_OFFSET_HI, 0);
  233. OUTPW(GE_OFFSET_HI, 0);
  234. OUTPW(MEM_CNTL,0x5006);
  235. /*
  236. * Reset the engine and FIFO, then return to normal operation.
  237. */
  238. OUTPW(SUBSYS_CNTL,0x9000);
  239. OUTPW(SUBSYS_CNTL,0x5000);
  240. /*
  241. * The hardware cursor is available only for Mach 32 cards.
  242. * disable the cursor and initialize it to display quadrant I - 0
  243. */
  244. if (phwDeviceExtension->ModelNumber == MACH32_ULTRA)
  245. {
  246. OUTPW(CURSOR_OFFSET_HI,0);
  247. OUTPW(HORZ_CURSOR_OFFSET,0);
  248. OUTP(VERT_CURSOR_OFFSET,0);
  249. OUTPW(CURSOR_COLOR_0, 0x0FF00); /* Colour 0 black, colour 1 white */
  250. OUTPW(EXT_CURSOR_COLOR_0,0); // black
  251. OUTPW(EXT_CURSOR_COLOR_1,0xffff); // white
  252. }
  253. return;
  254. } /* Initialize_m() */
  255. /**************************************************************************
  256. *
  257. * VP_STATUS MapVideoMemory_m(RequestPacket, QueryPtr);
  258. *
  259. * PVIDEO_REQUEST_PACKET RequestPacket; Request packet with input and output buffers
  260. * struct query_structure *QueryPtr; Query information for the card
  261. *
  262. * DESCRIPTION:
  263. * Map the card's video memory into system memory and store the mapped
  264. * address and size in OutputBuffer.
  265. *
  266. * RETURN VALUE:
  267. * NO_ERROR if successful
  268. * error code if failed
  269. *
  270. * GLOBALS CHANGED:
  271. * FrameLength and PhysicalFrameAddress fields of phwDeviceExtension
  272. * if Mach 32 card without linear framebuffer.
  273. *
  274. * CALLED BY:
  275. * IOCTL_VIDEO_MAP_VIDEO_MEMORY packet of ATIMPStartIO()
  276. *
  277. * AUTHOR:
  278. * Robert Wolff
  279. *
  280. * CHANGE HISTORY:
  281. *
  282. * TEST HISTORY:
  283. *
  284. ***************************************************************************/
  285. VP_STATUS MapVideoMemory_m(PVIDEO_REQUEST_PACKET RequestPacket, struct query_structure *QueryPtr)
  286. {
  287. PVIDEO_MEMORY_INFORMATION memoryInformation;
  288. ULONG inIoSpace; /* Scratch variable used by VideoPortMapMemory() */
  289. VP_STATUS status; /* Error code obtained from O/S calls */
  290. memoryInformation = RequestPacket->OutputBuffer;
  291. memoryInformation->VideoRamBase = ((PVIDEO_MEMORY)
  292. (RequestPacket->InputBuffer))->RequestedVirtualAddress;
  293. /*
  294. * The VideoRamLength field contains the amount of video memory
  295. * on the card. The FrameBufferLength field contains the
  296. * size of the aperture in bytes
  297. *
  298. * Initially assume that the linear aperture is available.
  299. * For our 8514/A-compatible cards, we always enable a 4M aperture
  300. * if the LFB is available, so map the full 4M even if the
  301. * aperture size is greater than the amount of video memory.
  302. */
  303. memoryInformation->VideoRamLength = phwDeviceExtension->VideoRamSize;
  304. memoryInformation->FrameBufferLength = 4 * ONE_MEG;
  305. /*
  306. * If the linear aperture is not available (==0), and we are
  307. * dealing with a card which can use the VGA 64k aperture,
  308. * map it in.
  309. */
  310. if (QueryPtr->q_aperture_cfg == 0)
  311. {
  312. if ((phwDeviceExtension->ModelNumber == MACH32_ULTRA) &&
  313. (QueryPtr->q_VGA_type == 1))
  314. {
  315. phwDeviceExtension->FrameLength = 0x10000;
  316. phwDeviceExtension->PhysicalFrameAddress.LowPart = 0x0A0000;
  317. memoryInformation->FrameBufferLength = phwDeviceExtension->FrameLength;
  318. }
  319. else{
  320. /*
  321. * This card can't use either linear or VGA aperture.
  322. * Set frame buffer size to zero and return.
  323. */
  324. memoryInformation->VideoRamBase = 0;
  325. memoryInformation->FrameBufferLength = 0;
  326. memoryInformation->FrameBufferBase = 0;
  327. return NO_ERROR;
  328. }
  329. }
  330. inIoSpace = 0;
  331. #if 0 /* defined(ALPHA) if display driver can handle dense LFB */
  332. if (QueryPtr->q_bus_type == BUS_PCI)
  333. inIoSpace = 4;
  334. #endif
  335. status = VideoPortMapMemory(phwDeviceExtension,
  336. phwDeviceExtension->PhysicalFrameAddress,
  337. &(memoryInformation->FrameBufferLength),
  338. &inIoSpace,
  339. &(memoryInformation->VideoRamBase));
  340. memoryInformation->FrameBufferBase = memoryInformation->VideoRamBase;
  341. return status;
  342. } /* MapVideoMemory_m() */
  343. /**************************************************************************
  344. *
  345. * VP_STATUS QueryPublicAccessRanges_m(RequestPacket);
  346. *
  347. * PVIDEO_REQUEST_PACKET RequestPacket; Request packet with input and output buffers
  348. *
  349. * DESCRIPTION:
  350. * Map and return information on the video card's public access ranges.
  351. *
  352. * RETURN VALUE:
  353. * NO_ERROR if successful
  354. * error code if failed
  355. *
  356. * GLOBALS CHANGED:
  357. * none
  358. *
  359. * CALLED BY:
  360. * IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES packet of ATIMPStartIO()
  361. *
  362. * AUTHOR:
  363. * Robert Wolff
  364. *
  365. * CHANGE HISTORY:
  366. *
  367. * TEST HISTORY:
  368. *
  369. ***************************************************************************/
  370. VP_STATUS QueryPublicAccessRanges_m(PVIDEO_REQUEST_PACKET RequestPacket)
  371. {
  372. PVIDEO_PUBLIC_ACCESS_RANGES portAccess;
  373. PHYSICAL_ADDRESS physicalPortBase;
  374. ULONG physicalPortLength;
  375. if ( RequestPacket->OutputBufferLength <
  376. (RequestPacket->StatusBlock->Information =
  377. sizeof(VIDEO_PUBLIC_ACCESS_RANGES)) )
  378. {
  379. return ERROR_INSUFFICIENT_BUFFER;
  380. }
  381. portAccess = RequestPacket->OutputBuffer;
  382. portAccess->VirtualAddress = (PVOID) NULL; // Requested VA
  383. portAccess->InIoSpace = 1; // In IO space
  384. portAccess->MappedInIoSpace = portAccess->InIoSpace;
  385. physicalPortBase.HighPart = 0x00000000;
  386. physicalPortBase.LowPart = 0x00000000;
  387. // physicalPortLength = LINEDRAW+2 - physicalPortBase.LowPart;
  388. physicalPortLength = 0x10000;
  389. // *SANITIZE* If MM available, give MM ports instead.
  390. return VideoPortMapMemory(phwDeviceExtension,
  391. physicalPortBase,
  392. &physicalPortLength,
  393. &(portAccess->MappedInIoSpace),
  394. &(portAccess->VirtualAddress));
  395. } /* QueryPublicAccessRanges_m() */
  396. /**************************************************************************
  397. *
  398. * VP_STATUS QueryCurrentMode_m(RequestPacket, QueryPtr);
  399. *
  400. * PVIDEO_REQUEST_PACKET RequestPacket; Request packet with input and output buffers
  401. * struct query_structure *QueryPtr; Query information for the card
  402. *
  403. * DESCRIPTION:
  404. * Get screen information and colour masks for the current video mode.
  405. *
  406. * RETURN VALUE:
  407. * NO_ERROR if successful
  408. * error code if failed
  409. *
  410. * GLOBALS CHANGED:
  411. * none
  412. *
  413. * CALLED BY:
  414. * IOCTL_VIDEO_QUERY_CURRENT_MODE packet of ATIMPStartIO()
  415. *
  416. * AUTHOR:
  417. * Robert Wolff
  418. *
  419. * CHANGE HISTORY:
  420. *
  421. * TEST HISTORY:
  422. *
  423. ***************************************************************************/
  424. VP_STATUS QueryCurrentMode_m(PVIDEO_REQUEST_PACKET RequestPacket, struct query_structure *QueryPtr)
  425. {
  426. PVIDEO_MODE_INFORMATION ModeInformation;
  427. /*
  428. * If the output buffer is too small to hold the information we need
  429. * to put in it, return with the appropriate error code.
  430. */
  431. if (RequestPacket->OutputBufferLength <
  432. (RequestPacket->StatusBlock->Information =
  433. sizeof(VIDEO_MODE_INFORMATION)) )
  434. {
  435. return ERROR_INSUFFICIENT_BUFFER;
  436. }
  437. /*
  438. * Fill in the mode information structure.
  439. */
  440. ModeInformation = RequestPacket->OutputBuffer;
  441. QuerySingleMode_m(ModeInformation, QueryPtr, phwDeviceExtension->ModeIndex);
  442. return NO_ERROR;
  443. } /* QueryCurrentMode_m() */
  444. /**************************************************************************
  445. *
  446. * VP_STATUS QueryAvailModes_m(RequestPacket, QueryPtr);
  447. *
  448. * PVIDEO_REQUEST_PACKET RequestPacket; Request packet with input and output buffers
  449. * struct query_structure *QueryPtr; Query information for the card
  450. *
  451. * DESCRIPTION:
  452. * Get screen information and colour masks for all available video modes.
  453. *
  454. * RETURN VALUE:
  455. * NO_ERROR if successful
  456. * error code if failed
  457. *
  458. * GLOBALS CHANGED:
  459. * none
  460. *
  461. * CALLED BY:
  462. * IOCTL_VIDEO_QUERY_AVAIL_MODES packet of ATIMPStartIO()
  463. *
  464. * AUTHOR:
  465. * Robert Wolff
  466. *
  467. * CHANGE HISTORY:
  468. *
  469. * TEST HISTORY:
  470. *
  471. ***************************************************************************/
  472. VP_STATUS QueryAvailModes_m(PVIDEO_REQUEST_PACKET RequestPacket, struct query_structure *QueryPtr)
  473. {
  474. PVIDEO_MODE_INFORMATION ModeInformation;
  475. ULONG CurrentMode;
  476. /*
  477. * If the output buffer is too small to hold the information we need
  478. * to put in it, return with the appropriate error code.
  479. */
  480. if (RequestPacket->OutputBufferLength <
  481. (RequestPacket->StatusBlock->Information =
  482. QueryPtr->q_number_modes * sizeof(VIDEO_MODE_INFORMATION)) )
  483. {
  484. return ERROR_INSUFFICIENT_BUFFER;
  485. }
  486. /*
  487. * Fill in the mode information structure.
  488. */
  489. ModeInformation = RequestPacket->OutputBuffer;
  490. /*
  491. * For each mode supported by the card, store the mode characteristics
  492. * in the output buffer.
  493. */
  494. for (CurrentMode = 0; CurrentMode < QueryPtr->q_number_modes; CurrentMode++, ModeInformation++)
  495. QuerySingleMode_m(ModeInformation, QueryPtr, CurrentMode);
  496. return NO_ERROR;
  497. } /* QueryCurrentMode_m() */
  498. /**************************************************************************
  499. *
  500. * static void QuerySingleMode_m(ModeInformation, QueryPtr, ModeIndex);
  501. *
  502. * PVIDEO_MODE_INFORMATION ModeInformation; Table to be filled in
  503. * struct query_structure *QueryPtr; Query information for the card
  504. * ULONG ModeIndex; Index of mode table to use
  505. *
  506. * DESCRIPTION:
  507. * Fill in a single Windows NT mode information table using data from
  508. * one of our CRT parameter tables.
  509. *
  510. * GLOBALS CHANGED:
  511. * none
  512. *
  513. * CALLED BY:
  514. * QueryCurrentMode_m() and QueryAvailModes_m()
  515. *
  516. * AUTHOR:
  517. * Robert Wolff
  518. *
  519. * CHANGE HISTORY:
  520. *
  521. * TEST HISTORY:
  522. *
  523. ***************************************************************************/
  524. static void QuerySingleMode_m(PVIDEO_MODE_INFORMATION ModeInformation,
  525. struct query_structure *QueryPtr,
  526. ULONG ModeIndex)
  527. {
  528. struct st_mode_table *CrtTable; /* Pointer to current mode table */
  529. CrtTable = (struct st_mode_table *)QueryPtr;
  530. ((struct query_structure *)CrtTable)++;
  531. CrtTable += ModeIndex;
  532. ModeInformation->Length = sizeof(VIDEO_MODE_INFORMATION);
  533. ModeInformation->ModeIndex = ModeIndex;
  534. ModeInformation->VisScreenWidth = CrtTable->m_x_size;
  535. ModeInformation->VisScreenHeight = CrtTable->m_y_size;
  536. // * Bytes per line = ((pixels/line) * (bits/pixel)) / (bits/byte))
  537. ModeInformation->ScreenStride = (CrtTable->m_screen_pitch * CrtTable->m_pixel_depth) / 8;
  538. ModeInformation->NumberOfPlanes = 1;
  539. ModeInformation->BitsPerPlane = (USHORT) CrtTable->m_pixel_depth;
  540. ModeInformation->Frequency = CrtTable->Refresh;
  541. /*
  542. * Driver can't measure the screen size,
  543. * so take reasonable values (16" diagonal).
  544. */
  545. ModeInformation->XMillimeter = 320;
  546. ModeInformation->YMillimeter = 240;
  547. switch(ModeInformation->BitsPerPlane)
  548. {
  549. case 16:
  550. ModeInformation->RedMask = 0x0000f800;
  551. ModeInformation->GreenMask = 0x000007e0;
  552. ModeInformation->BlueMask = 0x0000001f;
  553. ModeInformation->NumberRedBits = 5;
  554. ModeInformation->NumberGreenBits = 6;
  555. ModeInformation->NumberBlueBits = 5;
  556. CrtTable->ColourDepthInfo = PIX_WIDTH_16BPP | ORDER_16BPP_565;
  557. break;
  558. case 24:
  559. /*
  560. * Windows NT uses RGB as the standard 24BPP mode,
  561. * so use this ordering for all DACs except the
  562. * Brooktree 48x which only supports BGR.
  563. */
  564. if (QueryPtr->q_DAC_type != DAC_BT48x)
  565. {
  566. ModeInformation->RedMask = 0x00ff0000;
  567. ModeInformation->GreenMask = 0x0000ff00;
  568. ModeInformation->BlueMask = 0x000000ff;
  569. CrtTable->ColourDepthInfo = PIX_WIDTH_24BPP | ORDER_24BPP_RGB;
  570. }
  571. else{
  572. ModeInformation->RedMask = 0x000000ff;
  573. ModeInformation->GreenMask = 0x0000ff00;
  574. ModeInformation->BlueMask = 0x00ff0000;
  575. CrtTable->ColourDepthInfo = PIX_WIDTH_24BPP | ORDER_24BPP_BGR;
  576. }
  577. ModeInformation->NumberRedBits = 8;
  578. ModeInformation->NumberGreenBits = 8;
  579. ModeInformation->NumberBlueBits = 8;
  580. break;
  581. case 32:
  582. /*
  583. * Only the Brooktree 481 requires BGR,
  584. * and it doesn't support 32BPP.
  585. */
  586. ModeInformation->RedMask = 0xff000000;
  587. ModeInformation->GreenMask = 0x00ff0000;
  588. ModeInformation->BlueMask = 0x0000ff00;
  589. ModeInformation->NumberRedBits = 8;
  590. ModeInformation->NumberGreenBits = 8;
  591. ModeInformation->NumberBlueBits = 8;
  592. CrtTable->ColourDepthInfo = PIX_WIDTH_24BPP | ORDER_24BPP_RGBx;
  593. break;
  594. default:
  595. ModeInformation->RedMask = 0x00000000;
  596. ModeInformation->GreenMask = 0x00000000;
  597. ModeInformation->BlueMask = 0x00000000;
  598. ModeInformation->NumberRedBits = 6;
  599. ModeInformation->NumberGreenBits = 6;
  600. ModeInformation->NumberBlueBits = 6;
  601. CrtTable->ColourDepthInfo = PIX_WIDTH_8BPP;
  602. break;
  603. }
  604. ModeInformation->AttributeFlags = VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS;
  605. if (CrtTable->m_pixel_depth <= 8)
  606. {
  607. ModeInformation->AttributeFlags |= VIDEO_MODE_PALETTE_DRIVEN |
  608. VIDEO_MODE_MANAGED_PALETTE;
  609. }
  610. /*
  611. * Bit 4 of the m_disp_cntl field is set for interlaced and
  612. * cleared for noninterlaced.
  613. *
  614. * The display applet gets confused if some of the "Use hardware
  615. * default" modes are interlaced and some are noninterlaced
  616. * (two "Use hardware default" entries are shown in the refresh
  617. * rate list). To avoid this, report all mode tables stored in
  618. * the EEPROM as noninterlaced, even if they are interlaced.
  619. * "Canned" mode tables give true reports.
  620. */
  621. if ((CrtTable->m_disp_cntl & 0x010) && (ModeInformation->Frequency != DEFAULT_REFRESH))
  622. ModeInformation->AttributeFlags |= VIDEO_MODE_INTERLACED;
  623. else
  624. ModeInformation->AttributeFlags &= ~VIDEO_MODE_INTERLACED;
  625. /*
  626. * Fill in the video memory bitmap width and height fields.
  627. * The descriptions are somewhat ambiguous - assume that
  628. * "bitmap width" is the same as ScreenStride (bytes from
  629. * start of one scanline to start of the next) and "bitmap
  630. * height" refers to the number of complete scanlines which
  631. * will fit into video memory.
  632. */
  633. ModeInformation->VideoMemoryBitmapWidth = ModeInformation->ScreenStride;
  634. ModeInformation->VideoMemoryBitmapHeight = (QueryPtr->q_memory_size * QUARTER_MEG) / ModeInformation->VideoMemoryBitmapWidth;
  635. return;
  636. } /* QuerySingleMode_m() */
  637. //
  638. // When coming back from hibernate, mach32s can lock up and blackscreen.
  639. // This is because the card itself has to be reinitialized.
  640. // This initialization include at least the frame buffer initialization
  641. // and the initialization of the use of memory mapped registers.
  642. //
  643. VOID
  644. EnableMach32FrameBufferAndMemMappedRegisters(
  645. PHW_DEVICE_EXTENSION pHwDeviceExtension
  646. )
  647. {
  648. USHORT temp, temp1;
  649. //
  650. // enable the framebuffer.
  651. //
  652. temp = INPW(MEM_CFG) & 0x0fffc; /* Preserve bits 2-15 */
  653. temp |= 0x0002; /* 4M aperture */
  654. OUTPW(MEM_CFG, temp);
  655. //
  656. // enable memory mapped register use.
  657. // save SRC_X ???
  658. OUTPW(SRC_X, 0x0AAAA);
  659. temp = INPW(R_SRC_X);
  660. if (temp != 0x02AA)
  661. VideoDebugPrint((DEBUG_NORMAL, "Can't use memory mapped ranges, read %x\n", temp));
  662. temp1 = INPW(LOCAL_CONTROL);
  663. temp1 |= 0x0020; // Enable memory mapped registers
  664. OUTPW(LOCAL_CONTROL, temp1);
  665. //restore SRC_X???: OUTPW(SRC_X, temp);
  666. }
  667. /**************************************************************************
  668. *
  669. * void SetCurrentMode_m(QueryPtr, CrtTable);
  670. *
  671. * struct query_structure *QueryPtr; Query information for the card
  672. * struct st_mode_table *CrtTable; CRT parameter table for desired mode
  673. *
  674. * DESCRIPTION:
  675. * Switch into the specified video mode.
  676. *
  677. * GLOBALS CHANGED:
  678. * none
  679. *
  680. * CALLED BY:
  681. * IOCTL_VIDEO_SET_CURRENT_MODE packet of ATIMPStartIO()
  682. *
  683. * AUTHOR:
  684. * Robert Wolff
  685. *
  686. * CHANGE HISTORY:
  687. * 1994 01 13 Added initialization of bank manager
  688. *
  689. * TEST HISTORY:
  690. *
  691. ***************************************************************************/
  692. void SetCurrentMode_m(struct query_structure *QueryPtr, struct st_mode_table *CrtTable)
  693. {
  694. WORD MiscOptions; /* Contents of MISC_OPTIONS register */
  695. USHORT Scratch, USTemp; /* Temporary variable */
  696. //
  697. // When coming back from hibernate, mach32s can lock up and blackscreen.
  698. // This is because the card itself has to be reinitialized.
  699. // This initialization include at least the frame buffer initialization
  700. // and the initialization of the use of memory mapped registers.
  701. //
  702. if (phwDeviceExtension->ModelNumber == MACH32_ULTRA)
  703. {
  704. // enable the framebuffer.
  705. Scratch = INPW(MEM_CFG) & 0x0fffc; /* Preserve bits 2-15 */
  706. Scratch |= 0x0002; /* 4M aperture */
  707. OUTPW(MEM_CFG, Scratch);
  708. // enable memory mapped register use.
  709. // save SRC_X ???
  710. OUTPW(SRC_X, 0x0AAAA);
  711. Scratch = INPW(R_SRC_X);
  712. if (Scratch != 0x02AA)
  713. VideoDebugPrint((DEBUG_NORMAL, "Can't use memory mapped ranges, read %x\n", Scratch));
  714. USTemp = INPW(LOCAL_CONTROL);
  715. USTemp |= 0x0020; // Enable memory mapped registers
  716. OUTPW(LOCAL_CONTROL, USTemp);
  717. //restore SRC_X???: OUTPW(SRC_X, Scratch);
  718. }
  719. /*
  720. * Put the DAC in a known state before we start.
  721. */
  722. UninitTiDac_m();
  723. Passth8514_m(SHOW_ACCEL); // turn vga pass through off
  724. /*
  725. * On cards with the "MISC_OPTIONS doesn't report video memory size
  726. * correctly" bug, reset MISC_OPTIONS to show the true amount of
  727. * video memory. This is done here rather than when we determine
  728. * how much memory is present in order to avoid trashing the "blue
  729. * screen" (no adverse effects on operation, but would generate
  730. * large numbers of user complaints).
  731. */
  732. if (((QueryPtr->q_asic_rev == CI_68800_6) || (QueryPtr->q_asic_rev == CI_68800_AX)) &&
  733. (QueryPtr->q_VGA_type == 1) &&
  734. ((QueryPtr->q_memory_type == VMEM_DRAM_256Kx4) ||
  735. (QueryPtr->q_memory_type == VMEM_DRAM_256Kx16) ||
  736. (QueryPtr->q_memory_type == VMEM_DRAM_256Kx4_GRAP)))
  737. {
  738. MiscOptions = INPW(MISC_OPTIONS) & MEM_SIZE_STRIPPED;
  739. switch (QueryPtr->q_memory_size)
  740. {
  741. case VRAM_512k:
  742. MiscOptions |= MEM_SIZE_512K;
  743. break;
  744. case VRAM_1mb:
  745. MiscOptions |= MEM_SIZE_1M;
  746. break;
  747. case VRAM_2mb:
  748. MiscOptions |= MEM_SIZE_2M;
  749. break;
  750. case VRAM_4mb:
  751. MiscOptions |= MEM_SIZE_4M;
  752. break;
  753. }
  754. OUTPW(MISC_OPTIONS, MiscOptions);
  755. }
  756. setmode_m(CrtTable, (ULONG_PTR) &(phwDeviceExtension->RomBaseRange), (ULONG) phwDeviceExtension->ModelNumber);
  757. /*
  758. * On a Mach 8 card, 1280x1024 can only be done in split
  759. * pixel mode. If we are running on a Mach 8, and this
  760. * resolution was selected, go into split pixel mode.
  761. *
  762. * Bit 4 of EXT_GE_CONFIG is set for split pixel mode and
  763. * clear for normal mode. Bit 3 must be set, since clearing
  764. * it accesses EEPROM read/write mode.
  765. */
  766. if ((phwDeviceExtension->ModelNumber == _8514_ULTRA)
  767. || (phwDeviceExtension->ModelNumber == GRAPHICS_ULTRA))
  768. {
  769. if (QueryPtr->q_desire_x == 1280)
  770. OUTPW(EXT_GE_CONFIG, 0x0018);
  771. else OUTPW(EXT_GE_CONFIG, 0x0008);
  772. }
  773. /*
  774. * Default to 8 bits per pixel. Modes which require a different
  775. * setting will change this in the init_ti_<depth>_m() function.
  776. */
  777. OUTP(DAC_MASK, 0xff);
  778. if (phwDeviceExtension->ModelNumber == MACH32_ULTRA)
  779. {
  780. switch (CrtTable->m_pixel_depth) // program the DAC for the
  781. { // other resolutions
  782. case 4:
  783. case 8:
  784. InitTi_8_m((WORD)(CrtTable->ColourDepthInfo | 0x0a));
  785. break;
  786. case 16:
  787. InitTi_16_m((WORD)(CrtTable->ColourDepthInfo | 0x0a), (ULONG_PTR) &(phwDeviceExtension->RomBaseRange)); /* 16 bit 565 */
  788. break;
  789. case 24:
  790. case 32:
  791. /*
  792. * RGB/BGR and 24/32 bit mode information is
  793. * stored in CrtTable->ColourDepthInfo.
  794. */
  795. InitTi_24_m((WORD)(CrtTable->ColourDepthInfo | 0x0a), (ULONG_PTR) &(phwDeviceExtension->RomBaseRange));
  796. break;
  797. }
  798. }
  799. /*
  800. * If we are going to be using the VGA aperture on a Mach 32,
  801. * initialize the bank manager by saving the ATI extended register
  802. * values and putting the VGA controller into packed pixel mode.
  803. *
  804. * We can't identify this case by looking at
  805. * phwDeviceExtension->FrameLength because it is set to 0x10000
  806. * when the VGA aperture is being used in the
  807. * IOCTL_VIDEO_MAP_VIDEO_MEMORY packet which may or may not
  808. * have been called by the time we reach this point.
  809. */
  810. if ((phwDeviceExtension->ModelNumber == MACH32_ULTRA) &&
  811. (QueryPtr->q_aperture_cfg == 0) &&
  812. (QueryPtr->q_VGA_type == 1))
  813. {
  814. for (Scratch = 0; Scratch <= 2; Scratch++)
  815. {
  816. OUTP(reg1CE, (BYTE)(SavedExtRegs[Scratch] & 0x00FF));
  817. SavedExtRegs[Scratch] = (SavedExtRegs[Scratch] & 0x00FF) | (INP(reg1CF) << 8);
  818. }
  819. OUTPW(HI_SEQ_ADDR, 0x0F02);
  820. OUTPW(HI_SEQ_ADDR, 0x0A04);
  821. OUTPW(reg3CE, 0x1000);
  822. OUTPW(reg3CE, 0x0001);
  823. OUTPW(reg3CE, 0x0002);
  824. OUTPW(reg3CE, 0x0003);
  825. OUTPW(reg3CE, 0x0004);
  826. OUTPW(reg3CE, 0x0005);
  827. OUTPW(reg3CE, 0x0506);
  828. OUTPW(reg3CE, 0x0F07);
  829. OUTPW(reg3CE, 0xFF08);
  830. OUTPW(reg1CE, 0x28B0); /* Enable 256 colour, 1M video RAM */
  831. OUTPW(reg1CE, 0x04B6); /* Select linear addressing */
  832. OUTP(reg1CE, 0xBE);
  833. OUTPW(reg1CE, (WORD)(((INP(reg1CF) & 0xF7) << 8) | 0xBE));
  834. }
  835. /*
  836. * phwDeviceExtension->ReInitializing becomes TRUE in
  837. * IOCTL_VIDEO_SET_COLOR_REGISTERS packet of ATIMPStartIO().
  838. *
  839. * If this is not the first time we are switching into graphics
  840. * mode, set the palette to the last set of colours that was
  841. * selected while in graphics mode.
  842. */
  843. if (phwDeviceExtension->ReInitializing)
  844. {
  845. SetPalette_m(phwDeviceExtension->Clut,
  846. phwDeviceExtension->FirstEntry,
  847. phwDeviceExtension->NumEntries);
  848. }
  849. /*
  850. * Clear visible screen.
  851. *
  852. * 24 and 32 BPP would require a q_desire_y value beyond the
  853. * maximum allowable clipping value (1535) if we clear the screen
  854. * using a normal blit. Since these pixel depths are only supported
  855. * up to 800x600, we can fake it by doing a 16BPP blit of double the
  856. * screen height, clipping the special case of 640x480 24BPP on
  857. * a 1M card (this is the only true colour mode that will fit in
  858. * 1M, so if we hit this case on a 1M card, we know which mode
  859. * we're dealing with) to avoid running off the end of video memory.
  860. */
  861. if (CrtTable->m_pixel_depth >= 24)
  862. {
  863. /*
  864. * Save the colour depth configuration and switch into 16BPP
  865. */
  866. Scratch = INPW(R_EXT_GE_CONFIG);
  867. OUTPD(EXT_GE_CONFIG, (Scratch & 0xFFCF) | PIX_WIDTH_16BPP);
  868. CheckFIFOSpace_m(SIXTEEN_WORDS);
  869. OUTPW(DP_CONFIG, 0x2011);
  870. OUTPW(ALU_FG_FN, 0x7); // Paint
  871. OUTPW(FRGD_COLOR, 0); // Black
  872. OUTPW(CUR_X, 0);
  873. OUTPW(CUR_Y, 0);
  874. OUTPW(DEST_X_START, 0);
  875. OUTPW(DEST_X_END, QueryPtr->q_desire_x);
  876. if (QueryPtr->q_memory_size == VRAM_1mb)
  877. OUTPW(DEST_Y_END, 720); /* Only 640x480 24BPP will fit in 1M */
  878. else
  879. OUTPW(DEST_Y_END, (WORD)(2*(QueryPtr->q_desire_y)));
  880. /*
  881. * Let the blit finish then restore the colour depth configuration
  882. */
  883. WaitForIdle_m();
  884. OUTPD(EXT_GE_CONFIG, Scratch);
  885. }
  886. else{
  887. /*
  888. * Other colour depths can be handled by a normal blit, and the
  889. * LFB may not be available, so use a blit to clear the screen.
  890. */
  891. CheckFIFOSpace_m(SIXTEEN_WORDS);
  892. OUTPW(DP_CONFIG, 0x2011);
  893. OUTPW(ALU_FG_FN, 0x7); // Paint
  894. OUTPW(FRGD_COLOR, 0); // Black
  895. OUTPW(CUR_X, 0);
  896. OUTPW(CUR_Y, 0);
  897. OUTPW(DEST_X_START, 0);
  898. OUTPW(DEST_X_END, QueryPtr->q_desire_x);
  899. OUTPW(DEST_Y_END, QueryPtr->q_desire_y);
  900. }
  901. #if 0
  902. /*
  903. * In 800x600 24BPP, set the offset to start 1 pixel into video
  904. * memory to avoid screen tearing. The MAP_VIDEO_MEMORY packet
  905. * must adjust the framebuffer base to compensate for this.
  906. */
  907. if ((QueryPtr->q_desire_x == 800) && (QueryPtr->q_pix_depth == 24))
  908. {
  909. OUTPW(CRT_OFFSET_LO, 3);
  910. }
  911. else
  912. {
  913. OUTPW(CRT_OFFSET_HI, 0);
  914. }
  915. #endif
  916. WaitForIdle_m();
  917. return;
  918. } /* SetCurrentMode_m() */
  919. /**************************************************************************
  920. *
  921. * void ResetDevice_m(void);
  922. *
  923. * DESCRIPTION:
  924. * Reset the accelerator to allow the VGA miniport to switch
  925. * into a VGA mode.
  926. *
  927. * GLOBALS CHANGED:
  928. * none
  929. *
  930. * CALLED BY:
  931. * IOCTL_VIDEO_RESET_DEVICE packet of ATIMPStartIO()
  932. *
  933. * AUTHOR:
  934. * Robert Wolff
  935. *
  936. * CHANGE HISTORY:
  937. *
  938. * TEST HISTORY:
  939. *
  940. ***************************************************************************/
  941. void ResetDevice_m(void)
  942. {
  943. VIDEO_X86_BIOS_ARGUMENTS Registers; /* Used in VideoPortInt10() calls */
  944. /*
  945. * If we are using the VGA aperture on a Mach 32, put its
  946. * VGA controller into planar mode.
  947. */
  948. if (phwDeviceExtension->FrameLength == 0x10000)
  949. {
  950. OUTPW(reg1CE, SavedExtRegs[0]);
  951. OUTPW(reg1CE, SavedExtRegs[1]);
  952. OUTPW(reg1CE, SavedExtRegs[2]);
  953. OUTP(reg1CE, 0xBE);
  954. OUTPW(reg1CE, (WORD)(((INP(reg1CF) & 0xF7) << 8) | 0xBE));
  955. }
  956. UninitTiDac_m();
  957. Passth8514_m(SHOW_VGA);
  958. VideoPortZeroMemory(&Registers, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  959. Registers.Eax = 0x0003; // set text mode 3
  960. VideoPortInt10(phwDeviceExtension, &Registers);
  961. } /* ResetDevice_m() */
  962. /**************************************************************************
  963. *
  964. * VP_STATUS SetPowerManagement_m(QueryPtr, DpmsState);
  965. *
  966. * struct query_structure *QueryPtr; Query information for the card
  967. * DWORD DpmsState; Desired DPMS state
  968. * (VIDEO_POWER_STATE enumeration)
  969. *
  970. * DESCRIPTION:
  971. * Switch into the desired DPMS state.
  972. *
  973. * RETURN VALUE:
  974. * NO_ERROR if successful
  975. * ERROR_INVALID_PARAMETER if invalid state requested.
  976. *
  977. * GLOBALS CHANGED:
  978. * none
  979. *
  980. * CALLED BY:
  981. * IOCTL_VIDEO_SET_POWER_MANAGEMENT packet of ATIMPStartIO()
  982. *
  983. * AUTHOR:
  984. * Robert Wolff
  985. *
  986. * CHANGE HISTORY:
  987. *
  988. * TEST HISTORY:
  989. *
  990. ***************************************************************************/
  991. VP_STATUS SetPowerManagement_m(struct query_structure *QueryPtr, DWORD DpmsState)
  992. {
  993. struct st_mode_table *CrtTable; /* Mode table, used to obtain sync values */
  994. /*
  995. * Only accept valid states.
  996. */
  997. if ((DpmsState < VideoPowerOn) || (DpmsState > VideoPowerOff))
  998. return ERROR_INVALID_PARAMETER;
  999. /*
  1000. * Set CrtTable to point to the mode table associated with the
  1001. * selected mode.
  1002. *
  1003. * When a pointer to a structure is incremented by an integer,
  1004. * the integer represents the number of structure-sized blocks
  1005. * to skip over, not the number of bytes to skip over.
  1006. */
  1007. CrtTable = (struct st_mode_table *)QueryPtr;
  1008. ((struct query_structure *)CrtTable)++;
  1009. CrtTable += phwDeviceExtension->ModeIndex;
  1010. SavedDPMSState = DpmsState;
  1011. /*
  1012. * Mach 32 rev. 6 and later supports turning the sync signals on and off
  1013. * through the HORZ_OVERSCAN registers, but some chips that report as
  1014. * rev. 6 don't have this implemented. Also, Mach 32 rev. 3 and Mach 8
  1015. * don't support this mechanism.
  1016. *
  1017. * Disabling the sync by setting it to start after the total will work
  1018. * for all chips. Most chips will de-synchronize if the sync is set
  1019. * to 1 more than the total, but some need higher values. To be sure
  1020. * of de-synchronizing, set the disabled sync signal to start at
  1021. * the highest possible value.
  1022. */
  1023. switch (DpmsState)
  1024. {
  1025. case VideoPowerOn:
  1026. OUTP(H_SYNC_STRT, CrtTable->m_h_sync_strt);
  1027. OUTPW(V_SYNC_STRT, CrtTable->m_v_sync_strt);
  1028. break;
  1029. case VideoPowerStandBy:
  1030. OUTP(H_SYNC_STRT, 0xFF);
  1031. OUTPW(V_SYNC_STRT, CrtTable->m_v_sync_strt);
  1032. break;
  1033. case VideoPowerSuspend:
  1034. OUTP(H_SYNC_STRT, CrtTable->m_h_sync_strt);
  1035. OUTPW(V_SYNC_STRT, 0x0FFF);
  1036. break;
  1037. case VideoPowerOff:
  1038. OUTP(H_SYNC_STRT, 0xFF);
  1039. OUTPW(V_SYNC_STRT, 0x0FFF);
  1040. break;
  1041. /*
  1042. * This case should never happen, because the initial
  1043. * acceptance of only valid states should have already
  1044. * rejected anything that will appear here.
  1045. */
  1046. default:
  1047. break;
  1048. }
  1049. return NO_ERROR;
  1050. } /* SetPowerManagement_m() */
  1051. DWORD GetPowerManagement_m(PHW_DEVICE_EXTENSION phwDeviceExtension)
  1052. /*
  1053. * DESCRIPTION:
  1054. * Report which DPMS state we are in.
  1055. *
  1056. * PARAMETERS:
  1057. * phwDeviceExtension Points to per-adapter device extension.
  1058. *
  1059. * RETURN VALUE:
  1060. * Current DPMS state (VIDEO_POWER_STATE enumeration).
  1061. */
  1062. {
  1063. ASSERT(phwDeviceExtension != NULL);
  1064. /*
  1065. * On the Mach 8, the sync start registers are write-only, so
  1066. * we can't check which state we are in. For this reason, we
  1067. * have saved the state we switched into using SetPowerManagement_m().
  1068. * On the Mach 32, we can either use this saved state or read
  1069. * the sync start registers, but using the same method as for
  1070. * the Mach 8 reduces complexity.
  1071. */
  1072. return SavedDPMSState;
  1073. } /* GetPowerManagement_m() */
  1074. /**************************************************************************
  1075. *
  1076. * VP_STATUS ShareVideoMemory_m(RequestPacket, QueryPtr);
  1077. *
  1078. * PVIDEO_REQUEST_PACKET RequestPacket; Request packet with input and output buffers
  1079. * struct query_structure *QueryPtr; Query information for the card
  1080. *
  1081. * DESCRIPTION:
  1082. * Allow applications to do direct screen access through DCI.
  1083. *
  1084. * RETURN VALUE:
  1085. * NO_ERROR if successful
  1086. * error code if failed
  1087. *
  1088. * CALLED BY:
  1089. * IOCTL_VIDEO_SHARE_VIDEO_MEMORY packet of ATIMPStartIO()
  1090. *
  1091. * AUTHOR:
  1092. * Robert Wolff
  1093. *
  1094. * CHANGE HISTORY:
  1095. *
  1096. * TEST HISTORY:
  1097. *
  1098. ***************************************************************************/
  1099. VP_STATUS ShareVideoMemory_m(PVIDEO_REQUEST_PACKET RequestPacket, struct query_structure *QueryPtr)
  1100. {
  1101. PVIDEO_SHARE_MEMORY InputPtr; /* Pointer to input structure */
  1102. PVIDEO_SHARE_MEMORY_INFORMATION OutputPtr; /* Pointer to output structure */
  1103. PHYSICAL_ADDRESS ShareAddress; /* Physical address of video memory */
  1104. PVOID VirtualAddress; /* Virtual address to map video memory at */
  1105. ULONG SharedViewSize; /* Size of block to share */
  1106. ULONG SpaceType; /* Sparse or dense space? */
  1107. VP_STATUS Status; /* Status to return */
  1108. /*
  1109. * We can only share the aperture with application programs if there
  1110. * is an aperture available. If both the LFB and the on-board VGA
  1111. * and therefore the VGA aperture) are disabled, report that we
  1112. * can't share the aperture.
  1113. */
  1114. if ((QueryPtr->q_aperture_cfg == 0) && (QueryPtr->q_VGA_type == 0))
  1115. return ERROR_INVALID_FUNCTION;
  1116. InputPtr = RequestPacket->InputBuffer;
  1117. if ((InputPtr->ViewOffset > phwDeviceExtension->VideoRamSize) ||
  1118. ((InputPtr->ViewOffset + InputPtr->ViewSize) > phwDeviceExtension->VideoRamSize))
  1119. {
  1120. VideoDebugPrint((DEBUG_ERROR, "ShareVideoMemory_m() - access beyond video memory\n"));
  1121. return ERROR_INVALID_PARAMETER;
  1122. }
  1123. RequestPacket->StatusBlock->Information = sizeof(VIDEO_SHARE_MEMORY_INFORMATION);
  1124. /*
  1125. * Beware: the input buffer and the output buffer are the same buffer,
  1126. * and therefore data should not be copied from one to the other.
  1127. */
  1128. VirtualAddress = InputPtr->ProcessHandle;
  1129. SharedViewSize = InputPtr->ViewSize;
  1130. SpaceType = 0;
  1131. #if defined(_ALPHA_)
  1132. /*
  1133. * Use dense space mapping whenever we can, because that will
  1134. * allow us to support DCI and direct GDI access.
  1135. *
  1136. * Dense space is extremely slow with ISA cards on the newer Alphas,
  1137. * because any byte- or word-write requires a read/modify/write
  1138. * operation, and the ALpha can only ever do 64-bit reads when in
  1139. * dense mode. As a result, these operations would always require
  1140. * 4 reads and 2 writes on the ISA bus. Also, some older Alphas
  1141. * don't support dense space mapping.
  1142. *
  1143. * Any Alpha that supports PCI can support dense space mapping, and
  1144. * because the bus is wider and faster, the read/modify/write has
  1145. * less of an impact on performance.
  1146. */
  1147. if (QueryPtr->q_bus_type == BUS_PCI)
  1148. SpaceType = 4;
  1149. #endif
  1150. /*
  1151. * NOTE: we are ignoring ViewOffset
  1152. */
  1153. ShareAddress.QuadPart = phwDeviceExtension->PhysicalFrameAddress.QuadPart;
  1154. /*
  1155. * If the LFB is enabled, use ordinary mapping. If we have only
  1156. * the paged aperture, we must map to banked memory. Since the
  1157. * LFB is always aligned on a 1M boundary (4M boundary for 4M
  1158. * aperture), this check for the paged aperture will never falsely
  1159. * detect a LFB as paged.
  1160. */
  1161. if (phwDeviceExtension->PhysicalFrameAddress.LowPart == 0x0A0000)
  1162. {
  1163. /*
  1164. * On some versions of the DDK, VideoPortMapBankedMemory() is
  1165. * not available. If this is the case, force an error.
  1166. * This routine should be available in all versions of
  1167. * the DDK which support DCI, since it is used for DCI
  1168. * support on cards with banked apertures.
  1169. */
  1170. #if defined(IOCTL_VIDEO_SHARE_VIDEO_MEMORY)
  1171. Status = VideoPortMapBankedMemory(
  1172. phwDeviceExtension,
  1173. ShareAddress,
  1174. &SharedViewSize,
  1175. &SpaceType,
  1176. &VirtualAddress,
  1177. 0x10000, /* 64k VGA aperture */
  1178. FALSE, /* No separate read/write banks */
  1179. BankMap_m, /* Our bank-mapping routine */
  1180. (PVOID) phwDeviceExtension);
  1181. #else
  1182. Status = ERROR_INVALID_FUNCTION;
  1183. #endif
  1184. }
  1185. else /* LFB */
  1186. {
  1187. Status = VideoPortMapMemory(phwDeviceExtension,
  1188. ShareAddress,
  1189. &SharedViewSize,
  1190. &SpaceType,
  1191. &VirtualAddress);
  1192. }
  1193. OutputPtr = RequestPacket->OutputBuffer;
  1194. OutputPtr->SharedViewOffset = InputPtr->ViewOffset;
  1195. OutputPtr->VirtualAddress = VirtualAddress;
  1196. OutputPtr->SharedViewSize = SharedViewSize;
  1197. return Status;
  1198. } /* ShareVideoMemory_m() */
  1199. /**************************************************************************
  1200. *
  1201. * void BankMap_m(BankRead, BankWrite, Context);
  1202. *
  1203. * ULONG BankRead; Bank to read
  1204. * ULONG BankWrite; Bank to write
  1205. * PVOID Context; Pointer to hardware-specific information
  1206. *
  1207. * DESCRIPTION:
  1208. * Map the selected bank of video memory into the 64k VGA aperture.
  1209. * We don't support separate read and write banks, so we use BankWrite
  1210. * to set the read/write bank, and ignore BankRead.
  1211. *
  1212. * CALLED BY:
  1213. * This is an entry point, rather than being called
  1214. * by other miniport functions.
  1215. *
  1216. * NOTE:
  1217. * This function is called directly by the memory manager during page
  1218. * fault handling, and so cannot be made pageable.
  1219. *
  1220. * AUTHOR:
  1221. * Robert Wolff
  1222. *
  1223. * CHANGE HISTORY:
  1224. *
  1225. * TEST HISTORY:
  1226. *
  1227. ***************************************************************************/
  1228. void BankMap_m(ULONG BankRead, ULONG BankWrite, PVOID Context)
  1229. {
  1230. OUTPW( reg1CE, (USHORT)(((BankWrite & 0x0f) << 9) | 0xb2));
  1231. OUTPW( reg1CE, (USHORT)(((BankWrite & 0x30) << 4) | 0xae));
  1232. return;
  1233. } /* BankMap_m() */