mirror of
https://github.com/reactos/reactos.git
synced 2024-10-04 00:13:57 +00:00
- Add inital support for PCI and ISA interrupts.
- Use different register allocation to be more efficient on certain systems. - Add tables and initial code for Lazy IRQL support. svn path=/trunk/; revision=44115
This commit is contained in:
parent
8e510a0ea2
commit
c02b96254e
|
@ -69,25 +69,73 @@ KiI8259MaskTable:
|
||||||
.long 0xFFFFFFFB /* IRQL 30 */
|
.long 0xFFFFFFFB /* IRQL 30 */
|
||||||
.long 0xFFFFFFFB /* IRQL 31 */
|
.long 0xFFFFFFFB /* IRQL 31 */
|
||||||
|
|
||||||
HalpSysIntHandler:
|
FindHigherIrqlMask:
|
||||||
.rept 7
|
.long 0xFFFFFFFE /* IRQL 0 */
|
||||||
|
.long 0xFFFFFFFC /* IRQL 1 */
|
||||||
|
.long 0xFFFFFFF8 /* IRQL 2 */
|
||||||
|
.long 0xFFFFFFF0 /* IRQL 3 */
|
||||||
|
.long 0x7FFFFF0 /* IRQL 4 */
|
||||||
|
.long 0x3FFFFF0 /* IRQL 5 */
|
||||||
|
.long 0x1FFFFF0 /* IRQL 6 */
|
||||||
|
.long 0x0FFFFF0 /* IRQL 7 */
|
||||||
|
.long 0x7FFFF0 /* IRQL 8 */
|
||||||
|
.long 0x3FFFF0 /* IRQL 9 */
|
||||||
|
.long 0x1FFFF0 /* IRQL 10 */
|
||||||
|
.long 0x0FFFF0 /* IRQL 11 */
|
||||||
|
.long 0x7FFF0 /* IRQL 12 */
|
||||||
|
.long 0x3FFF0 /* IRQL 13 */
|
||||||
|
.long 0x1FFF0 /* IRQL 14 */
|
||||||
|
.long 0x0FFF0 /* IRQL 15 */
|
||||||
|
.long 0x7FF0 /* IRQL 16 */
|
||||||
|
.long 0x3FF0 /* IRQL 17 */
|
||||||
|
.long 0x1FF0 /* IRQL 18 */
|
||||||
|
.long 0x1FF0 /* IRQL 19 */
|
||||||
|
.long 0x17F0 /* IRQL 20 */
|
||||||
|
.long 0x13F0 /* IRQL 21 */
|
||||||
|
.long 0x11F0 /* IRQL 22 */
|
||||||
|
.long 0x10F0 /* IRQL 23 */
|
||||||
|
.long 0x1070 /* IRQL 24 */
|
||||||
|
.long 0x1030 /* IRQL 25 */
|
||||||
|
.long 0x1010 /* IRQL 26 */
|
||||||
|
.long 0x10 /* IRQL 27 */
|
||||||
|
.long 0 /* IRQL 28 */
|
||||||
|
.long 0 /* IRQL 29 */
|
||||||
|
.long 0 /* IRQL 30 */
|
||||||
|
.long 0 /* IRQL 31 */
|
||||||
|
|
||||||
|
HalpSpecialDismissTable:
|
||||||
|
.rept 7
|
||||||
.long GenericIRQ /* IRQ 0-7 */
|
.long GenericIRQ /* IRQ 0-7 */
|
||||||
.endr
|
.endr
|
||||||
.long IRQ7 /* IRQ 7 */
|
.long IRQ7 /* IRQ 7 */
|
||||||
.rept 7
|
.rept 5
|
||||||
.long GenericIRQ /* IRQ 8-15 */
|
.long GenericIRQ /* IRQ 8-12 */
|
||||||
.endr
|
.endr
|
||||||
|
.long IRQ13 /* IRQ 13 */
|
||||||
|
.long GenericIRQ /* IRQ 14 */
|
||||||
.long IRQ15 /* IRQ 15 */
|
.long IRQ15 /* IRQ 15 */
|
||||||
.rept 20
|
.rept 20
|
||||||
.long GenericIRQ /* IRQ 16-35 */
|
.long GenericIRQ /* IRQ 16-35 */
|
||||||
.endr
|
.endr
|
||||||
#if DBG
|
#if DBG
|
||||||
.rept 172
|
.rept 172
|
||||||
.long InvalidIRQ /* IRQ 36-207 */
|
.long InvalidIRQ /* IRQ 36-207 */
|
||||||
.endr
|
.endr
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SoftIntByteTable:
|
HalpSpecialDismissLevelTable:
|
||||||
|
.rept 7
|
||||||
|
.long GenericIRQLevel /* IRQ 0-7 */
|
||||||
|
.endr
|
||||||
|
.long IRQ7Level /* IRQ 7 */
|
||||||
|
.rept 5
|
||||||
|
.long GenericIRQLevel /* IRQ 8-12 */
|
||||||
|
.endr
|
||||||
|
.long IRQ13Level /* IRQ 13 */
|
||||||
|
.long GenericIRQLevel /* IRQ 14 */
|
||||||
|
.long IRQ15Level /* IRQ 15 */
|
||||||
|
|
||||||
|
SWInterruptLookUpTable:
|
||||||
.byte PASSIVE_LEVEL /* IRR 0 */
|
.byte PASSIVE_LEVEL /* IRR 0 */
|
||||||
.byte PASSIVE_LEVEL /* IRR 1 */
|
.byte PASSIVE_LEVEL /* IRR 1 */
|
||||||
.byte APC_LEVEL /* IRR 2 */
|
.byte APC_LEVEL /* IRR 2 */
|
||||||
|
@ -97,12 +145,12 @@ SoftIntByteTable:
|
||||||
.byte DISPATCH_LEVEL /* IRR 6 */
|
.byte DISPATCH_LEVEL /* IRR 6 */
|
||||||
.byte DISPATCH_LEVEL /* IRR 7 */
|
.byte DISPATCH_LEVEL /* IRR 7 */
|
||||||
|
|
||||||
SoftIntHandlerTable:
|
SWInterruptHandlerTable:
|
||||||
.long _KiUnexpectedInterrupt /* PASSIVE_LEVEL */
|
.long _KiUnexpectedInterrupt /* PASSIVE_LEVEL */
|
||||||
.long _HalpApcInterrupt /* APC_LEVEL */
|
.long _HalpApcInterrupt /* APC_LEVEL */
|
||||||
.long _HalpDispatchInterrupt /* DISPATCH_LEVEL */
|
.long _HalpDispatchInterrupt /* DISPATCH_LEVEL */
|
||||||
|
|
||||||
SoftIntHandlerTable2:
|
SWInterruptHandlerTable2:
|
||||||
.long _KiUnexpectedInterrupt /* PASSIVE_LEVEL */
|
.long _KiUnexpectedInterrupt /* PASSIVE_LEVEL */
|
||||||
.long _HalpApcInterrupt2ndEntry /* APC_LEVEL */
|
.long _HalpApcInterrupt2ndEntry /* APC_LEVEL */
|
||||||
.long _HalpDispatchInterrupt2ndEntry /* DISPATCH_LEVEL */
|
.long _HalpDispatchInterrupt2ndEntry /* DISPATCH_LEVEL */
|
||||||
|
@ -112,6 +160,39 @@ _UnhandledMsg:
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
/* HAL interrupt handlers */
|
||||||
|
GENERATE_HAL_INT_HANDLERS
|
||||||
|
|
||||||
|
.globl _HalpHardwareInterruptLevel
|
||||||
|
.func HalpHardwareInterruptLevel
|
||||||
|
_HalpHardwareInterruptLevel:
|
||||||
|
|
||||||
|
/* Get IRQL and check for pending interrupts */
|
||||||
|
mov eax, PCR[KPCR_IRQL]
|
||||||
|
mov ecx, PCR[KPCR_IRR]
|
||||||
|
and ecx, FindHigherIrqlMask[eax*4]
|
||||||
|
jz NothingHardware
|
||||||
|
|
||||||
|
/* Check the active IRR */
|
||||||
|
test dword ptr PCR[KPCR_IRR_ACTIVE], 0xFFFFFFF0
|
||||||
|
jnz NothingHardware
|
||||||
|
|
||||||
|
/* Check for pending software interrupts */
|
||||||
|
mov eax, ecx
|
||||||
|
bsr ecx, eax
|
||||||
|
mov eax, 1
|
||||||
|
shl eax, cl
|
||||||
|
|
||||||
|
/* Clear IRR */
|
||||||
|
xor PCR[KPCR_IRR], eax
|
||||||
|
|
||||||
|
/* Now dispatch the interrupt */
|
||||||
|
call SWInterruptHandlerTable[ecx*4]
|
||||||
|
|
||||||
|
NothingHardware:
|
||||||
|
ret
|
||||||
|
.endfunc
|
||||||
|
|
||||||
.globl _HalpInitPICs@0
|
.globl _HalpInitPICs@0
|
||||||
.func HalpInitPICs@0
|
.func HalpInitPICs@0
|
||||||
_HalpInitPICs@0:
|
_HalpInitPICs@0:
|
||||||
|
@ -150,7 +231,23 @@ InitLoop:
|
||||||
cmp ax, 0
|
cmp ax, 0
|
||||||
jnz InitLoop
|
jnz InitLoop
|
||||||
|
|
||||||
/* Restore interrupts and return */
|
/* Read EISA Edge/Level Register */
|
||||||
|
mov edx, 0x4D1
|
||||||
|
in al, dx
|
||||||
|
mov ah, al
|
||||||
|
dec edx
|
||||||
|
in al, dx
|
||||||
|
|
||||||
|
/* Clear reserved bits and see if there's anything there */
|
||||||
|
and eax, 0xDEF8
|
||||||
|
cmp eax, 0xDEF8
|
||||||
|
jz NoEisa
|
||||||
|
|
||||||
|
/* FIXME */
|
||||||
|
//UNHANDLED_PATH
|
||||||
|
|
||||||
|
/* Restore interrupts and return */
|
||||||
|
NoEisa:
|
||||||
popf
|
popf
|
||||||
pop esi
|
pop esi
|
||||||
ret
|
ret
|
||||||
|
@ -192,12 +289,12 @@ InitLoop:
|
||||||
|
|
||||||
/* Get highest pending software interrupt and check if it's higher */
|
/* Get highest pending software interrupt and check if it's higher */
|
||||||
xor edx, edx
|
xor edx, edx
|
||||||
mov dl, SoftIntByteTable[eax]
|
mov dl, SWInterruptLookUpTable[eax]
|
||||||
cmp dl, cl
|
cmp dl, cl
|
||||||
jbe AfterCall
|
jbe AfterCall
|
||||||
|
|
||||||
/* Call the pending interrupt */
|
/* Call the pending interrupt */
|
||||||
call SoftIntHandlerTable[edx*4]
|
call SWInterruptHandlerTable[edx*4]
|
||||||
|
|
||||||
AfterCall:
|
AfterCall:
|
||||||
|
|
||||||
|
@ -249,38 +346,53 @@ _HalEnableSystemInterrupt@12:
|
||||||
cmp ecx, CLOCK2_LEVEL
|
cmp ecx, CLOCK2_LEVEL
|
||||||
jnb Invalid
|
jnb Invalid
|
||||||
|
|
||||||
/* Get the current PCI Edge/Level control registers */
|
#if 0
|
||||||
mov edx, 0x4D1
|
/* Is PCI IRQ Routing enabled? */
|
||||||
in al, dx
|
cmp byte ptr _HalpIrqMiniportInitialized, 0
|
||||||
shl ax, 8
|
jz NoMiniport
|
||||||
mov edx, 0x4D0
|
|
||||||
in al, dx
|
|
||||||
mov dx, 1
|
|
||||||
shl dx, cl
|
|
||||||
and dx, 0xDEF8
|
|
||||||
|
|
||||||
/* Check if this is a latched interrupt */
|
/* UNHANDLED */
|
||||||
cmp dword ptr [esp+12], 0
|
UNHANDLED_PATH
|
||||||
|
|
||||||
|
NoMiniport:
|
||||||
|
/* Check if this is an EISA IRQ */
|
||||||
|
bt _HalpEisaIrqIgnore, ecx
|
||||||
|
jb IgnoredIrq
|
||||||
|
|
||||||
|
/* Clear the EISA Edge/Level Control Register */
|
||||||
|
btr _HalpEisaELCR, ecx
|
||||||
|
|
||||||
|
/* Get the interrupt type */
|
||||||
|
mov al, [esp+12]
|
||||||
|
cmp al, 0
|
||||||
jnz Latched
|
jnz Latched
|
||||||
|
|
||||||
/* Use OR for edge interrupt */
|
/* Check the register again */
|
||||||
or ax, dx
|
bt _HalpEisaELCR, ecx
|
||||||
jmp AfterMask
|
jb Dismiss
|
||||||
|
|
||||||
|
/* Check if the miniport is active */
|
||||||
|
cmp byte ptr _HalpIrqMiniportInitialized, 0
|
||||||
|
jz Dismiss
|
||||||
|
|
||||||
|
/* Update the EISA Edge/Level Control Register */
|
||||||
|
bts _HalpEisaELCR, ecx
|
||||||
|
|
||||||
|
Dismiss:
|
||||||
|
/* Use the level hardware interrupt handler */
|
||||||
|
mov dword ptr SWInterruptHandlerTableHardware[ecx*4], offset _HalpHardwareInterruptLevel
|
||||||
|
mov edx, HalpSpecialDismissLevelTable[ecx*4]
|
||||||
|
mov HalpSpecialDismissTable[ecx*4], edx
|
||||||
|
|
||||||
Latched:
|
Latched:
|
||||||
|
/* Is PCI IRQ Routing enabled? */
|
||||||
|
cmp byte ptr _HalpIrqMiniportInitialized, 0
|
||||||
|
jz IgnoredIrq
|
||||||
|
|
||||||
/* Mask it out for level interrupt */
|
/* UNHANDLED */
|
||||||
not dx
|
UNHANDLED_PATH
|
||||||
and ax, dx
|
#endif
|
||||||
|
IgnoredIrq:
|
||||||
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 */
|
/* Calculate the new IDR */
|
||||||
mov eax, 1
|
mov eax, 1
|
||||||
shl eax, cl
|
shl eax, cl
|
||||||
|
@ -316,9 +428,10 @@ Invalid:
|
||||||
_HalBeginSystemInterrupt@12:
|
_HalBeginSystemInterrupt@12:
|
||||||
|
|
||||||
/* Convert to IRQ and call the handler */
|
/* Convert to IRQ and call the handler */
|
||||||
movzx ebx, byte ptr [esp+8]
|
xor ecx, ecx
|
||||||
sub ebx, PRIMARY_VECTOR_BASE
|
mov cl, byte ptr [esp+8]
|
||||||
jmp HalpSysIntHandler[ebx*4]
|
sub ecx, PRIMARY_VECTOR_BASE
|
||||||
|
jmp HalpSpecialDismissTable[ecx*4]
|
||||||
|
|
||||||
IRQ15:
|
IRQ15:
|
||||||
/* This is IRQ 15, check if it's spurious */
|
/* This is IRQ 15, check if it's spurious */
|
||||||
|
@ -330,6 +443,7 @@ IRQ15:
|
||||||
jnz GenericIRQ
|
jnz GenericIRQ
|
||||||
|
|
||||||
/* Cascaded interrupt... dismiss it and return FALSE */
|
/* Cascaded interrupt... dismiss it and return FALSE */
|
||||||
|
CascadedInterrupt:
|
||||||
mov al, 0x62
|
mov al, 0x62
|
||||||
out 0x20, al
|
out 0x20, al
|
||||||
mov eax, 0
|
mov eax, 0
|
||||||
|
@ -348,15 +462,21 @@ IRQ7:
|
||||||
mov eax, 0
|
mov eax, 0
|
||||||
ret 12
|
ret 12
|
||||||
|
|
||||||
GenericIRQ:
|
IRQ13:
|
||||||
/* Return the current IRQL */
|
/* AT 80287 latch clear */
|
||||||
mov eax, [esp+12]
|
xor al, al
|
||||||
mov ecx, PCR[KPCR_IRQL]
|
out 0xF0, al
|
||||||
mov [eax], cl
|
|
||||||
|
|
||||||
/* Set the new IRQL */
|
GenericIRQ:
|
||||||
movzx eax, byte ptr [esp+4]
|
/* Get current and new IRQL */
|
||||||
|
xor eax, eax
|
||||||
|
mov al, byte ptr [esp+4]
|
||||||
|
mov ebx, PCR[KPCR_IRQL]
|
||||||
|
|
||||||
|
/* Set and save old */
|
||||||
mov PCR[KPCR_IRQL], eax
|
mov PCR[KPCR_IRQL], eax
|
||||||
|
mov edx, [esp+12]
|
||||||
|
mov [edx], bl
|
||||||
|
|
||||||
/* Set IRQ mask in the PIC */
|
/* Set IRQ mask in the PIC */
|
||||||
mov eax, KiI8259MaskTable[eax*4]
|
mov eax, KiI8259MaskTable[eax*4]
|
||||||
|
@ -366,14 +486,18 @@ GenericIRQ:
|
||||||
out 0xA1, al
|
out 0xA1, al
|
||||||
|
|
||||||
/* Check to which PIC the EOI was sent */
|
/* Check to which PIC the EOI was sent */
|
||||||
mov eax, ebx
|
mov eax, ecx
|
||||||
cmp eax, 8
|
cmp eax, 8
|
||||||
jnb Pic1
|
jnb Pic1
|
||||||
|
|
||||||
/* Write mask to master PIC */
|
/* Write mask to master PIC */
|
||||||
or al, 0x60
|
or al, 0x60
|
||||||
out 0x20, al
|
out 0x20, al
|
||||||
jmp DoneBegin
|
|
||||||
|
/* Enable interrupts and return TRUE */
|
||||||
|
sti
|
||||||
|
mov eax, 1
|
||||||
|
ret 12
|
||||||
|
|
||||||
Pic1:
|
Pic1:
|
||||||
/* Write mask to slave PIC */
|
/* Write mask to slave PIC */
|
||||||
|
@ -382,9 +506,7 @@ Pic1:
|
||||||
mov al, 0x62
|
mov al, 0x62
|
||||||
out 0x20, al
|
out 0x20, al
|
||||||
|
|
||||||
DoneBegin:
|
|
||||||
/* Enable interrupts and return TRUE */
|
/* Enable interrupts and return TRUE */
|
||||||
in al, 0x21
|
|
||||||
sti
|
sti
|
||||||
mov eax, 1
|
mov eax, 1
|
||||||
ret 12
|
ret 12
|
||||||
|
@ -397,12 +519,111 @@ InvalidIRQ:
|
||||||
#endif
|
#endif
|
||||||
.endfunc
|
.endfunc
|
||||||
|
|
||||||
|
IRQ15Level:
|
||||||
|
/* This is IRQ 15, check if it's spurious */
|
||||||
|
mov al, 0xB
|
||||||
|
out 0xA0, al
|
||||||
|
jmp $+2
|
||||||
|
in al, 0xA0
|
||||||
|
test al, 0x80
|
||||||
|
jnz GenericIRQLevel
|
||||||
|
jmp CascadedInterrupt
|
||||||
|
|
||||||
|
IRQ7Level:
|
||||||
|
/* This is IRQ 7, check if it's spurious */
|
||||||
|
mov al, 0xB
|
||||||
|
out 0x20, al
|
||||||
|
jmp $+2
|
||||||
|
in al, 0x20
|
||||||
|
test al, 0x80
|
||||||
|
jnz GenericIRQLevel
|
||||||
|
|
||||||
|
/* It is, return FALSE */
|
||||||
|
SpuriousInterrupt:
|
||||||
|
mov eax, 0
|
||||||
|
ret 12
|
||||||
|
|
||||||
|
IRQ13Level:
|
||||||
|
/* AT 80287 latch clear */
|
||||||
|
xor al, al
|
||||||
|
out 0xF0, al
|
||||||
|
|
||||||
|
GenericIRQLevel:
|
||||||
|
/* Save IRQL */
|
||||||
|
xor eax, eax
|
||||||
|
mov al, [esp+4]
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
/* Compute new IRR */
|
||||||
|
mov eax, ecx
|
||||||
|
mov ebx, 1
|
||||||
|
add ecx, 4
|
||||||
|
shl ebx, cl
|
||||||
|
or PCR[KPCR_IRR], ebx
|
||||||
|
|
||||||
|
/* Get IRQLs */
|
||||||
|
mov cl, [esp+4]
|
||||||
|
mov bl, PCR[KPCR_IRQL]
|
||||||
|
mov edx, [esp+12]
|
||||||
|
|
||||||
|
/* Check to which PIC the EOI was sent */
|
||||||
|
cmp eax, 8
|
||||||
|
jnb Pic1Level
|
||||||
|
|
||||||
|
/* Write mask to master PIC */
|
||||||
|
or al, 0x60
|
||||||
|
out 0x20, al
|
||||||
|
|
||||||
|
/* Check for spurious */
|
||||||
|
cmp cl, bl
|
||||||
|
jbe SpuriousInterrupt
|
||||||
|
|
||||||
|
/* Write IRQL values */
|
||||||
|
movzx ecx, cl
|
||||||
|
mov PCR[KPCR_IRQL], ecx
|
||||||
|
mov [edx], bl
|
||||||
|
|
||||||
|
/* Enable interrupts and return TRUE */
|
||||||
|
sti
|
||||||
|
mov eax, 1
|
||||||
|
ret 12
|
||||||
|
|
||||||
|
Pic1Level:
|
||||||
|
/* Write mask to slave and master PIC */
|
||||||
|
add al, 0x58
|
||||||
|
out 0xA0, al
|
||||||
|
mov al, 0x62
|
||||||
|
out 0x20, al
|
||||||
|
|
||||||
|
/* Was this a lower interrupt? */
|
||||||
|
cmp cl, bl
|
||||||
|
jbe SpuriousInterrupt
|
||||||
|
|
||||||
|
/* Write IRQL values */
|
||||||
|
movzx ecx, cl
|
||||||
|
mov PCR[KPCR_IRQL], ecx
|
||||||
|
mov [edx], bl
|
||||||
|
|
||||||
|
/* Enable interrupts and return TRUE */
|
||||||
|
sti
|
||||||
|
mov eax, 1
|
||||||
|
ret 12
|
||||||
|
|
||||||
.globl _HalEndSystemInterrupt@8
|
.globl _HalEndSystemInterrupt@8
|
||||||
.func HalEndSystemInterrupt@8
|
.func HalEndSystemInterrupt@8
|
||||||
_HalEndSystemInterrupt@8:
|
_HalEndSystemInterrupt@8:
|
||||||
|
|
||||||
/* Get the IRQL and check if it's a software interrupt */
|
/* Read IRQL */
|
||||||
movzx ecx, byte ptr [esp+4]
|
xor ecx, ecx
|
||||||
|
mov cl, [esp+4]
|
||||||
|
|
||||||
|
/* Check if it's a software interrupt */
|
||||||
cmp dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
|
cmp dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
|
||||||
jbe SkipMask2
|
jbe SkipMask2
|
||||||
|
|
||||||
|
@ -418,7 +639,7 @@ SkipMask2:
|
||||||
/* Set IRQL and check if there are pending software interrupts */
|
/* Set IRQL and check if there are pending software interrupts */
|
||||||
mov PCR[KPCR_IRQL], ecx
|
mov PCR[KPCR_IRQL], ecx
|
||||||
mov eax, PCR[KPCR_IRR]
|
mov eax, PCR[KPCR_IRR]
|
||||||
mov al, SoftIntByteTable[eax]
|
mov al, SWInterruptLookUpTable[eax]
|
||||||
cmp al, cl
|
cmp al, cl
|
||||||
ja DoCall
|
ja DoCall
|
||||||
ret 8
|
ret 8
|
||||||
|
@ -427,7 +648,7 @@ DoCall:
|
||||||
|
|
||||||
/* There are pending software interrupts, call their handlers */
|
/* There are pending software interrupts, call their handlers */
|
||||||
add esp, 12
|
add esp, 12
|
||||||
jmp SoftIntHandlerTable2[eax*4]
|
jmp SWInterruptHandlerTable2[eax*4]
|
||||||
.endfunc
|
.endfunc
|
||||||
|
|
||||||
.globl @KfLowerIrql@4
|
.globl @KfLowerIrql@4
|
||||||
|
@ -435,19 +656,21 @@ DoCall:
|
||||||
_@KfLowerIrql@4:
|
_@KfLowerIrql@4:
|
||||||
@KfLowerIrql@4:
|
@KfLowerIrql@4:
|
||||||
|
|
||||||
/* Save flags since we'll disable interrupts */
|
/* Cleanup IRQL */
|
||||||
pushf
|
and ecx, 0xFF
|
||||||
|
|
||||||
/* Validate IRQL */
|
/* Validate IRQL */
|
||||||
movzx ecx, cl
|
#if DBG
|
||||||
#if DBG
|
|
||||||
cmp cl, PCR[KPCR_IRQL]
|
cmp cl, PCR[KPCR_IRQL]
|
||||||
ja InvalidIrql
|
ja InvalidIrql
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Save flags since we'll disable interrupts */
|
||||||
|
pushf
|
||||||
|
cli
|
||||||
|
|
||||||
/* Disable interrupts and check if IRQL is below DISPATCH_LEVEL */
|
/* Disable interrupts and check if IRQL is below DISPATCH_LEVEL */
|
||||||
cmp dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
|
cmp dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
|
||||||
cli
|
|
||||||
jbe SkipMask
|
jbe SkipMask
|
||||||
|
|
||||||
/* Clear interrupt masks since there's a pending hardware interrupt */
|
/* Clear interrupt masks since there's a pending hardware interrupt */
|
||||||
|
@ -462,7 +685,7 @@ SkipMask:
|
||||||
/* Set the new IRQL and check if there's a pending software interrupt */
|
/* Set the new IRQL and check if there's a pending software interrupt */
|
||||||
mov PCR[KPCR_IRQL], ecx
|
mov PCR[KPCR_IRQL], ecx
|
||||||
mov eax, PCR[KPCR_IRR]
|
mov eax, PCR[KPCR_IRR]
|
||||||
mov al, SoftIntByteTable[eax]
|
mov al, SWInterruptLookUpTable[eax]
|
||||||
cmp al, cl
|
cmp al, cl
|
||||||
ja DoCall3
|
ja DoCall3
|
||||||
|
|
||||||
|
@ -487,7 +710,7 @@ InvalidIrql:
|
||||||
|
|
||||||
DoCall3:
|
DoCall3:
|
||||||
/* There is, call it */
|
/* There is, call it */
|
||||||
call SoftIntHandlerTable[eax*4]
|
call SWInterruptHandlerTable[eax*4]
|
||||||
|
|
||||||
/* Restore interrupts and return */
|
/* Restore interrupts and return */
|
||||||
popf
|
popf
|
||||||
|
@ -499,9 +722,9 @@ DoCall3:
|
||||||
_@KfRaiseIrql@4:
|
_@KfRaiseIrql@4:
|
||||||
@KfRaiseIrql@4:
|
@KfRaiseIrql@4:
|
||||||
|
|
||||||
/* Get the IRQL */
|
/* Get the IRQL */
|
||||||
mov eax, PCR[KPCR_IRQL]
|
|
||||||
movzx ecx, cl
|
movzx ecx, cl
|
||||||
|
mov eax, PCR[KPCR_IRQL]
|
||||||
|
|
||||||
#if DBG
|
#if DBG
|
||||||
/* Validate it */
|
/* Validate it */
|
||||||
|
@ -521,7 +744,7 @@ _@KfRaiseIrql@4:
|
||||||
cli
|
cli
|
||||||
|
|
||||||
/* Set the new IRQL */
|
/* Set the new IRQL */
|
||||||
mov PCR[KPCR_IRQL], cl
|
mov PCR[KPCR_IRQL], ecx
|
||||||
|
|
||||||
/* Mask the interrupts in the PIC */
|
/* Mask the interrupts in the PIC */
|
||||||
mov eax, KiI8259MaskTable[ecx*4]
|
mov eax, KiI8259MaskTable[ecx*4]
|
||||||
|
@ -536,7 +759,6 @@ _@KfRaiseIrql@4:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
SetIrql:
|
SetIrql:
|
||||||
|
|
||||||
/* Set the IRQL and return */
|
/* Set the IRQL and return */
|
||||||
mov PCR[KPCR_IRQL], ecx
|
mov PCR[KPCR_IRQL], ecx
|
||||||
ret
|
ret
|
||||||
|
@ -598,29 +820,17 @@ InvalidRaise:
|
||||||
.func KeRaiseIrqlToSynchLevel@0
|
.func KeRaiseIrqlToSynchLevel@0
|
||||||
_KeRaiseIrqlToSynchLevel@0:
|
_KeRaiseIrqlToSynchLevel@0:
|
||||||
|
|
||||||
/* Disable interrupts */
|
/* Get the current IRQL */
|
||||||
pushf
|
|
||||||
cli
|
|
||||||
|
|
||||||
/* Mask out interrupts */
|
|
||||||
mov eax, KiI8259MaskTable[SYNCH_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 SYNCH */
|
|
||||||
mov eax, PCR[KPCR_IRQL]
|
mov eax, PCR[KPCR_IRQL]
|
||||||
|
|
||||||
|
/* Set SYNCH_LEVEL */
|
||||||
mov dword ptr PCR[KPCR_IRQL], SYNCH_LEVEL
|
mov dword ptr PCR[KPCR_IRQL], SYNCH_LEVEL
|
||||||
popf
|
|
||||||
|
|
||||||
#if DBG
|
#if DBG
|
||||||
/* Validate raise */
|
/* Make sure we were not higher then dispatch */
|
||||||
cmp eax, SYNCH_LEVEL
|
cmp eax, SYNCH_LEVEL
|
||||||
ja InvalidSyRaise
|
ja InvalidSyRaise
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Return */
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
#if DBG
|
#if DBG
|
||||||
|
@ -737,7 +947,7 @@ SoftwareInt:
|
||||||
/* Check if there are pending software interrupts */
|
/* Check if there are pending software interrupts */
|
||||||
mov PCR[KPCR_IRQL], ecx
|
mov PCR[KPCR_IRQL], ecx
|
||||||
mov eax, PCR[KPCR_IRR]
|
mov eax, PCR[KPCR_IRR]
|
||||||
mov al, SoftIntByteTable[eax]
|
mov al, SWInterruptLookUpTable[eax]
|
||||||
cmp al, cl
|
cmp al, cl
|
||||||
ja DoCall2
|
ja DoCall2
|
||||||
ret 4
|
ret 4
|
||||||
|
@ -745,5 +955,5 @@ SoftwareInt:
|
||||||
DoCall2:
|
DoCall2:
|
||||||
/* There are pending softwate interrupts, call their handlers */
|
/* There are pending softwate interrupts, call their handlers */
|
||||||
add esp, 8
|
add esp, 8
|
||||||
jmp SoftIntHandlerTable2[eax*4]
|
jmp SWInterruptHandlerTable2[eax*4]
|
||||||
.endfunc
|
.endfunc
|
||||||
|
|
|
@ -191,6 +191,40 @@ _KiUnexpectedInterrupt&Number:
|
||||||
.endr
|
.endr
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
//
|
||||||
|
// @name GENERATE_HAL_INT_HANDLER
|
||||||
|
//
|
||||||
|
// This macro creates a HAL hardware interrupt handler.
|
||||||
|
//
|
||||||
|
// @param None.
|
||||||
|
//
|
||||||
|
// @remark None.
|
||||||
|
//
|
||||||
|
.macro GENERATE_HAL_INT_HANDLER Number
|
||||||
|
.func HalpHardwareInterrupt&Number
|
||||||
|
_HalpHardwareInterrupt&Number:
|
||||||
|
int PRIMARY_VECTOR_BASE + Number
|
||||||
|
ret
|
||||||
|
.endfunc
|
||||||
|
.endm
|
||||||
|
|
||||||
|
//
|
||||||
|
// @name GENERATE_HAL_INT_HANDLERS
|
||||||
|
//
|
||||||
|
// This macro creates the unexpected interrupt handlers.
|
||||||
|
//
|
||||||
|
// @param None.
|
||||||
|
//
|
||||||
|
// @remark None.
|
||||||
|
//
|
||||||
|
.macro GENERATE_HAL_INT_HANDLERS
|
||||||
|
.set i, 0
|
||||||
|
.rept 16
|
||||||
|
GENERATE_HAL_INT_HANDLER %i
|
||||||
|
.set i, i + 1
|
||||||
|
.endr
|
||||||
|
.endm
|
||||||
|
|
||||||
//
|
//
|
||||||
// @name INVALID_V86_OPCODE
|
// @name INVALID_V86_OPCODE
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue