mirror of https://github.com/lianthony/NT4.0
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.
711 lines
18 KiB
711 lines
18 KiB
;++
|
|
;
|
|
;Copyright (c) 1992 NCR Corporation
|
|
;
|
|
;Module Name:
|
|
;
|
|
; ncrsyint.asm
|
|
;
|
|
;Abstract:
|
|
;
|
|
; This module implements the HAL routines to enable/disable system
|
|
; interrupts.
|
|
;
|
|
;Author:
|
|
;
|
|
; Richard Barton (o-richb) 24-Jan-1992
|
|
;
|
|
;Environment:
|
|
;
|
|
; Kernel Mode
|
|
;
|
|
;Revision History:
|
|
;
|
|
;--
|
|
|
|
|
|
.486p
|
|
.xlist
|
|
include hal386.inc
|
|
include callconv.inc ; calling convention macros
|
|
include i386\ix8259.inc
|
|
include i386\kimacro.inc
|
|
include mac386.inc
|
|
include i386\ncr.inc
|
|
.list
|
|
|
|
EXTRNP KfLowerIrql,1,,FASTCALL
|
|
EXTRNP _NCRClearQicIpi,1
|
|
EXTRNP _HalQicRequestIpi,2
|
|
EXTRNP _NCRAdjustDynamicClaims,0
|
|
extrn KiI8259MaskTable:DWORD
|
|
extrn _NCRLogicalNumberToPhysicalMask:DWORD
|
|
extrn _NCRProcessorIDR:DWORD
|
|
extrn _NCRNeverClaimIRQs:DWORD
|
|
extrn _NCRMaxIRQsToClaim:DWORD
|
|
extrn _NCRGlobalClaimedIRQs:DWORD
|
|
ifdef DBG
|
|
extrn _NCRProcessorClaimedIRQs:DWORD
|
|
extrn _NCRClaimCount:DWORD
|
|
extrn _NCRStolenCount:DWORD
|
|
extrn _NCRUnclaimCount:DWORD
|
|
endif
|
|
|
|
|
|
ifdef IRQL_METRICS
|
|
extrn HalPostponedIntCount:dword
|
|
endif
|
|
|
|
|
|
_TEXT SEGMENT DWORD USE32 PUBLIC 'CODE'
|
|
ASSUME CS:FLAT, DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
|
|
|
|
|
|
;++
|
|
;BOOLEAN
|
|
;HalBeginSystemInterrupt(
|
|
; IN KIRQL Irql
|
|
; IN CCHAR Vector,
|
|
; OUT PKIRQL OldIrql
|
|
; )
|
|
;
|
|
;
|
|
;
|
|
;Routine Description:
|
|
;
|
|
; This routine is used to determine whether the given interrupt is
|
|
; spurious and to raise the irql to the given value.
|
|
; It is called before the interrupt service routine code is executed.
|
|
;
|
|
; N.B. This routine does NOT preserve EAX or EBX
|
|
;
|
|
; On a UP machine the interrupt dismissed at BeginSystemInterrupt time.
|
|
; This is fine since the irql is being raise to mask it off.
|
|
; HalEndSystemInterrupt is simply a LowerIrql request.
|
|
;
|
|
;
|
|
;Arguments:
|
|
;
|
|
; Irql - Supplies the IRQL to raise to
|
|
;
|
|
; Vector - Supplies the vector of the interrupt being handled
|
|
;
|
|
; OldIrql- Location to return OldIrql
|
|
;
|
|
;
|
|
;Return Value:
|
|
;
|
|
; FALSE - Interrupt is spurious and should be ignored
|
|
;
|
|
; TRUE - Interrupt is real and Irql raised.
|
|
;
|
|
;--
|
|
HbsiIrql equ byte ptr [esp+4]
|
|
HbsiVector equ byte ptr [esp+8]
|
|
HbsiOldIrql equ dword ptr [esp+12]
|
|
|
|
cPublicProc _HalBeginSystemInterrupt ,3
|
|
cPublicFpo 3,0
|
|
movzx ebx,HbsiVector ; (eax) = System Vector
|
|
sub ebx, PRIMARY_VECTOR_BASE ; (eax) = 8259 IRQ #
|
|
cmp ebx, 1FH ; if greater then CPI
|
|
ja HalpNotSpurious
|
|
|
|
;
|
|
; we could be spurious at irq 7
|
|
;
|
|
mov eax,ebx ; lets mask off whether it is
|
|
and eax,0fh ; secondary or primary
|
|
cmp eax, 7H
|
|
jne HbsiCheckIrq0F
|
|
|
|
align dword
|
|
HbsiCheckIrq07:
|
|
;
|
|
; Check to see if this is a spurious interrupt at irq7
|
|
;
|
|
in al, PIC1_PORT0 ; (al) = content of PIC 1 ISR
|
|
test al, 10000000B ; Is In-Service register set?
|
|
jnz short HalpNotSpurious ; No, so this is NOT a spurious int
|
|
xor eax, eax ; return FALSE
|
|
stdRET _HalBeginSystemInterrupt
|
|
|
|
align dword
|
|
HbsiCheckIrq0F:
|
|
|
|
;
|
|
; we could be spurious with irq F
|
|
;
|
|
mov eax,ebx ; lets mask off whether it is
|
|
and eax,0fh ; secondary or primary
|
|
cmp eax, 0FH
|
|
jne HalpNotSpurious
|
|
|
|
;
|
|
; Check to see if this is a spurious interrupt at irq F
|
|
;
|
|
in al, PIC2_PORT0 ; (al) = content of PIC 1 ISR
|
|
test al, 10000000B ; Is In-Service register set?
|
|
jnz short HalpNotSpurious ; No, this is NOT a spurious int,
|
|
; go do the normal interrupt stuff
|
|
|
|
;
|
|
; This is a spurious interrupt.
|
|
; Because the slave PIC is cascaded to irq2 of master PIC, we need to
|
|
; dismiss the interupt on master PIC's irq2.
|
|
;
|
|
|
|
mov al, PIC2_EOI ; Specific eoi to master for pic2 eoi
|
|
out PIC1_PORT0, al ; send irq2 specific eoi to master
|
|
|
|
xor eax, eax ; return FALSE
|
|
stdRET _HalBeginSystemInterrupt
|
|
|
|
align dword
|
|
HalpNotSpurious:
|
|
if DBG
|
|
cmp ebx, 4FH
|
|
jbe @f
|
|
int 3
|
|
align dword
|
|
@@:
|
|
|
|
endif
|
|
;
|
|
; Store OldIrql
|
|
;
|
|
mov eax, HbsiOldIrql
|
|
mov cl, PCR[PcIrql]
|
|
mov [eax], cl
|
|
|
|
;
|
|
; Raise IRQL to requested level
|
|
;
|
|
mov al, HbsiIrql ; (eax) = irql
|
|
; (ebx) = IRQ #
|
|
;
|
|
; Now we check to make sure the Irql of this interrupt > current Irql.
|
|
; If it is not, we dismiss it as spurious and set the appropriate bit
|
|
; in the IRR so we can dispatch the interrupt when Irql is lowered
|
|
;
|
|
cmp al, cl
|
|
jbe Hbsi300
|
|
;
|
|
; now check for a cpi.
|
|
;
|
|
|
|
cmp ebx, NCR_CPI_VECTOR_BASE - PRIMARY_VECTOR_BASE ; check for VIC ipi
|
|
mov PCR[PcIrql], al ; set new Irql
|
|
jb CheckClaim
|
|
|
|
cmp ebx, NCR_QIC_CPI_VECTOR_BASE - PRIMARY_VECTOR_BASE ; check for QIC ipi
|
|
jb VicEOI
|
|
|
|
and ebx,7H ; only the mask of irq
|
|
stdCall _NCRClearQicIpi, <ebx>
|
|
|
|
jmp NCRCPIEOId
|
|
|
|
VicEOI:
|
|
and bl, 7H ; only the mask of irq
|
|
mov al, bl
|
|
or al, PIC1_EOI_MASK ; create specific eoi mask for master
|
|
out PIC1_PORT0, al ; dismiss the interrupt
|
|
|
|
NCRCPIEOId:
|
|
sti
|
|
mov eax, 1 ; return TRUE, interrupt dismissed
|
|
stdRET _HalBeginSystemInterrupt
|
|
|
|
;RMU
|
|
;
|
|
; Logic used to dynamicly claim device interrupts
|
|
;
|
|
|
|
CheckClaim:
|
|
mov ecx, ebx ; get vector
|
|
|
|
;
|
|
; Lets check for a status change interrupt because it is a broadcast interrupt
|
|
; and is sent to all processors. In this case we skip the Claim logic completely.
|
|
; If we try to claim this interrupt it will cause problems because it is valid for a
|
|
; processor to get this interrupt while another processor has it claimed.
|
|
;
|
|
|
|
cmp ecx, 027h ; status change interrupt is at vector PRIMARY_VECTOR_BASE + 027H
|
|
jz DontClaim ; done claim if equal
|
|
|
|
;
|
|
;
|
|
;
|
|
|
|
and ecx, 0fh ; now is irql
|
|
mov eax, 1 ; build irq mask
|
|
shl eax, cl
|
|
|
|
test eax, _NCRNeverClaimIRQs ; see if we should never claim it irq
|
|
jnz DontClaim
|
|
|
|
mov ecx, _NCRGlobalClaimedIRQs
|
|
mov edx, PCR[PcHal.PcrMyClaimedIRQs]
|
|
and ecx, eax ; set if irq claimed globally
|
|
and edx, eax ; set if irq claimed privately
|
|
|
|
test edx, ecx ; if irq already claimed
|
|
jz AdjustClaim
|
|
|
|
DontClaim:
|
|
sti
|
|
mov eax, 1 ; return TRUE, interrupt dismissed
|
|
stdRET _HalBeginSystemInterrupt
|
|
|
|
AdjustClaim:
|
|
test edx, edx
|
|
not edx ; is it claimed privately?
|
|
jnz PrivateUnclaim ; yes, then clear claim
|
|
|
|
test ecx,ecx ; is it claimed by another?
|
|
jnz Unclaimed ; don't unclaim
|
|
|
|
mov ecx, PCR[PcHal.PcrMyClaimedIRQsCount] ; see if you have our fair share
|
|
cmp ecx, _NCRMaxIRQsToClaim ; of irqs claimed then handle if
|
|
jl ClaimForMe ; but don't claim
|
|
|
|
HandleNoClaim:
|
|
sti
|
|
mov eax, 1 ; return TRUE, interrupt dismissed
|
|
stdRET _HalBeginSystemInterrupt
|
|
|
|
ClaimForMe:
|
|
|
|
mov edx, eax
|
|
push ebx ; save vector
|
|
mov ebx, PCR[PcHal.PcrMyClaimedIRQs] ; our claimed irqs
|
|
or ebx, eax
|
|
mov eax, _NCRGlobalClaimedIRQs ; what global claim should be
|
|
GlobalClaim:
|
|
test eax,edx ; this irq has been stolen
|
|
jnz IRQStolen ; by another processor
|
|
mov ecx,ebx
|
|
or ecx,eax
|
|
lock cmpxchg _NCRGlobalClaimedIRQs, ecx
|
|
jne GlobalClaim
|
|
|
|
add esp,4 ; throw away saved vector we do
|
|
; not need it
|
|
;
|
|
; Lets claim the interrupt now
|
|
;
|
|
mov eax,ebx
|
|
mov PCR[PcHal.PcrMyClaimedIRQs],eax ; claim irq privately
|
|
|
|
VIC_WRITE ClaimRegLsb ; set VIC claim registers
|
|
shr eax,8
|
|
VIC_WRITE ClaimRegMsb
|
|
inc PCR[PcHal.PcrMyClaimedIRQsCount]
|
|
|
|
mov eax,PCR[PcHal.PcrMyClaimedIRQsCount]
|
|
VIC_WRITE ActivityReg
|
|
|
|
ifdef DBG
|
|
mov ecx,PCR[PcNumber]
|
|
mov eax,PCR[PcHal.PcrMyClaimedIRQs]
|
|
mov _NCRProcessorClaimedIRQs[ecx*4], eax
|
|
inc _NCRClaimCount;
|
|
endif
|
|
|
|
; done claiming
|
|
ClaimDone:
|
|
|
|
sti
|
|
mov eax, 1 ; return TRUE, interrupt dismissed
|
|
stdRET _HalBeginSystemInterrupt
|
|
|
|
IRQStolen:
|
|
|
|
ifdef DBG
|
|
inc _NCRStolenCount;
|
|
endif
|
|
|
|
pop ebx ; restore vector
|
|
and ebx, 0fh ; clear high nibble due to SMC or Status Change vector
|
|
cmp ebx, 8 ; EOI to master or slave?
|
|
mov al, bl
|
|
jae short SHbsiEOIMaster ; EIO to both master and slave
|
|
or al, PIC1_EOI_MASK ; create specific eoi mask for master
|
|
out PIC1_PORT0, al ; dismiss the interrupt
|
|
jmp short SHbsiMasterEOId
|
|
|
|
SHbsiEOIMaster:
|
|
mov al, OCW2_NON_SPECIFIC_EOI ; send non specific eoi to slave
|
|
out PIC2_PORT0, al
|
|
mov al, PIC2_EOI ; specific eoi to master for pic2 eoi
|
|
out PIC1_PORT0, al ; send irq2 specific eoi to master
|
|
SHbsiMasterEOId:
|
|
|
|
xor eax, eax ; return FALSE, spurious interrupt
|
|
stdRET _HalBeginSystemInterrupt
|
|
|
|
align dword
|
|
Hbsi300:
|
|
;
|
|
; Raise Irql to prevent it from happening again
|
|
;
|
|
|
|
;
|
|
; Get the PIC masks for Irql
|
|
;
|
|
movzx eax, cl
|
|
mov PCR[PcHal.PcrMyPICsIrql], eax
|
|
mov eax, KiI8259MaskTable[eax*4]
|
|
or eax, PCR[PcIDR]
|
|
;
|
|
; Write the new interrupt mask register back to the 8259
|
|
;
|
|
SET_IRQ_MASK
|
|
;
|
|
; if this isn't a CPI, EOI the interrupt to give the VIC a chance
|
|
; to reroute it
|
|
;
|
|
cmp ebx, NCR_CPI_VECTOR_BASE - PRIMARY_VECTOR_BASE ; EOI for CPI?
|
|
jae NCRPostponeCPI ; no need to EOI CPI
|
|
;
|
|
;RMU
|
|
; Logic used to unclaim interrupts. This is done when drivers have disabled
|
|
; an interrupt.
|
|
;
|
|
;
|
|
mov ecx, ebx ; get vector
|
|
and ecx, 0fh ; now is irql
|
|
mov eax, 1 ; build irq mask
|
|
shl eax, cl
|
|
mov edx, PCR[PcHal.PcrMyClaimedIRQs]
|
|
and edx, eax ; claiming fixed?
|
|
jz Unclaimed ; don't unclaim
|
|
|
|
mov ecx, PCR[PcHal.PcrMyClaimedIRQsCount] ; if we don't have our fair
|
|
cmp ecx, _NCRMaxIRQsToClaim ; share of irqs claimed then
|
|
jle Unclaimed ; don't unclaim
|
|
|
|
not edx ; clear irq bit
|
|
mov eax, _NCRGlobalClaimedIRQs ; what global claim should be
|
|
GlobalUnclaim:
|
|
mov ecx, edx
|
|
and ecx, eax
|
|
lock cmpxchg _NCRGlobalClaimedIRQs, ecx
|
|
jne GlobalUnclaim
|
|
|
|
PrivateUnclaim:
|
|
mov eax, PCR[PcHal.PcrMyClaimedIRQs]
|
|
and eax, edx
|
|
|
|
mov PCR[PcHal.PcrMyClaimedIRQs],eax
|
|
VIC_WRITE ClaimRegLsb
|
|
shr eax,8
|
|
VIC_WRITE ClaimRegMsb
|
|
dec PCR[PcHal.PcrMyClaimedIRQsCount]
|
|
|
|
mov eax,PCR[PcHal.PcrMyClaimedIRQsCount]
|
|
VIC_WRITE ActivityReg
|
|
|
|
ifdef DBG
|
|
mov ecx,PCR[PcNumber]
|
|
mov eax,PCR[PcHal.PcrMyClaimedIRQs]
|
|
mov _NCRProcessorClaimedIRQs[ecx*4], eax
|
|
inc _NCRUnclaimCount;
|
|
endif
|
|
|
|
;
|
|
Unclaimed:
|
|
|
|
and ebx, 0fh ; clear high nibble due to SMC or Status Change vector
|
|
cmp ebx, 8 ; EOI to master or slave?
|
|
mov al, bl
|
|
jae short HbsiEOIMaster ; EIO to both master and slave
|
|
or al, PIC1_EOI_MASK ; create specific eoi mask for master
|
|
out PIC1_PORT0, al ; dismiss the interrupt
|
|
jmp short HbsiMasterEOId
|
|
|
|
HbsiEOIMaster:
|
|
mov al, OCW2_NON_SPECIFIC_EOI ; send non specific eoi to slave
|
|
out PIC2_PORT0, al
|
|
mov al, PIC2_EOI ; specific eoi to master for pic2 eoi
|
|
out PIC1_PORT0, al ; send irq2 specific eoi to master
|
|
HbsiMasterEOId:
|
|
|
|
ifdef IRQL_METRICS
|
|
lock inc HalPostponedIntCount
|
|
endif
|
|
|
|
xor eax, eax ; return FALSE, spurious interrupt
|
|
stdRET _HalBeginSystemInterrupt
|
|
|
|
align dword
|
|
NCRPostponeCPI:
|
|
;
|
|
; CPIs must be reissued since when we EOI them they're gone
|
|
;
|
|
|
|
cmp ebx, NCR_QIC_CPI_VECTOR_BASE - PRIMARY_VECTOR_BASE ; check for QIC ipi
|
|
jb VicCPI
|
|
|
|
movzx ecx, bl
|
|
sub ecx, NCR_QIC_CPI_VECTOR_BASE - PRIMARY_VECTOR_BASE
|
|
and ecx, 7
|
|
|
|
;
|
|
; Clear the current CPI so we can reissue it again
|
|
;
|
|
|
|
push ecx
|
|
stdCall _NCRClearQicIpi, <ecx>
|
|
pop ecx
|
|
|
|
;
|
|
; now reissue the same CPI... since our mask is raised and we've EOId
|
|
; the other we'll get this one when we lower our masks
|
|
;
|
|
|
|
mov eax, PCR[PcHal.PcrMyLogicalMask]
|
|
stdCall _HalQicRequestIpi,<eax,ecx>
|
|
|
|
jmp ReissuedCPIDone
|
|
VicCPI:
|
|
movzx ecx, bl
|
|
sub ecx, NCR_CPI_VECTOR_BASE - PRIMARY_VECTOR_BASE
|
|
and ecx, 7
|
|
mov al, cl
|
|
or al, PIC1_EOI_MASK ; create specific eoi mask for master
|
|
out PIC1_PORT0, al ; dismiss the interrupt
|
|
|
|
;
|
|
; now reissue the same CPI...since our mask is raised and we've EOId
|
|
; the other we'll get this one when we lower our masks.
|
|
;
|
|
shr ecx, 1 ; we're determining which VIC
|
|
lea edx, [ecx*8] ; offset corresponds to the
|
|
adc edx, VIC_BASE_ADDRESS ; given vector
|
|
mov eax, PCR[PcHal.PcrMyLogicalNumber]
|
|
mov eax, dword ptr _NCRLogicalNumberToPhysicalMask[eax*4]
|
|
out dx, al
|
|
|
|
ReissuedCPIDone:
|
|
|
|
ifdef IRQL_METRICS
|
|
lock inc HalPostponedIntCount
|
|
endif
|
|
|
|
xor eax, eax ; return FALSE, spurious interrupt
|
|
stdRET _HalBeginSystemInterrupt
|
|
|
|
stdENDP _HalBeginSystemInterrupt
|
|
|
|
;++
|
|
;BOOLEAN
|
|
;HalEndSystemInterrupt(
|
|
; IN KIRQL Irql
|
|
; IN CCHAR Vector,
|
|
; )
|
|
;
|
|
;
|
|
;
|
|
;Routine Description:
|
|
;
|
|
; This routine is used to dismiss the specified interrupt vector and
|
|
; to lower the irql to the given value.
|
|
; It is called after the interrupt service routine code is executed.
|
|
;
|
|
; N.B. This routine does NOT preserve EAX or EBX
|
|
;
|
|
;Arguments:
|
|
;
|
|
; Irql - Supplies the interrupt level of the interrupt to be dismissed
|
|
;
|
|
; Vector - Supplies the vector of the interrupt to be dismissed
|
|
;
|
|
;Return Value:
|
|
;
|
|
; None.
|
|
;
|
|
;--
|
|
HesiIrql equ [esp+4]
|
|
HesiVector equ [esp+8]
|
|
|
|
cPublicProc _HalEndSystemInterrupt ,2
|
|
cPublicFpo 2,0
|
|
movzx eax, byte ptr HesiVector ; (eax) = System Vector
|
|
sub eax, PRIMARY_VECTOR_BASE ; (eax) = 8259 IRQ #
|
|
if DBG
|
|
cmp eax, 4FH
|
|
jbe Hesi00
|
|
int 3
|
|
align dword
|
|
Hesi00:
|
|
|
|
endif
|
|
|
|
;
|
|
; Dismiss interrupt. Current interrupt is already masked off. note that
|
|
; cpi's are eoi'ed at the beginning.
|
|
;
|
|
cmp eax, NCR_CPI_VECTOR_BASE - PRIMARY_VECTOR_BASE ; EOI for CPI?
|
|
mov ecx, HesiIrql ; (cl) = NewIrql
|
|
jae short Hesi10 ; no need to EOI CPI
|
|
and eax, 0fh ; clear high nibble due to SMC or Status Change vector
|
|
|
|
cmp eax, 8 ; EOI to master or slave?
|
|
|
|
jae short Hesi100 ; EIO to both master and slave
|
|
or al, PIC1_EOI_MASK ; create specific eoi mask for master
|
|
out PIC1_PORT0, al ; dismiss the interrupt
|
|
|
|
Hesi10:
|
|
fstCall KfLowerIrql ; (cl) = NewIrql
|
|
stdRet _HalEndSystemInterrupt
|
|
|
|
Hesi100:
|
|
mov al, OCW2_NON_SPECIFIC_EOI ; send non specific eoi to slave
|
|
out PIC2_PORT0, al
|
|
mov al, PIC2_EOI ; specific eoi to master for pic2 eoi
|
|
out PIC1_PORT0, al ; send irq2 specific eoi to master
|
|
|
|
fstCall KfLowerIrql ; (cl) = NewIrql
|
|
stdRet _HalEndSystemInterrupt
|
|
|
|
stdENDP _HalEndSystemInterrupt
|
|
|
|
;++
|
|
;VOID
|
|
;HalDisableSystemInterrupt(
|
|
; IN CCHAR Vector,
|
|
; IN KIRQL Irql
|
|
; )
|
|
;
|
|
;
|
|
;
|
|
;Routine Description:
|
|
;
|
|
; Disables a system interrupt.
|
|
;
|
|
;Arguments:
|
|
;
|
|
; Vector - Supplies the vector of the interrupt to be disabled
|
|
;
|
|
; Irql - Supplies the interrupt level of the interrupt to be disabled
|
|
;
|
|
;Return Value:
|
|
;
|
|
; None.
|
|
;
|
|
;--
|
|
|
|
cPublicProc _HalDisableSystemInterrupt ,2
|
|
cPublicFpo 2,0
|
|
|
|
;
|
|
|
|
movzx ecx, byte ptr [esp+4] ; (ecx) = Vector
|
|
and ecx, 0FH ; (ecx) = 8259 irq #
|
|
mov edx, 1
|
|
shl edx, cl ; (ebx) = bit in IMR to disable
|
|
cli
|
|
or PCR[PcIDR], edx
|
|
|
|
;
|
|
; save IDR in table for use by NCRAdjustDynamicClaims
|
|
;
|
|
mov eax,PCR[PcNumber]
|
|
or _NCRProcessorIDR[eax*4],edx
|
|
;
|
|
xor eax, eax
|
|
;
|
|
; Get the current interrupt mask register from the 8259
|
|
;
|
|
in al, PIC2_PORT1
|
|
shl eax, 8
|
|
in al, PIC1_PORT1
|
|
;
|
|
; Mask off the interrupt to be disabled
|
|
;
|
|
or eax, edx
|
|
;
|
|
; Write the new interrupt mask register back to the 8259
|
|
;
|
|
out PIC1_PORT1, al
|
|
shr eax, 8
|
|
out PIC2_PORT1, al
|
|
PIC2DELAY
|
|
|
|
sti
|
|
|
|
stdCall _NCRAdjustDynamicClaims
|
|
|
|
stdRET _HalDisableSystemInterrupt
|
|
|
|
stdENDP _HalDisableSystemInterrupt
|
|
|
|
;++
|
|
;
|
|
;BOOLEAN
|
|
;HalEnableSystemInterrupt(
|
|
; IN ULONG Vector,
|
|
; IN KIRQL Irql,
|
|
; IN KINTERRUPT_MODE InterruptMode
|
|
; )
|
|
;
|
|
;
|
|
;Routine Description:
|
|
;
|
|
; Enables a system interrupt
|
|
;
|
|
;Arguments:
|
|
;
|
|
; Vector - Supplies the vector of the interrupt to be enabled
|
|
;
|
|
; Irql - Supplies the interrupt level of the interrupt to be enabled.
|
|
;
|
|
;Return Value:
|
|
;
|
|
; None.
|
|
;
|
|
;--
|
|
|
|
cPublicProc _HalEnableSystemInterrupt ,3
|
|
cPublicFpo 3,0
|
|
|
|
mov ecx, dword ptr [esp+4] ; (ecx) = Vector
|
|
and ecx, 0FH
|
|
mov eax, 1
|
|
shl eax, cl ; (ebx) = bit in IMR to enable
|
|
not eax
|
|
|
|
cli
|
|
and PCR[PcIDR], eax
|
|
;
|
|
; save IDR in table for use by NCRAdjustDynamicClaims
|
|
;
|
|
mov edx,PCR[PcNumber]
|
|
and _NCRProcessorIDR[edx*4],eax
|
|
;
|
|
; Get the PIC masks for Irql 0
|
|
;
|
|
mov eax, KiI8259MaskTable[0]
|
|
or eax, PCR[PcIDR]
|
|
;
|
|
; Write the new interrupt mask register back to the 8259
|
|
;
|
|
SET_IRQ_MASK
|
|
|
|
sti
|
|
|
|
stdCall _NCRAdjustDynamicClaims
|
|
|
|
mov eax, 1 ; return TRUE
|
|
stdRET _HalEnableSystemInterrupt
|
|
|
|
stdENDP _HalEnableSystemInterrupt
|
|
|
|
|
|
_TEXT ENDS
|
|
|
|
END
|