Windows NT 4.0 source code leak
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.

385 lines
10 KiB

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