hal!HalEndSystemInterrupt函数为什么能调用nt!KiDispatchInterrupt函数因为hal!HalRequestSoftwareInterrupt最后设置PCR[PcHal.DpcPending]为1
第一部分:
HeiNewIrql equ [esp + 4]
HeiVector equ [esp + 8]
cPublicProc _HalEndSystemInterrupt ,2
cPublicFpo 2, 0
xor ecx,ecx
mov cl, byte ptr HeiNewIrql ; get new IRQL
mov cl, _HalpIRQLtoTPR[ecx] ; get corresponding TPR value
mov dword ptr APIC[LU_EOI], 0 ; send EOI to APIC local unit
APICFIX edx
cmp cl, DPC_VECTOR ; Is new irql < DPC?
jc short es10 ; Yes, go check for pending DPC
es05: mov dword ptr APIC[LU_TPR], ecx ; Set new Priority
;
; We have to ensure that the requested priority is set before
; we return. The caller is counting on it.
;
mov edx, dword ptr APIC[LU_TPR]
CHECKTPR ecx, edx
stdRET _HalEndSystemInterrupt
es10: cmp PCR[PcHal.DpcPending], 0 ; Is a DPC pending?
mov PCR[PcHal.ShortDpc], 0 ; Clear short dpc flag
jz short es05 ; No, eoi
mov dword ptr APIC[LU_TPR], DPC_VECTOR ; lower to DPC level
APICFIX edx
push ebx ; Save EBX (used by KiDispatchInterrupt)
push ecx ; Save OldIrql
cPublicFpo 2, 2
sti
es20: mov PCR[PcHal.DpcPending], 0 ; Clear pending flag
stdCall _KiDispatchInterrupt ; Dispatch interrupt //这里调用了_KiDispatchInterrupt
cli
pop ecx
pop ebx
jmp short es05
stdENDP _HalEndSystemInterrupt
第二部分:
F:\srv03rtm>grep "DpcPending" -nr F:\srv03rtm\base\hals |grep -v "inary"
F:\srv03rtm\base\hals/halmps/i386/mpswint.asm:132:; DpcPending flag - whomever set ShortDpc will check the flag
F:\srv03rtm\base\hals/halmps/i386/mpswint.asm:136:rsi10: mov PCR[PcHal.DpcPending], 1
F:\srv03rtm\base\hals/halmps/i386/mpsysint.asm:121:es10: cmp PCR[PcHal.DpcPending], 0 ; Is a DPC pending?
F:\srv03rtm\base\hals/halmps/i386/mpsysint.asm:134:es20: mov PCR[PcHal.DpcPending], 0 ; Clear pending flag
参考:
cPublicFastCall HalRequestSoftwareInterrupt ,1
cPublicFpo 0,0
cmp cl, PCR[PcHal.ShortDpc]
je short rsi10
xor eax, eax
mov al, cl ; get irql
;
; In an APIC based system the TPR is the IDTEntry
;
xor ecx, ecx
mov cl, _HalpIRQLtoTPR[eax] ; get IDTEntry for IRQL
;
; Build the ICR Command - Fixed Delivery to Self, IDTEntry == al
;
or ecx, (DELIVER_FIXED OR ICR_SELF)
;
; Make sure the ICR is available
;
pushfd ; save interrupt mode
cli ; disable interrupt
STALL_WHILE_APIC_BUSY
;
; Now write the command to the Memory Mapped Register
;
mov dword ptr APIC[LU_INT_CMD_LOW], ecx
;
; We have to wait for the request to be delivered.
; If we don't wait here, then we will return to the caller
; before the request has been issued.
;
STALL_WHILE_APIC_BUSY
popfd ; restore original interrupt mode
fstRET HalRequestSoftwareInterrupt
;
; Requesting a DPC interrupt when ShortDpc is set. Just set the
; DpcPending flag - whomever set ShortDpc will check the flag
; at the proper time
;
rsi10: mov PCR[PcHal.DpcPending], 1这里!!!
fstRET HalRequestSoftwareInterrupt
参考: