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.

471 lines
11 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. spsysbus.c
  5. Abstract:
  6. Author:
  7. Environment:
  8. Revision History:
  9. --*/
  10. #include "halp.h"
  11. #include "spmp.inc"
  12. ULONG HalpDefaultInterruptAffinity;
  13. ULONG HalpCpuCount;
  14. BOOLEAN
  15. HalpTranslateSystemBusAddress(
  16. IN PBUS_HANDLER BusHandler,
  17. IN PBUS_HANDLER RootHandler,
  18. IN PHYSICAL_ADDRESS BusAddress,
  19. IN OUT PULONG AddressSpace,
  20. OUT PPHYSICAL_ADDRESS TranslatedAddress
  21. );
  22. ULONG
  23. HalpGetSystemInterruptVector(
  24. IN PBUS_HANDLER BusHandler,
  25. IN PBUS_HANDLER RootHandler,
  26. IN ULONG BusInterruptLevel,
  27. IN ULONG BusInterruptVector,
  28. OUT PKIRQL Irql,
  29. OUT PKAFFINITY Affinity
  30. );
  31. #ifdef ALLOC_PRAGMA
  32. #pragma alloc_text(PAGE,HalpGetSystemInterruptVector)
  33. #pragma alloc_text(PAGE,HalTranslatorReference)
  34. #pragma alloc_text(PAGE,HalTranslatorDereference)
  35. #pragma alloc_text(PAGE,HalIrqTranslateResourcesRoot)
  36. #pragma alloc_text(PAGE,HalIrqTranslateResourceRequirementsRoot)
  37. #pragma alloc_text(PAGE,HalpTransMemIoResource)
  38. #pragma alloc_text(PAGE,HalpTransMemIoResourceRequirement)
  39. #endif
  40. extern UCHAR SpCpuCount;
  41. extern Sp8259PerProcessorMode;
  42. extern UCHAR RegisteredProcessorCount;
  43. BOOLEAN
  44. HalpTranslateSystemBusAddress(
  45. IN PBUS_HANDLER BusHandler,
  46. IN PBUS_HANDLER RootHandler,
  47. IN PHYSICAL_ADDRESS BusAddress,
  48. IN OUT PULONG AddressSpace,
  49. OUT PPHYSICAL_ADDRESS TranslatedAddress
  50. )
  51. /*++
  52. Routine Description:
  53. This function translates a bus-relative address space and address into
  54. a system physical address.
  55. Arguments:
  56. BusAddress - Supplies the bus-relative address
  57. AddressSpace - Supplies the address space number.
  58. Returns the host address space number.
  59. AddressSpace == 0 => memory space
  60. AddressSpace == 1 => I/O space
  61. TranslatedAddress - Supplies a pointer to return the translated address
  62. Return Value:
  63. A return value of TRUE indicates that a system physical address
  64. corresponding to the supplied bus relative address and bus address
  65. number has been returned in TranslatedAddress.
  66. A return value of FALSE occurs if the translation for the address was
  67. not possible
  68. --*/
  69. {
  70. PSUPPORTED_RANGE pRange;
  71. pRange = NULL;
  72. switch (*AddressSpace) {
  73. case 0:
  74. // verify memory address is within buses memory limits
  75. for (pRange = &BusHandler->BusAddresses->PrefetchMemory; pRange; pRange = pRange->Next) {
  76. if (BusAddress.QuadPart >= pRange->Base &&
  77. BusAddress.QuadPart <= pRange->Limit) {
  78. break;
  79. }
  80. }
  81. if (!pRange) {
  82. for (pRange = &BusHandler->BusAddresses->Memory; pRange; pRange = pRange->Next) {
  83. if (BusAddress.QuadPart >= pRange->Base &&
  84. BusAddress.QuadPart <= pRange->Limit) {
  85. break;
  86. }
  87. }
  88. }
  89. break;
  90. case 1:
  91. // verify IO address is within buses IO limits
  92. for (pRange = &BusHandler->BusAddresses->IO; pRange; pRange = pRange->Next) {
  93. if (BusAddress.QuadPart >= pRange->Base &&
  94. BusAddress.QuadPart <= pRange->Limit) {
  95. break;
  96. }
  97. }
  98. break;
  99. }
  100. if (pRange) {
  101. TranslatedAddress->QuadPart = BusAddress.QuadPart + pRange->SystemBase;
  102. *AddressSpace = pRange->SystemAddressSpace;
  103. return TRUE;
  104. }
  105. return FALSE;
  106. }
  107. ULONG
  108. HalpGetSystemInterruptVector(
  109. IN PBUS_HANDLER BusHandler,
  110. IN PBUS_HANDLER RootHandler,
  111. IN ULONG BusInterruptLevel,
  112. IN ULONG BusInterruptVector,
  113. OUT PKIRQL pIrql,
  114. OUT PKAFFINITY pAffinity
  115. )
  116. /*++
  117. Routine Description:
  118. Arguments:
  119. BusInterruptLevel - Supplies the bus specific interrupt level.
  120. BusInterruptVector - Supplies the bus specific interrupt vector.
  121. Irql - Returns the system request priority.
  122. Affinity - Returns the system wide irq affinity.
  123. Return Value:
  124. Returns the system interrupt vector corresponding to the specified device.
  125. --*/
  126. {
  127. ULONG SystemVector;
  128. ULONG Cpu;
  129. ULONG Affinity;
  130. KIRQL Irql;
  131. UNREFERENCED_PARAMETER( BusHandler );
  132. UNREFERENCED_PARAMETER( RootHandler );
  133. UNREFERENCED_PARAMETER( BusInterruptVector );
  134. //
  135. // Set default SystemVector, IRQL & CPU
  136. //
  137. SystemVector = BusInterruptLevel + PRIMARY_VECTOR_BASE;
  138. Irql = (KIRQL)(HIGHEST_LEVEL_FOR_8259 + PRIMARY_VECTOR_BASE - SystemVector);
  139. Cpu = 0;
  140. if (SystemVector < PRIMARY_VECTOR_BASE ||
  141. SystemVector > PRIMARY_VECTOR_BASE + HIGHEST_LEVEL_FOR_8259 ||
  142. HalpIDTUsageFlags[SystemVector].Flags & IDTOwned ) {
  143. //
  144. // This is an illegal BusInterruptVector and cannot be connected.
  145. //
  146. return(0);
  147. }
  148. //
  149. // If this is machine has reported SMP Dev Ints then lets
  150. // use them in a static interrupt distribution method.
  151. // Notice some devices are kept on P0 for compatibility.
  152. // These interrupts and their devices are not generally used
  153. // for steady state operations.
  154. //
  155. if (Sp8259PerProcessorMode & SP_SMPDEVINTS) {
  156. //
  157. // This is for overriding some devices that belong on P0.
  158. //
  159. switch (BusInterruptLevel) {
  160. case 1: // keyboard
  161. case 3: // com2
  162. case 4: // com1
  163. case 5: // SysMgmt Modem
  164. case 6: // floppy
  165. case 12: // mouse
  166. // use first cpu
  167. break;
  168. case 13: // Health (IPIs on all)
  169. // use first cpu, as:
  170. Irql = IPI_LEVEL;
  171. SystemVector = PRIMARY_VECTOR_BASE + SECOND_IPI_DISPATCH;
  172. break;
  173. default:
  174. Cpu = SystemVector % HalpCpuCount;
  175. break;
  176. }
  177. }
  178. //
  179. // Get Affinity for Cpu
  180. //
  181. Affinity = 1 << Cpu;
  182. ASSERT (Affinity);
  183. //
  184. // Done
  185. //
  186. *pAffinity = Affinity;
  187. *pIrql = Irql;
  188. return SystemVector;
  189. }
  190. NTSTATUS
  191. HalIrqTranslateResourceRequirementsRoot(
  192. IN PVOID Context,
  193. IN PIO_RESOURCE_DESCRIPTOR Source,
  194. IN PDEVICE_OBJECT PhysicalDeviceObject,
  195. OUT PULONG TargetCount,
  196. OUT PIO_RESOURCE_DESCRIPTOR *Target
  197. )
  198. /*++
  199. Routine Description:
  200. This function takes an IO_RESOURCE_DESCRIPTOR and translates
  201. it from an IO-bus-relative to a Processor-bus-relative form. In this
  202. x86-specific example, an IO-bus-relative form is the ISA IRQ and the
  203. Processor-bus-relative form is the IDT entry and the associated IRQL.
  204. This is essentially a PnP form of HalGetInterruptVector.
  205. Arguments:
  206. Context - unused
  207. Source - descriptor that we are translating
  208. PhysicalDeviceObject- unused
  209. TargetCount - 1
  210. Target - translated descriptor
  211. Return Value:
  212. status
  213. --*/
  214. {
  215. return STATUS_NOT_IMPLEMENTED;
  216. }
  217. NTSTATUS
  218. HalIrqTranslateResourcesRoot(
  219. IN PVOID Context,
  220. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
  221. IN RESOURCE_TRANSLATION_DIRECTION Direction,
  222. IN ULONG AlternativesCount, OPTIONAL
  223. IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
  224. IN PDEVICE_OBJECT PhysicalDeviceObject,
  225. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
  226. )
  227. {
  228. return STATUS_NOT_IMPLEMENTED;
  229. }
  230. NTSTATUS
  231. HalpTransMemIoResourceRequirement(
  232. IN PVOID Context,
  233. IN PIO_RESOURCE_DESCRIPTOR Source,
  234. IN PDEVICE_OBJECT PhysicalDeviceObject,
  235. OUT PULONG TargetCount,
  236. OUT PIO_RESOURCE_DESCRIPTOR *Target
  237. )
  238. /*++
  239. Routine Description:
  240. This routine translates memory and IO resource requirements.
  241. Parameters:
  242. Context - The context from the TRANSLATOR_INTERFACE
  243. Source - The interrupt requirement to translate
  244. PhysicalDeviceObject - The device requesting the resource
  245. TargetCount - Pointer to where to return the number of descriptors this
  246. requirement translates into
  247. Target - Pointer to where a pointer to a callee allocated buffer containing
  248. the translated descriptors should be placed.
  249. Return Value:
  250. STATUS_SUCCESS or an error status
  251. Note:
  252. We do not perform any translation.
  253. --*/
  254. {
  255. ASSERT(Source);
  256. ASSERT(Target);
  257. ASSERT(TargetCount);
  258. ASSERT(Source->Type == CmResourceTypeMemory ||
  259. Source->Type == CmResourceTypePort);
  260. //
  261. // Allocate space for the target
  262. //
  263. *Target = ExAllocatePoolWithTag(PagedPool,
  264. sizeof(IO_RESOURCE_DESCRIPTOR),
  265. ' laH');
  266. if (!*Target) {
  267. return STATUS_INSUFFICIENT_RESOURCES;
  268. }
  269. //
  270. // Copy the source to target and update the fields that have changed
  271. //
  272. **Target = *Source;
  273. *TargetCount = 1;
  274. return STATUS_SUCCESS;
  275. }
  276. NTSTATUS
  277. HalpTransMemIoResource(
  278. IN PVOID Context,
  279. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
  280. IN RESOURCE_TRANSLATION_DIRECTION Direction,
  281. IN ULONG AlternativesCount, OPTIONAL
  282. IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
  283. IN PDEVICE_OBJECT PhysicalDeviceObject,
  284. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
  285. )
  286. /*++
  287. Routine Description:
  288. This routine translates memory and IO resources. On generic x86
  289. machines, such as those that use this HAL, there isn't actually
  290. any translation.
  291. Parameters:
  292. Context - The context from the TRANSLATOR_INTERFACE
  293. Source - The interrupt resource to translate
  294. Direction - The direction in relation to the Pnp device tree translation
  295. should occur in.
  296. AlternativesCount - The number of alternatives this resource was selected
  297. from.
  298. Alternatives - Array of alternatives this resource was selected from.
  299. PhysicalDeviceObject - The device requesting the resource
  300. Target - Pointer to a caller allocated buffer to hold the translted resource
  301. descriptor.
  302. Return Value:
  303. STATUS_SUCCESS or an error status
  304. --*/
  305. {
  306. NTSTATUS status;
  307. //
  308. // Copy the target to the source
  309. //
  310. *Target = *Source;
  311. switch (Direction) {
  312. case TranslateChildToParent:
  313. //
  314. // Make sure PnP knows it doesn't have to walk up the tree
  315. // translating at each point.
  316. //
  317. status = STATUS_TRANSLATION_COMPLETE;
  318. break;
  319. case TranslateParentToChild:
  320. //
  321. // We do not translate requirements so do nothing...
  322. //
  323. status = STATUS_SUCCESS;
  324. break;
  325. default:
  326. status = STATUS_INVALID_PARAMETER;
  327. }
  328. return status;
  329. }
  330. VOID
  331. HalTranslatorReference(
  332. PVOID Context
  333. )
  334. {
  335. return;
  336. }
  337. VOID
  338. HalTranslatorDereference(
  339. PVOID Context
  340. )
  341. {
  342. return;
  343. }