Author: sir_richard
Date: Mon Jan 25 00:19:40 2010
New Revision: 45235

URL: http://svn.reactos.org/svn/reactos?rev=45235&view=rev
Log:
[HAL]: Document and implement KiI8259MaskTable in C using actual bit positions. 
Each mapping is best to the best of my ability.
[HAL]: Implement KfRaiseIrql in C, remove ASM version.

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=45235&r1=45234&r2=45235&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 00:19:40 2010
@@ -624,67 +624,6 @@
     ret
 .endfunc
 
-.globl @kfraisei...@4
-.func @kfraisei...@4
-...@kfraiseirql@4:
-...@kfraiseirql@4:
-
-    /* Get the IRQL */
-    movzx ecx, cl
-    mov eax, PCR[KPCR_IRQL]
-
-#if DBG
-    /* Validate it */
-    cmp eax, ecx
-    ja InvalidKfRaise
-#endif
-
-    /* Check if it's in the software level */
-    cmp cl, DISPATCH_LEVEL
-    jbe SetIrql
-
-    /* Save the current IRQL */
-    mov edx, eax
-
-    /* It's a hardware IRQL, so disable interrupts */
-    pushf
-    cli
-
-    /* Set the new IRQL */
-    mov PCR[KPCR_IRQL], ecx
-
-    /* Mask the interrupts in the PIC */
-    mov eax, KiI8259MaskTable[ecx*4]
-    or eax, PCR[KPCR_IDR]
-    out 0x21, al
-    shr eax, 8
-    out 0xA1, al
-
-    /* Restore interrupts and return old IRQL */
-    popf
-    mov eax, edx
-    ret
-
-SetIrql:
-    /* Set the IRQL and return */
-    mov PCR[KPCR_IRQL], ecx
-    ret
-
-#if DBG
-InvalidKfRaise:
-    /* Set to passive */
-    mov dword ptr PCR[KPCR_IRQL], PASSIVE_LEVEL
-
-    /* Bugcheck the system */
-    push 9
-    push 0
-    push ecx
-    push eax
-    push IRQL_NOT_GREATER_OR_EQUAL
-    call _kebugchec...@20
-#endif
-.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=45235&r1=45234&r2=45235&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 00:19:40 2010
@@ -13,6 +13,87 @@
 #include <debug.h>
 
 /* GLOBALS 
********************************************************************/
+
+/* This table contains the static x86 PIC mapping between IRQLs and IRQs */
+ULONG KiI8259MaskTable[32] =
+{
+    /*
+     * It Device IRQLs only start at 4 or higher, so these are just software
+     * IRQLs that don't really change anything on the hardware
+     */
+    0b00000000000000000000000000000000, /* IRQL 0 */
+    0b00000000000000000000000000000000, /* IRQL 1 */
+    0b00000000000000000000000000000000, /* IRQL 2 */
+    0b00000000000000000000000000000000, /* IRQL 3 */
+    
+    /*
+     * These next IRQLs are actually useless from the PIC perspective, because
+     * with only 2 PICs, the mask you can send them is only 8 bits each, for 16
+     * bits total, so these IRQLs are masking off a phantom PIC.
+     */
+    0b11111111100000000000000000000000, /* IRQL 4 */
+    0b11111111110000000000000000000000, /* IRQL 5 */
+    0b11111111111000000000000000000000, /* IRQL 6 */
+    0b11111111111100000000000000000000, /* IRQL 7 */
+    0b11111111111110000000000000000000, /* IRQL 8 */
+    0b11111111111111000000000000000000, /* IRQL 9 */
+    0b11111111111111100000000000000000, /* IRQL 10 */
+    0b11111111111111110000000000000000, /* IRQL 11 */
+    
+    /*
+     * Okay, now we're finally starting to mask off IRQs on the slave PIC, from
+     * IRQ15 to IRQ8. This means the higher-level IRQs get less priority in the
+     * IRQL sense.
+     */
+    0b11111111111111111000000000000000, /* IRQL 12 */
+    0b11111111111111111100000000000000, /* IRQL 13 */
+    0b11111111111111111110000000000000, /* IRQL 14 */
+    0b11111111111111111111000000000000, /* IRQL 15 */
+    0b11111111111111111111100000000000, /* IRQL 16 */
+    0b11111111111111111111110000000000, /* IRQL 17 */
+    0b11111111111111111111111000000000, /* IRQL 18 */
+    0b11111111111111111111111000000000, /* IRQL 19 */
+    
+    /*
+     * Now we mask off the IRQs on the master. Notice the 0 "droplet"? You 
might
+     * have also seen that IRQL 18 and 19 are essentially equal as far as the
+     * PIC is concerned. That bit is actually IRQ8, which happens to be the 
RTC.
+     * The RTC will keep firing as long as we don't reach PROFILE_LEVEL which
+     * actually kills it. The RTC clock (unlike the system clock) is used by 
the
+     * profiling APIs in the HAL, so that explains the logic.
+     */
+    0b11111111111111111111111010000000, /* IRQL 20 */
+    0b11111111111111111111111011000000, /* IRQL 21 */
+    0b11111111111111111111111011100000, /* IRQL 22 */
+    0b11111111111111111111111011110000, /* IRQL 23 */
+    0b11111111111111111111111011111000, /* IRQL 24 */
+    0b11111111111111111111111011111000, /* IRQL 25 */
+    0b11111111111111111111111011111010, /* IRQL 26 */
+    0b11111111111111111111111111111010, /* IRQL 27 */
+    
+    /*
+     * IRQL 24 and 25 are actually identical, so IRQL 28 is actually the last
+     * IRQL to modify a bit on the master PIC. It happens to modify the very
+     * last of the IRQs, IRQ0, which corresponds to the system clock interval
+     * timer that keeps track of time (the Windows heartbeat). We only want to
+     * turn this off at a high-enough IRQL, which is why IRQLs 24 and 25 are 
the
+     * same to give this guy a chance to come up higher. Note that IRQL 28 is
+     * called CLOCK2_LEVEL, which explains the usage we just explained.
+     */
+    0b11111111111111111111111111111011, /* IRQL 28 */
+    
+    /*
+     * We have finished off with the PIC so there's nothing left to mask at the
+     * level of these IRQLs, making them only logical IRQLs on x86 machines.
+     * Note that we have another 0 "droplet" you might've caught since IRQL 26.
+     * In this case, it's the 2nd bit that never gets turned off, which is 
IRQ2,
+     * the cascade IRQ that we use to bridge the slave PIC with the master PIC.
+     * We never want to turn it off, so no matter the IRQL, it will be set to 
0.
+     */
+    0b11111111111111111111111111111011, /* IRQL 29 */
+    0b11111111111111111111111111111011, /* IRQL 30 */
+    0b11111111111111111111111111111011  /* IRQL 31 */
+};
 
 USHORT HalpEisaELCR;
 
@@ -191,6 +272,62 @@
     return CurrentIrql;
 }
 
+/*
+ * @implemented
+ */
+KIRQL
+FASTCALL
+KfRaiseIrql(IN KIRQL NewIrql)
+{
+    PKPCR Pcr = KeGetPcr();
+    ULONG EFlags;
+    KIRQL CurrentIrql;
+    PIC_MASK Mask;
+
+    /* Read current IRQL */
+    CurrentIrql = Pcr->Irql;
+    
+#ifdef IRQL_DEBUG
+    /* Validate correct raise */
+    if (CurrentIrql > NewIrql)
+    {
+        /* Crash system */
+        Pcr->Irql = PASSIVE_LEVEL;
+        KeBugCheckEx(IRQL_NOT_GREATER_OR_EQUAL,
+                     CurrentIrql,
+                     NewIrql,
+                     0,
+                     9);
+    }
+#endif
+    
+    /* Check if new IRQL affects hardware state */
+    if (NewIrql > DISPATCH_LEVEL)
+    {
+        /* Save current interrupt state and disable interrupts */
+        EFlags = __readeflags();
+        _disable();
+        
+        /* Update the IRQL */
+        Pcr->Irql = NewIrql;
+        
+        /* Set new PIC mask */
+        Mask.Both = KiI8259MaskTable[NewIrql] | Pcr->IDR;
+        __outbyte(PIC1_DATA_PORT, Mask.Master);
+        __outbyte(PIC2_DATA_PORT, Mask.Slave);
+        
+        /* Restore interrupt state */
+        __writeeflags(EFlags);
+    }
+    else
+    {
+        /* Set new IRQL */
+        Pcr->Irql = NewIrql;
+    }
+    
+    /* Return old IRQL */
+    return CurrentIrql;
+}
 
 /* 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=45235&r1=45234&r2=45235&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 00:19:40 
2010
@@ -282,6 +282,19 @@
     USHORT Bits;
 } EISA_ELCR, *PEISA_ELCR;
 
+typedef struct _PIC_MASK
+{
+    union
+    {
+        struct
+        {
+            UCHAR Master;
+            UCHAR Slave;
+        };
+        USHORT Both;
+    };    
+} PIC_MASK, *PPIC_MASK;
+
 //
 // Mm PTE/PDE to Hal PTE/PDE
 //


Reply via email to