📄 irq.s
字号:
Pic1:
/* Write mask to slave PIC */
mov al, 0x20
out 0xA0, al
mov al, 0x62
out 0x20, al
DoneBegin:
/* Enable interrupts and return TRUE */
in al, 0x21
sti
mov eax, 1
ret 12
#if DBG
InvalidIRQ:
/* Dismiss it */
mov eax, 0
ret 12
#endif
.endfunc
.globl _HalEndSystemInterrupt@8
.func HalEndSystemInterrupt@8
_HalEndSystemInterrupt@8:
/* Get the IRQL and check if it's a software interrupt */
movzx ecx, byte ptr [esp+4]
cmp dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
jbe SkipMask2
/* Hardware interrupt, mask the appropriate IRQs in the PIC */
mov eax, KiI8259MaskTable[ecx*4]
or eax, PCR[KPCR_IDR]
out 0x21, al
shr eax, 8
out 0xA1, al
SkipMask2:
/* Set IRQL and check if there are pending software interrupts */
mov PCR[KPCR_IRQL], ecx
mov eax, PCR[KPCR_IRR]
mov al, SoftIntByteTable[eax]
cmp al, cl
ja DoCall
ret 8
DoCall:
/* There are pending software interrupts, call their handlers */
add esp, 12
jmp SoftIntHandlerTable2[eax*4]
.endfunc
.globl @KfLowerIrql@4
.func @KfLowerIrql@4
_@KfLowerIrql@4:
@KfLowerIrql@4:
/* Save flags since we'll disable interrupts */
pushf
/* Validate IRQL */
movzx ecx, cl
#if DBG
cmp cl, PCR[KPCR_IRQL]
ja InvalidIrql
#endif
/* Disable interrupts and check if IRQL is below DISPATCH_LEVEL */
cmp dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
cli
jbe SkipMask
/* Clear interrupt masks since there's a pending hardware interrupt */
mov eax, KiI8259MaskTable[ecx*4]
or eax, PCR[KPCR_IDR]
out 0x21, al
shr eax, 8
out 0xA1, al
SkipMask:
/* Set the new IRQL and check if there's a pending software interrupt */
mov PCR[KPCR_IRQL], ecx
mov eax, PCR[KPCR_IRR]
mov al, SoftIntByteTable[eax]
cmp al, cl
ja DoCall3
/* Restore interrupts and return */
popf
ret
#if DBG
InvalidIrql:
/* Set HIGH_LEVEL */
mov eax, PCR[KPCR_IRQL]
mov dword ptr PCR[KPCR_IRQL], HIGH_LEVEL
/* Bugcheck the system */
push 3
push 0
push ecx
push eax
push IRQL_NOT_LESS_OR_EQUAL
call _KeBugCheckEx@20
#endif
DoCall3:
/* There is, call it */
call SoftIntHandlerTable[eax*4]
/* Restore interrupts and return */
popf
ret
.endfunc
.globl @KfRaiseIrql@4
.func @KfRaiseIrql@4
_@KfRaiseIrql@4:
@KfRaiseIrql@4:
/* Get the IRQL */
mov eax, PCR[KPCR_IRQL]
movzx ecx, cl
#if DBG
/* Validate it */
cmp eax, ecx
ja InvalidKfRaise
#endif
/* Check if it's in the software level */
cmp cl, DISPATCH_LEVEL
jbe SetIrql
/* Save the current IRQL */
mov edx, eax
/* It's a hardware IRQL, so disable interrupts */
pushf
cli
/* Set the new IRQL */
mov PCR[KPCR_IRQL], cl
/* Mask the interrupts in the PIC */
mov eax, KiI8259MaskTable[ecx*4]
or eax, PCR[KPCR_IDR]
out 0x21, al
shr eax, 8
out 0xA1, al
/* Restore interrupts and return old IRQL */
popf
mov eax, edx
ret
SetIrql:
/* Set the IRQL and return */
mov PCR[KPCR_IRQL], ecx
ret
#if DBG
InvalidKfRaise:
/* Set to passive */
mov dword ptr PCR[KPCR_IRQL], PASSIVE_LEVEL
/* Bugcheck the system */
push 9
push 0
push ecx
push eax
push IRQL_NOT_GREATER_OR_EQUAL
call _KeBugCheckEx@20
#endif
.endfunc
.globl _KeGetCurrentIrql@0
.func KeGetCurrentIrql@0
_KeGetCurrentIrql@0:
/* Return the IRQL */
mov eax, PCR[KPCR_IRQL]
ret
.endfunc
.globl _KeRaiseIrqlToDpcLevel@0
.func KeRaiseIrqlToDpcLevel@0
_KeRaiseIrqlToDpcLevel@0:
/* Get the current IRQL */
mov eax, PCR[KPCR_IRQL]
/* Set DISPATCH_LEVEL */
mov dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
#if DBG
/* Make sure we were not higher then dispatch */
cmp eax, DISPATCH_LEVEL
ja InvalidRaise
#endif
ret
#if DBG
InvalidRaise:
/* Bugcheck the system */
push 1
push 0
push DISPATCH_LEVEL
push eax
push IRQL_NOT_GREATER_OR_EQUAL
call _KeBugCheckEx@20
#endif
.endfunc
.globl _KeRaiseIrqlToSynchLevel@0
.func KeRaiseIrqlToSynchLevel@0
_KeRaiseIrqlToSynchLevel@0:
/* Disable interrupts */
pushf
cli
/* Mask out interrupts */
mov eax, KiI8259MaskTable[DISPATCH_LEVEL*4]
or eax, PCR[KPCR_IDR]
out 0x21, al
shr eax, 8
out 0xA1, al
/* Return the old IRQL, enable interrupts and set to DISPATCH */
mov eax, PCR[KPCR_IRQL]
mov dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
popf
#if DBG
/* Validate raise */
cmp eax, DISPATCH_LEVEL
ja InvalidSyRaise
#endif
/* Return */
ret
#if DBG
InvalidSyRaise:
/* Bugcheck the system */
push 2
push 0
push DISPATCH_LEVEL
push eax
push IRQL_NOT_GREATER_OR_EQUAL
call _KeBugCheckEx@20
#endif
.endfunc
.globl _HalpApcInterrupt
.func HalpApcInterrupt
TRAP_FIXUPS hapc_a, hapc_t, DoFixupV86, DoFixupAbios
_HalpApcInterrupt:
/* Create fake interrupt stack */
pop eax
pushf
push cs
push eax
/* Enter interrupt */
INT_PROLOG hapc_a, hapc_t, DoPushFakeErrorCode
.endfunc
.globl _HalpApcInterrupt2ndEntry
.func HalpApcInterrupt2ndEntry
_HalpApcInterrupt2ndEntry:
/* Save current IRQL and set to APC level */
push PCR[KPCR_IRQL]
mov dword ptr PCR[KPCR_IRQL], APC_LEVEL
and dword ptr PCR[KPCR_IRR], ~(1 << APC_LEVEL)
/* Enable interrupts and check if we came from User/V86 mode */
sti
mov eax, [ebp+KTRAP_FRAME_CS]
and eax, MODE_MASK
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jz DeliverApc
/* Set user mode delivery */
or eax, UserMode
DeliverApc:
/* Deliver the APCs */
push ebp
push 0
push eax
call _KiDeliverApc@12
/* Disable interrupts and end it */
cli
call _HalpEndSoftwareInterrupt@4
jmp _Kei386EoiHelper@0
.endfunc
.globl _HalpDispatchInterrupt
.func HalpDispatchInterrupt
TRAP_FIXUPS hdpc_a, hdpc_t, DoFixupV86, DoFixupAbios
_HalpDispatchInterrupt:
/* Create fake interrupt stack */
pop eax
pushf
push cs
push eax
/* Enter interrupt */
INT_PROLOG hdpc_a, hdpc_t, DoPushFakeErrorCode
.endfunc
.globl _HalpDispatchInterrupt2ndEntry
.func HalpDispatchInterrupt2ndEntry
_HalpDispatchInterrupt2ndEntry:
/* Save current IRQL and set to DPC level */
push PCR[KPCR_IRQL]
mov dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
and dword ptr PCR[KPCR_IRR], ~(1 << DISPATCH_LEVEL)
/* Enable interrupts and let the kernel handle this */
sti
call _KiDispatchInterrupt@0
/* Disable interrupts and end it */
cli
call _HalpEndSoftwareInterrupt@4
jmp _Kei386EoiHelper@0
.endfunc
.globl _HalpEndSoftwareInterrupt@4
.func HalpEndSoftwareInterrupt@4
_HalpEndSoftwareInterrupt@4:
/* Get the IRQL and check if we're in the software region */
movzx ecx, byte ptr [esp+4]
cmp dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
jbe SoftwareInt
/* Set the right mask in the PIC for the hardware IRQ */
mov eax, KiI8259MaskTable[ecx*4]
or eax, PCR[KPCR_IDR]
out 0x21, al
shr eax, 8
out 0xA1, al
SoftwareInt:
/* Check if there are pending software interrupts */
mov PCR[KPCR_IRQL], ecx
mov eax, PCR[KPCR_IRR]
mov al, SoftIntByteTable[eax]
cmp al, cl
ja DoCall2
ret 4
DoCall2:
/* There are pending softwate interrupts, call their handlers */
add esp, 8
jmp SoftIntHandlerTable2[eax*4]
.endfunc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -