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.

285 lines
8.4 KiB

  1. /*========================================================================== *
  2. *
  3. * Copyright (C) 1994-1998 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: ddagp.c
  6. * Content: Functions for dealing with AGP memory in DirectDraw
  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. #ifndef PAGE_SIZE
  19. #define PAGE_SIZE 4096
  20. #endif
  21. #define PAGE_COUNT(Bytes) (((Bytes) + (PAGE_SIZE - 1)) / PAGE_SIZE)
  22. #define PAGE_ROUND(Bytes) (((Bytes) + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1))
  23. //
  24. // AGP memory policy parameters.
  25. //
  26. // Maximum amount of AGP memory to use. Currently 32MB.
  27. // Recomputed when the DirectDraw interface is created.
  28. DWORD dwAGPPolicyMaxBytes = 32 * 1024 * 1024;
  29. // Amount of memory to commit when a commit is needed.
  30. // Reset when the DirectDraw interface is created.
  31. DWORD dwAGPPolicyCommitDelta = DEFAULT_AGP_COMMIT_DELTA;
  32. #if DBG
  33. // Internal tracking of current AGP memory size.
  34. DWORD dwAGPPolicyCurrentBytes = 0;
  35. #endif
  36. DWORD AGPReserve( HANDLE hdev, DWORD dwSize, BOOL fIsUC, BOOL fIsWC,
  37. FLATPTR *pfpLinStart, LARGE_INTEGER *pliDevStart,
  38. PVOID *ppvReservation )
  39. {
  40. DWORD dwNumPages;
  41. DDASSERT( INVALID_HANDLE_VALUE != hdev );
  42. DDASSERT( 0UL != dwSize );
  43. DDASSERT( NULL != pfpLinStart );
  44. DDASSERT( NULL != pliDevStart );
  45. DDASSERT( NULL != ppvReservation );
  46. /*
  47. * The first thing to do is make sure our AGP policy is respected.
  48. * The easy way to do that is to limit how much we reserve...
  49. */
  50. dwSize = min(dwSize, dwAGPPolicyMaxBytes);
  51. /*
  52. * DDraw will attempt to reserve space for the heap, but if that fails,
  53. * we'll ratchet down the reservation by 4 megs at a time until it works.
  54. * This is a defensive move that should prevent a few problems for AGP
  55. * aware drivers on memphis: they cannot know how large an aperture to
  56. * claim (cuz of weird OS restraints like the fact that
  57. * half the ap is reserved for UC and the other half WC etc, plus
  58. * random BIOS limitations.
  59. * We arbitrarily decide that 4 megs is the legal minimum.
  60. */
  61. while (dwSize >= 0x400000 )
  62. {
  63. dwNumPages = PAGE_COUNT(dwSize);
  64. if ( OsAGPReserve( hdev, dwNumPages, fIsUC, fIsWC,
  65. pfpLinStart, pliDevStart, ppvReservation ) )
  66. {
  67. return dwSize;
  68. }
  69. /*
  70. * If the driver asked for WC but the processor doesn't support WC,
  71. * then OsAGPReserve will have failed. The best thing to do is try
  72. * again with UC...
  73. * If the aperture size is the problem, then this will still fail
  74. * and we'll back off and try again WC.
  75. */
  76. if (fIsWC)
  77. {
  78. if ( OsAGPReserve( hdev, dwNumPages, TRUE, FALSE,
  79. pfpLinStart, pliDevStart, ppvReservation ) )
  80. {
  81. return dwSize;
  82. }
  83. }
  84. /*
  85. * Subtract 4 megs and try again
  86. */
  87. dwSize -= 0x400000;
  88. }
  89. return 0;
  90. } /* AGPReserve */
  91. BOOL AGPCommit( HANDLE hdev, PVOID pvReservation,
  92. DWORD dwOffset, DWORD dwSize )
  93. {
  94. DWORD dwFirstPage;
  95. DWORD dwLastPage;
  96. DDASSERT( INVALID_HANDLE_VALUE != hdev );
  97. DDASSERT( NULL != pvReservation );
  98. DDASSERT( 0UL != dwSize );
  99. #if DBG
  100. if( (dwAGPPolicyCurrentBytes + dwSize ) > dwAGPPolicyMaxBytes )
  101. {
  102. VDPF(( 0, V, "Maximum number of AGP bytes exceeded. Failing commit" ));
  103. return FALSE;
  104. }
  105. #endif
  106. /*
  107. * If the start lies in the middle of a page then we assume that the
  108. * page it lies in has already been committed.
  109. */
  110. dwFirstPage = PAGE_COUNT(dwOffset);
  111. /*
  112. * We assume that if the end lies in the middle of the page then that
  113. * page has not already been committed.
  114. */
  115. dwLastPage = PAGE_COUNT(dwOffset + dwSize);
  116. if( ( dwLastPage == dwFirstPage) ||
  117. OsAGPCommit( hdev, pvReservation,
  118. dwFirstPage, dwLastPage - dwFirstPage ) )
  119. {
  120. #if DBG
  121. dwAGPPolicyCurrentBytes += dwSize;
  122. #endif
  123. return TRUE;
  124. }
  125. else
  126. {
  127. return FALSE;
  128. }
  129. } /* AGPCommit */
  130. BOOL AGPDecommitAll( HANDLE hdev, PVOID pvReservation, DWORD dwSize )
  131. {
  132. DWORD dwNumPages;
  133. DDASSERT( INVALID_HANDLE_VALUE != hdev );
  134. DDASSERT( 0UL != pvReservation );
  135. DDASSERT( 0UL != dwSize );
  136. #if DBG
  137. /*
  138. * Can't do much if this baby fails so just decrement the page
  139. * count.
  140. */
  141. DDASSERT( dwAGPPolicyCurrentBytes >= dwSize );
  142. dwAGPPolicyCurrentBytes -= dwSize;
  143. #endif
  144. return OsAGPDecommitAll( hdev, pvReservation, PAGE_COUNT(dwSize) );
  145. } /* AGPDecommitAll */
  146. BOOL AGPFree( HANDLE hdev, PVOID pvReservation )
  147. {
  148. DDASSERT( INVALID_HANDLE_VALUE != hdev );
  149. DDASSERT( 0UL != pvReservation );
  150. return OsAGPFree( hdev, pvReservation );
  151. } /* AGPFree */
  152. #ifndef __NTDDKCOMP__
  153. #define OSR2_POINT_0_BUILD_NUMBER 1111
  154. #define OSR2_BUILD_NUMBER_A 1212
  155. #define OSR2_BUILD_NUMBER_B 1214
  156. /*
  157. * Does this operating system understand AGP?
  158. *
  159. * NOTE: There may be a better way of determining this but for now I will
  160. * assumed that Memphis and NT 5.0 class operating systems are AGP aware.
  161. *
  162. * NOTE: The VXD handle is (obviously) only important on Win95. On NT
  163. * NULL should be passed.
  164. */
  165. BOOL OSIsAGPAware( HANDLE hvxd )
  166. {
  167. OSVERSIONINFO osvi;
  168. BOOL success;
  169. BOOL fIsVMMAGPAware;
  170. ZeroMemory(&osvi, sizeof(osvi));
  171. osvi.dwOSVersionInfoSize = sizeof(osvi);
  172. success = GetVersionEx(&osvi);
  173. DDASSERT( success );
  174. if( VER_PLATFORM_WIN32_WINDOWS == osvi.dwPlatformId )
  175. {
  176. DPF( 5, "Major version = %d", osvi.dwMajorVersion );
  177. DPF( 5, "Minor version = %d", osvi.dwMinorVersion );
  178. DPF( 5, "Build number = %d", LOWORD(osvi.dwBuildNumber) );
  179. if( ( osvi.dwMajorVersion > 4UL ) ||
  180. ( ( osvi.dwMajorVersion == 4UL ) &&
  181. ( osvi.dwMinorVersion >= 10UL ) &&
  182. ( LOWORD( osvi.dwBuildNumber ) >= 1373 ) ) )
  183. {
  184. /*
  185. * Memphis or greater version of Win95. AGP support assumed.
  186. */
  187. DPF( 2, "AGP aware Windows95 detected. Enabling AGP" );
  188. return TRUE;
  189. }
  190. else if( ( osvi.dwMajorVersion == 4UL ) &&
  191. ( osvi.dwMinorVersion == 0UL ) &&
  192. ( ( LOWORD( osvi.dwBuildNumber ) == OSR2_BUILD_NUMBER_A ) ||
  193. ( LOWORD( osvi.dwBuildNumber ) == OSR2_BUILD_NUMBER_B ) ||
  194. ( LOWORD( osvi.dwBuildNumber ) == OSR2_POINT_0_BUILD_NUMBER ) ) )
  195. {
  196. DPF( 3, "Win95 OSR 2.1 detected. Checking VMM for AGP services" );
  197. fIsVMMAGPAware = FALSE;
  198. #ifdef WIN95
  199. DDASSERT( INVALID_HANDLE_VALUE != hvxd );
  200. fIsVMMAGPAware = vxdIsVMMAGPAware( hvxd );
  201. #else /* WIN95 */
  202. /*
  203. * Should never occur as this would mean we are running an NT
  204. * binary on a 95 system.
  205. */
  206. DDASSERT(FALSE);
  207. #endif /* WIN95 */
  208. if( fIsVMMAGPAware )
  209. {
  210. /*
  211. * AGP services are present in the VMM. Enable AGP.
  212. */
  213. DPF( 2, "OSR 2.1 VMM has AGP services. Enabled AGP" );
  214. return TRUE;
  215. }
  216. else
  217. {
  218. /*
  219. * No AGP services. Disable AGP.
  220. */
  221. DPF( 2, "OSR 2.1 VMM has no AGP services. AGP not available" );
  222. return FALSE;
  223. }
  224. }
  225. else
  226. {
  227. DPF( 2, "Win95 Gold, OSR 1.0 or OSR 2.0 detected. No AGP support available" );
  228. return FALSE;
  229. }
  230. }
  231. else if( VER_PLATFORM_WIN32_NT == osvi.dwPlatformId )
  232. {
  233. /*
  234. * AGP support assumed in NT 5.0 and above.
  235. */
  236. if( osvi.dwMajorVersion >= 5UL )
  237. {
  238. DPF( 2, "AGP aware WindowsNT detected. Enabling AGP" );
  239. return TRUE;
  240. }
  241. }
  242. /*
  243. * If we got to here we failed the AGP aware test.
  244. */
  245. DPF( 1, "Operating system is not AGP aware. Disabling AGP" );
  246. return FALSE;
  247. } /* OSIsAGPAware */
  248. #endif // __NTDDKCOMP__