mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 06:22:58 +00:00
[HAL]: KfLowerIrql in C instead of ASM. Add the SWInterruptLookUpTable and SWInterruptHandlerTable to the code and keep the same mechanism as the ASM code used.
svn path=/trunk/; revision=45240
This commit is contained in:
parent
8e91a3a3f9
commit
fdae8b5c9c
3 changed files with 75 additions and 66 deletions
|
@ -214,72 +214,6 @@ DoCall:
|
||||||
jmp SWInterruptHandlerTable2[eax*4]
|
jmp SWInterruptHandlerTable2[eax*4]
|
||||||
.endfunc
|
.endfunc
|
||||||
|
|
||||||
.globl @KfLowerIrql@4
|
|
||||||
.func @KfLowerIrql@4
|
|
||||||
_@KfLowerIrql@4:
|
|
||||||
@KfLowerIrql@4:
|
|
||||||
|
|
||||||
/* Cleanup IRQL */
|
|
||||||
and ecx, 0xFF
|
|
||||||
|
|
||||||
/* Validate IRQL */
|
|
||||||
#if DBG
|
|
||||||
cmp cl, PCR[KPCR_IRQL]
|
|
||||||
ja InvalidIrql
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Save flags since we'll disable interrupts */
|
|
||||||
pushf
|
|
||||||
cli
|
|
||||||
|
|
||||||
/* Disable interrupts and check if IRQL is below DISPATCH_LEVEL */
|
|
||||||
cmp dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
|
|
||||||
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, SWInterruptLookUpTable[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 SWInterruptHandlerTable[eax*4]
|
|
||||||
|
|
||||||
/* Restore interrupts and return */
|
|
||||||
popf
|
|
||||||
ret
|
|
||||||
.endfunc
|
|
||||||
|
|
||||||
.globl _HalpApcInterrupt
|
.globl _HalpApcInterrupt
|
||||||
.func HalpApcInterrupt
|
.func HalpApcInterrupt
|
||||||
TRAP_FIXUPS hapc_a, hapc_t, DoFixupV86, DoFixupAbios
|
TRAP_FIXUPS hapc_a, hapc_t, DoFixupV86, DoFixupAbios
|
||||||
|
|
|
@ -184,6 +184,27 @@ ULONG KiI8259MaskTable[32] =
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Denotes minimum required IRQL before we can process pending SW interrupts */
|
||||||
|
KIRQL SWInterruptLookUpTable[8] =
|
||||||
|
{
|
||||||
|
PASSIVE_LEVEL, /* IRR 0 */
|
||||||
|
PASSIVE_LEVEL, /* IRR 1 */
|
||||||
|
APC_LEVEL, /* IRR 2 */
|
||||||
|
APC_LEVEL, /* IRR 3 */
|
||||||
|
DISPATCH_LEVEL, /* IRR 4 */
|
||||||
|
DISPATCH_LEVEL, /* IRR 5 */
|
||||||
|
DISPATCH_LEVEL, /* IRR 6 */
|
||||||
|
DISPATCH_LEVEL /* IRR 7 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Handlers for pending software interrupts */
|
||||||
|
PHAL_SW_INTERRUPT_HANDLER SWInterruptHandlerTable[3] =
|
||||||
|
{
|
||||||
|
KiUnexpectedInterrupt,
|
||||||
|
HalpApcInterrupt,
|
||||||
|
HalpDispatchInterrupt
|
||||||
|
};
|
||||||
|
|
||||||
USHORT HalpEisaELCR;
|
USHORT HalpEisaELCR;
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
@ -418,6 +439,58 @@ KfRaiseIrql(IN KIRQL NewIrql)
|
||||||
return CurrentIrql;
|
return CurrentIrql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
KfLowerIrql(IN KIRQL OldIrql)
|
||||||
|
{
|
||||||
|
ULONG EFlags;
|
||||||
|
KIRQL PendingIrql;
|
||||||
|
PKPCR Pcr = KeGetPcr();
|
||||||
|
PIC_MASK Mask;
|
||||||
|
|
||||||
|
#ifdef IRQL_DEBUG
|
||||||
|
/* Validate correct lower */
|
||||||
|
if (OldIrql > Pcr->Irql)
|
||||||
|
{
|
||||||
|
/* Crash system */
|
||||||
|
KIRQL CurrentIrql = Pcr->Irql;
|
||||||
|
Pcr->Irql = HIGH_LEVEL;
|
||||||
|
KeBugCheckEx(IRQL_NOT_LESS_OR_EQUAL,
|
||||||
|
CurrentIrql,
|
||||||
|
OldIrql,
|
||||||
|
0,
|
||||||
|
3);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Save EFlags and disable interrupts */
|
||||||
|
EFlags = __readeflags();
|
||||||
|
_disable();
|
||||||
|
|
||||||
|
/* Check if currentl IRQL affects hardware state */
|
||||||
|
if (Pcr->Irql > DISPATCH_LEVEL)
|
||||||
|
{
|
||||||
|
/* Set new PIC mask */
|
||||||
|
Mask.Both = KiI8259MaskTable[OldIrql] | Pcr->IDR;
|
||||||
|
__outbyte(PIC1_DATA_PORT, Mask.Master);
|
||||||
|
__outbyte(PIC2_DATA_PORT, Mask.Slave);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set old IRQL */
|
||||||
|
Pcr->Irql = OldIrql;
|
||||||
|
|
||||||
|
/* Check for pending software interrupts and compare with current IRQL */
|
||||||
|
PendingIrql = SWInterruptLookUpTable[Pcr->IRR];
|
||||||
|
if (PendingIrql > OldIrql) SWInterruptHandlerTable[PendingIrql]();
|
||||||
|
|
||||||
|
/* Restore interrupt state */
|
||||||
|
__writeeflags(EFlags);
|
||||||
|
}
|
||||||
|
|
||||||
/* SOFTWARE INTERRUPTS ********************************************************/
|
/* SOFTWARE INTERRUPTS ********************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -459,6 +459,8 @@ HalpEnableInterruptHandler(IN UCHAR Flags,
|
||||||
|
|
||||||
/* pic.c */
|
/* pic.c */
|
||||||
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts);
|
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts);
|
||||||
|
VOID HalpApcInterrupt(VOID);
|
||||||
|
VOID HalpDispatchInterrupt(VOID);
|
||||||
|
|
||||||
/* udelay.c */
|
/* udelay.c */
|
||||||
VOID NTAPI HalpInitializeClock(VOID);
|
VOID NTAPI HalpInitializeClock(VOID);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue