[HAL] Convert HalpEndSoftwareInterrupt2 to fastcall. CORE-14076
[reactos.git] / hal / halx86 / up / pic.c
index 4857c53..f61bf73 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
+VOID
+NTAPI
+HalpEndSoftwareInterrupt(IN KIRQL OldIrql,
+                         IN PKTRAP_FRAME TrapFrame);
+
 /* GLOBALS ********************************************************************/
 
 #ifndef _MINIHAL_
@@ -94,8 +99,7 @@ PHAL_DISMISS_INTERRUPT HalpSpecialDismissLevelTable[16] =
 /* This table contains the static x86 PIC mapping between IRQLs and IRQs */
 ULONG KiI8259MaskTable[32] =
 {
-#if defined(__GNUC__) && \
-    (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)
+#if defined(__GNUC__) || defined(__clang__) || (defined(_MSC_VER) && _MSC_VER >= 1900)
     /*
      * It Device IRQLs only start at 4 or higher, so these are just software
      * IRQLs that don't really change anything on the hardware
@@ -211,8 +215,7 @@ ULONG KiI8259MaskTable[32] =
 /* This table indicates which IRQs, if pending, can preempt a given IRQL level */
 ULONG FindHigherIrqlMask[32] =
 {
-#if defined(__GNUC__) && \
-    (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)
+#if defined(__GNUC__) || defined(__clang__) || (defined(_MSC_VER) && _MSC_VER >= 1900)
     /*
      * Software IRQLs, at these levels all hardware interrupts can preempt.
      * Each higher IRQL simply enables which software IRQL can preempt the
@@ -263,7 +266,7 @@ ULONG FindHigherIrqlMask[32] =
      * so it will always preempt until we reach PROFILE_LEVEL.
      */
     0b00000000000000000001011111110000, /* IRQL 20 */
-    0b00000000000000000001001111110000, /* IRQL 20 */
+    0b00000000000000000001001111110000, /* IRQL 21 */
     0b00000000000000000001000111110000, /* IRQL 22 */
     0b00000000000000000001000011110000, /* IRQL 23 */
     0b00000000000000000001000001110000, /* IRQL 24 */
@@ -416,10 +419,6 @@ NTAPI
 HalpInitializePICs(IN BOOLEAN EnableInterrupts)
 {
     ULONG EFlags;
-    I8259_ICW1 Icw1;
-    I8259_ICW2 Icw2;
-    I8259_ICW3 Icw3;
-    I8259_ICW4 Icw4;
     EISA_ELCR Elcr;
     ULONG i, j;
 
@@ -427,63 +426,8 @@ HalpInitializePICs(IN BOOLEAN EnableInterrupts)
     EFlags = __readeflags();
     _disable();
 
-    /* Initialize ICW1 for master, interval 8, edge-triggered mode with ICW4 */
-    Icw1.NeedIcw4 = TRUE;
-    Icw1.InterruptMode = EdgeTriggered;
-    Icw1.OperatingMode = Cascade;
-    Icw1.Interval = Interval8;
-    Icw1.Init = TRUE;
-    Icw1.InterruptVectorAddress = 0; /* This is only used in MCS80/85 mode */
-    __outbyte(PIC1_CONTROL_PORT, Icw1.Bits);
-
-    /* Set interrupt vector base */
-    Icw2.Bits = PRIMARY_VECTOR_BASE;
-    __outbyte(PIC1_DATA_PORT, Icw2.Bits);
-
-    /* Connect slave to IRQ 2 */
-    Icw3.Bits = 0;
-    Icw3.SlaveIrq2 = TRUE;
-    __outbyte(PIC1_DATA_PORT, Icw3.Bits);
-
-    /* Enable 8086 mode, non-automatic EOI, non-buffered mode, non special fully nested mode */
-    Icw4.Reserved = 0;
-    Icw4.SystemMode = New8086Mode;
-    Icw4.EoiMode = NormalEoi;
-    Icw4.BufferedMode = NonBuffered;
-    Icw4.SpecialFullyNestedMode = FALSE;
-    __outbyte(PIC1_DATA_PORT, Icw4.Bits);
-
-    /* Mask all interrupts */
-    __outbyte(PIC1_DATA_PORT, 0xFF);
-
-    /* Initialize ICW1 for master, interval 8, edge-triggered mode with ICW4 */
-    Icw1.NeedIcw4 = TRUE;
-    Icw1.InterruptMode = EdgeTriggered;
-    Icw1.OperatingMode = Cascade;
-    Icw1.Interval = Interval8;
-    Icw1.Init = TRUE;
-    Icw1.InterruptVectorAddress = 0; /* This is only used in MCS80/85 mode */
-    __outbyte(PIC2_CONTROL_PORT, Icw1.Bits);
-
-    /* Set interrupt vector base */
-    Icw2.Bits = PRIMARY_VECTOR_BASE + 8;
-    __outbyte(PIC2_DATA_PORT, Icw2.Bits);
-
-    /* Slave ID */
-    Icw3.Bits = 0;
-    Icw3.SlaveId = 2;
-    __outbyte(PIC2_DATA_PORT, Icw3.Bits);
-
-    /* Enable 8086 mode, non-automatic EOI, non-buffered mode, non special fully nested mode */
-    Icw4.Reserved = 0;
-    Icw4.SystemMode = New8086Mode;
-    Icw4.EoiMode = NormalEoi;
-    Icw4.BufferedMode = NonBuffered;
-    Icw4.SpecialFullyNestedMode = FALSE;
-    __outbyte(PIC2_DATA_PORT, Icw4.Bits);
-
-    /* Mask all interrupts */
-    __outbyte(PIC2_DATA_PORT, 0xFF);
+    /* Initialize and mask the PIC */
+    HalpInitializeLegacyPICs();
 
     /* Read EISA Edge/Level Register for master and slave */
     Elcr.Bits = (__inbyte(EISA_ELCR_SLAVE) << 8) | __inbyte(EISA_ELCR_MASTER);
@@ -732,15 +676,17 @@ HalClearSoftwareInterrupt(IN KIRQL Irql)
     KeGetPcr()->IRR &= ~(1 << Irql);
 }
 
-VOID
-NTAPI
-HalpEndSoftwareInterrupt(IN KIRQL OldIrql,
-                         IN PKTRAP_FRAME TrapFrame)
+PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY
+FASTCALL
+HalpEndSoftwareInterrupt2(IN KIRQL OldIrql,
+                          IN PKTRAP_FRAME TrapFrame)
 {
     ULONG PendingIrql, PendingIrqlMask, PendingIrqMask;
     PKPCR Pcr = KeGetPcr();
     PIC_MASK Mask;
 
+    UNREFERENCED_PARAMETER(TrapFrame);
+
     /* Set old IRQL */
     Pcr->Irql = OldIrql;
 
@@ -749,10 +695,10 @@ HalpEndSoftwareInterrupt(IN KIRQL OldIrql,
     {
         /* Check for pending software interrupts and compare with current IRQL */
         PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
-        if (!PendingIrqlMask) return;
+        if (!PendingIrqlMask) return NULL;
 
         /* Check for in-service delayed interrupt */
-        if (Pcr->IrrActive & 0xFFFFFFF0) return;
+        if (Pcr->IrrActive & 0xFFFFFFF0) return NULL;
 
         /* Check if pending IRQL affects hardware state */
         BitScanReverse(&PendingIrql, PendingIrqlMask);
@@ -777,10 +723,11 @@ HalpEndSoftwareInterrupt(IN KIRQL OldIrql,
         else
         {
             /* No need to loop checking for hardware interrupts */
-            SWInterruptHandlerTable2[PendingIrql](TrapFrame);
-            UNREACHABLE;
+            return SWInterruptHandlerTable2[PendingIrql];
         }
     }
+
+    return NULL;
 }
 
 /* EDGE INTERRUPT DISMISSAL FUNCTIONS *****************************************/