Author: sir_richard Date: Mon Jan 25 02:20:43 2010 New Revision: 45240
URL: http://svn.reactos.org/svn/reactos?rev=45240&view=rev Log: [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.
Modified: trunk/reactos/hal/halx86/generic/irq.S trunk/reactos/hal/halx86/generic/pic.c trunk/reactos/hal/halx86/include/halp.h
Modified: trunk/reactos/hal/halx86/generic/irq.S URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/irq.S?re... ============================================================================== --- trunk/reactos/hal/halx86/generic/irq.S [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/generic/irq.S [iso-8859-1] Mon Jan 25 02:20:43 2010 @@ -214,72 +214,6 @@ 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
Modified: trunk/reactos/hal/halx86/generic/pic.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/pic.c?re... ============================================================================== --- trunk/reactos/hal/halx86/generic/pic.c [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/generic/pic.c [iso-8859-1] Mon Jan 25 02:20:43 2010 @@ -184,6 +184,27 @@ #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 @@ 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 ********************************************************/
/*
Modified: trunk/reactos/hal/halx86/include/halp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/include/halp.h?r... ============================================================================== --- trunk/reactos/hal/halx86/include/halp.h [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/include/halp.h [iso-8859-1] Mon Jan 25 02:20:43 2010 @@ -459,6 +459,8 @@
/* pic.c */ VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts); +VOID HalpApcInterrupt(VOID); +VOID HalpDispatchInterrupt(VOID);
/* udelay.c */ VOID NTAPI HalpInitializeClock(VOID);