hal!HalEndSystemInterrupt函数分析之什么时候调用nt!KiDispatchInterrupt函数
Breakpoint 10 hit
eax=ffdff000 ebx=105ecdf6 ecx=00000000 edx=000002fe esi=80affb39 edi=a81aad98
eip=80b00720 esp=f78d6ca0 ebp=f78d6cb8 iopl=0 nv up ei pl nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000202
nt!KiDispatchInterrupt:
80b00720 648b1d1c000000 mov ebx,dword ptr fs:[1Ch] fs:0030:0000001c=ffdff000
0: kd> kc
00 nt!KiDispatchInterrupt
01 hal!HalEndSystemInterrupt
02 nt!KeUpdateSystemTime
03 nt!KiXMMIZeroPagesNoSave
04 nt!MiZeroPageWorker
WARNING: Frame IP not in any known module. Following frames may be wrong.
05 0x0
06 nt!ExpWorkerThread
07 nt!PspSystemThreadStartup
08 nt!KiThreadStartup
0: kd> kv
ChildEBP RetAddr Args to Child
00 f78d6c9c 804ee92c 00000000 105ecdf6 80affb45 nt!KiDispatchInterrupt (FPO: [0,0,0]) [d:\srv03rtm\base\ntos\ke\i386\ctxswap.asm @ 175]
01 f78d6ca8 80affb45 105ecd00 000000d1 f78d6d4c hal!HalEndSystemInterrupt+0x5c (FPO: [2,2,0]) [d:\srv03rtm\base\hals\halmps\i386\mpsysint.asm @ 138]
02 f78d6ca8 80a464d6 105ecd00 000000d1 f78d6d4c nt!KeUpdateSystemTime+0x11d (FPO: [0,2] TrapFrame @ f78d6cb8) [d:\srv03rtm\base\ntos\ke\i386\clockint.asm @ 302]
03 f78d6d40 80ab0973 02ddd46e c03deae0 f78d6d80 nt!KiXMMIZeroPagesNoSave+0xa (FPO: [0,1,0]) [d:\srv03rtm\base\ntos\ke\i386\zero.asm @ 176]
04 f78d6d4c f78d6d80 80ab0986 89dd0da0 80bf5c80 nt!MiZeroPageWorker+0x267 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\mm\zeropage.c @ 557]
WARNING: Frame IP not in any known module. Following frames may be wrong.
05 f78d6d80 80af2bb9 f7ab8000 00000000 89dd0da0 0xf78d6d80
06 f78d6dac 80d391f0 89dcf290 00000000 00000000 nt!ExpWorkerThread+0x10f (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\ex\worker.c @ 1153]
07 f78d6ddc 80b00d52 80af2aaa 00000000 00000000 nt!PspSystemThreadStartup+0x2e (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\ps\create.c @ 2213]
08 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16 [d:\srv03rtm\base\ntos\ke\i386\threadbg.asm @ 81]
0: kd> !irql
Debugger saved IRQL for processor 0x0 -- 2 (DISPATCH_LEVEL)
;++
;
; VOID
; HalpEndSystemInterrupt
; IN KIRQL NewIrql,
; IN ULONG Vector
; )
;
; Routine Description:
;
; This routine is used to lower IRQL to the specified value.
; The IRQL and PIRQL will be updated accordingly. Also, this
; routine checks to see if any software interrupt should be
; generated. The following condition will cause software
; interrupt to be simulated:
; any software interrupt which has higher priority than
; current IRQL's is pending.
;
; NOTE: This routine simulates software interrupt as long as
; any pending SW interrupt level is higher than the current
; IRQL, even when interrupts are disabled.
;
; Arguments:
;
; NewIrql - the new irql to be set.
;
; Vector - Vector number of the interrupt
;
; Note that esp+12 is the beginning of interrupt/trap frame and upon
; entering to this routine the interrupts are off.
;
; Return Value:
;
; None.
;
;--
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
cli
pop ecx
pop ebx
jmp short es05
stdENDP _HalEndSystemInterrupt