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.

292 lines
5.1 KiB

  1. /*++
  2. Module Name:
  3. pmpic.c
  4. Abstract:
  5. This file contains functions that are specific to
  6. the PIC version of the ACPI hal.
  7. Author:
  8. Jake Oshins
  9. Environment:
  10. Kernel mode only.
  11. Revision History:
  12. */
  13. #include "halp.h"
  14. #include "acpitabl.h"
  15. #include "xxacpi.h"
  16. #include "eisa.h"
  17. #include "ixsleep.h"
  18. VOID
  19. HalpAcpiSetTempPicState(
  20. VOID
  21. );
  22. VOID
  23. HalpMaskAcpiInterrupt(
  24. VOID
  25. );
  26. VOID
  27. HalpUnmaskAcpiInterrupt(
  28. VOID
  29. );
  30. extern PVOID HalpEisaControlBase;
  31. #define EISA_CONTROL (PUCHAR)&((PEISA_CONTROL) HalpEisaControlBase)
  32. BOOLEAN HalpPicStateIntact = TRUE;
  33. #ifdef ALLOC_PRAGMA
  34. #pragma alloc_text(PAGELK, HalpAcpiSetTempPicState)
  35. #pragma alloc_text(PAGELK, HalpSetAcpiEdgeLevelRegister)
  36. #pragma alloc_text(PAGELK, HalpAcpiPicStateIntact)
  37. #pragma alloc_text(PAGELK, HalpSaveInterruptControllerState)
  38. #pragma alloc_text(PAGELK, HalpRestoreInterruptControllerState)
  39. #pragma alloc_text(PAGELK, HalpSetInterruptControllerWakeupState)
  40. #pragma alloc_text(PAGELK, HalpPostSleepMP)
  41. #pragma alloc_text(PAGELK, HalpMaskAcpiInterrupt)
  42. #pragma alloc_text(PAGELK, HalpUnmaskAcpiInterrupt)
  43. #pragma alloc_text(PAGE, HaliSetVectorState)
  44. #pragma alloc_text(PAGE, HaliIsVectorValid)
  45. #endif
  46. VOID
  47. HaliSetVectorState(
  48. IN ULONG Vector,
  49. IN ULONG Flags
  50. )
  51. {
  52. return;
  53. }
  54. BOOLEAN
  55. HaliIsVectorValid(
  56. IN ULONG Vector
  57. )
  58. {
  59. if (Vector < 16) {
  60. return TRUE;
  61. }
  62. return FALSE;
  63. }
  64. VOID
  65. HalpAcpiSetTempPicState(
  66. VOID
  67. )
  68. {
  69. ULONG flags;
  70. USHORT picMask;
  71. _asm {
  72. pushfd
  73. pop eax
  74. mov flags, eax
  75. cli
  76. }
  77. HalpInitializePICs(FALSE);
  78. //
  79. // Halacpi lets the PCI interrupt programming be
  80. // dynamic. So...
  81. //
  82. // Unmask only the clock sources on the PIC and the
  83. // ACPI vector. The rest of the vectors will be
  84. // unmasked later, after we have restored PCI IRQ
  85. // routing.
  86. //
  87. picMask = 0xfefe; // mask everything but clocks
  88. //
  89. // Unmask ACPI vector
  90. //
  91. picMask &= ~(1 << (UCHAR)HalpFixedAcpiDescTable.sci_int_vector);
  92. //
  93. // Write the mask into the hardware.
  94. //
  95. WRITE_PORT_UCHAR(EISA_CONTROL->Interrupt1ControlPort1,
  96. (UCHAR)(picMask & 0xff));
  97. WRITE_PORT_UCHAR(EISA_CONTROL->Interrupt2ControlPort1,
  98. (UCHAR)((picMask >> 8) & 0xff));
  99. //
  100. // For now, set the edge-level control register
  101. // so that all vectors are edge except the
  102. // ACPI vector. This is done because the PIC
  103. // will trigger if an idle ISA vector is set to
  104. // edge. After the ACPI driver resets all the
  105. // PCI vectors to what we thought they should be,
  106. //
  107. HalpSetAcpiEdgeLevelRegister();
  108. HalpPicStateIntact = FALSE;
  109. _asm {
  110. mov eax, flags
  111. push eax
  112. popfd
  113. }
  114. }
  115. VOID
  116. HalpSetAcpiEdgeLevelRegister(
  117. VOID
  118. )
  119. {
  120. USHORT elcr;
  121. //
  122. // The idea here is to set the ELCR so that only the ACPI
  123. // vector is set to 'level.' That way we can reprogram
  124. // the PCI interrupt router without worrying that the
  125. // PIC will start triggering endless interrupts because
  126. // we have a source programmed to level that is being
  127. // routed to the ISA bus.
  128. //
  129. if (HalpFixedAcpiDescTable.sci_int_vector < PIC_VECTORS) {
  130. elcr = 1 << HalpFixedAcpiDescTable.sci_int_vector;
  131. WRITE_PORT_UCHAR(EISA_CONTROL->Interrupt1EdgeLevel,
  132. (UCHAR)(elcr & 0xff));
  133. WRITE_PORT_UCHAR(EISA_CONTROL->Interrupt2EdgeLevel,
  134. (UCHAR)(elcr >> 8));
  135. }
  136. }
  137. VOID
  138. HalpRestoreInterruptControllerState(
  139. VOID
  140. )
  141. {
  142. ULONG flags;
  143. USHORT picMask;
  144. _asm {
  145. pushfd
  146. pop eax
  147. mov flags, eax
  148. cli
  149. }
  150. //
  151. // This function is called after PCI interrupt routing has
  152. // been restored.
  153. //
  154. WRITE_PORT_UCHAR(EISA_CONTROL->Interrupt1ControlPort1,
  155. HalpMotherboardState.PicState.MasterMask);
  156. WRITE_PORT_UCHAR(EISA_CONTROL->Interrupt2ControlPort1,
  157. HalpMotherboardState.PicState.SlaveMask);
  158. HalpRestorePicEdgeLevelRegister();
  159. HalpPicStateIntact = TRUE;
  160. _asm {
  161. mov eax, flags
  162. push eax
  163. popfd
  164. }
  165. }
  166. BOOLEAN
  167. HalpAcpiPicStateIntact(
  168. VOID
  169. )
  170. {
  171. return HalpPicStateIntact;
  172. }
  173. VOID
  174. HalpSaveInterruptControllerState(
  175. VOID
  176. )
  177. {
  178. HalpSavePicState();
  179. }
  180. VOID
  181. HalpSetInterruptControllerWakeupState(
  182. ULONG Context
  183. )
  184. {
  185. HalpAcpiSetTempPicState();
  186. }
  187. VOID
  188. HalpPostSleepMP(
  189. IN LONG NumberProcessors,
  190. IN volatile PLONG Number
  191. )
  192. {
  193. }
  194. VOID
  195. HalpMaskAcpiInterrupt(
  196. VOID
  197. )
  198. {
  199. }
  200. VOID
  201. HalpUnmaskAcpiInterrupt(
  202. VOID
  203. )
  204. {
  205. }
  206. #if DBG
  207. NTSTATUS
  208. HalpGetApicIdByProcessorNumber(
  209. IN UCHAR Processor,
  210. IN OUT USHORT *ApicId
  211. )
  212. /*++
  213. Routine Description:
  214. This routine only exists on DEBUG builds of the PIC ACPI HAL because
  215. that HAL is build MP and the SRAT code will be included. The SRAT
  216. code will not be exercised but needs this routine in order to link.
  217. Arguments:
  218. Ignored.
  219. Return Value:
  220. STATUS_NOT_FOUND
  221. --*/
  222. {
  223. return STATUS_NOT_FOUND;
  224. }
  225. #endif