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.

837 lines
25 KiB

  1. title "Irql Processing"
  2. ;++
  3. ;
  4. ; Copyright (c) 1989 Microsoft Corporation
  5. ;
  6. ; Module Name:
  7. ;
  8. ; spirql.asm
  9. ;
  10. ; Abstract:
  11. ;
  12. ; SystemPro IRQL
  13. ;
  14. ; This module implements the code necessary to raise and lower i386
  15. ; Irql and dispatch software interrupts with the 8259 PIC.
  16. ;
  17. ; Author:
  18. ;
  19. ; Shie-Lin Tzong (shielint) 8-Jan-1990
  20. ;
  21. ; Environment:
  22. ;
  23. ; Kernel mode only.
  24. ;
  25. ; Revision History:
  26. ;
  27. ; John Vert (jvert) 27-Nov-1991
  28. ; Moved from kernel into HAL
  29. ;
  30. ;--
  31. .386p
  32. .xlist
  33. include hal386.inc
  34. include callconv.inc ; calling convention macros
  35. include i386\ix8259.inc
  36. include i386\kimacro.inc
  37. include i386\spmp.inc
  38. .list
  39. EXTRNP _KeBugCheck,1,IMPORT
  40. extrn _HalpApcInterrupt:near
  41. extrn _HalpDispatchInterrupt:near
  42. extrn _HalpSWNonPrimaryClockTick:near
  43. extrn _HalpApcInterrupt2ndEntry:NEAR
  44. extrn _HalpDispatchInterrupt2ndEntry:NEAR
  45. extrn _HalpSWNonPrimaryClockTick2ndEntry:NEAR
  46. extrn _KiUnexpectedInterrupt:near
  47. ;
  48. ; Initialization control words equates for the PICs
  49. ;
  50. ICW1_ICW4_NEEDED equ 01H
  51. ICW1_CASCADE equ 00H
  52. ICW1_INTERVAL8 equ 00H
  53. ICW1_LEVEL_TRIG equ 08H
  54. ICW1_EDGE_TRIG equ 00H
  55. ICW1_ICW equ 10H
  56. ICW4_8086_MODE equ 001H
  57. ICW4_NORM_EOI equ 000H
  58. ICW4_NON_BUF_MODE equ 000H
  59. ICW4_SPEC_FULLY_NESTED equ 010H
  60. ICW4_NOT_SPEC_FULLY_NESTED equ 000H
  61. OCW2_NON_SPECIFIC_EOI equ 020H
  62. OCW2_SPECIFIC_EOI equ 060H
  63. OCW2_SET_PRIORITY equ 0c0H
  64. PIC_SLAVE_IRQ equ 2
  65. PIC1_BASE equ 30H
  66. PIC2_BASE equ 38H
  67. ;
  68. ; Interrupt flag bit maks for EFLAGS
  69. ;
  70. EFLAGS_IF equ 200H
  71. EFLAGS_SHIFT equ 9
  72. ;
  73. ; Define the constants of Edge level Pic control.
  74. ;
  75. ; Background: Compaq Belize systems have an 8259 per processor and
  76. ; their own private Edge Level control registers (4d0,4d1).
  77. ;
  78. EDGELEVEL_CONTROL_1 equ 4D0H
  79. EDGELEVEL_CONTROL_2 equ 4D1H
  80. ;
  81. _TEXT SEGMENT DWORD PUBLIC 'DATA'
  82. ;
  83. ; PICsInitializationString - Master PIC initialization command string
  84. ;
  85. PICsInitializationString dw PIC1_PORT0
  86. ;
  87. ; Master PIC initialization command
  88. ;
  89. db ICW1_ICW + ICW1_EDGE_TRIG + ICW1_INTERVAL8 +\
  90. ICW1_CASCADE + ICW1_ICW4_NEEDED
  91. db PIC1_BASE
  92. db 1 SHL PIC_SLAVE_IRQ
  93. db ICW4_NOT_SPEC_FULLY_NESTED + \
  94. ICW4_NON_BUF_MODE + \
  95. ICW4_NORM_EOI + \
  96. ICW4_8086_MODE
  97. ;
  98. ; Slave PIC initialization command strings
  99. ;
  100. dw PIC2_PORT0
  101. db ICW1_ICW + ICW1_EDGE_TRIG + ICW1_INTERVAL8 +\
  102. ICW1_CASCADE + ICW1_ICW4_NEEDED
  103. db PIC2_BASE
  104. db PIC_SLAVE_IRQ
  105. db ICW4_NOT_SPEC_FULLY_NESTED + \
  106. ICW4_NON_BUF_MODE + \
  107. ICW4_NORM_EOI + \
  108. ICW4_8086_MODE
  109. dw 0 ; end of string
  110. PS2PICsInitializationString dw PIC1_PORT0
  111. ;
  112. ; Master PIC initialization command
  113. ;
  114. db ICW1_ICW + ICW1_LEVEL_TRIG + ICW1_INTERVAL8 +\
  115. ICW1_CASCADE + ICW1_ICW4_NEEDED
  116. db PIC1_BASE
  117. db 1 SHL PIC_SLAVE_IRQ
  118. db ICW4_NOT_SPEC_FULLY_NESTED + \
  119. ICW4_NON_BUF_MODE + \
  120. ICW4_NORM_EOI + \
  121. ICW4_8086_MODE
  122. ;
  123. ; Slave PIC initialization command strings
  124. ;
  125. dw PIC2_PORT0
  126. db ICW1_ICW + ICW1_LEVEL_TRIG + ICW1_INTERVAL8 +\
  127. ICW1_CASCADE + ICW1_ICW4_NEEDED
  128. db PIC2_BASE
  129. db PIC_SLAVE_IRQ
  130. db ICW4_NOT_SPEC_FULLY_NESTED + \
  131. ICW4_NON_BUF_MODE + \
  132. ICW4_NORM_EOI + \
  133. ICW4_8086_MODE
  134. dw 0 ; end of string
  135. align 4
  136. public KiI8259MaskTable
  137. KiI8259MaskTable label dword
  138. dd 00000000000000000000000000000000B ; irql 0
  139. dd 00000000000000000000000000000000B ; irql 1
  140. dd 00000000000000000000000000000000B ; irql 2
  141. dd 00000000000000000000000000000000B ; irql 3
  142. dd 00000000000000000000000000000000B ; irql 4
  143. dd 11111111110000000000000000000000B ; irql 5
  144. dd 11111111111000000000000000000000B ; irql 6
  145. dd 11111111111100000000000000000000B ; irql 7
  146. dd 11111111111110000000000000000000B ; irql 8
  147. dd 11111111111111000000000000000000B ; irql 9
  148. dd 11111111111111100000000000000000B ; irql 10
  149. dd 11111111111111110000000000000000B ; irql 11
  150. dd 11111111111111111000000000000000B ; irql 12
  151. dd 11111111111111111100000000000000B ; irql 13
  152. dd 11111111111111111100000000000000B ; irql 14
  153. dd 11111111111111111101000000000000B ; irql 15
  154. dd 11111111111111111101100000000000B ; irql 16
  155. dd 11111111111111111101110000000000B ; irql 17
  156. dd 11111111111111111101111000000000B ; irql 18
  157. dd 11111111111111111101111000000000B ; irql 19
  158. dd 11111111111111111101111010000000B ; irql 20
  159. dd 11111111111111111101111011000000B ; irql 21
  160. dd 11111111111111111101111011100000B ; irql 22
  161. dd 11111111111111111101111011110000B ; irql 23
  162. dd 11111111111111111101111011111000B ; irql 24
  163. dd 11111111111111111101111011111000B ; irql 25
  164. dd 11111111111111111101111011111010B ; irql 26
  165. dd 11111111111111111101111111111010B ; irql 27
  166. dd 11111111111111111101111111111011B ; irql 28
  167. dd 11111111111111111111111111111011B ; irql 29
  168. dd 11111111111111111111111111111011B ; irql 30
  169. dd 11111111111111111111111111111011B ; irql 31
  170. ; |
  171. ; 32109876543210
  172. ; |
  173. ; + - Raise SystemPros IPI vector (13)
  174. ; to IPI_LEVEL
  175. align 4
  176. ;
  177. ; The following tables define the addresses of software interrupt routers
  178. ;
  179. ;
  180. ; Use this table if there is NO machine state frame on stack already
  181. ;
  182. public SWInterruptHandlerTable
  183. SWInterruptHandlerTable label dword
  184. dd offset FLAT:_KiUnexpectedInterrupt ; irql 0
  185. dd offset FLAT:_HalpApcInterrupt ; irql 1
  186. dd offset FLAT:_HalpDispatchInterrupt ; irql 2
  187. dd offset FLAT:_KiUnexpectedInterrupt ; irql 3
  188. dd offset FLAT:_HalpSWNonPrimaryClockTick ; irql 4
  189. ;
  190. ; Use this table if there is a machine state frame on stack already
  191. ;
  192. public SWInterruptHandlerTable2
  193. SWInterruptHandlerTable2 label dword
  194. dd offset FLAT:_KiUnexpectedInterrupt ; irql 0
  195. dd offset FLAT:_HalpApcInterrupt2ndEntry ; irql 1
  196. dd offset FLAT:_HalpDispatchInterrupt2ndEntry ; irql 2
  197. dd offset FLAT:_KiUnexpectedInterrupt ; irql 3
  198. dd offset FLAT:_HalpSWNonPrimaryClockTick2ndEntry ; irql 4
  199. ;
  200. ; The following table picks up the highest pending software irq level
  201. ; from software irr
  202. ;
  203. public SWInterruptLookUpTable
  204. SWInterruptLookUpTable label byte
  205. db 0 ; SWIRR=0, so highest pending SW irql= 0
  206. db 0 ; SWIRR=1, so highest pending SW irql= 0
  207. db 1 ; SWIRR=2, so highest pending SW irql= 1
  208. db 1 ; SWIRR=3, so highest pending SW irql= 1
  209. db 2 ; SWIRR=4, so highest pending SW irql= 2
  210. db 2 ; SWIRR=5, so highest pending SW irql= 2
  211. db 2 ; SWIRR=6, so highest pending SW irql= 2
  212. db 2 ; SWIRR=7, so highest pending SW irql= 2
  213. db 3 ; SWIRR=8, so highest pending SW irql= 3
  214. db 3 ; SWIRR=9, so highest pending SW irql= 3
  215. db 3 ; SWIRR=A, so highest pending SW irql= 3
  216. db 3 ; SWIRR=B, so highest pending SW irql= 3
  217. db 3 ; SWIRR=C, so highest pending SW irql= 3
  218. db 3 ; SWIRR=D, so highest pending SW irql= 3
  219. db 3 ; SWIRR=E, so highest pending SW irql= 3
  220. db 3 ; SWIRR=F, so highest pending SW irql= 3
  221. db 4 ; SWIRR=10, so highest pending SW irql= 4
  222. db 4 ; SWIRR=11, so highest pending SW irql= 4
  223. db 4 ; SWIRR=12, so highest pending SW irql= 4
  224. db 4 ; SWIRR=13, so highest pending SW irql= 4
  225. db 4 ; SWIRR=14, so highest pending SW irql= 4
  226. db 4 ; SWIRR=15, so highest pending SW irql= 4
  227. db 4 ; SWIRR=16, so highest pending SW irql= 4
  228. db 4 ; SWIRR=17, so highest pending SW irql= 4
  229. db 4 ; SWIRR=18, so highest pending SW irql= 4
  230. db 4 ; SWIRR=19, so highest pending SW irql= 4
  231. db 4 ; SWIRR=1A, so highest pending SW irql= 4
  232. db 4 ; SWIRR=1B, so highest pending SW irql= 4
  233. db 4 ; SWIRR=1C, so highest pending SW irql= 4
  234. db 4 ; SWIRR=1D, so highest pending SW irql= 4
  235. db 4 ; SWIRR=1E, so highest pending SW irql= 4
  236. db 4 ; SWIRR=1F, so highest pending SW irql= 4
  237. _TEXT ends
  238. _DATA SEGMENT DWORD PUBLIC 'DATA'
  239. ;
  240. ; Only P0 has its Edge Level masks on port 4d0 and port 4d1 setup
  241. ; correctly. We hold the P0 values here for the other processors.
  242. ;
  243. align 4
  244. public _SpP0EdgeLevelValue
  245. _SpP0EdgeLevelValue dw 0
  246. _DATA ENDS
  247. _TEXT SEGMENT DWORD PUBLIC 'CODE'
  248. ASSUME DS:FLAT, ES:FLAT, SS:FLAT, FS:NOTHING, GS:NOTHING
  249. PAGE
  250. SUBTTL "Raise Irql"
  251. ;++
  252. ;
  253. ; KIRQL
  254. ; FASTCALL
  255. ; KfRaiseIrql (
  256. ; IN KIRQL NewIrql
  257. ; )
  258. ;
  259. ; Routine Description:
  260. ;
  261. ; This routine is used to raise IRQL to the specified value.
  262. ; Also, a mask will be used to mask off all the lower lever 8259
  263. ; interrupts.
  264. ;
  265. ; Arguments:
  266. ;
  267. ; (cl) = NewIrql - the new irql to be raised to
  268. ;
  269. ; Return Value:
  270. ;
  271. ; OldIrql - the addr of a variable which old irql should be stored
  272. ;
  273. ;--
  274. cPublicFastCall KfRaiseIrql,1
  275. cPublicFpo 0,0
  276. xor eax, eax ; avoid partial stall
  277. mov al, fs:PcIrql ; get current irql
  278. pushfd ; save caller's eflags
  279. cPublicFpo 0,1
  280. if DBG
  281. cmp al,cl ; old > new?
  282. jbe short Kri99 ; no, we're OK
  283. movzx eax, al
  284. movzx ecx, cl
  285. push ecx ; put new irql where we can find it
  286. push eax ; put old irql where we can find it
  287. mov byte ptr fs:PcIrql,0 ; avoid recursive error
  288. stdCall _KeBugCheck, <IRQL_NOT_GREATER_OR_EQUAL>
  289. align 4
  290. Kri99:
  291. endif
  292. cli ; disable interrupt
  293. cmp byte ptr fs:PcHal.PcrPic, 0
  294. je PxRaiseIrql ; dispatch according to processor
  295. @@:
  296. ; P0RaiseIrql
  297. cmp cl,DISPATCH_LEVEL ; software level?
  298. mov fs:PcIrql, cl ; set the new irql
  299. jbe short kri10 ; go skip setting 8259 hardware
  300. movzx ecx, cl
  301. mov dl, al ; Save OldIrql
  302. mov eax, KiI8259MaskTable[ecx*4]; get pic masks for the new irql
  303. or eax, fs:PcIDR ; mask irqs which are disabled
  304. SET_8259_MASK ; set 8259 masks
  305. mov al, dl ; Restore OldIrql
  306. kri10: popfd ; restore flags (including interrupts)
  307. fstRET KfRaiseIrql
  308. align 4
  309. PxRaiseIrql:
  310. ;
  311. ; Even though SystemPro P2 cannot touch 8259 ports, we still need to
  312. ; make sure interrupts are off when requested to raise to IPI_LEVEL or
  313. ; above.
  314. ;
  315. cmp cl, IPI_LEVEL ; If raise to IPI_LEVEL?
  316. jb short @f ; if ne, don't edit flag
  317. and dword ptr [esp], NOT EFLAGS_IF ; clear IF bit in return EFLAGS
  318. align 4
  319. @@:
  320. mov fs:PcIrql, cl ; set the new irql
  321. popfd ; restore flags (including interrupts)
  322. fstRET KfRaiseIrql
  323. fstENDP KfRaiseIrql
  324. ;++
  325. ;
  326. ; VOID
  327. ; KIRQL
  328. ; KeRaiseIrqlToDpcLevel (
  329. ; )
  330. ;
  331. ; Routine Description:
  332. ;
  333. ; This routine is used to raise IRQL to DPC level.
  334. ; The APIC TPR is used to block all lower-priority HW interrupts.
  335. ;
  336. ; Arguments:
  337. ;
  338. ; Return Value:
  339. ;
  340. ; OldIrql - the addr of a variable which old irql should be stored
  341. ;
  342. ;--
  343. cPublicProc _KeRaiseIrqlToDpcLevel,0
  344. cPublicFpo 0, 0
  345. mov ecx, DISPATCH_LEVEL
  346. jmp @KfRaiseIrql
  347. stdENDP _KeRaiseIrqlToDpcLevel
  348. ;++
  349. ;
  350. ; VOID
  351. ; KIRQL
  352. ; KeRaiseIrqlToSynchLevel (
  353. ; )
  354. ;
  355. ; Routine Description:
  356. ;
  357. ; This routine is used to raise IRQL to SYNC level.
  358. ; The APIC TPR is used to block all lower-priority HW interrupts.
  359. ;
  360. ; Arguments:
  361. ;
  362. ; Return Value:
  363. ;
  364. ; OldIrql - the addr of a variable which old irql should be stored
  365. ;
  366. ;--
  367. cPublicProc _KeRaiseIrqlToSynchLevel,0
  368. mov ecx, SYNCH_LEVEL
  369. jmp @KfRaiseIrql
  370. stdENDP _KeRaiseIrqlToSynchLevel
  371. page ,132
  372. subttl "Lower irql"
  373. ;++
  374. ;
  375. ; VOID
  376. ; FASTCALL
  377. ; KfLowerIrql (
  378. ; IN KIRQL NewIrql
  379. ; )
  380. ;
  381. ; Routine Description:
  382. ;
  383. ; This routine is used to lower IRQL to the specified value.
  384. ; The IRQL and PIRQL will be updated accordingly. Also, this
  385. ; routine checks to see if any software interrupt should be
  386. ; generated. The following condition will cause software
  387. ; interrupt to be simulated:
  388. ; any software interrupt which has higher priority than
  389. ; current IRQL's is pending.
  390. ;
  391. ; NOTE: This routine simulates software interrupt as long as
  392. ; any pending SW interrupt level is higher than the current
  393. ; IRQL, even when interrupts are disabled.
  394. ;
  395. ; Arguments:
  396. ;
  397. ; (cl) = NewIrql - the new irql to be set.
  398. ;
  399. ; Return Value:
  400. ;
  401. ; None.
  402. ;
  403. ;--
  404. cPublicFastCall KfLowerIrql,1
  405. pushfd ; save caller's eflags
  406. if DBG
  407. cmp cl,fs:PcIrql
  408. jbe short Kli99
  409. movzx ecx, cl
  410. push ecx ; new irql for debugging
  411. push fs:PcIrql ; old irql for debugging
  412. mov byte ptr fs:PcIrql,HIGH_LEVEL ; avoid recursive error
  413. stdCall _KeBugCheck, <IRQL_NOT_LESS_OR_EQUAL>
  414. align 4
  415. Kli99:
  416. endif
  417. cli
  418. cmp byte ptr fs:PcHal.PcrPic, 0
  419. je PxLowerIrql ; dispatch according to processor
  420. @@:
  421. ; P1LowerIrql:
  422. cmp byte ptr fs:PcIrql,DISPATCH_LEVEL ; Software level?
  423. jbe short kli02 ; yes, go skip setting 8259 hw
  424. movzx ecx, cl
  425. mov eax, KiI8259MaskTable[ecx*4]; get pic masks for the new irql
  426. or eax, fs:PcIDR ; mask irqs which are disabled
  427. SET_8259_MASK ; set 8259 masks
  428. kli02: mov fs:PcIrql, cl ; set the new irql
  429. mov eax, fs:PcIRR ; get SW interrupt request register
  430. mov al, SWInterruptLookUpTable[eax] ; get the highest pending
  431. ; software interrupt level
  432. cmp al, cl ; Is highest SW int level > irql?
  433. ja short Kli10 ; yes, go simulate interrupt
  434. popfd ; restore flags, including ints
  435. fstRET KfLowerIrql
  436. ; When we come to Kli10, (eax) = soft interrupt index
  437. align 4
  438. Kli10:
  439. call SWInterruptHandlerTable[eax*4] ; SIMULATE INTERRUPT
  440. ; to the appropriate handler
  441. popfd
  442. fstRET KfLowerIrql
  443. PxLowerIrql:
  444. cmp cl, IPI_LEVEL ; If lower to IPI_LEVEL?
  445. ; cy = yes
  446. sbb edx, edx ; edx = 0 (nc), -1 (cy)
  447. and edx, EFLAGS_IF
  448. or dword ptr [esp], edx ; set EFLAG_IF if irql<IPI_LEVEL
  449. mov fs:PcIrql, cl ; set the new irql
  450. mov eax, fs:PcIRR ; get SW interrupt request register
  451. mov al, SWInterruptLookUpTable[eax] ; get the highest pending
  452. ; software interrupt level
  453. cmp al, cl ; Is highest SW int level > irql?
  454. ja short Kli10 ; yes, go simulate interrupt
  455. popfd ; restore flags, including ints
  456. fstRET KfLowerIrql
  457. fstENDP KfLowerIrql
  458. ;++
  459. ;
  460. ; VOID
  461. ; HalpEndSystemInterrupt
  462. ; IN KIRQL NewIrql,
  463. ; IN ULONG Vector
  464. ; )
  465. ;
  466. ; Routine Description:
  467. ;
  468. ; This routine is used to lower IRQL to the specified value.
  469. ; The IRQL and PIRQL will be updated accordingly. Also, this
  470. ; routine checks to see if any software interrupt should be
  471. ; generated. The following condition will cause software
  472. ; interrupt to be simulated:
  473. ; any software interrupt which has higher priority than
  474. ; current IRQL's is pending.
  475. ;
  476. ; NOTE: This routine simulates software interrupt as long as
  477. ; any pending SW interrupt level is higher than the current
  478. ; IRQL, even when interrupts are disabled.
  479. ;
  480. ; Arguments:
  481. ;
  482. ; NewIrql - the new irql to be set.
  483. ;
  484. ; Vector - Vector number of the interrupt
  485. ;
  486. ; Note that esp+8 is the beginning of interrupt/trap frame and upon
  487. ; entering to this routine the interrupts are off.
  488. ;
  489. ; Return Value:
  490. ;
  491. ; None.
  492. ;
  493. ;--
  494. HeiNewIrql equ [esp + 4]
  495. cPublicProc _HalEndSystemInterrupt ,2
  496. xor ecx, ecx
  497. mov cl, byte ptr HeiNewIrql ; get new irql value
  498. cmp byte ptr fs:PcHal.PcrPic, 0
  499. je short Hei02
  500. ; P1LowerIrql:
  501. cmp byte ptr fs:PcIrql, DISPATCH_LEVEL ; Software level?
  502. jbe short Hei02 ; yes, go skip setting 8259 hw
  503. mov eax, KiI8259MaskTable[ecx*4]; get pic masks for the new irql
  504. or eax, fs:PcIDR ; mask irqs which are disabled
  505. SET_8259_MASK ; set 8259 masks
  506. ;
  507. ; Unlike KeLowerIrql, we don't check if the the irql is lowered to
  508. ; below IPI level and enable interrupt for second processor. This is because
  509. ; the correct interrupt flag is already stored in the TsEflags of Trap frame.
  510. ;
  511. align 4
  512. Hei02: mov fs:PcIrql, cl ; set the new irql
  513. mov eax, fs:PcIRR ; get SW interrupt request register
  514. mov al, SWInterruptLookUpTable[eax] ; get the highest pending
  515. ; software interrupt level
  516. cmp al, cl ; Is highest SW int level > irql?
  517. ja short Hei10 ; yes, go simulate interrupt
  518. stdRET _HalEndSystemInterrupt ; cRetURN
  519. ; When we come to Kli10, (eax) = soft interrupt index
  520. align 4
  521. Hei10: add esp, 12
  522. jmp SWInterruptHandlerTable2[eax*4] ; SIMULATE INTERRUPT
  523. ; to the appropriate handler
  524. stdENDP _HalEndSystemInterrupt
  525. ;++
  526. ;
  527. ; VOID
  528. ; HalpEndSoftwareInterrupt
  529. ; IN KIRQL NewIrql,
  530. ; )
  531. ;
  532. ; Routine Description:
  533. ;
  534. ; This routine is used to lower IRQL from software interrupt
  535. ; level to the specified value.
  536. ; The IRQL and PIRQL will be updated accordingly. Also, this
  537. ; routine checks to see if any software interrupt should be
  538. ; generated. The following condition will cause software
  539. ; interrupt to be simulated:
  540. ; any software interrupt which has higher priority than
  541. ; current IRQL's is pending.
  542. ;
  543. ; NOTE: This routine simulates software interrupt as long as
  544. ; any pending SW interrupt level is higher than the current
  545. ; IRQL, even when interrupts are disabled.
  546. ;
  547. ; Arguments:
  548. ;
  549. ; NewIrql - the new irql to be set.
  550. ;
  551. ; Note that esp+8 is the beginning of interrupt/trap frame and upon
  552. ; entering to this routine the interrupts are off.
  553. ;
  554. ; Return Value:
  555. ;
  556. ; None.
  557. ;
  558. ;--
  559. HesNewIrql equ [esp + 4]
  560. cPublicProc _HalpEndSoftwareInterrupt,1
  561. cPublicFpo 1,0
  562. mov ecx, [esp+4]
  563. fstCall KfLowerIrql
  564. cli
  565. stdRet _HalpEndSoftwareInterrupt
  566. stdENDP _HalpEndSoftwareInterrupt
  567. page ,132
  568. subttl "Get current irql"
  569. ;++
  570. ;
  571. ; KIRQL
  572. ; KeGetCurrentIrql (VOID)
  573. ;
  574. ; Routine Description:
  575. ;
  576. ; This routine returns to current IRQL.
  577. ;
  578. ; Arguments:
  579. ;
  580. ; None.
  581. ;
  582. ; Return Value:
  583. ;
  584. ; The current IRQL.
  585. ;
  586. ;--
  587. cPublicProc _KeGetCurrentIrql ,0
  588. movzx eax,byte ptr fs:PcIrql ; Current irql is in the PCR
  589. stdRET _KeGetCurrentIrql
  590. stdENDP _KeGetCurrentIrql
  591. ;++
  592. ;
  593. ; KIRQL
  594. ; HalpDisableAllInterrupts (VOID)
  595. ;
  596. ; Routine Description:
  597. ;
  598. ; This routine is called during a system crash. The hal needs all
  599. ; interrupts disabled.
  600. ;
  601. ; Arguments:
  602. ;
  603. ; None.
  604. ;
  605. ; Return Value:
  606. ;
  607. ; None - all interrupts are masked off
  608. ;
  609. ;--
  610. cPublicProc _HalpDisableAllInterrupts,0
  611. ;
  612. ; Raising to HIGH_LEVEL disables interrupts for the SystemPro HAL
  613. ;
  614. mov ecx, HIGH_LEVEL
  615. fstCall KfRaiseIrql
  616. stdRET _HalpDisableAllInterrupts
  617. stdENDP _HalpDisableAllInterrupts
  618. ;++
  619. ;
  620. ; VOID
  621. ; HalpReenableInterrupts (
  622. ; IN KIRQL Irql
  623. ; )
  624. ;
  625. ; Routine Description:
  626. ;
  627. ; Restores irql level.
  628. ;
  629. ; Arguments:
  630. ;
  631. ; Irql - Irql state to restore to.
  632. ;
  633. ; Return Value:
  634. ;
  635. ; None
  636. ;
  637. ;--
  638. HriNewIrql equ [esp + 4]
  639. cPublicProc _HalpReenableInterrupts,1
  640. cPublicFpo 1, 0
  641. movzx ecx, byte ptr HriNewIrql
  642. fstCall KfLowerIrql
  643. stdRET _HalpReenableInterrupts
  644. stdENDP _HalpReenableInterrupts
  645. page ,132
  646. subttl "Interrupt Controller Chip Initialization"
  647. ;++
  648. ;
  649. ; VOID
  650. ; HalpInitializePICs (
  651. ; )
  652. ;
  653. ; Routine Description:
  654. ;
  655. ; This routine sends the 8259 PIC initialization commands and
  656. ; masks all the interrupts on 8259s.
  657. ;
  658. ; Arguments:
  659. ;
  660. ; None
  661. ;
  662. ; Return Value:
  663. ;
  664. ; None.
  665. ;
  666. ;--
  667. cPublicProc _HalpInitializePICs ,1
  668. pushfd
  669. push esi ; save caller's esi
  670. cli ; disable interrupt
  671. lea esi, PICsInitializationString
  672. lodsw ; (AX) = PIC port 0 address
  673. Hip10: movzx edx, ax
  674. outsb ; output ICW1
  675. IODelay
  676. inc edx ; (DX) = PIC port 1 address
  677. outsb ; output ICW2
  678. IODelay
  679. outsb ; output ICW3
  680. IODelay
  681. outsb ; output ICW4
  682. IODelay
  683. mov al, 0FFH ; mask all 8259 irqs
  684. out dx,al ; write mask to PIC
  685. lodsw
  686. cmp ax, 0 ; end of init string?
  687. jne short Hip10 ; go init next PIC
  688. ;
  689. ; If P0 then squirrel away 4d0 and 4d1 for the other processor to use.
  690. ;
  691. cmp byte ptr fs:PcHal.PcrNumber, 0 ; Is this processor 0
  692. jne short Hip16
  693. mov dx, EDGELEVEL_CONTROL_2 ; Yes then save 4d0-4d1
  694. in al, dx
  695. shl eax, 8
  696. mov dx, EDGELEVEL_CONTROL_1
  697. in al, dx
  698. mov _SpP0EdgeLevelValue, ax
  699. jmp short Hip18
  700. ;
  701. ; If not P0 then program 4d0 and 4d1 to the values P0 used for them!
  702. ;
  703. Hip16:
  704. mov ax, _SpP0EdgeLevelValue
  705. mov dx, EDGELEVEL_CONTROL_1
  706. out dx, al
  707. inc edx
  708. shr eax, 8
  709. mov dx, EDGELEVEL_CONTROL_2
  710. out dx, al
  711. Hip18:
  712. pop esi ; restore caller's esi
  713. popfd ; restore interrupts
  714. stdRET _HalpInitializePICs
  715. stdENDP _HalpInitializePICs
  716. _TEXT ends
  717. end