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.

441 lines
14 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * ***************
  4. * * SAMPLE CODE *
  5. * ***************
  6. *
  7. * Module Name: Permedia.h
  8. *
  9. * Content: various definitions for the Permedia DMA and FIFO interface
  10. * and the Permedia class
  11. *
  12. * Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
  13. * Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
  14. \*****************************************************************************/
  15. #ifndef __permedia__
  16. #define __permedia__
  17. #include "mini.h"
  18. #define FASTCALL __fastcall
  19. #if defined(_X86_)
  20. typedef LONG __fastcall _InterlockedExchange( IN OUT PLONG, IN LONG);
  21. typedef _InterlockedExchange *PInterlockedExchange;
  22. #endif
  23. #if defined(_ALPHA_)
  24. extern "C" VOID __MB(VOID);
  25. #endif
  26. //
  27. // handy typedefs for FlushDMA and CheckForEOB function pointers
  28. //
  29. typedef VOID (GFNFLUSHDMA)(P2DMA*);
  30. typedef VOID (GFNCHECKEOB)(P2DMA*, LONG);
  31. // Some macros for DirectDraw
  32. #define IN_VRETRACE(xppdev) bInVerticalRetrace(xppdev)
  33. #define IN_DISPLAY(xppdev) (!IN_VRETRACE(xppdev))
  34. #define CURRENT_VLINE(xppdev) lCurrentLine(xppdev)
  35. #define DRAW_ENGINE_BUSY bDrawEngineBusy(pP2dma)
  36. #define SYNC_WITH_PERMEDIA vSyncWithPermedia(pP2dma)
  37. #define READ_CTRL_REG(uiReg)\
  38. READ_REGISTER_ULONG(&pP2dma->pCtrlBase[uiReg/sizeof(ULONG)])
  39. #define P2_READ_CTRL_REG(uiReg)\
  40. READ_REGISTER_ULONG(&ppdev->pCtrlBase[uiReg/sizeof(ULONG)])
  41. #define WRITE_CTRL_REG(uiReg, uiValue)\
  42. { \
  43. WRITE_REGISTER_ULONG(&pP2dma->pCtrlBase[uiReg/sizeof(ULONG)],uiValue); \
  44. MEMORY_BARRIER();\
  45. }
  46. // For sending permedia tags.
  47. #define SEND_PERMEDIA_DATA(tag,data) \
  48. LD_INPUT_FIFO(__Permedia2Tag##tag, data)
  49. #define SEND_PERMEDIA_DATA_OFFSET(tag,data, i) \
  50. LD_INPUT_FIFO(__Permedia2Tag##tag+i, data)
  51. #define COPY_PERMEDIA_DATA(tag,data) \
  52. LD_INPUT_FIFO( __Permedia2Tag##tag, *((unsigned long*) &(data)))
  53. #define HOLD_CMD(tag, count) ( __Permedia2Tag##tag | ((count-1) << 16))
  54. // use macros instead of inlines for Fifo downloads.
  55. //@@BEGIN_DDKSPLIT
  56. #if DBG && MULTITHREADED
  57. #define PERMEDIA_DEFS(xppdev) \
  58. P2DMA *pP2dma=xppdev->pP2dma; \
  59. PULONG pTmp; \
  60. if (pP2dma != NULL) { pP2dma->ppdev = xppdev; }
  61. #else
  62. //@@END_DDKSPLIT
  63. #define PERMEDIA_DEFS(xppdev) \
  64. P2DMA *pP2dma=xppdev->pP2dma;\
  65. PULONG pTmp;
  66. //@@BEGIN_DDKSPLIT
  67. #endif
  68. //@@END_DDKSPLIT
  69. //----------------------------------------------------------------------------
  70. //
  71. // here are the API macros for DMA transport
  72. //
  73. //
  74. // RESERVEDMAPTR(n) // reserve n entries for DMA
  75. // n=GetFreeEntries() // get number of free entries to fill
  76. // (optional)
  77. // up to n LD_INPUT_FIFO
  78. // COMMITDMAPTR() // adjust DMA buffer pointer
  79. //
  80. // FLUSHDMA();
  81. //
  82. //----------------------------------------------------------------------------
  83. //@@BEGIN_DDKSPLIT
  84. #if 1
  85. #define RESERVEDMAWORDS(n) \
  86. { \
  87. ASSERTLOCK(pP2dma->ppdev, RESERVEDMAWORDS); \
  88. pTmp=ReserveDMAPtr(pP2dma,n); \
  89. }
  90. #define RESERVEDMAPTR(n) \
  91. { \
  92. ASSERTLOCK(pP2dma->ppdev, RESERVEDMAPTR); \
  93. pTmp=ReserveDMAPtr(pP2dma,2*n); \
  94. }
  95. #else
  96. //@@END_DDKSPLIT
  97. #define RESERVEDMAWORDS(n) \
  98. { pTmp=ReserveDMAPtr(pP2dma,n);}
  99. #define RESERVEDMAPTR(n) \
  100. { pTmp=ReserveDMAPtr(pP2dma,2*n);}
  101. //@@BEGIN_DDKSPLIT
  102. #endif
  103. //@@END_DDKSPLIT
  104. #define COMMITDMAPTR() \
  105. { CommitDMAPtr(pP2dma,pTmp);}
  106. #define GETFREEENTRIES() \
  107. GetFreeEntries(pP2dma)
  108. #define FLUSHDMA() (pP2dma->pgfnFlushDMA)(pP2dma)
  109. // compiler does not resolve C++ inlines until use of /Ob1,
  110. // so write inline as a real macro
  111. #define LD_INPUT_FIFO(uiTag, uiData) \
  112. { *pTmp++=(uiTag);\
  113. *pTmp++=(uiData);\
  114. }
  115. #define LD_INPUT_FIFO_DATA(uiData) \
  116. *pTmp++=(uiData);
  117. //-----------------------------------------------------------------------------
  118. //
  119. // define register file of Permedia 2 chip and other chip constants
  120. //
  121. //-----------------------------------------------------------------------------
  122. #define PREG_RESETSTATUS 0x0
  123. #define PREG_INTENABLE 0x8
  124. #define PREG_INTFLAGS 0x10
  125. #define PREG_INFIFOSPACE 0x18
  126. #define PREG_OUTFIFOWORDS 0x20
  127. #define PREG_INDMAADDRESS 0x28
  128. #define PREG_INDMACOUNT 0x30
  129. #define PREG_ERRORFLAGS 0x38
  130. #define PREG_VCLKCTL 0x40
  131. #define PERMEDIA_REG_TESTREGISTER 0x48
  132. #define PREG_APERTUREONE 0x50
  133. #define PREG_APERTURETWO 0x58
  134. #define PREG_DMACONTROL 0x60
  135. #define PREG_FIFODISCON 0x68
  136. #define PREG_FIFODISCON_GPACTIVE 0x80000000L
  137. #define PREG_CHIPCONFIG 0x70
  138. #define PREG_OUTDMAADDRESS 0x80
  139. #define PREG_OUTDMACOUNT 0x88
  140. #define PREG_AGPTEXBASEADDRESS 0x90
  141. #define PREG_BYDMAADDRESS 0xa0
  142. #define PREG_BYDMASTRIDE 0xb8
  143. #define PREG_BYDMAMEMADDR 0xc0
  144. #define PREG_BYDMASIZE 0xc8
  145. #define PREG_BYDMABYTEMASK 0xd0
  146. #define PREG_BYDMACONTROL 0xd8
  147. #define PREG_BYDMACOMPLETE 0xe8
  148. #define PREG_FIFOINTERFACE 0x2000
  149. #define PREG_LINECOUNT 0x3070
  150. #define PREG_VBEND 0x3040
  151. #define PREG_SCREENBASE 0x3000
  152. #define PREG_SCREENBASERIGHT 0x3080
  153. #define PREG_VIDEOCONTROL 0x3058
  154. #define PREG_VC_STEREOENABLE 0x800
  155. // use this for stereo
  156. #define PREG_VC_SCREENBASEPENDING 0xc180
  157. #define PREG_VC_RIGHTFRAME 0x2000
  158. // for non stereo modes
  159. // #define PREG_VC_SCREENBASEPENDING 0x080
  160. // GP video enabled/disabled bit of VideoControl
  161. #define PREG_VC_VIDEO_ENABLE 0x0001
  162. #define P2_EXTERNALVIDEO 0x4000
  163. #define CTRLBASE 0
  164. #define COREBASE 0x8000
  165. #define GPFIFO 0x2000
  166. #define MAXINPUTFIFOLENGTH 0x100
  167. //-----------------------------------------------------------------------------
  168. //
  169. // various register flags
  170. //
  171. //-----------------------------------------------------------------------------
  172. #define PREG_INTFLAGS_DMA 1
  173. #define PREG_INTFLAGS_VS 0x10
  174. #define PREG_INTFLAGS_ERROR 0x8
  175. #define PREG_INTFLAGS_SYNC 2
  176. //
  177. // DisconnectControl bits
  178. //
  179. #define DISCONNECT_INPUT_FIFO_ENABLE 0x1
  180. #define DISCONNECT_OUTPUT_FIFO_ENABLE 0x2
  181. #define DISCONNECT_INOUT_ENABLE (DISCONNECT_INPUT_FIFO_ENABLE | \
  182. DISCONNECT_OUTPUT_FIFO_ENABLE)
  183. #define DISCONNECT_INOUT_DISABLE 0x0
  184. //-----------------------------------------------------------------------------
  185. //
  186. // Size of DMA buffer. Since we use only one wraparound DMA Buffer
  187. // with continous physical memory, it should not be too long.
  188. // We allocate this buffer at start of day and keep it forever, unless
  189. // somebody forces an unload of the display driver. Selecting a larger
  190. // size makes it more likely for the call to fail.
  191. //
  192. // The usage counter for the DMA memory is handled in the miniport, because
  193. // the Permedia class gets unloaded on a mode switch.
  194. //
  195. //-----------------------------------------------------------------------------
  196. // DMA command buffer stream size and minimum size
  197. #define DMACMDSIZE DMA_BUFFERSIZE
  198. #define DMACMDMINSIZE 0x2000L
  199. #define MAXBLKSIZE 0x1000 // limit block transfers to 16 kb per chunk
  200. // to have a good balance between download
  201. // speed and latencies
  202. #define ALIGNFACTOR 0x400 // alignment factor (4kb page)
  203. //-----------------------------------------------------------------------------
  204. //
  205. // shared memory section of P2 interrupt driven DMA handler
  206. //
  207. //-----------------------------------------------------------------------------
  208. struct _P2DMA {
  209. INTERRUPT_CONTROL_BLOCK ICB;
  210. // these are the linear Permedia base addresses of the control registers
  211. // and the Fifo area
  212. ULONG *pCtrlBase;
  213. ULONG *pGPFifo;
  214. // handle to videoport of instance
  215. HANDLE hDriver;
  216. LONG lDMABufferSize; // size of DMA buffer in ULONGs
  217. ULONG uiInstances; // currently active driver instances using
  218. // the shared memory
  219. ULONG ulIntFlags; // cache for interrupt flag register
  220. #if defined(_X86_)
  221. // pointer to Interlockedexchange function in
  222. // the kernel.
  223. PInterlockedExchange pInterlockedExchange;
  224. #endif
  225. BOOL bDMAEmulation; // remember if we run in DMA emulation
  226. GFNCHECKEOB*pgfnCheckEOB; // DMA CheckEOB buffer function pointer
  227. GFNFLUSHDMA*pgfnFlushDMA; // DMA FlushDMA buffer function pointer
  228. ULONG *pSharedDMABuffer; // virtual address of shared DMA buffer
  229. LONG lSharedDMABufferSize; // size of shared DMA buffer in BYTEs
  230. ULONG *pEmulatedDMABuffer; // address of DMA emulation buffer
  231. LONG lEmulatedDMABufferSize;// size of DMA emulation buffer in BYTEs
  232. BOOL bEnabled; // check if the DMA code is enabled
  233. #if DBG
  234. LONG lDBGState; // keep track of state in debug version
  235. // 0: idle
  236. // 2: ReserveDMAPtr was called
  237. LONG bDBGIgnoreAssert;
  238. ULONG *pDBGReservedEntries; // pointer to which we have reserved
  239. // for debugging checks
  240. //@@BEGIN_DDKSPLIT
  241. #if MULTITHREADED
  242. PPDev ppdev; // For checking multithreaded semaphore
  243. #endif
  244. //@@END_DDKSPLIT
  245. #endif
  246. } ;
  247. //-----------------------------------------------------------------------------
  248. //
  249. // definitions for functions which are different in non-DMA, DMA and
  250. // multiprocessing DMA cases. bInitializeP2DMA will decide which ones to use
  251. // and preset the function pointers.
  252. //
  253. //-----------------------------------------------------------------------------
  254. VOID vFlushDMA(P2DMA *pP2dma);
  255. VOID vFlushDMAMP(P2DMA *pP2dma);
  256. VOID vFlushDMAEmulation(P2DMA *pP2dma);
  257. VOID vCheckForEOB(P2DMA *pP2dma,LONG lEntries);
  258. VOID vCheckForEOBMP(P2DMA *pP2dma,LONG lEntries);
  259. VOID vCheckForEOBEmulation(P2DMA *pP2dma,LONG lEntries);
  260. //-----------------------------------------------------------------------------
  261. //
  262. // more helper and blockdownload functions
  263. //
  264. //-----------------------------------------------------------------------------
  265. VOID vWaitDMAComplete(P2DMA *pP2dma);
  266. LONG lWaitOutputFifoReady(P2DMA *pP2dma);
  267. BOOL bDrawEngineBusy(P2DMA *pP2dma);
  268. BOOL bInVerticalRetrace(PPDev ppdev);
  269. LONG lCurrentLine(PPDev ppdev);
  270. VOID vBlockLoadInputFifoByte (P2DMA *pP2dma,
  271. ULONG uiTag,
  272. BYTE *pImage,
  273. LONG lWords);
  274. VOID vBlockLoadInputFifo (P2DMA *pP2dma,
  275. ULONG uiTag,
  276. ULONG *pImage,
  277. LONG lWords);
  278. //-----------------------------------------------------------------------------
  279. //
  280. // Basic reserve/commit Api functions. They are provided as inlines for free
  281. // builds and as functions with debug checks in checked builds.
  282. //
  283. //-----------------------------------------------------------------------------
  284. ULONG *ReserveDMAPtr (P2DMA *pP2dma, const LONG nEntries);
  285. VOID CommitDMAPtr (P2DMA *pP2dma, ULONG *pDMAPtr);
  286. LONG GetFreeEntries(P2DMA *pP2dma);
  287. //
  288. // completely synchronize chip here
  289. //
  290. VOID vSyncWithPermedia(P2DMA *pP2dma);
  291. //
  292. // initialization and cleanup routines
  293. //
  294. BOOL bInitializeP2DMA( P2DMA *pP2dma,
  295. HANDLE hDriver,
  296. ULONG *pChipBase,
  297. DWORD dwAccelerationLevel,
  298. BOOL NewReference
  299. );
  300. VOID vFree(P2DMA *pP2dma);
  301. #if !DBG
  302. //----------------------------------------------------------------------------
  303. //
  304. // ReserveDMAPtr
  305. //
  306. // return a pointer to current position in DMA buffer. The function guarantees
  307. // that there are at least lEntries available in the buffer.
  308. // Otherwise the caller can ask GetFreeEntries and adjust the download to
  309. // batch more entries. The caller MUST call CommitDMAPtr after a call to
  310. // to ReserveDMAPtr to readjust the Index pointer.
  311. //
  312. //----------------------------------------------------------------------------
  313. inline ULONG *ReserveDMAPtr(P2DMA *pP2dma,const LONG lEntries)
  314. {
  315. while (pP2dma->ICB.pDMAWritePos+lEntries>=
  316. pP2dma->ICB.pDMAWriteEnd)
  317. {
  318. (*pP2dma->pgfnCheckEOB)(pP2dma,lEntries);
  319. }
  320. return (ULONG *)pP2dma->ICB.pDMAWritePos;
  321. }
  322. //----------------------------------------------------------------------------
  323. //
  324. // CommitDMAPtr
  325. //
  326. // pDMAPtr----DMA buffer address to which the caller has written to.
  327. //
  328. // Readjust write pointer after being reserved by ReserveDMAPtr.
  329. // By committing the pointer a DMA to the committed position could already
  330. // be started by interrupt handler!
  331. //
  332. //----------------------------------------------------------------------------
  333. inline VOID CommitDMAPtr(P2DMA *pP2dma,ULONG *pDMAPtr)
  334. {
  335. pP2dma->ICB.pDMAWritePos=pDMAPtr;
  336. }
  337. //----------------------------------------------------------------------------
  338. //
  339. // GetFreeEntries
  340. //
  341. // Get free entries available for consecutive writing to the DMA buffer.
  342. // The maximum number of returned entries is now MAXBLKSIZE.
  343. //
  344. // returns---number of available entries in ULONGS
  345. //
  346. //----------------------------------------------------------------------------
  347. inline LONG GetFreeEntries(P2DMA *pP2dma)
  348. {
  349. LONG EntriesAvailable = (LONG)(pP2dma->ICB.pDMAWriteEnd - pP2dma->ICB.pDMAWritePos);
  350. return min(MAXBLKSIZE,EntriesAvailable);
  351. }
  352. #endif
  353. #endif