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?rev=45240&r1=45239&r2=45240&view=diff
==============================================================================
--- 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 @kfloweri...@4
-.func @kfloweri...@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 _kebugchec...@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?rev=45240&r1=45239&r2=45240&view=diff
==============================================================================
--- 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?rev=45240&r1=45239&r2=45240&view=diff
==============================================================================
--- 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);


Reply via email to