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.

431 lines
14 KiB

  1. /*++
  2. Copyright (c) 1996, 1997 Microsoft Corporation
  3. Module Name:
  4. init.c
  5. Abstract:
  6. This module contains the initialization code for the Compaq driver.
  7. Author:
  8. John Vert (jvert) 10/21/1997
  9. Revision History:
  10. 12/15/97 John Theisen Modified to support Compaq Chipsets
  11. 10/09/98 John Theisen Modified to workaround an RCC silicon bug.
  12. If RCC Silicon Rev <= 4, then limit DATA_RATE to 1X.
  13. 10/09/98 John Theisen Modified to enable Shadowing in the SP700 prior to MMIO writes.
  14. 01/15/98 John Theisen Modified to set RQ depth to be 0x0F for all REV_IDs
  15. 03/14/00 Peter Johnston Add support for HE chipset.
  16. --*/
  17. #include "AGPCPQ.H"
  18. ULONG AgpExtensionSize = sizeof(AGPCPQ_EXTENSION);
  19. PAGP_FLUSH_PAGES AgpFlushPages = NULL; // not implemented
  20. NTSTATUS
  21. AgpInitializeTarget(
  22. IN PVOID AgpExtension
  23. )
  24. /*******************************************************************************
  25. *
  26. * Routine Functional Description:
  27. *
  28. * This function is the entrypoint for initialization of the AGP Target. It
  29. * is called first, and performs initialization of the chipset and extension.
  30. *
  31. * Assumptions: Regardless of whether we are running on a dual north bridge platform,
  32. * this driver will only be installed and invoked once (for the AGP bridge at B0D0F1).
  33. *
  34. * Arguments:
  35. *
  36. * AgpExtension -- Supplies the AGP Extension
  37. *
  38. * Return Value:
  39. *
  40. * STATUS_SUCCESS if successfull
  41. *
  42. *******************************************************************************/
  43. {
  44. ULONG DeviceVendorID = 0;
  45. ULONG BAR1 = 0;
  46. PAGPCPQ_EXTENSION Extension = AgpExtension;
  47. PHYSICAL_ADDRESS pa;
  48. ULONG BytesReturned = 0;
  49. AGPLOG(AGP_NOISE, ("AgpCpq: AgpInitializeTarget entered.\n"));
  50. //
  51. // Initialize our Extension
  52. //
  53. RtlZeroMemory(Extension, sizeof(AGPCPQ_EXTENSION));
  54. //
  55. // Verify that the chipset is a supported RCC Chipset.
  56. //
  57. ReadCPQConfig(&DeviceVendorID,OFFSET_DEVICE_VENDOR_ID,sizeof(DeviceVendorID));
  58. if ((DeviceVendorID != AGP_CNB20_LE_IDENTIFIER) &&
  59. (DeviceVendorID != AGP_CNB20_HE_IDENTIFIER) &&
  60. (DeviceVendorID != AGP_CNB20_HE4X_IDENTIFIER) &&
  61. (DeviceVendorID != AGP_CMIC_GC_IDENTIFIER)) {
  62. AGPLOG(AGP_CRITICAL,
  63. ("AGPCPQ - AgpInitializeTarget was called for platform %08x, which is not a known RCC AGP chipset!\n",
  64. DeviceVendorID));
  65. return(STATUS_UNSUCCESSFUL);
  66. }
  67. Extension->DeviceVendorID = DeviceVendorID;
  68. //
  69. // Read the chipset's BAR1 Register, and then map the chipset's
  70. // Memory Mapped Control Registers into kernel mode address space.
  71. //
  72. ReadCPQConfig(&BAR1,OFFSET_BAR1,sizeof(BAR1));
  73. pa.HighPart = 0;
  74. pa.LowPart = BAR1;
  75. Extension->MMIO = (PMM_CONTROL_REGS)MmMapIoSpace(pa, sizeof(MM_CONTROL_REGS), FALSE);
  76. if (Extension->MMIO == NULL)
  77. {
  78. AGPLOG(AGP_CRITICAL,
  79. ("AgpInitializeTarget - Couldn't allocate %08x bytes for MMIO\n",
  80. sizeof(MM_CONTROL_REGS)));
  81. return(STATUS_UNSUCCESSFUL);
  82. }
  83. //
  84. // Verify that the chipset's Revision ID is correct, but only complain, if it isn't.
  85. //
  86. if (Extension->MMIO->RevisionID < LOWEST_REVISION_ID_SUPPORTED)
  87. {
  88. AGPLOG(AGP_CRITICAL,
  89. ("AgpInitializeTarget - Revision ID = %08x, it should = 1.\n",
  90. Extension->MMIO->RevisionID));
  91. }
  92. //
  93. // Determine if there are two RCC North Bridges in this system.
  94. //
  95. DeviceVendorID = 0;
  96. BytesReturned = HalGetBusDataByOffset(PCIConfiguration, SECONDARY_LE_BUS_ID, SECONDARY_LE_HOSTPCI_SLOT_ID,
  97. &DeviceVendorID, OFFSET_DEVICE_VENDOR_ID, sizeof(DeviceVendorID));
  98. if((DeviceVendorID != Extension->DeviceVendorID) || (BytesReturned != sizeof(DeviceVendorID)) ) {
  99. Extension->IsHPSA = FALSE;
  100. } else {
  101. Extension->IsHPSA = TRUE;
  102. }
  103. //
  104. // Enable the GART cache
  105. //
  106. if (Extension->IsHPSA) DnbSetShadowBit(0);
  107. Extension->MMIO->FeatureControl.GARTCacheEnable = 1;
  108. Extension->GartPointer = 0;
  109. Extension->SpecialTarget = 0;
  110. //
  111. // If the chipset supports linking then enable linking.
  112. //
  113. if (Extension->MMIO->Capabilities.LinkingSupported==1) {
  114. Extension->MMIO->FeatureControl.LinkingEnable=1;
  115. }
  116. if (Extension->IsHPSA) DnbSetShadowBit(1);
  117. return(STATUS_SUCCESS);
  118. }
  119. NTSTATUS
  120. AgpInitializeMaster(
  121. IN PVOID AgpExtension,
  122. OUT ULONG *AgpCapabilities
  123. )
  124. /*******************************************************************************
  125. *
  126. * Routine Functional Description:
  127. *
  128. * This function is the entrypoint for initialization of the AGP Master. It
  129. * is called after Target initialization, and is intended to be used to
  130. * initialize the AGP capabilities of both master and target.
  131. *
  132. * Arguments:
  133. *
  134. * AgpExtension -- Supplies the AGP Extension
  135. *
  136. * AgpCapabilities -- Returns the "software-visible" capabilities of the device
  137. *
  138. * Return Value:
  139. *
  140. * NTSTATUS
  141. *
  142. *******************************************************************************/
  143. {
  144. NTSTATUS Status;
  145. PCI_AGP_CAPABILITY MasterCap;
  146. PCI_AGP_CAPABILITY TargetCap;
  147. PAGPCPQ_EXTENSION Extension = AgpExtension;
  148. ULONG SBAEnable;
  149. ULONG FastWrite;
  150. ULONG DataRate;
  151. UCHAR RevID = 0;
  152. BOOLEAN ReverseInit;
  153. AGPLOG(AGP_NOISE, ("AgpCpq: AgpInitializeMaster entered.\n"));
  154. //
  155. // Get the master and target AGP capabilities
  156. //
  157. Status = AgpLibGetMasterCapability(AgpExtension, &MasterCap);
  158. if (!NT_SUCCESS(Status))
  159. {
  160. AGPLOG(AGP_CRITICAL,
  161. ("AGPCPQInitializeDevice - AgpLibGetMasterCapability failed %08lx\n",
  162. Status));
  163. return(Status);
  164. }
  165. Status = AgpLibGetPciDeviceCapability(AGP_CPQ_BUS_ID,
  166. AGP_CPQ_PCIPCI_SLOT_ID,
  167. &TargetCap);
  168. if (!NT_SUCCESS(Status))
  169. {
  170. AGPLOG(AGP_CRITICAL,
  171. ("AGPCPQInitializeDevice - AgpLibGetPciDeviceCapability failed %08lx\n",
  172. Status));
  173. return(Status);
  174. }
  175. //
  176. // Determine the greatest common denominator for data rate.
  177. //
  178. DataRate = TargetCap.AGPStatus.Rate & MasterCap.AGPStatus.Rate;
  179. ASSERT(DataRate != 0);
  180. //
  181. // Select the highest common rate.
  182. //
  183. if (DataRate & PCI_AGP_RATE_4X) {
  184. DataRate = PCI_AGP_RATE_4X;
  185. } else if (DataRate & PCI_AGP_RATE_2X) {
  186. DataRate = PCI_AGP_RATE_2X;
  187. } else if (DataRate & PCI_AGP_RATE_1X) {
  188. DataRate = PCI_AGP_RATE_1X;
  189. }
  190. //
  191. // Previously a call was made to change the rate (successfully),
  192. // use this rate again now
  193. //
  194. if (Extension->SpecialTarget & AGP_FLAG_SPECIAL_RESERVE) {
  195. DataRate = (ULONG)((Extension->SpecialTarget &
  196. AGP_FLAG_SPECIAL_RESERVE) >>
  197. AGP_FLAG_SET_RATE_SHIFT);
  198. }
  199. //
  200. // FIX RCC silicon bugs:
  201. // If RevID <= 4, then the reported Data Rate is 2X but the chip only supports 1X.
  202. // Regardless of RevID the reported RQDepth should be 0x0F.
  203. //
  204. if (Extension->DeviceVendorID == AGP_CNB20_LE_IDENTIFIER) {
  205. ReadCPQConfig(&RevID, OFFSET_REV_ID, sizeof(RevID));
  206. ASSERT(TargetCap.AGPStatus.RequestQueueDepthMaximum == 0x10);
  207. TargetCap.AGPStatus.RequestQueueDepthMaximum = 0x0F;
  208. if (RevID <= MAX_REV_ID_TO_LIMIT_1X) {
  209. DataRate = PCI_AGP_RATE_1X;
  210. }
  211. }
  212. //
  213. // Enable SBA if both master and target support it.
  214. //
  215. SBAEnable = (TargetCap.AGPStatus.SideBandAddressing &
  216. MasterCap.AGPStatus.SideBandAddressing);
  217. //
  218. // Enable FastWrite if both master and target support it.
  219. //
  220. FastWrite = (TargetCap.AGPStatus.FastWrite &
  221. MasterCap.AGPStatus.FastWrite);
  222. //
  223. // Enable the Master first.
  224. //
  225. ReverseInit =
  226. (Extension->SpecialTarget & AGP_FLAG_REVERSE_INITIALIZATION) ==
  227. AGP_FLAG_REVERSE_INITIALIZATION;
  228. if (ReverseInit) {
  229. MasterCap.AGPCommand.Rate = DataRate;
  230. MasterCap.AGPCommand.AGPEnable = 1;
  231. MasterCap.AGPCommand.SBAEnable = SBAEnable;
  232. MasterCap.AGPCommand.FastWriteEnable = FastWrite;
  233. MasterCap.AGPCommand.RequestQueueDepth = TargetCap.AGPStatus.RequestQueueDepthMaximum;
  234. Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap);
  235. if (!NT_SUCCESS(Status))
  236. {
  237. AGPLOG(AGP_CRITICAL,
  238. ("AGPCPQInitializeDevice - AgpLibSetMasterCapability %08lx failed %08lx\n",
  239. &MasterCap,
  240. Status));
  241. }
  242. }
  243. //
  244. // Now enable the Target.
  245. //
  246. TargetCap.AGPCommand.Rate = DataRate;
  247. TargetCap.AGPCommand.AGPEnable = 1;
  248. TargetCap.AGPCommand.SBAEnable = SBAEnable;
  249. TargetCap.AGPCommand.FastWriteEnable = FastWrite;
  250. Status = AgpLibSetPciDeviceCapability(AGP_CPQ_BUS_ID,
  251. AGP_CPQ_PCIPCI_SLOT_ID,
  252. &TargetCap);
  253. if (!NT_SUCCESS(Status))
  254. {
  255. AGPLOG(AGP_CRITICAL,
  256. ("AGPCPQInitializeDevice - AgpLibSetPciDeviceCapability %08lx for target failed %08lx\n",
  257. &TargetCap,
  258. Status));
  259. return(Status);
  260. }
  261. if (!ReverseInit) {
  262. MasterCap.AGPCommand.Rate = DataRate;
  263. MasterCap.AGPCommand.AGPEnable = 1;
  264. MasterCap.AGPCommand.SBAEnable = SBAEnable;
  265. MasterCap.AGPCommand.FastWriteEnable = FastWrite;
  266. MasterCap.AGPCommand.RequestQueueDepth = TargetCap.AGPStatus.RequestQueueDepthMaximum;
  267. Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap);
  268. if (!NT_SUCCESS(Status))
  269. {
  270. AGPLOG(AGP_CRITICAL,
  271. ("AGPCPQInitializeDevice - AgpLibSetMasterCapability %08lx failed %08lx\n",
  272. &MasterCap,
  273. Status));
  274. }
  275. }
  276. #if DBG
  277. {
  278. PCI_AGP_CAPABILITY CurrentCap;
  279. //
  280. // Read them back, see if it worked
  281. //
  282. Status = AgpLibGetMasterCapability(AgpExtension, &CurrentCap);
  283. ASSERT(NT_SUCCESS(Status));
  284. //
  285. // If the target request queue depth is greater than the master will
  286. // allow, it will be trimmed. Loosen the assert to not require an
  287. // exact match.
  288. //
  289. ASSERT(CurrentCap.AGPCommand.RequestQueueDepth <= MasterCap.AGPCommand.RequestQueueDepth);
  290. CurrentCap.AGPCommand.RequestQueueDepth = MasterCap.AGPCommand.RequestQueueDepth;
  291. ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand, &MasterCap.AGPCommand, sizeof(CurrentCap.AGPCommand)));
  292. Status = AgpLibGetPciDeviceCapability(AGP_CPQ_BUS_ID,
  293. AGP_CPQ_PCIPCI_SLOT_ID,
  294. &CurrentCap);
  295. ASSERT(NT_SUCCESS(Status));
  296. ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand, &TargetCap.AGPCommand,
  297. sizeof(CurrentCap.AGPCommand)));
  298. }
  299. #endif
  300. //
  301. // Indicate that we can map memory through the GART aperture
  302. //
  303. *AgpCapabilities = AGP_CAPABILITIES_MAP_PHYSICAL;
  304. return(Status);
  305. }
  306. NTSTATUS
  307. DnbSetShadowBit(
  308. ULONG SetToOne
  309. )
  310. //
  311. // This routine is required, (because of a new requirement in the RCC chipset.).
  312. // When there are two NorthBridge's, the shadow bit must be set to 0 prior
  313. // to any MMIO writes, and then set back to 1 when done.
  314. //
  315. {
  316. NTSTATUS Status = STATUS_SUCCESS; // Assume Success
  317. UCHAR ShadowByte = 0;
  318. ULONG BytesReturned = 0;
  319. ULONG length = 1;
  320. if (SetToOne == 1) {
  321. //
  322. // Set the shadow bit to a one. (This disables shadowing.)
  323. //
  324. BytesReturned = HalGetBusDataByOffset(PCIConfiguration, SECONDARY_LE_BUS_ID,
  325. SECONDARY_LE_HOSTPCI_SLOT_ID, &ShadowByte, OFFSET_SHADOW_BYTE, length);
  326. if(BytesReturned != length) {
  327. AGPLOG(AGP_CRITICAL,("ERROR: Failed to read shadow register!\n"));
  328. Status = STATUS_UNSUCCESSFUL;
  329. goto exit_routine;
  330. }
  331. ShadowByte |= FLAG_DISABLE_SHADOW;
  332. HalSetBusDataByOffset(PCIConfiguration, SECONDARY_LE_BUS_ID,
  333. SECONDARY_LE_HOSTPCI_SLOT_ID, &ShadowByte, OFFSET_SHADOW_BYTE, length);
  334. if(BytesReturned != length) {
  335. AGPLOG(AGP_CRITICAL,("ERROR: Failed to write shadow register!\n"));
  336. Status = STATUS_UNSUCCESSFUL;
  337. goto exit_routine;
  338. }
  339. } else {
  340. //
  341. // Set the shadow bit to a zero. (This enables shadowing.)
  342. //
  343. BytesReturned = HalGetBusDataByOffset(PCIConfiguration, SECONDARY_LE_BUS_ID,
  344. SECONDARY_LE_HOSTPCI_SLOT_ID, &ShadowByte, OFFSET_SHADOW_BYTE, length);
  345. if(BytesReturned != length) {
  346. AGPLOG(AGP_CRITICAL,("ERROR: Failed to read shadow register!"));
  347. Status = STATUS_UNSUCCESSFUL;
  348. goto exit_routine;
  349. }
  350. ShadowByte &= MASK_ENABLE_SHADOW;
  351. HalSetBusDataByOffset(PCIConfiguration, SECONDARY_LE_BUS_ID,
  352. SECONDARY_LE_HOSTPCI_SLOT_ID, &ShadowByte, OFFSET_SHADOW_BYTE, length);
  353. if(BytesReturned != length) {
  354. AGPLOG(AGP_CRITICAL,("ERROR: Failed to write shadow register!"));
  355. Status = STATUS_UNSUCCESSFUL;
  356. goto exit_routine;
  357. }
  358. }
  359. exit_routine:
  360. return(Status);
  361. }