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.

553 lines
12 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. ixbusdat.c
  5. Abstract:
  6. This module contains the IoXxx routines for the NT I/O system that
  7. are hardware dependent. Were these routines not hardware dependent,
  8. they would reside in the iosubs.c module.
  9. Author:
  10. Environment:
  11. Kernel mode
  12. Revision History:
  13. --*/
  14. #include "bootia64.h"
  15. #include "arc.h"
  16. #include "ixfwhal.h"
  17. #if defined(NEC_98)
  18. #include "nec98.h"
  19. #else //NEC_98
  20. #include "eisa.h"
  21. #endif //NEC_98
  22. #include "mca.h"
  23. #include "ntconfig.h"
  24. #if defined(NEC_98)
  25. #else
  26. ULONG
  27. HalpGetCmosData(
  28. IN ULONG BusNumber,
  29. IN ULONG SlotNumber,
  30. IN PVOID Buffer,
  31. IN ULONG Length
  32. );
  33. ULONG
  34. HalpGetPosData(
  35. IN ULONG BusNumber,
  36. IN ULONG SlotNumber,
  37. IN PVOID Buffer,
  38. IN ULONG Offset,
  39. IN ULONG Length
  40. );
  41. ULONG
  42. HalpGetEisaData(
  43. IN ULONG BusNumber,
  44. IN ULONG SlotNumber,
  45. IN PVOID Buffer,
  46. IN ULONG Offset,
  47. IN ULONG Length
  48. );
  49. #endif //!NEC_98
  50. ULONG
  51. HalpGetPCIData(
  52. IN ULONG BusNumber,
  53. IN ULONG SlotNumber,
  54. IN PVOID Buffer,
  55. IN ULONG Offset,
  56. IN ULONG Length
  57. );
  58. ULONG
  59. HalpSetPCIData(
  60. IN ULONG BusNumber,
  61. IN ULONG SlotNumber,
  62. IN PVOID Buffer,
  63. IN ULONG Offset,
  64. IN ULONG Length
  65. );
  66. NTSTATUS
  67. HalpAssignPCISlotResources (
  68. IN ULONG BusNumber,
  69. IN ULONG Slot,
  70. IN OUT PCM_RESOURCE_LIST *AllocatedResources
  71. );
  72. /*
  73. *
  74. * Router functions. Routes each call to specific handler
  75. *
  76. */
  77. ULONG
  78. HalGetBusData(
  79. IN BUS_DATA_TYPE BusDataType,
  80. IN ULONG BusNumber,
  81. IN ULONG SlotNumber,
  82. IN PVOID Buffer,
  83. IN ULONG Length
  84. )
  85. {
  86. return HalGetBusDataByOffset (BusDataType,BusNumber,SlotNumber,Buffer,0,Length);
  87. }
  88. ULONG
  89. HalGetBusDataByOffset (
  90. IN BUS_DATA_TYPE BusDataType,
  91. IN ULONG BusNumber,
  92. IN ULONG Slot,
  93. IN PVOID Buffer,
  94. IN ULONG Offset,
  95. IN ULONG Length
  96. )
  97. /*++
  98. Routine Description:
  99. Dispatcher for GetBusData
  100. --*/
  101. {
  102. switch (BusDataType) {
  103. #if defined(NEC_98)
  104. #else
  105. case Cmos:
  106. if (Offset != 0) {
  107. return 0;
  108. }
  109. return HalpGetCmosData(BusNumber, Slot, Buffer, Length);
  110. case Pos:
  111. return HalpGetPosData(BusNumber, Slot, Buffer, Offset, Length);
  112. case EisaConfiguration:
  113. return HalpGetEisaData(BusNumber, Slot, Buffer, Offset, Length);
  114. #endif //NEC_98
  115. case PCIConfiguration:
  116. return HalpGetPCIData(BusNumber, Slot, Buffer, Offset, Length);
  117. }
  118. return 0;
  119. }
  120. ULONG
  121. HalSetBusData(
  122. IN BUS_DATA_TYPE BusDataType,
  123. IN ULONG BusNumber,
  124. IN ULONG SlotNumber,
  125. IN PVOID Buffer,
  126. IN ULONG Length
  127. )
  128. {
  129. return HalSetBusDataByOffset (BusDataType,BusNumber,SlotNumber,Buffer,0,Length);
  130. }
  131. ULONG
  132. HalSetBusDataByOffset(
  133. IN BUS_DATA_TYPE BusDataType,
  134. IN ULONG BusNumber,
  135. IN ULONG Slot,
  136. IN PVOID Buffer,
  137. IN ULONG Offset,
  138. IN ULONG Length
  139. )
  140. /*++
  141. Routine Description:
  142. Dispatcher for SetBusData
  143. --*/
  144. {
  145. switch (BusDataType) {
  146. case PCIConfiguration:
  147. return HalpSetPCIData(BusNumber, Slot, Buffer, Offset, Length);
  148. }
  149. return 0;
  150. }
  151. NTSTATUS
  152. HalAssignSlotResources (
  153. IN PUNICODE_STRING RegistryPath,
  154. IN PUNICODE_STRING DriverClassName OPTIONAL,
  155. IN PDRIVER_OBJECT DriverObject,
  156. IN PDEVICE_OBJECT DeviceObject OPTIONAL,
  157. IN INTERFACE_TYPE BusType,
  158. IN ULONG BusNumber,
  159. IN ULONG SlotNumber,
  160. IN OUT PCM_RESOURCE_LIST *AllocatedResources
  161. )
  162. /*++
  163. Routine Description:
  164. Dispatcher for AssignSlotResources
  165. --*/
  166. {
  167. switch (BusType) {
  168. case PCIBus:
  169. return HalpAssignPCISlotResources (
  170. BusNumber,
  171. SlotNumber,
  172. AllocatedResources
  173. );
  174. default:
  175. break;
  176. }
  177. return STATUS_NOT_FOUND;
  178. }
  179. /**
  180. **
  181. ** Standard PC bus functions
  182. **
  183. **/
  184. BOOLEAN
  185. HalTranslateBusAddress(
  186. IN INTERFACE_TYPE InterfaceType,
  187. IN ULONG BusNumber,
  188. IN PHYSICAL_ADDRESS BusAddress,
  189. IN OUT PULONG AddressSpace,
  190. OUT PPHYSICAL_ADDRESS TranslatedAddress
  191. )
  192. /*++
  193. Routine Description:
  194. This function translates a bus-relative address space and address into
  195. a system physical address.
  196. Arguments:
  197. BusNumber - Supplies the bus number. This is ignored on
  198. standard x86 systems
  199. BusAddress - Supplies the bus-relative address
  200. AddressSpace - Supplies the address space number.
  201. Returns the host address space number.
  202. AddressSpace == 0 => I/O space
  203. AddressSpace == 1 => memory space
  204. TranslatedAddress - Pointer to a physical_address.
  205. Return Value:
  206. System physical address corresponding to the supplied bus relative
  207. address and bus address number.
  208. --*/
  209. {
  210. TranslatedAddress->HighPart = 0;
  211. TranslatedAddress->LowPart = BusAddress.LowPart;
  212. return(TRUE);
  213. }
  214. #if defined(NEC_98)
  215. #else
  216. ULONG
  217. HalpGetPosData (
  218. IN ULONG BusNumber,
  219. IN ULONG SlotNumber,
  220. IN PVOID Buffer,
  221. IN ULONG DOffset,
  222. IN ULONG Length
  223. )
  224. /*--
  225. Arguments:
  226. BusDataType - Supplies the type of bus.
  227. BusNumber - Indicates which bus.
  228. Buffer - Supplies the space to store the data.
  229. Length - Supplies a count in bytes of the maximum amount to return.
  230. Return Value:
  231. Returns the amount of data stored into the buffer.
  232. --*/
  233. {
  234. PVOID McaRegisterBase = 0;
  235. ULONG Index = 0;
  236. PUCHAR DataBuffer = Buffer;
  237. ULONG DataLength = 0;
  238. PUCHAR PosBase;
  239. ULONG Offset;
  240. if (DOffset != 0 || MachineType != MACHINE_TYPE_MCA) {
  241. return 0;
  242. }
  243. PosBase = (PUCHAR) &((PMCA_CONTROL) McaRegisterBase)->Pos;
  244. //
  245. // Place the specified adapter into setup mode.
  246. //
  247. WRITE_PORT_UCHAR((PVOID) &((PMCA_CONTROL) McaRegisterBase)->AdapterSetup,
  248. (UCHAR) ( MCA_ADAPTER_SETUP_ON | SlotNumber ));
  249. while (DataLength < Length && DataLength < 6) {
  250. DataBuffer[DataLength] = READ_PORT_UCHAR( PosBase + DataLength );
  251. DataLength++;
  252. }
  253. while (DataLength < Length) {
  254. WRITE_PORT_UCHAR((PVOID) &((PPROGRAMMABLE_OPTION_SELECT)
  255. PosBase)->SubaddressExtensionLsb, (UCHAR) Index);
  256. WRITE_PORT_UCHAR((PVOID) &((PPROGRAMMABLE_OPTION_SELECT)
  257. PosBase)->SubaddressExtensionMsb, (UCHAR) (Index >> 8));
  258. DataBuffer[Index + 6] = READ_PORT_UCHAR(
  259. (PVOID) &((PPROGRAMMABLE_OPTION_SELECT)PosBase)->OptionSelectData2);
  260. DataLength++;
  261. if (DataLength < Length) {
  262. Offset = DataLength + ((Length - DataLength) / 2);
  263. DataBuffer[Offset] = READ_PORT_UCHAR(
  264. (PVOID) &((PPROGRAMMABLE_OPTION_SELECT)PosBase)->OptionSelectData3);
  265. DataLength++;
  266. Index++;
  267. }
  268. }
  269. //
  270. // Disable adapter setup.
  271. //
  272. WRITE_PORT_UCHAR((PVOID) &((PMCA_CONTROL) McaRegisterBase)->AdapterSetup,
  273. (UCHAR) ( MCA_ADAPTER_SETUP_OFF ));
  274. return 1;
  275. }
  276. ULONG
  277. HalpGetEisaData (
  278. IN ULONG BusNumber,
  279. IN ULONG SlotNumber,
  280. IN PVOID Buffer,
  281. IN ULONG Offset,
  282. IN ULONG Length
  283. )
  284. /*--
  285. Arguments:
  286. BusDataType - Supplies the type of bus.
  287. BusNumber - Indicates which bus.
  288. Buffer - Supplies the space to store the data.
  289. Length - Supplies a count in bytes of the maximum amount to return.
  290. Return Value:
  291. Returns the amount of data stored into the buffer.
  292. --*/
  293. {
  294. ULONG DataLength = 0;
  295. ULONG i;
  296. ULONG TotalDataSize;
  297. ULONG SlotDataSize;
  298. ULONG PartialCount;
  299. ULONG Index = 0;
  300. PUCHAR DataBuffer = Buffer;
  301. PCONFIGURATION_COMPONENT_DATA ConfigData;
  302. PCM_EISA_SLOT_INFORMATION SlotInformation;
  303. PCM_PARTIAL_RESOURCE_LIST Descriptor;
  304. PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource;
  305. BOOLEAN Found = FALSE;
  306. if (MachineType != MACHINE_TYPE_EISA) {
  307. return 0;
  308. }
  309. ConfigData = KeFindConfigurationEntry(
  310. FwConfigurationTree,
  311. AdapterClass,
  312. EisaAdapter,
  313. NULL
  314. );
  315. if (ConfigData == NULL) {
  316. #if defined(ENABLE_LOADER_EBUG)
  317. DbgPrint("HalGetBusData: KeFindConfigurationEntry failed\n");
  318. #endif
  319. return(0);
  320. }
  321. Descriptor = ConfigData->ConfigurationData;
  322. PartialResource = Descriptor->PartialDescriptors;
  323. PartialCount = Descriptor->Count;
  324. for (i = 0; i < PartialCount; i++) {
  325. //
  326. // Do each partial Resource
  327. //
  328. switch (PartialResource->Type) {
  329. case CmResourceTypeNull:
  330. case CmResourceTypePort:
  331. case CmResourceTypeInterrupt:
  332. case CmResourceTypeMemory:
  333. case CmResourceTypeDma:
  334. //
  335. // We dont care about these.
  336. //
  337. PartialResource++;
  338. break;
  339. case CmResourceTypeDeviceSpecific:
  340. //
  341. // Bingo!
  342. //
  343. TotalDataSize = PartialResource->u.DeviceSpecificData.DataSize;
  344. SlotInformation = (PCM_EISA_SLOT_INFORMATION)
  345. ((PUCHAR)PartialResource +
  346. sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
  347. while (((LONG)TotalDataSize) > 0) {
  348. if (SlotInformation->ReturnCode == EISA_EMPTY_SLOT) {
  349. SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION);
  350. } else {
  351. SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION) +
  352. SlotInformation->NumberFunctions *
  353. sizeof(CM_EISA_FUNCTION_INFORMATION);
  354. }
  355. if (SlotDataSize > TotalDataSize) {
  356. //
  357. // Something is wrong again
  358. //
  359. #if defined(ENABLE_LOADER_EBUG)
  360. DbgPrint("HalGetBusData: SlotDataSize > TotalDataSize\n");
  361. #endif
  362. return(0);
  363. }
  364. if (SlotNumber != 0) {
  365. SlotNumber--;
  366. SlotInformation = (PCM_EISA_SLOT_INFORMATION)
  367. ((PUCHAR)SlotInformation + SlotDataSize);
  368. TotalDataSize -= SlotDataSize;
  369. continue;
  370. }
  371. //
  372. // This is our slot
  373. //
  374. Found = TRUE;
  375. break;
  376. }
  377. //
  378. // End loop
  379. //
  380. i = PartialCount;
  381. break;
  382. default:
  383. #if defined(ENABLE_LOADER_EBUG)
  384. DbgPrint("Bad Data in registry!\n");
  385. #endif
  386. return(0);
  387. }
  388. }
  389. if (Found) {
  390. //
  391. // As a hack if the length is zero then the buffer points to a
  392. // PVOID where the pointer to the data should be stored. This is
  393. // done in the loader because we quickly run out of heap scaning
  394. // all of the EISA configuration data.
  395. //
  396. if (Length == 0) {
  397. //
  398. // Return the pointer to the mini-port driver.
  399. //
  400. *((PVOID *)Buffer) = SlotInformation;
  401. return(SlotDataSize);
  402. }
  403. i = Length + Offset;
  404. if (i > SlotDataSize) {
  405. i = SlotDataSize;
  406. }
  407. DataLength = i - Offset;
  408. RtlMoveMemory(Buffer, ((PUCHAR) SlotInformation + Offset), DataLength);
  409. }
  410. return(DataLength);
  411. }
  412. #endif //NEC_98