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.

393 lines
11 KiB

  1. /*========================================================================== *
  2. *
  3. * Copyright (C) 1994-1998 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: ddagp9x.c
  6. * Content: Functions for dealing with AGP memory in DirectDraw on Win9x
  7. *
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 18-jan-97 colinmc initial implementation
  12. * 13-mar-97 colinmc Bug 6533: Pass uncached flag to VMM correctly
  13. * 07-may-97 colinmc Add support for AGP on OSR 2.1
  14. * 12-Feb-98 DrewB Split into common, Win9x and NT sections.
  15. *
  16. ***************************************************************************/
  17. #include "ddrawpr.h"
  18. #ifdef WIN95
  19. /*
  20. * We define the page lock IOCTLs here so that we don't have to include ddvxd.h.
  21. * These must match the corresponding entries in ddvxd.h
  22. */
  23. #define DDVXD_IOCTL_GARTRESERVE 57
  24. #define DDVXD_IOCTL_GARTCOMMIT 58
  25. #define DDVXD_IOCTL_GARTUNCOMMIT 59
  26. #define DDVXD_IOCTL_GARTFREE 60
  27. #define DDVXD_IOCTL_GARTMEMATTRIBUTES 61
  28. #define DDVXD_IOCTL_ISVMMAGPAWARE 68
  29. #define PAGE_SIZE 4096
  30. #define PAGE_COUNT(Bytes) (((Bytes) + (PAGE_SIZE - 1)) / PAGE_SIZE)
  31. #define PAGE_ROUND(Bytes) (((Bytes) + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1))
  32. #undef DPF_MODNAME
  33. #define DPF_MODNAME "OsAGPReserve"
  34. /*
  35. * OsAGPReserve
  36. *
  37. * Reserve a portion of the address space for use as an AGP aperature.
  38. */
  39. BOOL OsAGPReserve( HANDLE hdev, DWORD dwNumPages, BOOL fIsUC, BOOL fIsWC,
  40. FLATPTR *lpfpGARTLin, LARGE_INTEGER *pliGARTDev,
  41. PVOID *ppvReservation )
  42. {
  43. DWORD cbReturned;
  44. BOOL rc;
  45. struct GRInput
  46. {
  47. DWORD dwNumPages; /* Number of bytes of address space to reserve */
  48. DWORD dwAlign; /* Alignment of start of address space */
  49. DWORD fIsUC; /* Address range should be uncachable */
  50. DWORD fIsWC; /* Address range should be write combining */
  51. } grInput;
  52. struct GROutput
  53. {
  54. FLATPTR fpGARTLin; /* Linear address of reserved space */
  55. FLATPTR fpGARTDev; /* High physical address of reserved space */
  56. } grOutput;
  57. DDASSERT( INVALID_HANDLE_VALUE != hdev );
  58. DDASSERT( 0UL != dwNumPages );
  59. DDASSERT( NULL != lpfpGARTLin );
  60. DDASSERT( NULL != pliGARTDev );
  61. *lpfpGARTLin = 0UL;
  62. pliGARTDev->QuadPart = 0UL;
  63. grInput.dwNumPages = dwNumPages;
  64. grInput.dwAlign = 0; /* Hard code alignment of 4K for now */
  65. grInput.fIsUC = fIsUC;
  66. grInput.fIsWC = fIsWC;
  67. DPF( 5, "OsGARTReserve" );
  68. DPF( 5, "Number of pages to reserve = 0x%08x", grInput.dwNumPages );
  69. DPF( 5, "Uncachable = 0x%08x", fIsUC );
  70. DPF( 5, "Write combining = 0x%08x", fIsWC );
  71. rc = DeviceIoControl( hdev,
  72. DDVXD_IOCTL_GARTRESERVE,
  73. &grInput,
  74. sizeof( grInput ),
  75. &grOutput,
  76. sizeof( grOutput ),
  77. &cbReturned,
  78. NULL );
  79. if( rc )
  80. {
  81. DDASSERT( cbReturned == sizeof(grOutput) );
  82. if( 0UL == grOutput.fpGARTLin )
  83. {
  84. DPF(2, "Linear address of GART range is NULL. Call failed, reducing size by 4 Meg" );
  85. rc = FALSE;
  86. }
  87. else
  88. {
  89. *lpfpGARTLin = grOutput.fpGARTLin;
  90. *ppvReservation = (LPVOID)grOutput.fpGARTLin;
  91. pliGARTDev->QuadPart = grOutput.fpGARTDev;
  92. DPF( 5,"returned GARTLin: %08x",*lpfpGARTLin);
  93. DPF( 5,"returned GARTDev: %08x",pliGARTDev->QuadPart);
  94. }
  95. }
  96. else
  97. {
  98. DPF( 0, "Could not reserve 0x%08x pages of GART space", grInput.dwNumPages );
  99. }
  100. return rc;
  101. } /* OsAGPReserve */
  102. #undef DPF_MODNAME
  103. #define DPF_MODNAME "OsAGPCommit"
  104. /*
  105. * OsAGPCommit
  106. *
  107. * Commit memory to the given portion of a previously reserved GART
  108. * range
  109. */
  110. BOOL OsAGPCommit( HANDLE hdev, PVOID pvReservation,
  111. DWORD dwPageOffset, DWORD dwNumPages )
  112. {
  113. DWORD cbReturned;
  114. BOOL rc;
  115. struct GCInput
  116. {
  117. FLATPTR fpGARTLin; /* Start of GART range reserved previously */
  118. DWORD dwPageOffset; /* Offset from start of GART range of first page to be commited */
  119. DWORD dwNumPages; /* Number of pages to be commited */
  120. DWORD dwFlags; /* Flags (zero init) */
  121. } gcInput;
  122. struct GCOutput
  123. {
  124. BOOL fSuccess; /* Result of GARTCommit */
  125. FLATPTR fpGARTDev; /* Device address of memory commited */
  126. } gcOutput;
  127. DDASSERT( INVALID_HANDLE_VALUE != hdev );
  128. gcInput.fpGARTLin = (FLATPTR) pvReservation;
  129. gcInput.dwFlags = 0;
  130. /*
  131. * If the start lies in the middle of a page then we assume that the
  132. * page it lies in has already been commited.
  133. */
  134. gcInput.dwPageOffset = dwPageOffset;
  135. /*
  136. * We assume that if the end lies in the middle of the page then that
  137. * page has not already been commited.
  138. */
  139. gcInput.dwNumPages = dwNumPages;
  140. if( 0UL == gcInput.dwNumPages )
  141. {
  142. DPF( 0, "All necessary GART pages already commited. Done." );
  143. return TRUE;
  144. }
  145. DPF( 5, "OsGARTCommit" );
  146. DPF( 5, "GART linear start address = 0x%08x", pvReservation );
  147. DPF( 5, "Offset from start of reserved address space = 0x%08x", gcInput.dwPageOffset );
  148. DPF( 5, "Number of pages to commit = 0x%08x", gcInput.dwNumPages );
  149. rc = DeviceIoControl( hdev,
  150. DDVXD_IOCTL_GARTCOMMIT,
  151. &gcInput,
  152. sizeof( gcInput ),
  153. &gcOutput,
  154. sizeof( gcOutput ),
  155. &cbReturned,
  156. NULL );
  157. if( rc )
  158. {
  159. DDASSERT( cbReturned == sizeof(gcOutput) );
  160. if( !gcOutput.fSuccess )
  161. {
  162. DPF_ERR( "Attempt to commit GART memory failed. Insufficient memory" );
  163. rc = FALSE;
  164. }
  165. else
  166. {
  167. DDASSERT( 0UL != gcOutput.fpGARTDev );
  168. }
  169. }
  170. else
  171. {
  172. DPF( 0, "Could not commit 0x%08x pages of GART space", gcInput.dwNumPages );
  173. }
  174. return rc;
  175. } /* OsAGPCommit */
  176. #undef DPF_MODNAME
  177. #define DPF_MODNAME "OsAGPDecommitAll"
  178. /*
  179. * OsAGPDecommitAll
  180. *
  181. * Decommit a range of GART space previously commited with GARTCommit
  182. */
  183. BOOL OsAGPDecommitAll( HANDLE hdev, PVOID pvReservation, DWORD dwNumPages )
  184. {
  185. DWORD dwDummy;
  186. DWORD cbReturned;
  187. BOOL rc;
  188. struct GUInput
  189. {
  190. FLATPTR fpGARTLin; /* Start of GART range reserved previously */
  191. DWORD dwPageOffset; /* Offset from start of GART range of first page to decommit */
  192. DWORD dwNumPages; /* Number of pages to decommit */
  193. } guInput;
  194. DDASSERT( INVALID_HANDLE_VALUE != hdev );
  195. DDASSERT( 0UL != pvReservation );
  196. DDASSERT( 0UL != dwNumPages );
  197. guInput.fpGARTLin = (FLATPTR) pvReservation;
  198. guInput.dwPageOffset = 0;
  199. guInput.dwNumPages = dwNumPages;
  200. DPF( 5, "OsGARTUnCommit" );
  201. DPF( 5, "GART linear start address = 0x%08x", pvReservation );
  202. DPF( 5, "Offset from start of reserved address space = 0x%08x", guInput.dwPageOffset );
  203. DPF( 5, "Number of pages to decommit = 0x%08x", guInput.dwNumPages );
  204. rc = DeviceIoControl( hdev,
  205. DDVXD_IOCTL_GARTUNCOMMIT,
  206. &guInput,
  207. sizeof( guInput ),
  208. &dwDummy,
  209. sizeof( dwDummy ),
  210. &cbReturned,
  211. NULL );
  212. #ifdef DEBUG
  213. if( rc )
  214. {
  215. DDASSERT( cbReturned == sizeof(dwDummy) );
  216. }
  217. else
  218. {
  219. DPF( 0, "Could not decommit 0x%08x pages of GART space", guInput.dwNumPages );
  220. }
  221. #endif /* DEBUG */
  222. return rc;
  223. } /* OsAGPDecommitAll */
  224. #undef DPF_MODNAME
  225. #define DPF_MODNAME "OsGARTFree"
  226. /*
  227. * OsAGPFree
  228. *
  229. * Free a GART range previously reserved with GARTReserve
  230. */
  231. BOOL OsAGPFree( HANDLE hdev, PVOID pvReservation )
  232. {
  233. DWORD dwDummy;
  234. DWORD cbReturned;
  235. BOOL rc;
  236. LPVOID fpGARTLin = pvReservation;
  237. DDASSERT( INVALID_HANDLE_VALUE != hdev );
  238. DDASSERT( 0UL != fpGARTLin );
  239. DPF( 5, "OsGARTFree" );
  240. DPF( 5, "GART linear start address = 0x%08x", fpGARTLin );
  241. rc = DeviceIoControl( hdev,
  242. DDVXD_IOCTL_GARTFREE,
  243. &fpGARTLin,
  244. sizeof( fpGARTLin ),
  245. &dwDummy,
  246. sizeof( dwDummy ),
  247. &cbReturned,
  248. NULL );
  249. #ifdef DEBUG
  250. if( rc )
  251. {
  252. DDASSERT( cbReturned == sizeof(dwDummy) );
  253. }
  254. else
  255. {
  256. DPF( 0, "Could not free GART space at 0x%08x", fpGARTLin );
  257. }
  258. #endif /* DEBUG */
  259. return rc;
  260. } /* OsAGPFree */
  261. // Not currently used.
  262. #if 0
  263. #undef DPF_MODNAME
  264. #define DPF_MODNAME "OsGARTMemAttributes"
  265. /*
  266. * OsGARTMemAttributes
  267. *
  268. * Get the memory attributes of a GART memory range previously allocated
  269. * with GARTReserve
  270. */
  271. BOOL OsGARTMemAttributes( HANDLE hdev, FLATPTR fpGARTLin, LPDWORD lpdwAttribs )
  272. {
  273. DWORD cbReturned;
  274. BOOL rc;
  275. DWORD dwAttribs;
  276. DDASSERT( INVALID_HANDLE_VALUE != hdev );
  277. DDASSERT( 0UL != fpGARTLin );
  278. DDASSERT( NULL != lpdwAttribs );
  279. *lpdwAttribs = 0UL;
  280. DPF( 5, "OsGARTMemAttributes" );
  281. DPF( 5, "GART linear start address = 0x%08x", fpGARTLin );
  282. rc = DeviceIoControl( hdev,
  283. DDVXD_IOCTL_GARTMEMATTRIBUTES,
  284. &fpGARTLin,
  285. sizeof( fpGARTLin ),
  286. &dwAttribs,
  287. sizeof( dwAttribs ),
  288. &cbReturned,
  289. NULL );
  290. if( rc )
  291. {
  292. DDASSERT( cbReturned == sizeof(dwAttribs) );
  293. *lpdwAttribs = dwAttribs;
  294. }
  295. else
  296. {
  297. DPF( 0, "Could not get the memory attributes of GART space at 0x%08x", fpGARTLin );
  298. }
  299. return rc;
  300. } /* OsGARTMemAttributes */
  301. #endif // Unused code.
  302. #undef DPF_MODNAME
  303. #define DPF_MODNAME "vxdVMMIsAGPAware"
  304. /*
  305. * vxdIsVMMAGPAware
  306. *
  307. * Does the VMM we are running on export the AGP services?
  308. */
  309. BOOL vxdIsVMMAGPAware( HANDLE hdev )
  310. {
  311. DWORD cbReturned;
  312. BOOL rc;
  313. BOOL fIsAGPAware;
  314. DDASSERT( INVALID_HANDLE_VALUE != hdev );
  315. DPF( 4, "vxdIsVMMAGPAware" );
  316. rc = DeviceIoControl( hdev,
  317. DDVXD_IOCTL_ISVMMAGPAWARE,
  318. NULL,
  319. 0UL,
  320. &fIsAGPAware,
  321. sizeof( fIsAGPAware ),
  322. &cbReturned,
  323. NULL );
  324. if( rc )
  325. {
  326. DDASSERT( cbReturned == sizeof(fIsAGPAware) );
  327. return fIsAGPAware;
  328. }
  329. else
  330. {
  331. DPF_ERR( "Could not determine if OS is AGP aware. Assuming it's not" );
  332. return FALSE;
  333. }
  334. } /* vxdIsVMMAGPAware */
  335. #endif // WIN95