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.

393 lines
11 KiB

  1. ;++
  2. ;
  3. ;Copyright (c) 1991 Microsoft Corporation
  4. ;
  5. ;Module Name:
  6. ;
  7. ; spsysint.asm
  8. ;
  9. ;Abstract:
  10. ;
  11. ; This module implements the HAL routines to enable/disable system
  12. ; interrupts, for the MP systempro implementation
  13. ;
  14. ;Author:
  15. ;
  16. ; John Vert (jvert) 22-Jul-1991
  17. ;
  18. ;Environment:
  19. ;
  20. ; Kernel Mode
  21. ;
  22. ;Revision History:
  23. ;
  24. ;--
  25. .386p
  26. .xlist
  27. include hal386.inc
  28. include callconv.inc ; calling convention macros
  29. include i386\ix8259.inc
  30. include i386\kimacro.inc
  31. include mac386.inc
  32. include i386\spmp.inc
  33. .list
  34. extrn KiI8259MaskTable:DWORD
  35. EXTRNP _KeBugCheck,1,IMPORT
  36. ;
  37. ; Constants used to initialize CMOS/Real Time Clock
  38. ;
  39. CMOS_CONTROL_PORT EQU 70h ; command port for cmos
  40. CMOS_DATA_PORT EQU 71h ; cmos data port
  41. ;
  42. ; Macros to Read/Write/Reset CMOS to initialize RTC
  43. ;
  44. ; CMOS_READ
  45. ;
  46. ; Description: This macro read a byte from the CMOS register specified
  47. ; in (AL).
  48. ;
  49. ; Parameter: (AL) = address/register to read
  50. ; Return: (AL) = data
  51. ;
  52. CMOS_READ MACRO
  53. OUT CMOS_CONTROL_PORT,al ; ADDRESS LOCATION AND DISABLE NMI
  54. IODelay ; I/O DELAY
  55. IN AL,CMOS_DATA_PORT ; READ IN REQUESTED CMOS DATA
  56. IODelay ; I/O DELAY
  57. ENDM
  58. _DATA SEGMENT DWORD PUBLIC 'DATA'
  59. align dword
  60. ;
  61. ; HalDismissSystemInterrupt does an indirect jump through this table so it
  62. ; can quickly execute specific code for different interrupts.
  63. ;
  64. public HalpSpecialDismissTable
  65. HalpSpecialDismissTable label dword
  66. dd offset FLAT:HalpDismissNormal ; irq 0
  67. dd offset FLAT:HalpDismissNormal ; irq 1
  68. dd offset FLAT:HalpDismissNormal ; irq 2
  69. dd offset FLAT:HalpDismissNormal ; irq 3
  70. dd offset FLAT:HalpDismissNormal ; irq 4
  71. dd offset FLAT:HalpDismissNormal ; irq 5
  72. dd offset FLAT:HalpDismissNormal ; irq 6
  73. dd offset FLAT:HalpDismissIrq07 ; irq 7
  74. dd offset FLAT:HalpDismissNormal ; irq 8
  75. dd offset FLAT:HalpDismissNormal ; irq 9
  76. dd offset FLAT:HalpDismissNormal ; irq A
  77. dd offset FLAT:HalpDismissNormal ; irq B
  78. dd offset FLAT:HalpDismissNormal ; irq C
  79. dd offset FLAT:HalpDismissNormal ; irq D
  80. dd offset FLAT:HalpDismissNormal ; irq E
  81. dd offset FLAT:HalpDismissIrq0f ; irq F
  82. dd offset FLAT:HalpDismissNormal ; irq 10
  83. dd offset FLAT:HalpDismissNormal ; irq 11
  84. dd offset FLAT:HalpDismissNormal ; irq 12
  85. dd offset FLAT:HalpDismissNormal ; irq 13
  86. dd offset FLAT:HalpDismissNormal ; irq 14
  87. dd offset FLAT:HalpDismissNormal ; irq 15
  88. dd offset FLAT:HalpDismissNormal ; irq 16
  89. dd offset FLAT:HalpDismissNormal ; irq 17
  90. dd offset FLAT:HalpDismissNormal ; irq 18
  91. dd offset FLAT:HalpDismissNormal ; irq 19
  92. dd offset FLAT:HalpDismissNormal ; irq 1A
  93. dd offset FLAT:HalpDismissNormal ; irq 1B
  94. dd offset FLAT:HalpDismissNormal ; irq 1C
  95. dd offset FLAT:HalpDismissNormal ; irq 1D
  96. dd offset FLAT:HalpDismissNormal ; irq 1E
  97. dd offset FLAT:HalpDismissNormal ; irq 1F
  98. dd offset FLAT:HalpDismissNormal ; irq 20
  99. dd offset FLAT:HalpDismissNormal ; irq 21
  100. dd offset FLAT:HalpDismissNormal ; irq 22
  101. dd offset FLAT:HalpDismissNormal ; irq 23
  102. dd offset FLAT:HalpDispatch ; irq 24 - 2nd level dispatch from ipi
  103. _DATA ENDS
  104. _TEXT SEGMENT DWORD PUBLIC 'CODE'
  105. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  106. ;++
  107. ;BOOLEAN
  108. ;HalBeginSystemInterrupt(
  109. ; IN KIRQL Irql
  110. ; IN CCHAR Vector,
  111. ; OUT PKIRQL OldIrql
  112. ; )
  113. ;
  114. ;
  115. ;
  116. ;Routine Description:
  117. ;
  118. ; This routine is used to dismiss the specified vector number. It is called
  119. ; before any interrupt service routine code is executed.
  120. ;
  121. ; N.B. This routine does NOT preserve EAX or EBX
  122. ;
  123. ; On the SystemPro, since all interrupt go to P0, HalBeing/EndSystem-
  124. ; Interrupt are treated very much like the UP case. All calls to this
  125. ; function will occur from P0.
  126. ;
  127. ;Arguments:
  128. ;
  129. ; Irql - Supplies the IRQL to raise to
  130. ;
  131. ; Vector - Supplies the vector of the interrupt to be dismissed
  132. ;
  133. ; OldIrql- Location to return OldIrql
  134. ;
  135. ;
  136. ;Return Value:
  137. ;
  138. ; FALSE - Interrupt is spurious and should be ignored
  139. ;
  140. ; TRUE - Interrupt successfully dismissed and Irql raised.
  141. ;
  142. ;--
  143. align dword
  144. HbsiIrql equ byte ptr [esp+4]
  145. HbsiVector equ byte ptr [esp+8]
  146. HbsiOldIrql equ dword ptr [esp+12]
  147. cPublicProc _HalBeginSystemInterrupt ,3
  148. mov ebx, dword ptr HbsiVector ; (ebx) = System Vector
  149. sub ebx, PRIMARY_VECTOR_BASE ; (ebx) = 8259 IRQ #
  150. cmp ebx, 25h ; Interrupt in table?
  151. jnc hbsi00 ; no go handle
  152. jmp HalpSpecialDismissTable[ebx*4]
  153. hbsi00:
  154. ;
  155. ; Interrupt is out of range. There's no EOI here since it wouldn't
  156. ; have been out of range if it occured on either interrupt controller
  157. ; which is known about.
  158. ;
  159. xor eax,eax ; return FALSE
  160. stdRET _HalBeginSystemInterrupt
  161. align 4
  162. HalpDismissIrq0f:
  163. ;
  164. ; Check to see if this is a spurious interrupt
  165. ;
  166. mov al, OCW3_READ_ISR ; tell 8259 we want to read ISR
  167. out PIC2_PORT0, al
  168. IODelay ; delay
  169. in al, PIC2_PORT0 ; (al) = content of PIC 1 ISR
  170. test al, 10000000B ; Is In-Service register set?
  171. jnz short HalpDismissNormal ; No, this is NOT a spurious int,
  172. ; go do the normal interrupt stuff
  173. ;
  174. ; This is a spurious interrupt.
  175. ; Because the slave PIC is cascaded to irq2 of master PIC, we need to
  176. ; dismiss the interupt on master PIC's irq2.
  177. ;
  178. mov al, PIC2_EOI ; Specific eoi to master for pic2 eoi
  179. out PIC1_PORT0, al ; send irq2 specific eoi to master
  180. xor eax,eax ; return FALSE
  181. stdRET _HalBeginSystemInterrupt
  182. align 4
  183. HalpDismissIrq07:
  184. ;
  185. ; Check to see if this is a spurious interrupt
  186. ;
  187. mov al, OCW3_READ_ISR ; tell 8259 we want to read ISR
  188. out PIC1_PORT0, al
  189. IODelay ; delay
  190. in al, PIC1_PORT0 ; (al) = content of PIC 1 ISR
  191. test al, 10000000B ; Is In-Service register set?
  192. jnz short HalpDismissNormal ; No, so this is NOT a spurious int
  193. xor eax, eax ; return FALSE
  194. stdRET _HalBeginSystemInterrupt
  195. align 4
  196. HalpDismissNormal:
  197. ;
  198. ; Store OldIrql
  199. ;
  200. mov eax, HbsiOldIrql
  201. mov cl, fs:PcIrql
  202. mov byte ptr [eax], cl
  203. ;
  204. ; Raise IRQL to requested level
  205. ;
  206. xor eax, eax
  207. mov al, HbsiIrql ; (eax) = irql
  208. ; (ebx) = IRQ #
  209. mov fs:PcIrql, al ; set new Irql
  210. mov eax, KiI8259MaskTable[eax*4] ; get 8259's masks
  211. or eax, fs:PcIDR ; mask disabled irqs
  212. SET_8259_MASK ; send mask to 8259s
  213. ;
  214. ; Dismiss interrupt. Current interrupt is already masked off.
  215. ;
  216. mov eax, ebx ; (eax) = IRQ #
  217. cmp eax, 8 ; EOI to master or slave?
  218. jae short Hbsi100 ; EIO to both master and slave
  219. or al, PIC1_EOI_MASK ; create specific eoi mask for master
  220. out PIC1_PORT0, al ; dismiss the interrupt
  221. jmp short Hbsi200 ; IO delay
  222. align 4
  223. Hbsi100:
  224. mov al, OCW2_NON_SPECIFIC_EOI ; send non specific eoi to slave
  225. out PIC2_PORT0, al
  226. mov al, PIC2_EOI ; specific eoi to master for pic2 eoi
  227. out PIC1_PORT0, al ; send irq2 specific eoi to master
  228. align 4
  229. Hbsi200:
  230. PIC1DELAY
  231. HalpDispatch:
  232. sti
  233. mov eax, 1 ; return TRUE, interrupt dismissed
  234. stdRET _HalBeginSystemInterrupt
  235. stdENDP _HalBeginSystemInterrupt
  236. ;++
  237. ;VOID
  238. ;HalDisableSystemInterrupt(
  239. ; IN CCHAR Vector,
  240. ; IN KIRQL Irql
  241. ; )
  242. ;
  243. ;
  244. ;
  245. ;Routine Description:
  246. ;
  247. ; Disables a system interrupt.
  248. ;
  249. ;Arguments:
  250. ;
  251. ; Vector - Supplies the vector of the interrupt to be disabled
  252. ;
  253. ; Irql - Supplies the interrupt level of the interrupt to be disabled
  254. ;
  255. ;Return Value:
  256. ;
  257. ; None.
  258. ;
  259. ;--
  260. cPublicProc _HalDisableSystemInterrupt ,2
  261. ;
  262. movzx ecx, byte ptr [esp+4] ; (ecx) = Vector
  263. sub ecx, PRIMARY_VECTOR_BASE ; (ecx) = 8259 irq #
  264. mov edx, 1
  265. shl edx, cl ; (ebx) = bit in IMR to disable
  266. cli
  267. or fs:PcIDR, edx
  268. xor eax, eax
  269. ;
  270. ; Get the current interrupt mask register from the 8259
  271. ;
  272. in al, PIC2_PORT1
  273. shl eax, 8
  274. in al, PIC1_PORT1
  275. ;
  276. ; Mask off the interrupt to be disabled
  277. ;
  278. or eax, edx
  279. ;
  280. ; Write the new interrupt mask register back to the 8259
  281. ;
  282. out PIC1_PORT1, al
  283. shr eax, 8
  284. out PIC2_PORT1, al
  285. PIC2DELAY
  286. sti
  287. stdRET _HalDisableSystemInterrupt
  288. stdENDP _HalDisableSystemInterrupt
  289. ;++
  290. ;
  291. ;BOOLEAN
  292. ;HalEnableSystemInterrupt(
  293. ; IN ULONG Vector,
  294. ; IN KIRQL Irql,
  295. ; IN KINTERRUPT_MODE InterruptMode
  296. ; )
  297. ;
  298. ;
  299. ;Routine Description:
  300. ;
  301. ; Enables a system interrupt
  302. ;
  303. ;Arguments:
  304. ;
  305. ; Vector - Supplies the vector of the interrupt to be enabled
  306. ;
  307. ; Irql - Supplies the interrupt level of the interrupt to be enabled.
  308. ;
  309. ;Return Value:
  310. ;
  311. ; None.
  312. ;
  313. ;--
  314. cPublicProc _HalEnableSystemInterrupt ,3
  315. mov ecx, dword ptr [esp+4] ; (ecx) = vector
  316. sub ecx, PRIMARY_VECTOR_BASE
  317. jc hes_error
  318. cmp ecx, CLOCK2_LEVEL
  319. jnc hes_error
  320. mov eax, 1
  321. shl eax, cl ; (ebx) = bit in IMR to enable
  322. not eax
  323. pushfd
  324. cli
  325. and fs:PcIDR, eax
  326. ;
  327. ; Get the PIC masks for the current Irql
  328. ;
  329. movzx eax, byte ptr fs:PcIrql
  330. mov eax, KiI8259MaskTable[eax*4]
  331. or eax, fs:PcIDR
  332. ;
  333. ; Write the new interrupt mask register back to the 8259
  334. ;
  335. SET_8259_MASK
  336. popfd
  337. mov eax, 1 ; return TRUE
  338. stdRET _HalEnableSystemInterrupt
  339. hes_error:
  340. if DBG
  341. int 3
  342. endif
  343. xor eax, eax ; FALSE
  344. stdRET _HalEnableSystemInterrupt
  345. stdENDP _HalEnableSystemInterrupt
  346. _TEXT ENDS
  347. END