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.

357 lines
10 KiB

  1. /*++
  2. Copyright (2) 2002 Microsoft Corporation
  3. Module Name:
  4. init.c
  5. Abstract:
  6. This module contains the initialization support routines for the
  7. MS AGP v3 Filter Driver
  8. Author:
  9. Eric F. Nelson (enelson) June 6, 2002
  10. Revision History:
  11. --*/
  12. #include "agp.h"
  13. #include "uagp35.h"
  14. ULONG AgpExtensionSize = sizeof(UAGP35_EXTENSION);
  15. PAGP_FLUSH_PAGES AgpFlushPages = NULL; // Not implemented (yet)
  16. NTSTATUS
  17. AgpInitializeTarget(
  18. IN PVOID AgpExtension
  19. )
  20. /*++
  21. Routine Description:
  22. Entrypoint for target initialization, this is called first
  23. Arguments:
  24. AgpExtension - Supplies our AGP3 extension
  25. Return Value:
  26. STATUS_SUCCESS
  27. --*/
  28. {
  29. ULONG DeviceId;
  30. NTSTATUS Status;
  31. PCI_AGP_CAPABILITY TargetCap;
  32. PUAGP35_EXTENSION Extension = AgpExtension;
  33. //
  34. // Zero/init our AGP3 extension
  35. //
  36. RtlZeroMemory(AgpExtension, sizeof(UAGP35_EXTENSION));
  37. //
  38. // Figure out what type of AGP3 capability our target is
  39. //
  40. Status = AgpLibGetTargetCapability(AgpExtension, &TargetCap);
  41. if (!NT_SUCCESS(Status)) {
  42. AGPLOG(AGP_CRITICAL,
  43. ("UAGP35TargetInit: AgpLibGetTargetCapability "
  44. "failed %08lx\n"));
  45. return Status;
  46. }
  47. Extension->CapabilityId = TargetCap.Header.CapabilityID;
  48. //
  49. // Make sure the capability is v3!!!
  50. //
  51. if ((TargetCap.Major < 3) ||
  52. ((TargetCap.Major == 3) && (TargetCap.Minor < 5))) {
  53. AGPLOG(AGP_CRITICAL,
  54. ("UAGP35TargetInit: Capability version (%d) != 3\n",
  55. TargetCap.Major));
  56. return STATUS_NOT_SUPPORTED;
  57. }
  58. //
  59. // Save the vendor and device IDs in case we need to "tweak"
  60. // something for a particular platform
  61. //
  62. AgpLibReadAgpTargetConfig(AgpExtension, &DeviceId, 0, sizeof(DeviceId));
  63. Extension->DeviceId = DeviceId;
  64. return STATUS_SUCCESS;
  65. }
  66. NTSTATUS
  67. AgpInitializeMaster(
  68. IN PVOID AgpExtension,
  69. OUT ULONG *AgpCapabilities
  70. )
  71. /*++
  72. Routine Description:
  73. Entrypoint for master initialization, this is called after target
  74. initialization and should be used to initialize the AGP capabilities
  75. of both master and target
  76. This is also called when the master transitions into the D0 state
  77. Arguments:
  78. AgpExtension - Supplies our AGP3 extension
  79. AgpCapabilities - Returns the capabilities of this AGP device
  80. Return Value:
  81. STATUS_SUCCESS, or an appropriate error status
  82. --*/
  83. {
  84. NTSTATUS Status;
  85. PCI_AGP_CAPABILITY MasterCap;
  86. PCI_AGP_CAPABILITY TargetCap;
  87. ULONG ApertureBase;
  88. PUAGP35_EXTENSION Extension = AgpExtension;
  89. ULONG SBAEnable;
  90. ULONG DataRate;
  91. ULONG FourGBEnable = OFF;
  92. ULONG FastWrite;
  93. BOOLEAN ReverseInit;
  94. #if DBG
  95. PCI_AGP_CAPABILITY CurrentCap;
  96. #endif
  97. //
  98. // Get the master and target AGP capabilities
  99. //
  100. Status = AgpLibGetMasterCapability(AgpExtension, &MasterCap);
  101. if (!NT_SUCCESS(Status)) {
  102. AGPLOG(AGP_CRITICAL,
  103. ("UAGP35MasterInit: AgpLibGetMasterCapability failed %08lx\n"));
  104. return Status;
  105. }
  106. //
  107. // Some broken cards (Matrox Millenium II "AGP") report no valid
  108. // supported transfer rates. These are not really AGP cards. They
  109. // have an AGP Capabilities structure that reports no capabilities.
  110. //
  111. if (MasterCap.AGPStatus.Rate == 0) {
  112. AGPLOG(AGP_CRITICAL,
  113. ("UAGP35MasterInit: AgpLibGetMasterCapability returned "
  114. "no valid transfer rate\n"));
  115. return STATUS_INVALID_DEVICE_REQUEST;
  116. }
  117. Status = AgpLibGetTargetCapability(AgpExtension, &TargetCap);
  118. if (!NT_SUCCESS(Status)) {
  119. AGPLOG(AGP_CRITICAL,
  120. ("UAGP35MasterInit: AgpLibGetTargetCapability "
  121. "failed %08lx\n"));
  122. return Status;
  123. }
  124. //
  125. // Determine the greatest common denominator for data rate.
  126. //
  127. DataRate = TargetCap.AGPStatus.Rate & MasterCap.AGPStatus.Rate;
  128. AGP_ASSERT(DataRate != 0);
  129. //
  130. // Select the highest common rate
  131. //
  132. if (DataRate & PCI_AGP_RATE_4X) {
  133. DataRate = PCI_AGP_RATE_4X;
  134. } else if (DataRate & PCI_AGP_RATE_2X) {
  135. DataRate = PCI_AGP_RATE_2X;
  136. } else if (DataRate & PCI_AGP_RATE_1X) {
  137. DataRate = PCI_AGP_RATE_1X;
  138. }
  139. //
  140. // Previously a call was made to change the rate (successfully),
  141. // use this rate again now
  142. //
  143. if (Extension->SpecialTarget & AGP_FLAG_SPECIAL_RESERVE) {
  144. DataRate = (ULONG)((Extension->SpecialTarget &
  145. AGP_FLAG_SPECIAL_RESERVE) >>
  146. AGP_FLAG_SET_RATE_SHIFT);
  147. //
  148. // If we're in AGP3 mode, and our rate was successfully
  149. // programmed, then we must convert into AGP2 rate bits
  150. //
  151. if (TargetCap.AGPStatus.Agp3Mode == ON) {
  152. ASSERT(MasterCap.AGPStatus.Agp3Mode == ON);
  153. ASSERT((DataRate == 8) || (DataRate == PCI_AGP_RATE_4X));
  154. DataRate >>= 2;
  155. }
  156. }
  157. //
  158. // Enable SBA if both master and target support it
  159. //
  160. SBAEnable = TargetCap.AGPStatus.SideBandAddressing &
  161. MasterCap.AGPStatus.SideBandAddressing;
  162. //
  163. // Enable FastWrite if both master and target support it
  164. //
  165. FastWrite = TargetCap.AGPStatus.FastWrite &
  166. MasterCap.AGPStatus.FastWrite;
  167. //
  168. // Enable 4GB addressing if aperture is 64-bit
  169. //
  170. AgpLibReadAgpTargetConfig(AgpExtension,
  171. &ApertureBase,
  172. APERTURE_BASE,
  173. sizeof(ApertureBase));
  174. if (ApertureBase & APERTURE_BASE64_MASK) {
  175. FourGBEnable = ON;
  176. Extension->FourGBEnable = TRUE;
  177. }
  178. //
  179. // Indicate whether we can map memory through the GART aperture
  180. //
  181. *AgpCapabilities = (TargetCap.AGPStatus.HostTransDisable) ? 0:
  182. AGP_CAPABILITIES_MAP_PHYSICAL;
  183. MasterCap.AGPCommand.Rate = DataRate;
  184. TargetCap.AGPCommand.Rate = DataRate;
  185. MasterCap.AGPCommand.AGPEnable = ON;
  186. TargetCap.AGPCommand.AGPEnable = ON;
  187. MasterCap.AGPCommand.SBAEnable = SBAEnable;
  188. TargetCap.AGPCommand.SBAEnable = SBAEnable;
  189. MasterCap.AGPCommand.FastWriteEnable = FastWrite;
  190. TargetCap.AGPCommand.FastWriteEnable = FastWrite;
  191. MasterCap.AGPCommand.FourGBEnable = FourGBEnable;
  192. TargetCap.AGPCommand.FourGBEnable = FourGBEnable;
  193. MasterCap.AGPCommand.RequestQueueDepth =
  194. TargetCap.AGPStatus.RequestQueueDepthMaximum;
  195. MasterCap.AGPCommand.AsyncReqSize =
  196. TargetCap.AGPStatus.AsyncRequestSize;
  197. //
  198. // Patch rate for early rev VIA 8X silicon errata
  199. //
  200. if ((Extension->SpecialTarget & AGP_FLAG_SPECIAL_VIA_AGP2_RATE_PATCH) &&
  201. (TargetCap.AGPStatus.Agp3Mode == OFF)) {
  202. switch (DataRate) {
  203. case PCI_AGP_RATE_1X:
  204. case PCI_AGP_RATE_2X:
  205. MasterCap.AGPCommand.Rate = PCI_AGP_RATE_1X;
  206. TargetCap.AGPCommand.Rate = PCI_AGP_RATE_4X;
  207. break;
  208. case PCI_AGP_RATE_4X:
  209. MasterCap.AGPCommand.Rate = PCI_AGP_RATE_4X;
  210. TargetCap.AGPCommand.Rate = PCI_AGP_RATE_1X;
  211. }
  212. AGPLOG(AGP_WARNING,
  213. ("UAGP35MasterInit: AGP_FLAG_SPECIAL_VIA_AGP2_RATE_PATCH\n"));
  214. }
  215. //
  216. // Enable the Master first if the reverse init bit is set
  217. //
  218. ReverseInit =
  219. (Extension->SpecialTarget & AGP_FLAG_REVERSE_INITIALIZATION) ==
  220. AGP_FLAG_REVERSE_INITIALIZATION;
  221. if (ReverseInit) {
  222. Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap);
  223. if (!NT_SUCCESS(Status)) {
  224. AGPLOG(AGP_CRITICAL,
  225. ("UAGP35MasterInit: AgpLibSetMasterCapability %08lx "
  226. "failed %08lx\n",
  227. &MasterCap,
  228. Status));
  229. return Status;
  230. }
  231. }
  232. //
  233. // Otherwise enable the Target first
  234. //
  235. Status = AgpLibSetTargetCapability(AgpExtension, &TargetCap);
  236. if (!NT_SUCCESS(Status)) {
  237. AGPLOG(AGP_CRITICAL,
  238. ("UAGP35MasterInit: AgpLibSetTargetCapability %08lx "
  239. "for target failed %08lx\n",
  240. &TargetCap,
  241. Status));
  242. return Status;
  243. }
  244. if (!ReverseInit) {
  245. Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap);
  246. if (!NT_SUCCESS(Status)) {
  247. AGPLOG(AGP_CRITICAL,
  248. ("UAGP35MasterInit: AgpLibSetMasterCapability %08lx "
  249. "failed %08lx\n",
  250. &MasterCap,
  251. Status));
  252. }
  253. }
  254. #if DBG
  255. //
  256. // Read them back, see if it worked
  257. //
  258. Status = AgpLibGetMasterCapability(AgpExtension, &CurrentCap);
  259. AGP_ASSERT(NT_SUCCESS(Status));
  260. //
  261. // If the target request queue depth is greater than the master will
  262. // allow, it will be trimmed, so loosen the assert to not require an
  263. // exact match
  264. //
  265. // We'll do the same for asynchronous request queue depth too
  266. //
  267. AGP_ASSERT(CurrentCap.AGPCommand.RequestQueueDepth <=
  268. MasterCap.AGPCommand.RequestQueueDepth);
  269. AGP_ASSERT(CurrentCap.AGPCommand.AsyncReqSize <=
  270. MasterCap.AGPCommand.AsyncReqSize);
  271. CurrentCap.AGPCommand.RequestQueueDepth =
  272. MasterCap.AGPCommand.RequestQueueDepth;
  273. CurrentCap.AGPCommand.AsyncReqSize = MasterCap.AGPCommand.AsyncReqSize;
  274. AGP_ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand,
  275. &MasterCap.AGPCommand,
  276. sizeof(CurrentCap.AGPCommand)));
  277. AGPLOG(AGP_NOISE,
  278. ("UAGP35MasterInit: WroteMasterCmd=%08x, ReadMasterCmd=%08lx\n",
  279. MasterCap.AGPCommand,
  280. CurrentCap.AGPCommand));
  281. Status = AgpLibGetTargetCapability(AgpExtension, &CurrentCap);
  282. AGP_ASSERT(NT_SUCCESS(Status));
  283. AGP_ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand,
  284. &TargetCap.AGPCommand,
  285. sizeof(CurrentCap.AGPCommand)));
  286. AGPLOG(AGP_NOISE,
  287. ("UAGP35MasterInit: WroteTargetCmd=%08x, ReadTargetCmd=%08lx\n",
  288. TargetCap.AGPCommand,
  289. CurrentCap.AGPCommand));
  290. #endif
  291. return Status;
  292. }