Source code of Windows XP (NT5)
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.

379 lines
11 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. init.c
  5. Abstract:
  6. This module contains the initialization code for AGP460.SYS.
  7. Author:
  8. Naga Gurumoorthy 6/11/1999
  9. Revision History:
  10. --*/
  11. #include "agp460.h"
  12. ULONG AgpExtensionSize = sizeof(AGP460_EXTENSION);
  13. PAGP_FLUSH_PAGES AgpFlushPages;
  14. NTSTATUS
  15. AgpInitializeTarget(
  16. IN PVOID AgpExtension
  17. )
  18. /*++
  19. Routine Description:
  20. Entrypoint for target initialization. This is called first.
  21. Arguments:
  22. AgpExtension - Supplies the AGP extension
  23. Return Value:
  24. NTSTATUS
  25. --*/
  26. {
  27. ULONG DeviceVendorID = 0;
  28. PAGP460_EXTENSION Extension = AgpExtension;
  29. AGPLOG(AGP_NOISE, ("AGP460: AgpInitializeTarget entered.\n"));
  30. //
  31. // Initialize our Extension
  32. //
  33. RtlZeroMemory(Extension, sizeof(AGP460_EXTENSION));
  34. //
  35. // TO DO: Check the Device & Vendor ID for 82460GX. - Naga G
  36. //
  37. //
  38. // Initialize our chipset-specific extension
  39. //
  40. Extension->ApertureStart.QuadPart = 0;
  41. Extension->ApertureLength = 0;
  42. Extension->Gart = NULL;
  43. Extension->GartLength = 0;
  44. Extension->GlobalEnable = FALSE;
  45. Extension->ChipsetPageSize = PAGESIZE_460GX_CHIPSET;
  46. Extension->GartPhysical.QuadPart = 0;
  47. Extension->bSupportMultipleAGPDevices = FALSE;
  48. Extension->bSupportsCacheCoherency = TRUE;
  49. Extension->SpecialTarget = 0;
  50. AgpFlushPages = Agp460FlushPages;
  51. AGPLOG(AGP_NOISE, ("AGP460: Leaving AgpInitializeTarget.\n"));
  52. return(STATUS_SUCCESS);
  53. }
  54. NTSTATUS
  55. AgpInitializeMaster(
  56. IN PVOID AgpExtension,
  57. OUT ULONG *AgpCapabilities
  58. )
  59. /*++
  60. Routine Description:
  61. Entrypoint for master initialization. This is called after target initialization
  62. and should be used to initialize the AGP capabilities of both master and target.
  63. This is also called when the master transitions into the D0 state.
  64. Arguments:
  65. AgpExtension - Supplies the AGP extension
  66. AgpCapabilities - Returns the capabilities of this AGP device.
  67. Return Value:
  68. STATUS_SUCCESS
  69. --*/
  70. {
  71. NTSTATUS Status;
  72. PCI_AGP_CAPABILITY MasterCap;
  73. PCI_AGP_CAPABILITY TargetCap;
  74. PAGP460_EXTENSION Extension = AgpExtension;
  75. ULONG SBAEnable;
  76. ULONG DataRate;
  77. ULONG FastWrite;
  78. ULONG CBN;
  79. BOOLEAN ReverseInit;
  80. #if DBG
  81. PCI_AGP_CAPABILITY CurrentCap;
  82. #endif
  83. AGPLOG(AGP_NOISE, ("AGP460: AgpInitializeMaster entered.\n"));
  84. //
  85. // VERY IMPORTANT: In 82460GX, the GART is not part of the main memory (though it
  86. // occupies a range in the address space) and is instead hanging off the GXB. This
  87. // will make accesses from the Graphics Card to the GART pretty fast. But, the price
  88. // we pay - processor can't access the GART. Therefore, we tell the rest of the
  89. // world that is NOT OK to map the physical addresses given by GART. Instead processor
  90. // accesses should use the MDL. This is done by setting the capabilities to 0.
  91. // - Naga G
  92. //
  93. *AgpCapabilities = 0;
  94. //
  95. // Get the master and target AGP capabilities
  96. //
  97. Status = AgpLibGetMasterCapability(AgpExtension, &MasterCap);
  98. if (!NT_SUCCESS(Status)) {
  99. AGPLOG(AGP_CRITICAL,
  100. ("AGP460InitializeDevice - AgpLibGetMasterCapability failed %08lx\n"));
  101. return(Status);
  102. }
  103. //
  104. // Some broken cards (Matrox Millenium II "AGP") report no valid
  105. // supported transfer rates. These are not really AGP cards. They
  106. // have an AGP Capabilities structure that reports no capabilities.
  107. //
  108. if (MasterCap.AGPStatus.Rate == 0) {
  109. AGPLOG(AGP_CRITICAL,
  110. ("AGP460InitializeDevice - AgpLibGetMasterCapability returned no valid transfer rate\n"));
  111. return(STATUS_INVALID_DEVICE_REQUEST);
  112. }
  113. // We can't get the capability for bus 0, dev 0 in 460GX. it is the SAC & we want the
  114. // GXB (Target).
  115. //Status = AgpLibGetPciDeviceCapability(0,0,&TargetCap);
  116. Read460CBN((PVOID)&CBN);
  117. // CBN is of one byte width, so zero out the other bits from 32-bits - Sunil
  118. EXTRACT_LSBYTE(CBN);
  119. Status = AgpLibGetPciDeviceCapability(CBN,AGP460_GXB_SLOT_ID,&TargetCap);
  120. if (!NT_SUCCESS(Status)) {
  121. AGPLOG(AGP_CRITICAL,
  122. ("AGP460InitializeDevice - AgpLibGetPciDeviceCapability failed %08lx\n"));
  123. return(Status);
  124. }
  125. //
  126. // Determine the greatest common denominator for data rate.
  127. //
  128. DataRate = TargetCap.AGPStatus.Rate & MasterCap.AGPStatus.Rate;
  129. ASSERT(DataRate != 0);
  130. //
  131. // Select the highest common rate.
  132. //
  133. if (DataRate & PCI_AGP_RATE_4X) {
  134. DataRate = PCI_AGP_RATE_4X;
  135. } else if (DataRate & PCI_AGP_RATE_2X) {
  136. DataRate = PCI_AGP_RATE_2X;
  137. } else if (DataRate & PCI_AGP_RATE_1X) {
  138. DataRate = PCI_AGP_RATE_1X;
  139. }
  140. //
  141. // Previously a call was made to change the rate (successfully),
  142. // use this rate again now
  143. //
  144. if (Extension->SpecialTarget & AGP_FLAG_SPECIAL_RESERVE) {
  145. DataRate = (ULONG)((Extension->SpecialTarget &
  146. AGP_FLAG_SPECIAL_RESERVE) >>
  147. AGP_FLAG_SET_RATE_SHIFT);
  148. }
  149. //
  150. // Enable SBA if both master and target support it.
  151. //
  152. SBAEnable = (TargetCap.AGPStatus.SideBandAddressing & MasterCap.AGPStatus.SideBandAddressing);
  153. //
  154. // Enable FastWrite if both master and target support it.
  155. //
  156. FastWrite = (TargetCap.AGPStatus.FastWrite & MasterCap.AGPStatus.FastWrite);
  157. //
  158. // Enable the Master first.
  159. //
  160. ReverseInit =
  161. (Extension->SpecialTarget & AGP_FLAG_REVERSE_INITIALIZATION) ==
  162. AGP_FLAG_REVERSE_INITIALIZATION;
  163. if (ReverseInit) {
  164. MasterCap.AGPCommand.Rate = DataRate;
  165. MasterCap.AGPCommand.AGPEnable = TRUE;
  166. MasterCap.AGPCommand.SBAEnable = SBAEnable;
  167. MasterCap.AGPCommand.FastWriteEnable = FastWrite;
  168. MasterCap.AGPCommand.FourGBEnable = FALSE;
  169. MasterCap.AGPCommand.RequestQueueDepth = TargetCap.AGPStatus.RequestQueueDepthMaximum;
  170. Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap);
  171. if (!NT_SUCCESS(Status)) {
  172. AGPLOG(AGP_CRITICAL,
  173. ("AGP460InitializeDevice - AgpLibSetMasterCapability %08lx failed %08lx\n",
  174. &MasterCap,
  175. Status));
  176. }
  177. }
  178. //
  179. // Now enable the Target.
  180. //
  181. TargetCap.AGPCommand.Rate = DataRate;
  182. TargetCap.AGPCommand.AGPEnable = TRUE;
  183. TargetCap.AGPCommand.SBAEnable = SBAEnable;
  184. TargetCap.AGPCommand.FastWriteEnable = FastWrite;
  185. TargetCap.AGPCommand.FourGBEnable = FALSE;
  186. Status = AgpLibSetPciDeviceCapability(CBN, AGP460_GXB_SLOT_ID, &TargetCap);
  187. if (!NT_SUCCESS(Status)) {
  188. AGPLOG(AGP_CRITICAL,
  189. ("AGP460InitializeDevice - AgpLibSetPciDeviceCapability %08lx for target failed %08lx\n",
  190. &TargetCap,
  191. Status));
  192. return(Status);
  193. }
  194. if (!ReverseInit) {
  195. MasterCap.AGPCommand.Rate = DataRate;
  196. MasterCap.AGPCommand.AGPEnable = TRUE;
  197. MasterCap.AGPCommand.SBAEnable = SBAEnable;
  198. MasterCap.AGPCommand.FastWriteEnable = FastWrite;
  199. MasterCap.AGPCommand.FourGBEnable = FALSE;
  200. MasterCap.AGPCommand.RequestQueueDepth = TargetCap.AGPStatus.RequestQueueDepthMaximum;
  201. Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap);
  202. if (!NT_SUCCESS(Status)) {
  203. AGPLOG(AGP_CRITICAL,
  204. ("AGP460InitializeDevice - AgpLibSetMasterCapability %08lx failed %08lx\n",
  205. &MasterCap,
  206. Status));
  207. }
  208. }
  209. #if DBG
  210. //
  211. // Read them back, see if it worked
  212. //
  213. Status = AgpLibGetMasterCapability(AgpExtension, &CurrentCap);
  214. ASSERT(NT_SUCCESS(Status));
  215. //
  216. // If the target request queue depth is greater than the master will
  217. // allow, it will be trimmed. Loosen the assert to not require an
  218. // exact match.
  219. //
  220. ASSERT(CurrentCap.AGPCommand.RequestQueueDepth <= MasterCap.AGPCommand.RequestQueueDepth);
  221. CurrentCap.AGPCommand.RequestQueueDepth = MasterCap.AGPCommand.RequestQueueDepth;
  222. ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand, &MasterCap.AGPCommand, sizeof(CurrentCap.AGPCommand)));
  223. // Status = AgpLibGetPciDeviceCapability(0,0,&CurrentCap);
  224. Status = AgpLibGetPciDeviceCapability(CBN,AGP460_GXB_SLOT_ID,&CurrentCap);
  225. ASSERT(NT_SUCCESS(Status));
  226. ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand, &TargetCap.AGPCommand, sizeof(CurrentCap.AGPCommand)));
  227. #endif
  228. AGPLOG(AGP_NOISE, ("AGP460: Leaving AgpInitializeMaster.\n"));
  229. return(Status);
  230. }
  231. NTSTATUS
  232. Agp460FlushPages(
  233. IN PAGP460_EXTENSION AgpContext,
  234. IN PMDL Mdl
  235. )
  236. /*++
  237. Routine Description:
  238. Flush entries in the GART. Currently a stub for
  239. Win64 version of 460GX filter driver. This flushing is done previously to
  240. avoid any caching issues due to the same memory aliased with different caching
  241. attributes. Now that is taken care by the memory manager calls themselves (Win64 only).
  242. Therefore we just have a stub so that nothing gets executed in the AGPLIB code. (see
  243. AGPLIB code for details)
  244. Arguments:
  245. AgpContext - Supplies the AGP context
  246. Mdl - Supplies the MDL describing the physical pages to be flushed
  247. Return Value:
  248. STATUS_SUCCESS
  249. --*/
  250. {
  251. AGPLOG(AGP_NOISE, ("AGP460: Entering AGPFlushPages.\n"));
  252. AGPLOG(AGP_NOISE, ("AGP460: Leaving AGPFlushPages.\n"));
  253. return STATUS_SUCCESS;
  254. }
  255. void Read460CBN(PVOID _CBN_)
  256. {
  257. ULONG _len_;
  258. _len_ = HalGetBusDataByOffset(PCIConfiguration,
  259. AGP460_SAC_BUS_ID,
  260. AGP460_SAC_CBN_SLOT_ID,
  261. _CBN_,
  262. 0x40,
  263. 1);
  264. ASSERT(_len_ == 1);
  265. return;
  266. }
  267. void Read460Config(ULONG _CBN_,PVOID _buf_,ULONG _offset_,ULONG _size_)
  268. {
  269. ULONG _len_;
  270. _len_ = HalGetBusDataByOffset(PCIConfiguration,
  271. _CBN_,
  272. AGP460_GXB_SLOT_ID,
  273. _buf_,
  274. _offset_,
  275. _size_);
  276. ASSERT(_len_ == (_size_));
  277. return;
  278. }
  279. void Write460Config(ULONG _CBN_,PVOID _buf_,ULONG _offset_,ULONG _size_)
  280. {
  281. ULONG _len_;
  282. _len_ = HalSetBusDataByOffset(PCIConfiguration,
  283. (_CBN_),
  284. AGP460_GXB_SLOT_ID,
  285. (_buf_),
  286. (_offset_),
  287. (_size_));
  288. ASSERT(_len_ == (_size_));
  289. return;
  290. }