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.

462 lines
16 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. //
  68. // Check for CNB_20_HE (function 1) -- 0x00091166 busted AGP3.5 rev >= 0xA0
  69. //
  70. if (DeviceVendorID == AGP_CNB20_HE_IDENTIFIER) {
  71. UCHAR Revision;
  72. BytesReturned = HalGetBusDataByOffset(PCIConfiguration,
  73. PRIMARY_HE_BUS_ID,
  74. PRIMARY_HE_PCIPCI_SLOT_ID,
  75. &Revision,
  76. OFFSET_REV_ID,
  77. sizeof(Revision));
  78. if ((BytesReturned == sizeof(Revision)) && (Revision >= 0xA0)) {
  79. AGPLOG(AGP_CRITICAL,
  80. ("AGPCPQ - AgpInitializeTarget was called for HE "
  81. "revision %08x, which is not a known good RCC AGP "
  82. "chipset revision!\n",
  83. Revision));
  84. return(STATUS_UNSUCCESSFUL);
  85. }
  86. }
  87. Extension->DeviceVendorID = DeviceVendorID;
  88. //
  89. // Read the chipset's BAR1 Register, and then map the chipset's
  90. // Memory Mapped Control Registers into kernel mode address space.
  91. //
  92. ReadCPQConfig(&BAR1,OFFSET_BAR1,sizeof(BAR1));
  93. pa.HighPart = 0;
  94. pa.LowPart = BAR1;
  95. Extension->MMIO = (PMM_CONTROL_REGS)MmMapIoSpace(pa, sizeof(MM_CONTROL_REGS), FALSE);
  96. if (Extension->MMIO == NULL)
  97. {
  98. AGPLOG(AGP_CRITICAL,
  99. ("AgpInitializeTarget - Couldn't allocate %08x bytes for MMIO\n",
  100. sizeof(MM_CONTROL_REGS)));
  101. return(STATUS_UNSUCCESSFUL);
  102. }
  103. //
  104. // Verify that the chipset's Revision ID is correct, but only complain, if it isn't.
  105. //
  106. if (Extension->MMIO->RevisionID < LOWEST_REVISION_ID_SUPPORTED)
  107. {
  108. AGPLOG(AGP_CRITICAL,
  109. ("AgpInitializeTarget - Revision ID = %08x, it should = 1.\n",
  110. Extension->MMIO->RevisionID));
  111. }
  112. //
  113. // Determine if there are two RCC North Bridges in this system.
  114. //
  115. DeviceVendorID = 0;
  116. BytesReturned = HalGetBusDataByOffset(PCIConfiguration, SECONDARY_LE_BUS_ID, SECONDARY_LE_HOSTPCI_SLOT_ID,
  117. &DeviceVendorID, OFFSET_DEVICE_VENDOR_ID, sizeof(DeviceVendorID));
  118. if((DeviceVendorID != Extension->DeviceVendorID) || (BytesReturned != sizeof(DeviceVendorID)) ) {
  119. Extension->IsHPSA = FALSE;
  120. } else {
  121. Extension->IsHPSA = TRUE;
  122. }
  123. //
  124. // Enable the GART cache
  125. //
  126. if (Extension->IsHPSA) DnbSetShadowBit(0);
  127. Extension->MMIO->FeatureControl.GARTCacheEnable = 1;
  128. //
  129. // The extension is zero'd above, so we don't need to init any data
  130. // to zero/NULL
  131. //
  132. //Extension->GartPointer = 0;
  133. //Extension->SpecialTarget = 0;
  134. //Extension->Gart = NULL;
  135. //Extension->Gart = NULL;
  136. //Extension->GartLength = 0;
  137. //Extension->Dir = NULL;
  138. //
  139. // If the chipset supports linking then enable linking.
  140. //
  141. if (Extension->MMIO->Capabilities.LinkingSupported==1) {
  142. Extension->MMIO->FeatureControl.LinkingEnable=1;
  143. }
  144. if (Extension->IsHPSA) DnbSetShadowBit(1);
  145. return(STATUS_SUCCESS);
  146. }
  147. NTSTATUS
  148. AgpInitializeMaster(
  149. IN PVOID AgpExtension,
  150. OUT ULONG *AgpCapabilities
  151. )
  152. /*******************************************************************************
  153. *
  154. * Routine Functional Description:
  155. *
  156. * This function is the entrypoint for initialization of the AGP Master. It
  157. * is called after Target initialization, and is intended to be used to
  158. * initialize the AGP capabilities of both master and target.
  159. *
  160. * Arguments:
  161. *
  162. * AgpExtension -- Supplies the AGP Extension
  163. *
  164. * AgpCapabilities -- Returns the "software-visible" capabilities of the device
  165. *
  166. * Return Value:
  167. *
  168. * NTSTATUS
  169. *
  170. *******************************************************************************/
  171. {
  172. NTSTATUS Status;
  173. PCI_AGP_CAPABILITY MasterCap;
  174. PCI_AGP_CAPABILITY TargetCap;
  175. PAGPCPQ_EXTENSION Extension = AgpExtension;
  176. ULONG SBAEnable;
  177. ULONG FastWrite;
  178. ULONG DataRate;
  179. UCHAR RevID = 0;
  180. BOOLEAN ReverseInit;
  181. AGPLOG(AGP_NOISE, ("AgpCpq: AgpInitializeMaster entered.\n"));
  182. //
  183. // Get the master and target AGP capabilities
  184. //
  185. Status = AgpLibGetMasterCapability(AgpExtension, &MasterCap);
  186. if (!NT_SUCCESS(Status))
  187. {
  188. AGPLOG(AGP_CRITICAL,
  189. ("AGPCPQInitializeDevice - AgpLibGetMasterCapability failed %08lx\n",
  190. Status));
  191. return(Status);
  192. }
  193. Status = AgpLibGetPciDeviceCapability(AGP_CPQ_BUS_ID,
  194. AGP_CPQ_PCIPCI_SLOT_ID,
  195. &TargetCap);
  196. if (!NT_SUCCESS(Status))
  197. {
  198. AGPLOG(AGP_CRITICAL,
  199. ("AGPCPQInitializeDevice - AgpLibGetPciDeviceCapability failed %08lx\n",
  200. Status));
  201. return(Status);
  202. }
  203. //
  204. // Determine the greatest common denominator for data rate.
  205. //
  206. DataRate = TargetCap.AGPStatus.Rate & MasterCap.AGPStatus.Rate;
  207. AGP_ASSERT(DataRate != 0);
  208. //
  209. // Select the highest common rate.
  210. //
  211. if (DataRate & PCI_AGP_RATE_4X) {
  212. DataRate = PCI_AGP_RATE_4X;
  213. } else if (DataRate & PCI_AGP_RATE_2X) {
  214. DataRate = PCI_AGP_RATE_2X;
  215. } else if (DataRate & PCI_AGP_RATE_1X) {
  216. DataRate = PCI_AGP_RATE_1X;
  217. }
  218. //
  219. // Previously a call was made to change the rate (successfully),
  220. // use this rate again now
  221. //
  222. if (Extension->SpecialTarget & AGP_FLAG_SPECIAL_RESERVE) {
  223. DataRate = (ULONG)((Extension->SpecialTarget &
  224. AGP_FLAG_SPECIAL_RESERVE) >>
  225. AGP_FLAG_SET_RATE_SHIFT);
  226. }
  227. //
  228. // FIX RCC silicon bugs:
  229. // If RevID <= 4, then the reported Data Rate is 2X but the chip only supports 1X.
  230. // Regardless of RevID the reported RQDepth should be 0x0F.
  231. //
  232. if (Extension->DeviceVendorID == AGP_CNB20_LE_IDENTIFIER) {
  233. ReadCPQConfig(&RevID, OFFSET_REV_ID, sizeof(RevID));
  234. AGP_ASSERT(TargetCap.AGPStatus.RequestQueueDepthMaximum == 0x10);
  235. TargetCap.AGPStatus.RequestQueueDepthMaximum = 0x0F;
  236. if (RevID <= MAX_REV_ID_TO_LIMIT_1X) {
  237. DataRate = PCI_AGP_RATE_1X;
  238. }
  239. }
  240. //
  241. // Enable SBA if both master and target support it.
  242. //
  243. SBAEnable = (TargetCap.AGPStatus.SideBandAddressing &
  244. MasterCap.AGPStatus.SideBandAddressing);
  245. //
  246. // Enable FastWrite if both master and target support it.
  247. //
  248. FastWrite = (TargetCap.AGPStatus.FastWrite &
  249. MasterCap.AGPStatus.FastWrite);
  250. //
  251. // Enable the Master first.
  252. //
  253. ReverseInit =
  254. (Extension->SpecialTarget & AGP_FLAG_REVERSE_INITIALIZATION) ==
  255. AGP_FLAG_REVERSE_INITIALIZATION;
  256. if (ReverseInit) {
  257. MasterCap.AGPCommand.Rate = DataRate;
  258. MasterCap.AGPCommand.AGPEnable = 1;
  259. MasterCap.AGPCommand.SBAEnable = SBAEnable;
  260. MasterCap.AGPCommand.FastWriteEnable = FastWrite;
  261. MasterCap.AGPCommand.RequestQueueDepth = TargetCap.AGPStatus.RequestQueueDepthMaximum;
  262. Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap);
  263. if (!NT_SUCCESS(Status))
  264. {
  265. AGPLOG(AGP_CRITICAL,
  266. ("AGPCPQInitializeDevice - AgpLibSetMasterCapability %08lx failed %08lx\n",
  267. &MasterCap,
  268. Status));
  269. }
  270. }
  271. //
  272. // Now enable the Target.
  273. //
  274. TargetCap.AGPCommand.Rate = DataRate;
  275. TargetCap.AGPCommand.AGPEnable = 1;
  276. TargetCap.AGPCommand.SBAEnable = SBAEnable;
  277. TargetCap.AGPCommand.FastWriteEnable = FastWrite;
  278. Status = AgpLibSetPciDeviceCapability(AGP_CPQ_BUS_ID,
  279. AGP_CPQ_PCIPCI_SLOT_ID,
  280. &TargetCap);
  281. if (!NT_SUCCESS(Status))
  282. {
  283. AGPLOG(AGP_CRITICAL,
  284. ("AGPCPQInitializeDevice - AgpLibSetPciDeviceCapability %08lx for target failed %08lx\n",
  285. &TargetCap,
  286. Status));
  287. return(Status);
  288. }
  289. if (!ReverseInit) {
  290. MasterCap.AGPCommand.Rate = DataRate;
  291. MasterCap.AGPCommand.AGPEnable = 1;
  292. MasterCap.AGPCommand.SBAEnable = SBAEnable;
  293. MasterCap.AGPCommand.FastWriteEnable = FastWrite;
  294. MasterCap.AGPCommand.RequestQueueDepth = TargetCap.AGPStatus.RequestQueueDepthMaximum;
  295. Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap);
  296. if (!NT_SUCCESS(Status))
  297. {
  298. AGPLOG(AGP_CRITICAL,
  299. ("AGPCPQInitializeDevice - AgpLibSetMasterCapability %08lx failed %08lx\n",
  300. &MasterCap,
  301. Status));
  302. }
  303. }
  304. #if DBG
  305. {
  306. PCI_AGP_CAPABILITY CurrentCap;
  307. //
  308. // Read them back, see if it worked
  309. //
  310. Status = AgpLibGetMasterCapability(AgpExtension, &CurrentCap);
  311. AGP_ASSERT(NT_SUCCESS(Status));
  312. //
  313. // If the target request queue depth is greater than the master will
  314. // allow, it will be trimmed. Loosen the assert to not require an
  315. // exact match.
  316. //
  317. AGP_ASSERT(CurrentCap.AGPCommand.RequestQueueDepth <= MasterCap.AGPCommand.RequestQueueDepth);
  318. CurrentCap.AGPCommand.RequestQueueDepth = MasterCap.AGPCommand.RequestQueueDepth;
  319. AGP_ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand, &MasterCap.AGPCommand, sizeof(CurrentCap.AGPCommand)));
  320. Status = AgpLibGetPciDeviceCapability(AGP_CPQ_BUS_ID,
  321. AGP_CPQ_PCIPCI_SLOT_ID,
  322. &CurrentCap);
  323. AGP_ASSERT(NT_SUCCESS(Status));
  324. AGP_ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand, &TargetCap.AGPCommand,
  325. sizeof(CurrentCap.AGPCommand)));
  326. }
  327. #endif
  328. //
  329. // Indicate that we can map memory through the GART aperture
  330. //
  331. *AgpCapabilities = AGP_CAPABILITIES_MAP_PHYSICAL;
  332. return(Status);
  333. }
  334. NTSTATUS
  335. DnbSetShadowBit(
  336. ULONG SetToOne
  337. )
  338. //
  339. // This routine is required, (because of a new requirement in the RCC chipset.).
  340. // When there are two NorthBridge's, the shadow bit must be set to 0 prior
  341. // to any MMIO writes, and then set back to 1 when done.
  342. //
  343. {
  344. NTSTATUS Status = STATUS_SUCCESS; // Assume Success
  345. UCHAR ShadowByte = 0;
  346. ULONG BytesReturned = 0;
  347. ULONG length = 1;
  348. if (SetToOne == 1) {
  349. //
  350. // Set the shadow bit to a one. (This disables shadowing.)
  351. //
  352. BytesReturned = HalGetBusDataByOffset(PCIConfiguration, SECONDARY_LE_BUS_ID,
  353. SECONDARY_LE_HOSTPCI_SLOT_ID, &ShadowByte, OFFSET_SHADOW_BYTE, length);
  354. if(BytesReturned != length) {
  355. AGPLOG(AGP_CRITICAL,("ERROR: Failed to read shadow register!\n"));
  356. Status = STATUS_UNSUCCESSFUL;
  357. goto exit_routine;
  358. }
  359. ShadowByte |= FLAG_DISABLE_SHADOW;
  360. HalSetBusDataByOffset(PCIConfiguration, SECONDARY_LE_BUS_ID,
  361. SECONDARY_LE_HOSTPCI_SLOT_ID, &ShadowByte, OFFSET_SHADOW_BYTE, length);
  362. if(BytesReturned != length) {
  363. AGPLOG(AGP_CRITICAL,("ERROR: Failed to write shadow register!\n"));
  364. Status = STATUS_UNSUCCESSFUL;
  365. goto exit_routine;
  366. }
  367. } else {
  368. //
  369. // Set the shadow bit to a zero. (This enables shadowing.)
  370. //
  371. BytesReturned = HalGetBusDataByOffset(PCIConfiguration, SECONDARY_LE_BUS_ID,
  372. SECONDARY_LE_HOSTPCI_SLOT_ID, &ShadowByte, OFFSET_SHADOW_BYTE, length);
  373. if(BytesReturned != length) {
  374. AGPLOG(AGP_CRITICAL,("ERROR: Failed to read shadow register!"));
  375. Status = STATUS_UNSUCCESSFUL;
  376. goto exit_routine;
  377. }
  378. ShadowByte &= MASK_ENABLE_SHADOW;
  379. HalSetBusDataByOffset(PCIConfiguration, SECONDARY_LE_BUS_ID,
  380. SECONDARY_LE_HOSTPCI_SLOT_ID, &ShadowByte, OFFSET_SHADOW_BYTE, length);
  381. if(BytesReturned != length) {
  382. AGPLOG(AGP_CRITICAL,("ERROR: Failed to write shadow register!"));
  383. Status = STATUS_UNSUCCESSFUL;
  384. goto exit_routine;
  385. }
  386. }
  387. exit_routine:
  388. return(Status);
  389. }