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.

325 lines
7.0 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 USE32 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. ; FASTCALL
  51. ; HalRequestSoftwareInterrupt (
  52. ; IN KIRQL RequestIrql
  53. ; )
  54. ;
  55. ; Routine Description:
  56. ;
  57. ; This routine is used to request a software interrupt to the
  58. ; system. Also, this routine checks to see if any software
  59. ; interrupt should be generated.
  60. ; The following condition will cause software interrupt to
  61. ; be simulated:
  62. ; any software interrupt which has higher priority than
  63. ; current IRQL's is pending.
  64. ;
  65. ; NOTE: This routine simulates software interrupt as long as
  66. ; any pending SW interrupt level is higher than the current
  67. ; IRQL, even when interrupts are disabled.
  68. ;
  69. ; Arguments:
  70. ;
  71. ; (cl) = RequestIrql - Supplies the request IRQL value
  72. ;
  73. ; Return Value:
  74. ;
  75. ; None.
  76. ;
  77. ;--
  78. ; equates for accessing arguments
  79. ;
  80. cPublicFastCall HalRequestSoftwareInterrupt ,1
  81. cPublicFpo 0, 1
  82. mov eax,1
  83. shl eax, cl ; convert to mask
  84. pushfd ; save interrupt mode
  85. cli ; disable interrupt
  86. or PCR[PcIRR], eax ; set the request bit
  87. mov cl, PCR[PcIrql] ; get current IRQL
  88. mov eax, PCR[PcIRR] ; get SW interrupt request register
  89. mov al, SWInterruptLookUpTable[eax] ; get the highest pending
  90. ; software interrupt level
  91. cmp al, cl ; Is highest SW int level > irql?
  92. jbe KsiExit ; No, jmp ksiexit
  93. call SWInterruptHandlerTable[eax*4] ; yes, simulate interrupt
  94. ; to the appropriate handler
  95. KsiExit:
  96. popfd ; restore original interrupt mode
  97. fstRET HalRequestSoftwareInterrupt
  98. fstENDP HalRequestSoftwareInterrupt
  99. page ,132
  100. subttl "Request Software Interrupt"
  101. ;++
  102. ;
  103. ; VOID
  104. ; HalClearSoftwareInterrupt (
  105. ; IN KIRQL RequestIrql
  106. ; )
  107. ;
  108. ; Routine Description:
  109. ;
  110. ; This routine is used to clear a possible pending software interrupt.
  111. ; Support for this function is optional, and allows the kernel to
  112. ; reduce the number of spurious software interrupts it receives/
  113. ;
  114. ; Arguments:
  115. ;
  116. ; (cl) = RequestIrql - Supplies the request IRQL value
  117. ;
  118. ; Return Value:
  119. ;
  120. ; None.
  121. ;
  122. ;--
  123. cPublicFastCall HalClearSoftwareInterrupt ,1
  124. cPublicFpo 0, 0
  125. mov eax,1
  126. shl eax, cl ; convert to mask
  127. not eax
  128. and PCR[PcIRR], eax ; clear pending irr bit
  129. fstRET HalClearSoftwareInterrupt
  130. fstENDP HalClearSoftwareInterrupt
  131. page ,132
  132. subttl "Dispatch Interrupt"
  133. ;++
  134. ;
  135. ; VOID
  136. ; HalpDispatchInterrupt(
  137. ; VOID
  138. ; );
  139. ;
  140. ; Routine Description:
  141. ;
  142. ; This routine is the interrupt handler for a software interrupt generated
  143. ; at DISPATCH_LEVEL. Its function is to save the machine state, raise
  144. ; Irql to DISPATCH_LEVEL, dismiss the interrupt, and call the DPC
  145. ; delivery routine.
  146. ;
  147. ; Arguments:
  148. ;
  149. ; None
  150. ; Interrupt is disabled
  151. ;
  152. ; Return Value:
  153. ;
  154. ; None.
  155. ;
  156. ;--
  157. ENTER_DR_ASSIST hdpi_a, hdpi_t
  158. align dword
  159. public _HalpDispatchInterrupt
  160. _HalpDispatchInterrupt proc
  161. ifdef IRQL_METRICS
  162. lock inc HalDpcSoftwareIntCount
  163. endif
  164. ;
  165. ; Create IRET frame on stack
  166. ;
  167. pop eax
  168. pushfd
  169. push cs
  170. push eax
  171. ;
  172. ; Save machine state on trap frame
  173. ;
  174. ENTER_INTERRUPT hdpi_a, hdpi_t
  175. .FPO ( FPO_LOCALS+1, 0, 0, 0, 0, FPO_TRAPFRAME )
  176. public _HalpDispatchInterrupt2ndEntry
  177. _HalpDispatchInterrupt2ndEntry:
  178. ; Save previous IRQL and set new priority level
  179. push PCR[PcIrql] ; save previous IRQL
  180. mov byte ptr PCR[PcIrql], DISPATCH_LEVEL; set new irql
  181. btr dword ptr PCR[PcIRR], DISPATCH_LEVEL; clear the pending bit in IRR
  182. ;
  183. ; Now it is safe to enable interrupt to allow higher priority interrupt
  184. ; to come in.
  185. ;
  186. sti
  187. ;
  188. ; Go do Dispatch Interrupt processing
  189. ;
  190. stdCall _KiDispatchInterrupt
  191. ;
  192. ; Do interrupt exit processing
  193. ;
  194. SOFT_INTERRUPT_EXIT ; will do an iret
  195. _HalpDispatchInterrupt endp
  196. page ,132
  197. subttl "APC Interrupt"
  198. ;++
  199. ;
  200. ; HalpApcInterrupt(
  201. ; VOID
  202. ; );
  203. ;
  204. ; Routine Description:
  205. ;
  206. ; This routine is entered as the result of a software interrupt generated
  207. ; at APC_LEVEL. Its function is to save the machine state, raise Irql to
  208. ; APC_LEVEL, dismiss the interrupt, and call the APC delivery routine.
  209. ;
  210. ; Arguments:
  211. ;
  212. ; None
  213. ; Interrupt is Disabled
  214. ;
  215. ; Return Value:
  216. ;
  217. ; None.
  218. ;
  219. ;--
  220. ENTER_DR_ASSIST hapc_a, hapc_t
  221. align dword
  222. public _HalpApcInterrupt
  223. _HalpApcInterrupt proc
  224. ifdef IRQL_METRICS
  225. lock inc HalApcSoftwareIntCount
  226. endif
  227. ;
  228. ; Create IRET frame on stack
  229. ;
  230. pop eax
  231. pushfd
  232. push cs
  233. push eax
  234. ;
  235. ; Save machine state in trap frame
  236. ;
  237. ENTER_INTERRUPT hapc_a, hapc_t
  238. .FPO ( FPO_LOCALS+1, 0, 0, 0, 0, FPO_TRAPFRAME )
  239. public _HalpApcInterrupt2ndEntry
  240. _HalpApcInterrupt2ndEntry:
  241. ;
  242. ; Save previous IRQL and set new priority level
  243. ;
  244. push PCR[PcIrql] ; save previous Irql
  245. mov byte ptr PCR[PcIrql], APC_LEVEL ; set new Irql
  246. btr dword ptr PCR[PcIRR], APC_LEVEL ; dismiss pending APC
  247. ;
  248. ; Now it is safe to enable interrupt to allow higher priority interrupt
  249. ; to come in.
  250. ;
  251. sti
  252. ;
  253. ; call the APC delivery routine.
  254. ;
  255. mov eax, [ebp]+TsSegCs ; get interrupted code's CS
  256. and eax, MODE_MASK ; extract the mode
  257. test dword ptr [ebp]+TsEFlags, EFLAGS_V86_MASK
  258. jz short @f
  259. or eax, MODE_MASK ; If v86 frame, then set user_mode
  260. @@:
  261. ;
  262. ; call APC deliver routine
  263. ; Previous mode
  264. ; Null exception frame
  265. ; Trap frame
  266. stdCall _KiDeliverApc, <eax, 0,ebp>
  267. ;
  268. ;
  269. ; Do interrupt exit processing
  270. ;
  271. SOFT_INTERRUPT_EXIT ; will do an iret
  272. _HalpApcInterrupt endp
  273. _TEXT$02 ends
  274. end