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

📄 irq.s

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 S
📖 第 1 页 / 共 2 页
字号:
/*
 * FILE:            hal/halx86/generic/irq.S
 * COPYRIGHT:       See COPYING in the top level directory
 * PURPOSE:         Software, System and Hardware IRQ Management
 * PROGRAMMER:      Alex Ionescu (alex@relsoft.net)
 */

/* INCLUDES ******************************************************************/

#include <asm.h>
#include <internal/i386/asmmacro.S>
.intel_syntax noprefix

/* GLOBALS *******************************************************************/

PICInitTable:

    /* Master PIC */
    .short 0x20                         /* Port */
    .byte 0x11                          /* Edge,, cascade, CAI 8, ICW4 */
    .byte PRIMARY_VECTOR_BASE           /* Base */
    .byte 4                             /* IRQ 4 connected to slave */
    .byte 1                             /* Non buffered, not nested, 8086 */

    /* Slave PIC */
    .short 0xA0                         /* Port */
    .byte 0x11                          /* Edge, cascade, CAI 8, ICW4 */
    .byte PRIMARY_VECTOR_BASE + 8       /* Base */
    .byte 2                             /* Slave ID: Slave 2 */
    .byte 1                             /* Non buffered, not nested, 8086 */

    /* End of initialization table */
    .short 0

KiI8259MaskTable:
    .long 0                             /* IRQL 0 */
    .long 0                             /* IRQL 1 */
    .long 0                             /* IRQL 2 */
    .long 0                             /* IRQL 3 */
    .long 0xFF800000                    /* IRQL 4 */
    .long 0xFFC00000                    /* IRQL 5 */
    .long 0xFFE00000                    /* IRQL 6 */
    .long 0xFFF00000                    /* IRQL 7 */
    .long 0xFFF80000                    /* IRQL 8 */
    .long 0xFFFC0000                    /* IRQL 9 */
    .long 0xFFFE0000                    /* IRQL 10 */
    .long 0xFFFF0000                    /* IRQL 11 */
    .long 0xFFFF8000                    /* IRQL 12 */
    .long 0xFFFFC000                    /* IRQL 13 */
    .long 0xFFFFE000                    /* IRQL 14 */
    .long 0xFFFFF000                    /* IRQL 15 */
    .long 0xFFFFF800                    /* IRQL 16 */
    .long 0xFFFFFC00                    /* IRQL 17 */
    .long 0xFFFFFE00                    /* IRQL 18 */
    .long 0xFFFFFE00                    /* IRQL 19 */
    .long 0xFFFFFE80                    /* IRQL 20 */
    .long 0xFFFFFEC0                    /* IRQL 21 */
    .long 0xFFFFFEE0                    /* IRQL 22 */
    .long 0xFFFFFEF0                    /* IRQL 23 */
    .long 0xFFFFFEF8                    /* IRQL 24 */
    .long 0xFFFFFEF8                    /* IRQL 25 */
    .long 0xFFFFFEFA                    /* IRQL 26 */
    .long 0xFFFFFFFA                    /* IRQL 27 */
    .long 0xFFFFFFFB                    /* IRQL 28 */
    .long 0xFFFFFFFB                    /* IRQL 29 */
    .long 0xFFFFFFFB                    /* IRQL 30 */
    .long 0xFFFFFFFB                    /* IRQL 31 */

HalpSysIntHandler:
.rept 7
    .long GenericIRQ                    /* IRQ 0-7 */
.endr
    .long IRQ7                          /* IRQ 7 */
.rept 7
    .long GenericIRQ                    /* IRQ 8-15 */
.endr
    .long IRQ15                         /* IRQ 15 */
.rept 20
    .long GenericIRQ                    /* IRQ 16-35 */
.endr
#if DBG
.rept 172
    .long InvalidIRQ                    /* IRQ 36-207 */
#endif
.endr

SoftIntByteTable:
    .byte PASSIVE_LEVEL                 /* IRR 0 */
    .byte PASSIVE_LEVEL                 /* IRR 1 */
    .byte APC_LEVEL                     /* IRR 2 */
    .byte APC_LEVEL                     /* IRR 3 */
    .byte DISPATCH_LEVEL                /* IRR 4 */
    .byte DISPATCH_LEVEL                /* IRR 5 */
    .byte DISPATCH_LEVEL                /* IRR 6 */
    .byte DISPATCH_LEVEL                /* IRR 7 */

SoftIntHandlerTable:
    .long _KiUnexpectedInterrupt        /* PASSIVE_LEVEL */
    .long _HalpApcInterrupt             /* APC_LEVEL */
    .long _HalpDispatchInterrupt        /* DISPATCH_LEVEL */

SoftIntHandlerTable2:
    .long _KiUnexpectedInterrupt        /* PASSIVE_LEVEL */
    .long _HalpApcInterrupt2ndEntry     /* APC_LEVEL */
    .long _HalpDispatchInterrupt2ndEntry /* DISPATCH_LEVEL */

_UnhandledMsg:
    .asciz "\n\x7\x7!!! Unhandled or Unexpected Code at line: %lx!!!\n"

/* FUNCTIONS *****************************************************************/

.globl _HalpInitPICs@0
.func HalpInitPICs@0
_HalpInitPICs@0:

    /* Save ESI and disable interrupts */
    push esi
    pushf
    cli

    /* Read the init table */
    lea esi, PICInitTable
    lodsw

InitLoop:

    /* Put the port in EDX */
    movzx edx, ax

    /* Initialize the PIC, using a delay for each command */
    outsb
    jmp $+2
    inc edx
    outsb
    jmp $+2
    outsb
    jmp $+2
    outsb
    jmp $+2

    /* Mask all interrupts */
    mov al, 0xFF
    out dx, al

    /* Check if we're done, otherwise initialize next PIC */
    lodsw
    cmp ax, 0
    jnz InitLoop

    /* Restore interrupts and return */
    popf
    pop esi
    ret
.endfunc

.globl @HalClearSoftwareInterrupt@4
.func @HalClearSoftwareInterrupt@4, @HalClearSoftwareInterrupt@4
@HalClearSoftwareInterrupt@4:

    /* Get IRR mask */
    mov eax, 1
    shl eax, cl
    not eax

    /* Set IRR */
    and PCR[KPCR_IRR], eax
    ret
.endfunc

.globl @HalRequestSoftwareInterrupt@4
.func @HalRequestSoftwareInterrupt@4, @HalRequestSoftwareInterrupt@4
@HalRequestSoftwareInterrupt@4:

    /* Get IRR mask */
    mov eax, 1
    shl eax, cl

    /* Disable interrupts */
    pushf
    cli

    /* Set IRR and get IRQL */
    or PCR[KPCR_IRR], eax
    mov ecx, PCR[KPCR_IRQL]

    /* Get software IRR mask */
    mov eax, PCR[KPCR_IRR]
    and eax, 3

    /* Get highest pending software interrupt and check if it's higher */
    xor edx, edx
    mov dl, SoftIntByteTable[eax]
    cmp dl, cl
    jbe AfterCall

    /* Call the pending interrupt */
    call SoftIntHandlerTable[edx*4]

AfterCall:

    /* Retore interrupts and return */
    popf
    ret
.endfunc

.globl _HalDisableSystemInterrupt@8
.func HalDisableSystemInterrupt@8
_HalDisableSystemInterrupt@8:

    /* Convert to vector */
    movzx ecx, byte ptr [esp+4]
    sub ecx, PRIMARY_VECTOR_BASE

    /* Disable interrupts and set the new IDR */
    mov edx, 1
    shl edx, cl
    cli
    or PCR[KPCR_IDR], edx

    /* Get the current mask */
    xor eax, eax
    in al, 0xA1
    shl eax, 8
    in al, 0x21

    /* Mask off the interrupt and write the new mask */
    or eax, edx
    out 0x21, al
    shr eax, 8
    out 0xA1, al

    /* Return with interrupts enabled */
    in al, 0xA1
    sti
    ret 8
.endfunc

.globl _HalEnableSystemInterrupt@12
.func HalEnableSystemInterrupt@12
_HalEnableSystemInterrupt@12:

    /* Get the vector and validate it */
    movzx ecx, byte ptr [esp+4]
    sub ecx, PRIMARY_VECTOR_BASE
    jb Invalid
    cmp ecx, CLOCK2_LEVEL
    jnb Invalid

    /* Get the current PCI Edge/Level control registers */
    mov edx, 0x4D1
    in al, dx
    shl ax, 8
    mov edx, 0x4D0
    in al, dx
    mov dx, 1
    shl dx, cl
    and dx, 0xDEF8

    /* Check if this is a latched interrupt */
    cmp dword ptr [esp+12], 0
    jnz Latched

    /* Use OR for edge interrupt */
    or ax, dx
    jmp AfterMask
Latched:

    /* Mask it out for level interrupt */
    not dx
    and ax, dx

AfterMask:

    /* Set the PCI Edge/Level control registers */
    mov edx, 0x4D0
    out dx, al
    shr ax, 8
    mov edx, 0x4D1
    out dx, al

    /* Calculate the new IDR */
    mov eax, 1
    shl eax, cl
    not eax
    cli
    and PCR[KPCR_IDR], eax

    /* Get the current IRQL and mask the IRQs in the PIC */
    mov eax, PCR[KPCR_IRQL]
    mov eax, KiI8259MaskTable[eax*4]
    or eax, PCR[KPCR_IDR]
    out 0x21, al
    shr eax, 8
    out 0xA1, al

    /* Enable interrupts and return TRUE */
    sti
    mov eax, 1
    ret 12

Invalid:

    /* Fail, invalid IRQ */
#if DBG
    int 3
#endif
    xor eax, eax
    ret 12
.endfunc

.globl _HalBeginSystemInterrupt@12
.func HalBeginSystemInterrupt@12
_HalBeginSystemInterrupt@12:

    /* Convert to IRQ and call the handler */
    movzx ebx, byte ptr [esp+8]
    sub ebx, PRIMARY_VECTOR_BASE
    jmp HalpSysIntHandler[ebx*4]

IRQ15:
    /* This is IRQ 15, check if it's spurious */
    mov al, 0xB
    out 0xA0, al
    jmp $+2
    in al, 0xA0
    test al, 0x80
    jnz GenericIRQ

    /* Cascaded interrupt... dismiss it and return FALSE */
    mov al, 0x62
    out 0x20, al
    mov eax, 0
    ret 12

IRQ7:
    /* This is IRQ 7, check if it's spurious */
    mov al, 0xB
    out 0x20, al
    jmp $+2
    in al, 0x20
    test al, 0x80
    jnz GenericIRQ

    /* It is, return FALSE */
    mov eax, 0
    ret 12

GenericIRQ:
    /* Return the current IRQL */
    mov eax, [esp+12]
    mov ecx, PCR[KPCR_IRQL]
    mov [eax], cl

    /* Set the new IRQL */
    movzx eax, byte ptr [esp+4]
    mov PCR[KPCR_IRQL], eax

    /* Set IRQ mask in the PIC */
    mov eax, KiI8259MaskTable[eax*4]
    or eax, PCR[KPCR_IDR]
    out 0x21, al
    shr eax, 8
    out 0xA1, al

    /* Check to which PIC the EOI was sent */
    mov eax, ebx
    cmp eax, 8
    jnb Pic1

    /* Write mask to master PIC */
    or al, 0x60
    out 0x20, al
    jmp DoneBegin

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -