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.

244 lines
6.1 KiB

  1. ;++
  2. ;
  3. ;Copyright (c) 1991 Microsoft Corporation
  4. ;Copyright (c) 1992 Intel Corporation
  5. ;All rights reserved
  6. ;
  7. ;INTEL CORPORATION PROPRIETARY INFORMATION
  8. ;
  9. ;This software is supplied to Microsoft under the terms
  10. ;of a license agreement with Intel Corporation and may not be
  11. ;copied nor disclosed except in accordance with the terms
  12. ;of that agreement.
  13. ;
  14. ;
  15. ;Module Name:
  16. ;
  17. ; mpsysint.asm
  18. ;
  19. ;Abstract:
  20. ;
  21. ; This module implements the HAL routines to begin/end
  22. ; system interrupts for a PC+MP implementation
  23. ;
  24. ;Author:
  25. ;
  26. ; John Vert (jvert) 22-Jul-1991
  27. ;
  28. ;Environment:
  29. ;
  30. ; Kernel Mode
  31. ;
  32. ;Revision History:
  33. ;
  34. ; Ron Mosgrove (Intel) Aug 1993
  35. ; Modified for PC+MP Systems
  36. ;
  37. ;--
  38. .386p
  39. .xlist
  40. include hal386.inc
  41. include callconv.inc ; calling convention macros
  42. include i386\kimacro.inc
  43. include mac386.inc
  44. include apic.inc
  45. include ntapic.inc
  46. .list
  47. EXTRNP _KeBugCheck,1,IMPORT
  48. EXTRNP _KiDispatchInterrupt,0,IMPORT
  49. extrn _HalpVectorToIRQL:byte
  50. extrn _HalpIRQLtoTPR:byte
  51. _TEXT SEGMENT DWORD PUBLIC 'CODE'
  52. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  53. page ,132
  54. subttl "End System Interrupt"
  55. ;++
  56. ;
  57. ; VOID
  58. ; HalpEndSystemInterrupt
  59. ; IN KIRQL NewIrql,
  60. ; IN ULONG Vector
  61. ; )
  62. ;
  63. ; Routine Description:
  64. ;
  65. ; This routine is used to lower IRQL to the specified value.
  66. ; The IRQL and PIRQL will be updated accordingly. Also, this
  67. ; routine checks to see if any software interrupt should be
  68. ; generated. The following condition will cause software
  69. ; interrupt to be simulated:
  70. ; any software interrupt which has higher priority than
  71. ; current IRQL's is pending.
  72. ;
  73. ; NOTE: This routine simulates software interrupt as long as
  74. ; any pending SW interrupt level is higher than the current
  75. ; IRQL, even when interrupts are disabled.
  76. ;
  77. ; Arguments:
  78. ;
  79. ; NewIrql - the new irql to be set.
  80. ;
  81. ; Vector - Vector number of the interrupt
  82. ;
  83. ; Note that esp+12 is the beginning of interrupt/trap frame and upon
  84. ; entering to this routine the interrupts are off.
  85. ;
  86. ; Return Value:
  87. ;
  88. ; None.
  89. ;
  90. ;--
  91. HeiNewIrql equ [esp + 4]
  92. HeiVector equ [esp + 8]
  93. cPublicProc _HalEndSystemInterrupt ,2
  94. cPublicFpo 2, 0
  95. xor ecx,ecx
  96. mov cl, byte ptr HeiNewIrql ; get new IRQL
  97. mov cl, _HalpIRQLtoTPR[ecx] ; get corresponding TPR value
  98. mov dword ptr APIC[LU_EOI], 0 ; send EOI to APIC local unit
  99. APICFIX edx
  100. cmp cl, DPC_VECTOR ; Is new irql < DPC?
  101. jc short es10 ; Yes, go check for pending DPC
  102. es05: mov dword ptr APIC[LU_TPR], ecx ; Set new Priority
  103. ;
  104. ; We have to ensure that the requested priority is set before
  105. ; we return. The caller is counting on it.
  106. ;
  107. mov edx, dword ptr APIC[LU_TPR]
  108. CHECKTPR ecx, edx
  109. stdRET _HalEndSystemInterrupt
  110. es10: cmp PCR[PcHal.DpcPending], 0 ; Is a DPC pending?
  111. mov PCR[PcHal.ShortDpc], 0 ; Clear short dpc flag
  112. jz short es05 ; No, eoi
  113. mov dword ptr APIC[LU_TPR], DPC_VECTOR ; lower to DPC level
  114. APICFIX edx
  115. push ebx ; Save EBX (used by KiDispatchInterrupt)
  116. push ecx ; Save OldIrql
  117. cPublicFpo 2, 2
  118. sti
  119. es20: mov PCR[PcHal.DpcPending], 0 ; Clear pending flag
  120. stdCall _KiDispatchInterrupt ; Dispatch interrupt
  121. cli
  122. pop ecx
  123. pop ebx
  124. jmp short es05
  125. stdENDP _HalEndSystemInterrupt
  126. ;++
  127. ;
  128. ;BOOLEAN
  129. ;HalBeginSystemInterrupt(
  130. ; IN KIRQL Irql
  131. ; IN ULONG Vector,
  132. ; OUT PKIRQL OldIrql
  133. ; )
  134. ;
  135. ;Routine Description:
  136. ;
  137. ; This routine raises the IRQL to the level of the specified
  138. ; interrupt vector. It is called by the hardware interrupt
  139. ; handler before any other interrupt service routine code is
  140. ; executed. The CPU interrupt flag is set on exit.
  141. ;
  142. ; On APIC-based systems we do not need to check for spurious
  143. ; interrupts since they now have their own vector. We also
  144. ; no longer need to check whether or not the incoming priority
  145. ; is higher than the current priority that is guaranteed by
  146. ; the priority mechanism of the APIC.
  147. ;
  148. ; SO
  149. ;
  150. ; All BeginSystemInterrupt needs to do is set the APIC TPR
  151. ; appropriate for the IRQL, and return TRUE. Note that to
  152. ; use the APIC ISR priority we are not going issue EOI until
  153. ; EndSystemInterrupt is called.
  154. ;
  155. ; Arguments:
  156. ;
  157. ; Irql - Supplies the IRQL to raise to
  158. ;
  159. ; Vector - Supplies the vector of the interrupt to be
  160. ; handled
  161. ;
  162. ; OldIrql- Location to return OldIrql
  163. ;
  164. ; Return Value:
  165. ;
  166. ; TRUE - Interrupt successfully dismissed and Irql raised.
  167. ; This routine can not fail.
  168. ;
  169. ;--
  170. align dword
  171. HbsiIrql equ byte ptr [esp+4]
  172. HbsiVector equ byte ptr [esp+8]
  173. HbsiOldIrql equ dword ptr [esp+12]
  174. cPublicProc _HalBeginSystemInterrupt ,3
  175. cPublicFpo 3, 0
  176. xor eax, eax
  177. mov al, HbsiIrql ; (eax) = New Vector
  178. mov al, _HalpIRQLtoTPR[eax] ; get corresponding TPR value
  179. ;
  180. ; Read the TPR for the Priority (Vector) in use,
  181. ; and convert it to an IRQL
  182. ;
  183. mov ecx, dword ptr APIC[LU_TPR] ; Get the Priority
  184. mov dword ptr APIC[LU_TPR], eax
  185. APICFIX edx
  186. mov eax, HbsiOldIrql ; return the current IRQL as OldIrql
  187. shr ecx, 4
  188. mov cl, byte ptr _HalpVectorToIRQL[ecx]
  189. mov byte ptr [eax], cl
  190. mov eax, 1 ; return TRUE
  191. sti
  192. ;
  193. ; If OldIrql < DISPATCH_LEVEL and new irql >= DISPATCH_LEVEL (which
  194. ; is assumed), then set
  195. ;
  196. cmp cl, DISPATCH_LEVEL
  197. jnc short bs10
  198. if DBG
  199. cmp PCR[PcHal.ShortDpc], 0
  200. je short @f
  201. int 3
  202. @@:
  203. endif
  204. mov PCR[PcHal.ShortDpc], DISPATCH_LEVEL
  205. bs10:
  206. stdRET _HalBeginSystemInterrupt
  207. stdENDP _HalBeginSystemInterrupt
  208. _TEXT ENDS
  209. END