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.

327 lines
7.1 KiB

  1. title "Software Interrupts"
  2. ;++
  3. ;
  4. ; Copyright (c) 1992 Microsoft Corporation
  5. ;
  6. ; Module Name:
  7. ;
  8. ; ixswint.asm
  9. ;
  10. ; Abstract:
  11. ;
  12. ; This module implements the software interrupt handlers
  13. ; for x86 machines
  14. ;
  15. ; Author:
  16. ;
  17. ; John Vert (jvert) 2-Jan-1992
  18. ;
  19. ; Environment:
  20. ;
  21. ; Kernel mode only.
  22. ;
  23. ; Revision History:
  24. ;
  25. ;--
  26. .386p
  27. .xlist
  28. include hal386.inc
  29. include callconv.inc ; calling convention macros
  30. include i386\ix8259.inc
  31. include i386\kimacro.inc
  32. .list
  33. EXTRNP _KiDeliverApc,3,IMPORT
  34. EXTRNP _KiDispatchInterrupt,0,IMPORT
  35. EXTRNP Kei386EoiHelper,0,IMPORT
  36. EXTRNP _HalEndSystemInterrupt,2
  37. extrn SWInterruptHandlerTable:dword
  38. extrn SWInterruptLookUpTable:byte
  39. ifdef IRQL_METRICS
  40. extrn HalApcSoftwareIntCount:dword
  41. extrn HalDpcSoftwareIntCount:dword
  42. endif
  43. _TEXT$02 SEGMENT DWORD PUBLIC 'CODE'
  44. ASSUME DS:FLAT, ES:FLAT, SS:FLAT, FS:NOTHING, GS:NOTHING
  45. page ,132
  46. subttl "Request Software Interrupt"
  47. ;++
  48. ;
  49. ; VOID
  50. ; HalRequestSoftwareInterrupt (
  51. ; IN KIRQL RequestIrql
  52. ; )
  53. ;
  54. ; Routine Description:
  55. ;
  56. ; This routine is used to request a software interrupt to the
  57. ; system. Also, this routine checks to see if any software
  58. ; interrupt should be generated.
  59. ; The following condition will cause software interrupt to
  60. ; be simulated:
  61. ; any software interrupt which has higher priority than
  62. ; current IRQL's is pending.
  63. ;
  64. ; NOTE: This routine simulates software interrupt as long as
  65. ; any pending SW interrupt level is higher than the current
  66. ; IRQL, even when interrupts are disabled.
  67. ;
  68. ; Arguments:
  69. ;
  70. ; (cl) = RequestIrql - Supplies the request IRQL value
  71. ;
  72. ; Return Value:
  73. ;
  74. ; None.
  75. ;
  76. ;--
  77. cPublicFastCall HalRequestSoftwareInterrupt ,1
  78. cPublicFpo 0, 1
  79. mov eax,1
  80. shl eax, cl ; convert to mask
  81. pushfd ; save interrupt mode
  82. cli ; disable interrupt
  83. or PCR[PcIRR], eax ; set the request bit
  84. mov cl, PCR[PcIrql] ; get current IRQL
  85. mov eax, PCR[PcIRR] ; get SW interrupt request register
  86. and eax, 3 ; mask off pending HW interrupts
  87. xor edx, edx
  88. mov dl, SWInterruptLookUpTable[eax] ; get the highest pending
  89. ; software interrupt level
  90. cmp dl, cl ; Is highest SW int level > irql?
  91. jbe short KsiExit ; No, jmp ksiexit
  92. call SWInterruptHandlerTable[edx*4] ; yes, simulate interrupt
  93. ; to the appropriate handler
  94. KsiExit:
  95. popfd ; restore original interrupt mode
  96. fstRET HalRequestSoftwareInterrupt
  97. fstENDP HalRequestSoftwareInterrupt
  98. page ,132
  99. subttl "Request Software Interrupt"
  100. ;++
  101. ;
  102. ; VOID
  103. ; HalClearSoftwareInterrupt (
  104. ; IN KIRQL RequestIrql
  105. ; )
  106. ;
  107. ; Routine Description:
  108. ;
  109. ; This routine is used to clear a possible pending software interrupt.
  110. ; Support for this function is optional, and allows the kernel to
  111. ; reduce the number of spurious software interrupts it receives/
  112. ;
  113. ; Arguments:
  114. ;
  115. ; (cl) = RequestIrql - Supplies the request IRQL value
  116. ;
  117. ; Return Value:
  118. ;
  119. ; None.
  120. ;
  121. ;--
  122. cPublicFastCall HalClearSoftwareInterrupt ,1
  123. cPublicFpo 0, 0
  124. mov eax,1
  125. shl eax, cl ; convert to mask
  126. not eax
  127. and PCR[PcIRR], eax ; clear pending irr bit
  128. fstRET HalClearSoftwareInterrupt
  129. fstENDP HalClearSoftwareInterrupt
  130. page ,132
  131. subttl "Dispatch Interrupt"
  132. ;++
  133. ;
  134. ; VOID
  135. ; HalpDispatchInterrupt(
  136. ; VOID
  137. ; );
  138. ;
  139. ; Routine Description:
  140. ;
  141. ; This routine is the interrupt handler for a software interrupt generated
  142. ; at DISPATCH_LEVEL. Its function is to save the machine state, raise
  143. ; Irql to DISPATCH_LEVEL, dismiss the interrupt, and call the DPC
  144. ; delivery routine.
  145. ;
  146. ; Arguments:
  147. ;
  148. ; None
  149. ; Interrupt is disabled
  150. ;
  151. ; Return Value:
  152. ;
  153. ; None.
  154. ;
  155. ;--
  156. ENTER_DR_ASSIST hdpi_a, hdpi_t
  157. align dword
  158. public _HalpDispatchInterrupt
  159. _HalpDispatchInterrupt proc
  160. ifdef IRQL_METRICS
  161. lock inc HalDpcSoftwareIntCount
  162. endif
  163. ;
  164. ; Create IRET frame on stack
  165. ;
  166. pop eax
  167. pushfd
  168. push cs
  169. push eax
  170. ;
  171. ; Save machine state on trap frame
  172. ;
  173. ENTER_INTERRUPT hdpi_a, hdpi_t
  174. .FPO ( FPO_LOCALS+1, 0, 0, 0, 0, FPO_TRAPFRAME )
  175. public _HalpDispatchInterrupt2ndEntry
  176. _HalpDispatchInterrupt2ndEntry:
  177. ; Save previous IRQL and set new priority level
  178. push PCR[PcIrql] ; save previous IRQL
  179. mov byte ptr PCR[PcIrql], DISPATCH_LEVEL; set new irql
  180. and dword ptr PCR[PcIRR], not (1 shl DISPATCH_LEVEL) ; clear the pending bit in IRR
  181. ;
  182. ; Now it is safe to enable interrupt to allow higher priority interrupt
  183. ; to come in.
  184. ;
  185. sti
  186. ;
  187. ; Go do Dispatch Interrupt processing
  188. ;
  189. stdCall _KiDispatchInterrupt
  190. ;
  191. ; Do interrupt exit processing
  192. ;
  193. SOFT_INTERRUPT_EXIT ; will do an iret
  194. _HalpDispatchInterrupt endp
  195. page ,132
  196. subttl "APC Interrupt"
  197. ;++
  198. ;
  199. ; HalpApcInterrupt(
  200. ; VOID
  201. ; );
  202. ;
  203. ; Routine Description:
  204. ;
  205. ; This routine is entered as the result of a software interrupt generated
  206. ; at APC_LEVEL. Its function is to save the machine state, raise Irql to
  207. ; APC_LEVEL, dismiss the interrupt, and call the APC delivery routine.
  208. ;
  209. ; Arguments:
  210. ;
  211. ; None
  212. ; Interrupt is Disabled
  213. ;
  214. ; Return Value:
  215. ;
  216. ; None.
  217. ;
  218. ;--
  219. ENTER_DR_ASSIST hapc_a, hapc_t
  220. align dword
  221. public _HalpApcInterrupt
  222. _HalpApcInterrupt proc
  223. ifdef IRQL_METRICS
  224. lock inc HalApcSoftwareIntCount
  225. endif
  226. ;
  227. ; Create IRET frame on stack
  228. ;
  229. pop eax
  230. pushfd
  231. push cs
  232. push eax
  233. ;
  234. ; Save machine state in trap frame
  235. ;
  236. ENTER_INTERRUPT hapc_a, hapc_t
  237. .FPO ( FPO_LOCALS+1, 0, 0, 0, 0, FPO_TRAPFRAME )
  238. public _HalpApcInterrupt2ndEntry
  239. _HalpApcInterrupt2ndEntry:
  240. ;
  241. ; Save previous IRQL and set new priority level
  242. ;
  243. push PCR[PcIrql] ; save previous Irql
  244. mov byte ptr PCR[PcIrql], APC_LEVEL ; set new Irql
  245. and dword ptr PCR[PcIRR], not (1 shl APC_LEVEL) ; dismiss pending APC
  246. ;
  247. ; Now it is safe to enable interrupt to allow higher priority interrupt
  248. ; to come in.
  249. ;
  250. sti
  251. ;
  252. ; call the APC delivery routine.
  253. ;
  254. mov eax, [ebp]+TsSegCs ; get interrupted code's CS
  255. and eax, MODE_MASK ; extract the mode
  256. test dword ptr [ebp]+TsEFlags, EFLAGS_V86_MASK
  257. jz short @f
  258. or eax, MODE_MASK ; If v86 frame, then set user_mode
  259. @@:
  260. ;
  261. ; call APC deliver routine
  262. ; Previous mode
  263. ; Null exception frame
  264. ; Trap frame
  265. stdCall _KiDeliverApc, <eax, 0,ebp>
  266. ;
  267. ;
  268. ; Do interrupt exit processing
  269. ;
  270. SOFT_INTERRUPT_EXIT ; will do an iret
  271. _HalpApcInterrupt endp
  272. _TEXT$02 ends
  273. end