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.

564 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. UNREFERENCED_PARAMETER( RegistryPath );
  168. UNREFERENCED_PARAMETER( DriverClassName );
  169. UNREFERENCED_PARAMETER( DriverObject );
  170. UNREFERENCED_PARAMETER( DeviceObject );
  171. switch (BusType) {
  172. case PCIBus:
  173. return HalpAssignPCISlotResources (
  174. BusNumber,
  175. SlotNumber,
  176. AllocatedResources
  177. );
  178. default:
  179. break;
  180. }
  181. return STATUS_NOT_FOUND;
  182. }
  183. /**
  184. **
  185. ** Standard PC bus functions
  186. **
  187. **/
  188. BOOLEAN
  189. HalTranslateBusAddress(
  190. IN INTERFACE_TYPE InterfaceType,
  191. IN ULONG BusNumber,
  192. IN PHYSICAL_ADDRESS BusAddress,
  193. IN OUT PULONG AddressSpace,
  194. OUT PPHYSICAL_ADDRESS TranslatedAddress
  195. )
  196. /*++
  197. Routine Description:
  198. This function translates a bus-relative address space and address into
  199. a system physical address.
  200. Arguments:
  201. BusNumber - Supplies the bus number. This is ignored on
  202. standard x86 systems
  203. BusAddress - Supplies the bus-relative address
  204. AddressSpace - Supplies the address space number.
  205. Returns the host address space number.
  206. AddressSpace == 0 => I/O space
  207. AddressSpace == 1 => memory space
  208. TranslatedAddress - Pointer to a physical_address.
  209. Return Value:
  210. System physical address corresponding to the supplied bus relative
  211. address and bus address number.
  212. --*/
  213. {
  214. UNREFERENCED_PARAMETER( InterfaceType );
  215. UNREFERENCED_PARAMETER( BusNumber );
  216. UNREFERENCED_PARAMETER( AddressSpace );
  217. TranslatedAddress->HighPart = 0;
  218. TranslatedAddress->LowPart = BusAddress.LowPart;
  219. return(TRUE);
  220. }
  221. #if defined(NEC_98)
  222. #else
  223. ULONG
  224. HalpGetPosData (
  225. IN ULONG BusNumber,
  226. IN ULONG SlotNumber,
  227. IN PVOID Buffer,
  228. IN ULONG DOffset,
  229. IN ULONG Length
  230. )
  231. /*--
  232. Arguments:
  233. BusDataType - Supplies the type of bus.
  234. BusNumber - Indicates which bus.
  235. Buffer - Supplies the space to store the data.
  236. Length - Supplies a count in bytes of the maximum amount to return.
  237. Return Value:
  238. Returns the amount of data stored into the buffer.
  239. --*/
  240. {
  241. PVOID McaRegisterBase = 0;
  242. ULONG Index = 0;
  243. PUCHAR DataBuffer = Buffer;
  244. ULONG DataLength = 0;
  245. PUCHAR PosBase;
  246. ULONG Offset;
  247. UNREFERENCED_PARAMETER( BusNumber );
  248. if (DOffset != 0 || MachineType != MACHINE_TYPE_MCA) {
  249. return 0;
  250. }
  251. PosBase = (PUCHAR) &((PMCA_CONTROL) McaRegisterBase)->Pos;
  252. //
  253. // Place the specified adapter into setup mode.
  254. //
  255. WRITE_PORT_UCHAR((PVOID) &((PMCA_CONTROL) McaRegisterBase)->AdapterSetup,
  256. (UCHAR) ( MCA_ADAPTER_SETUP_ON | SlotNumber ));
  257. while (DataLength < Length && DataLength < 6) {
  258. DataBuffer[DataLength] = READ_PORT_UCHAR( PosBase + DataLength );
  259. DataLength++;
  260. }
  261. while (DataLength < Length) {
  262. WRITE_PORT_UCHAR((PVOID) &((PPROGRAMMABLE_OPTION_SELECT)
  263. PosBase)->SubaddressExtensionLsb, (UCHAR) Index);
  264. WRITE_PORT_UCHAR((PVOID) &((PPROGRAMMABLE_OPTION_SELECT)
  265. PosBase)->SubaddressExtensionMsb, (UCHAR) (Index >> 8));
  266. DataBuffer[Index + 6] = READ_PORT_UCHAR(
  267. (PVOID) &((PPROGRAMMABLE_OPTION_SELECT)PosBase)->OptionSelectData2);
  268. DataLength++;
  269. if (DataLength < Length) {
  270. Offset = DataLength + ((Length - DataLength) / 2);
  271. DataBuffer[Offset] = READ_PORT_UCHAR(
  272. (PVOID) &((PPROGRAMMABLE_OPTION_SELECT)PosBase)->OptionSelectData3);
  273. DataLength++;
  274. Index++;
  275. }
  276. }
  277. //
  278. // Disable adapter setup.
  279. //
  280. WRITE_PORT_UCHAR((PVOID) &((PMCA_CONTROL) McaRegisterBase)->AdapterSetup,
  281. (UCHAR) ( MCA_ADAPTER_SETUP_OFF ));
  282. return 1;
  283. }
  284. ULONG
  285. HalpGetEisaData (
  286. IN ULONG BusNumber,
  287. IN ULONG SlotNumber,
  288. IN PVOID Buffer,
  289. IN ULONG Offset,
  290. IN ULONG Length
  291. )
  292. /*--
  293. Arguments:
  294. BusDataType - Supplies the type of bus.
  295. BusNumber - Indicates which bus.
  296. Buffer - Supplies the space to store the data.
  297. Length - Supplies a count in bytes of the maximum amount to return.
  298. Return Value:
  299. Returns the amount of data stored into the buffer.
  300. --*/
  301. {
  302. ULONG DataLength = 0;
  303. ULONG i;
  304. ULONG TotalDataSize;
  305. ULONG SlotDataSize = 0;
  306. ULONG PartialCount;
  307. PCONFIGURATION_COMPONENT_DATA ConfigData;
  308. PCM_EISA_SLOT_INFORMATION SlotInformation = NULL;
  309. PCM_PARTIAL_RESOURCE_LIST Descriptor;
  310. PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource;
  311. BOOLEAN Found = FALSE;
  312. UNREFERENCED_PARAMETER( BusNumber );
  313. if (MachineType != MACHINE_TYPE_EISA) {
  314. return 0;
  315. }
  316. ConfigData = KeFindConfigurationEntry(
  317. FwConfigurationTree,
  318. AdapterClass,
  319. EisaAdapter,
  320. NULL
  321. );
  322. if (ConfigData == NULL) {
  323. #if defined(ENABLE_LOADER_EBUG)
  324. DbgPrint("HalGetBusData: KeFindConfigurationEntry failed\n");
  325. #endif
  326. return(0);
  327. }
  328. Descriptor = ConfigData->ConfigurationData;
  329. PartialResource = Descriptor->PartialDescriptors;
  330. PartialCount = Descriptor->Count;
  331. for (i = 0; i < PartialCount; i++) {
  332. //
  333. // Do each partial Resource
  334. //
  335. switch (PartialResource->Type) {
  336. case CmResourceTypeNull:
  337. case CmResourceTypePort:
  338. case CmResourceTypeInterrupt:
  339. case CmResourceTypeMemory:
  340. case CmResourceTypeDma:
  341. //
  342. // We dont care about these.
  343. //
  344. PartialResource++;
  345. break;
  346. case CmResourceTypeDeviceSpecific:
  347. //
  348. // Bingo!
  349. //
  350. TotalDataSize = PartialResource->u.DeviceSpecificData.DataSize;
  351. SlotInformation = (PCM_EISA_SLOT_INFORMATION)
  352. ((PUCHAR)PartialResource +
  353. sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
  354. while (((LONG)TotalDataSize) > 0) {
  355. if (SlotInformation->ReturnCode == EISA_EMPTY_SLOT) {
  356. SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION);
  357. } else {
  358. SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION) +
  359. SlotInformation->NumberFunctions *
  360. sizeof(CM_EISA_FUNCTION_INFORMATION);
  361. }
  362. if (SlotDataSize > TotalDataSize) {
  363. //
  364. // Something is wrong again
  365. //
  366. #if defined(ENABLE_LOADER_EBUG)
  367. DbgPrint("HalGetBusData: SlotDataSize > TotalDataSize\n");
  368. #endif
  369. return(0);
  370. }
  371. if (SlotNumber != 0) {
  372. SlotNumber--;
  373. SlotInformation = (PCM_EISA_SLOT_INFORMATION)
  374. ((PUCHAR)SlotInformation + SlotDataSize);
  375. TotalDataSize -= SlotDataSize;
  376. continue;
  377. }
  378. //
  379. // This is our slot
  380. //
  381. Found = TRUE;
  382. break;
  383. }
  384. //
  385. // End loop
  386. //
  387. i = PartialCount;
  388. break;
  389. default:
  390. #if defined(ENABLE_LOADER_EBUG)
  391. DbgPrint("Bad Data in registry!\n");
  392. #endif
  393. return(0);
  394. }
  395. }
  396. if (Found) {
  397. //
  398. // As a hack if the length is zero then the buffer points to a
  399. // PVOID where the pointer to the data should be stored. This is
  400. // done in the loader because we quickly run out of heap scaning
  401. // all of the EISA configuration data.
  402. //
  403. if (Length == 0) {
  404. //
  405. // Return the pointer to the mini-port driver.
  406. //
  407. *((PVOID *)Buffer) = SlotInformation;
  408. return(SlotDataSize);
  409. }
  410. i = Length + Offset;
  411. if (i > SlotDataSize) {
  412. i = SlotDataSize;
  413. }
  414. DataLength = i - Offset;
  415. RtlMoveMemory(Buffer, ((PUCHAR) SlotInformation + Offset), DataLength);
  416. }
  417. return(DataLength);
  418. }
  419. #endif //NEC_98