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?r…
==============================================================================
--- 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?r…
==============================================================================
--- 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?…
==============================================================================
--- 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);