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.

427 lines
12 KiB

  1. /*++
  2. Copyright (c) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. init8x.c
  5. Abstract:
  6. This module contains the initialization code for AMDAGP8X.SYS.
  7. Author:
  8. John Vert (jvert) 10/21/1997
  9. Revision History:
  10. --*/
  11. /*
  12. ******************************************************************************
  13. * Archive File : $Archive: /Drivers/OS/Hammer/AGP/XP/amdagp/Init8x.c $
  14. *
  15. * $History: Init8x.c $
  16. *
  17. *
  18. ******************************************************************************
  19. */
  20. #include "amdagp8x.h"
  21. #define MAX_DEVICES 32
  22. #ifdef DISPLAY
  23. ULONG ErrorControl = 2;
  24. #else
  25. ULONG ErrorControl = 0;
  26. #endif
  27. ULONG VendorID = 0;
  28. ULONG DeviceID = 0;
  29. ULONG AgpLokarSlotID = 0;
  30. ULONG AgpHammerSlotID = 0;
  31. ULONG_PTR OutPostBase;
  32. ULONG AgpExtensionSize = sizeof(AGP_AMD_EXTENSION);
  33. //
  34. // Function Name: DisplayStatus()
  35. //
  36. // Description:
  37. // This routine displays the status value in the Post Display.
  38. //
  39. // Parameter:
  40. // StatusValue - Value to display.
  41. //
  42. // Return: None.
  43. //
  44. void
  45. DisplayStatus( IN UCHAR StatusValue )
  46. {
  47. UCHAR to80;
  48. if (ErrorControl) {
  49. to80 = StatusValue & 0xFF;
  50. WRITE_PORT_UCHAR((PUCHAR)OutPostBase, to80);
  51. }
  52. }
  53. //
  54. // Function Name: FindLokar()
  55. //
  56. // Description:
  57. // This routine locates which device number is assigned to Lokar.
  58. //
  59. // Parameter:
  60. // SlotID - Returned slot ID for Lokar.
  61. //
  62. // Return: None.
  63. //
  64. void
  65. FindLokar( OUT PULONG SlotID )
  66. {
  67. PCI_SLOT_NUMBER SlotNum;
  68. ULONG dev, TargetID;
  69. SlotNum.u.AsULONG = 0;
  70. *SlotID = 0;
  71. for (dev = 0; dev < MAX_DEVICES; dev++)
  72. {
  73. SlotNum.u.bits.DeviceNumber = dev;
  74. ReadAMDConfig(SlotNum.u.AsULONG, &TargetID, 0, sizeof(TargetID));
  75. if (((TargetID & DEVICEID_MASK) >> 16) == DEVICE_LOKAR)
  76. {
  77. *SlotID = SlotNum.u.AsULONG;
  78. AGPLOG(AGP_NOISE, ("FindLokar - SlotID=%x\n", *SlotID));
  79. break;
  80. }
  81. }
  82. }
  83. //
  84. // Function Name: FindHammer()
  85. //
  86. // Description:
  87. // This routine locates which device number is assigned to Hammer.
  88. //
  89. // Parameter:
  90. // SlotID - Returned slot ID for Hammer.
  91. //
  92. // Return: None.
  93. //
  94. void
  95. FindHammer( OUT PULONG SlotID )
  96. {
  97. PCI_SLOT_NUMBER SlotNum;
  98. ULONG dev, TargetID;
  99. SlotNum.u.AsULONG = 0;
  100. SlotNum.u.bits.FunctionNumber = 3;
  101. *SlotID = 0;
  102. for (dev = 0; dev < MAX_DEVICES; dev++)
  103. {
  104. SlotNum.u.bits.DeviceNumber = dev;
  105. ReadAMDConfig(SlotNum.u.AsULONG, &TargetID, 0, sizeof(TargetID));
  106. if (((TargetID & DEVICEID_MASK) >> 16) == DEVICE_HAMMER)
  107. {
  108. *SlotID = SlotNum.u.AsULONG;
  109. AGPLOG(AGP_NOISE, ("FindHammer - SlotID=%x\n", *SlotID));
  110. break;
  111. }
  112. }
  113. }
  114. //
  115. // Function Name: AgpInitializeTarget()
  116. //
  117. // Description:
  118. // Entrypoint for target initialization. This is called first.
  119. //
  120. // Parameters:
  121. // AgpExtension - Supplies the AGP extension.
  122. //
  123. // Return:
  124. // STATUS_SUCCESS on success, otherwise STATUS_UNSUCCESSFUL.
  125. //
  126. NTSTATUS
  127. AgpInitializeTarget( IN PVOID AgpExtension )
  128. {
  129. ULONG TargetId = 0;
  130. UNICODE_STRING tempString;
  131. unsigned short tempBuffer[20];
  132. PAGP_AMD_EXTENSION Extension = AgpExtension;
  133. //
  134. // This driver is not MP safe! If there is more than one processor
  135. // we simply fail start
  136. //
  137. if (KeNumberProcessors > 1) {
  138. return STATUS_NOT_SUPPORTED;
  139. }
  140. //
  141. // Register OutPostCode port, if specified by ErrorControl
  142. //
  143. if (ErrorControl) {
  144. PHYSICAL_ADDRESS PortAddress;
  145. PHYSICAL_ADDRESS MappedAddress;
  146. ULONG MemType = 1;
  147. PortAddress.LowPart = 0x80;
  148. PortAddress.HighPart = 0;
  149. HalTranslateBusAddress(Isa, 0, PortAddress, &MemType, &MappedAddress);
  150. if (MemType == 0)
  151. OutPostBase = (ULONG_PTR)MmMapIoSpace(MappedAddress, 1, FALSE);
  152. else
  153. OutPostBase = (ULONG_PTR)MappedAddress.LowPart;
  154. }
  155. if (ErrorControl == 2)
  156. AgpLogLevel = AGP_NOISE; // Log everything
  157. //
  158. // Make sure we are really loaded only on AMD Hammer / Lokar
  159. //
  160. FindLokar(&AgpLokarSlotID);
  161. FindHammer(&AgpHammerSlotID);
  162. ReadAMDConfig(AgpLokarSlotID, &TargetId, 0, sizeof(TargetId));
  163. VendorID = TargetId & VENDORID_MASK;
  164. DeviceID = (TargetId & DEVICEID_MASK) >> 16;
  165. ASSERT(VendorID == VENDOR_AMD);
  166. if (VendorID != VENDOR_AMD || DeviceID != DEVICE_LOKAR) {
  167. AGPLOG(AGP_CRITICAL,
  168. ("AGPAMD - AgpInitializeTarget called for platform %08lx which is not an AMD!\n",
  169. VendorID));
  170. return(STATUS_UNSUCCESSFUL);
  171. }
  172. //
  173. // Initialize our chipset-specific extension
  174. //
  175. Extension->ApertureStart.QuadPart = 0;
  176. Extension->ApertureLength = 0;
  177. Extension->Gart = NULL;
  178. Extension->GartLength = 0;
  179. Extension->GartPhysical.QuadPart = 0;
  180. Extension->SpecialTarget = 0;
  181. DisplayStatus(0x10);
  182. return(STATUS_SUCCESS);
  183. }
  184. //
  185. // Function Name: AgpInitializeMaster()
  186. //
  187. // Description:
  188. // Entrypoint for master initialization. This is called after target
  189. // initialization and should be used to initialize the AGP
  190. // capabilities of both master and target.
  191. //
  192. // Parameters:
  193. // AgpExtension - Supplies the AGP extension.
  194. // AgpCapabilities - Returns the capabilities of this AGP device.
  195. //
  196. // Return:
  197. // STATUS_SUCCESS on success, otherwise NTSTATUS.
  198. //
  199. NTSTATUS
  200. AgpInitializeMaster( IN PVOID AgpExtension,
  201. OUT ULONG *AgpCapabilities )
  202. {
  203. NTSTATUS Status;
  204. PCI_AGP_CAPABILITY MasterCap;
  205. PCI_AGP_CAPABILITY TargetCap;
  206. PAGP_AMD_EXTENSION Extension = AgpExtension;
  207. ULONG SBAEnable = 0;
  208. ULONG FWEnable = 0;
  209. ULONG FourGBEnable = 0;
  210. ULONG AperturePointer;
  211. ULONG DataRate;
  212. ULONG IrongateRev = 0;
  213. BOOLEAN ReverseInit;
  214. #if DBG
  215. PCI_AGP_CAPABILITY CurrentCap;
  216. #endif
  217. //
  218. // Indicate that we can map memory through the GART aperture
  219. //
  220. *AgpCapabilities = AGP_CAPABILITIES_MAP_PHYSICAL;
  221. //
  222. // Get the master and target AGP capabilities
  223. //
  224. Status = AgpLibGetMasterCapability(AgpExtension, &MasterCap);
  225. if (!NT_SUCCESS(Status)) {
  226. AGPLOG(AGP_CRITICAL,
  227. ("AGPAMDInitializeDevice - AgpLibGetMasterCapability failed %08lx\n",
  228. Status));
  229. DisplayStatus(0xA0);
  230. return(Status);
  231. }
  232. //
  233. // Some broken cards (Matrox Millenium II "AGP") report no valid
  234. // supported transfer rates. These are not really AGP cards. They
  235. // have an AGP Capabilities structure that reports no capabilities.
  236. //
  237. if (MasterCap.AGPStatus.Rate == 0) {
  238. AGPLOG(AGP_CRITICAL,
  239. ("AGPAMDInitializeDevice - AgpLibGetMasterCapability returned no valid transfer rate\n"));
  240. return(STATUS_INVALID_DEVICE_REQUEST);
  241. }
  242. Status = AgpLibGetPciDeviceCapability(AGP_GART_BUS_ID, AgpLokarSlotID, &TargetCap);
  243. if (!NT_SUCCESS(Status)) {
  244. AGPLOG(AGP_CRITICAL,
  245. ("AGPAMDInitializeDevice - AgpLibGetPciDeviceCapability failed %08lx\n",
  246. Status));
  247. DisplayStatus(0xA1);
  248. return(Status);
  249. }
  250. //
  251. // Determine the greatest common denominator for data rate.
  252. //
  253. DataRate = TargetCap.AGPStatus.Rate & MasterCap.AGPStatus.Rate;
  254. AGP_ASSERT(DataRate != 0);
  255. //
  256. // Select the highest common rate.
  257. //
  258. if (DataRate & PCI_AGP_RATE_4X) {
  259. DataRate = PCI_AGP_RATE_4X;
  260. } else if (DataRate & PCI_AGP_RATE_2X) {
  261. DataRate = PCI_AGP_RATE_2X;
  262. } else if (DataRate & PCI_AGP_RATE_1X) {
  263. DataRate = PCI_AGP_RATE_1X;
  264. }
  265. //
  266. // Previously a call was made to change the rate (successfully),
  267. // use this rate again now
  268. //
  269. if (Extension->SpecialTarget & AGP_FLAG_SPECIAL_RESERVE) {
  270. DataRate = (ULONG)((Extension->SpecialTarget &
  271. AGP_FLAG_SPECIAL_RESERVE) >>
  272. AGP_FLAG_SET_RATE_SHIFT);
  273. }
  274. //
  275. // Enable SBA if both master and target support it.
  276. //
  277. SBAEnable = (TargetCap.AGPStatus.SideBandAddressing &
  278. MasterCap.AGPStatus.SideBandAddressing);
  279. //
  280. // Enable FastWrite if both master and target support it.
  281. //
  282. FWEnable = (TargetCap.AGPStatus.FastWrite &
  283. MasterCap.AGPStatus.FastWrite);
  284. //
  285. // Enable 4GB addressing if aperture pointer is 64-bit.
  286. //
  287. ReadAMDConfig(AgpLokarSlotID, &AperturePointer, APBASE_OFFSET, sizeof(AperturePointer));
  288. if (AperturePointer & APBASE_64BIT_MASK)
  289. FourGBEnable = 1;
  290. //
  291. // Enable the Master first.
  292. //
  293. ReverseInit =
  294. (Extension->SpecialTarget & AGP_FLAG_REVERSE_INITIALIZATION) ==
  295. AGP_FLAG_REVERSE_INITIALIZATION;
  296. if (ReverseInit) {
  297. MasterCap.AGPCommand.Rate = DataRate;
  298. MasterCap.AGPCommand.AGPEnable = 1;
  299. MasterCap.AGPCommand.SBAEnable = SBAEnable;
  300. MasterCap.AGPCommand.RequestQueueDepth = TargetCap.AGPStatus.RequestQueueDepthMaximum;
  301. MasterCap.AGPCommand.FastWriteEnable = FWEnable;
  302. MasterCap.AGPCommand.FourGBEnable = FourGBEnable;
  303. Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap);
  304. if (!NT_SUCCESS(Status)) {
  305. AGPLOG(AGP_CRITICAL,
  306. ("AGPAMDInitializeDevice - AgpLibSetMasterCapability %08lx failed %08lx\n",
  307. &MasterCap,
  308. Status));
  309. DisplayStatus(0xA3);
  310. }else {
  311. AGPLOG(AGP_NOISE,
  312. ("AgpInitializeMaster - DataRate=%d, SBAEnable=%d\n",
  313. DataRate,
  314. SBAEnable));
  315. }
  316. }
  317. //
  318. // Now enable the Target.
  319. //
  320. TargetCap.AGPCommand.Rate = DataRate;
  321. TargetCap.AGPCommand.AGPEnable = 1;
  322. TargetCap.AGPCommand.SBAEnable = SBAEnable;
  323. TargetCap.AGPCommand.FastWriteEnable = FWEnable;
  324. TargetCap.AGPCommand.FourGBEnable = FourGBEnable;
  325. Status = AgpLibSetPciDeviceCapability(AGP_GART_BUS_ID, AgpLokarSlotID, &TargetCap);
  326. if (!NT_SUCCESS(Status)) {
  327. AGPLOG(AGP_CRITICAL,
  328. ("AGPAMDInitializeDevice - AgpLibSetPciDeviceCapability %08lx for target failed %08lx\n",
  329. &TargetCap,
  330. Status));
  331. DisplayStatus(0xA2);
  332. return(Status);
  333. }
  334. if (!ReverseInit) {
  335. MasterCap.AGPCommand.Rate = DataRate;
  336. MasterCap.AGPCommand.AGPEnable = 1;
  337. MasterCap.AGPCommand.SBAEnable = SBAEnable;
  338. MasterCap.AGPCommand.RequestQueueDepth = TargetCap.AGPStatus.RequestQueueDepthMaximum;
  339. MasterCap.AGPCommand.FastWriteEnable = FWEnable;
  340. MasterCap.AGPCommand.FourGBEnable = FourGBEnable;
  341. Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap);
  342. if (!NT_SUCCESS(Status)) {
  343. AGPLOG(AGP_CRITICAL,
  344. ("AGPAMDInitializeDevice - AgpLibSetMasterCapability %08lx failed %08lx\n",
  345. &MasterCap,
  346. Status));
  347. DisplayStatus(0xA3);
  348. }else {
  349. AGPLOG(AGP_NOISE,
  350. ("AgpInitializeMaster - DataRate=%d, SBAEnable=%d\n",
  351. DataRate,
  352. SBAEnable));
  353. }
  354. }
  355. #ifdef DEBUG2
  356. //
  357. // Read them back, see if it worked
  358. //
  359. Status = AgpLibGetMasterCapability(AgpExtension, &CurrentCap);
  360. AGP_ASSERT(NT_SUCCESS(Status));
  361. AGP_ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand, &MasterCap.AGPCommand, sizeof(CurrentCap.AGPCommand)));
  362. Status = AgpLibGetPciDeviceCapability(AGP_GART_BUS_ID, AgpLokarSlotID, &CurrentCap);
  363. AGP_ASSERT(NT_SUCCESS(Status));
  364. AGP_ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand, &TargetCap.AGPCommand, sizeof(CurrentCap.AGPCommand)));
  365. #endif
  366. DisplayStatus(0x20);
  367. return(Status);
  368. }