mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 19:21:38 +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]
|
||||
.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
|
||||
.func HalpApcInterrupt
|
||||
TRAP_FIXUPS hapc_a, hapc_t, DoFixupV86, DoFixupAbios
|
||||
|
|
|
@ -184,6 +184,27 @@ ULONG KiI8259MaskTable[32] =
|
|||
#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;
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
@ -418,6 +439,58 @@ KfRaiseIrql(IN KIRQL NewIrql)
|
|||
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 ********************************************************/
|
||||
|
||||
/*
|
||||
|
|
|
@ -459,6 +459,8 @@ HalpEnableInterruptHandler(IN UCHAR Flags,
|
|||
|
||||
/* pic.c */
|
||||
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts);
|
||||
VOID HalpApcInterrupt(VOID);
|
||||
VOID HalpDispatchInterrupt(VOID);
|
||||
|
||||
/* udelay.c */
|
||||
VOID NTAPI HalpInitializeClock(VOID);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue