⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irq.s

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 S
📖 第 1 页 / 共 2 页
字号:
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 + -