https://git.reactos.org/?p=reactos.git;a=commitdiff;h=361b6e39e3ce4c582db3026c44d3d8d7e442dca7

commit 361b6e39e3ce4c582db3026c44d3d8d7e442dca7
Author: Colin Finck <[email protected]>
AuthorDate: Sun Dec 17 09:51:37 2017 +0100

    [HALX86] Deduplicate initialization of legacy PICs and remove EOI in I/O 
APIC initialization, which causes an unexpected interrupt
---
 hal/halx86/apic/apic.c    | 72 +---------------------------------------
 hal/halx86/generic.cmake  |  1 +
 hal/halx86/generic/pic.c  | 84 +++++++++++++++++++++++++++++++++++++++++++++++
 hal/halx86/include/halp.h |  6 ++++
 hal/halx86/up/pic.c       | 69 +++-----------------------------------
 5 files changed, 96 insertions(+), 136 deletions(-)

diff --git a/hal/halx86/apic/apic.c b/hal/halx86/apic/apic.c
index a9d7f38813..54dbbf01f0 100644
--- a/hal/halx86/apic/apic.c
+++ b/hal/halx86/apic/apic.c
@@ -254,74 +254,6 @@ HalpSendEOI(VOID)
     ApicSendEOI();
 }
 
-VOID
-NTAPI
-HalpInitializeLegacyPIC(VOID)
-{
-    I8259_ICW1 Icw1;
-    I8259_ICW2 Icw2;
-    I8259_ICW3 Icw3;
-    I8259_ICW4 Icw4;
-
-    /* Initialize ICW1 for master, interval 8, edge-triggered mode with ICW4 */
-    Icw1.NeedIcw4 = TRUE;
-    Icw1.OperatingMode = Cascade;
-    Icw1.Interval = Interval8;
-    Icw1.InterruptMode = EdgeTriggered;
-    Icw1.Init = TRUE;
-    Icw1.InterruptVectorAddress = 0;
-    __outbyte(PIC1_CONTROL_PORT, Icw1.Bits);
-
-    /* ICW2 - interrupt vector offset */
-    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.SystemMode = New8086Mode;
-    Icw4.EoiMode = NormalEoi;
-    Icw4.BufferedMode = NonBuffered;
-    Icw4.SpecialFullyNestedMode = FALSE;
-    Icw4.Reserved = 0;
-    __outbyte(PIC1_DATA_PORT, Icw4.Bits);
-
-    /* Mask all interrupts */
-    __outbyte(PIC1_DATA_PORT, 0xFF);
-
-    /* Initialize ICW1 for slave, 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.SystemMode = New8086Mode;
-    Icw4.EoiMode = NormalEoi;
-    Icw4.BufferedMode = NonBuffered;
-    Icw4.SpecialFullyNestedMode = FALSE;
-    Icw4.Reserved = 0;
-    __outbyte(PIC2_DATA_PORT, Icw4.Bits);
-
-    /* Mask all interrupts */
-    __outbyte(PIC2_DATA_PORT, 0xFF);
-}
-
 VOID
 NTAPI
 ApicInitializeLocalApic(ULONG Cpu)
@@ -506,8 +438,6 @@ ApicInitializeIOApic(VOID)
     ReDirReg.Mask = 0;
     ReDirReg.Destination = ApicRead(APIC_ID);
     IOApicWrite(IOAPIC_REDTBL + 2 * APIC_CLOCK_INDEX, ReDirReg.Long0);
-
-    ApicSendEOI();
 }
 
 VOID
@@ -521,7 +451,7 @@ HalpInitializePICs(IN BOOLEAN EnableInterrupts)
     _disable();
 
     /* Initialize and mask the PIC */
-    HalpInitializeLegacyPIC();
+    HalpInitializeLegacyPICs();
 
     /* Initialize the I/O APIC */
     ApicInitializeIOApic();
diff --git a/hal/halx86/generic.cmake b/hal/halx86/generic.cmake
index 916be84c08..143f6d18e3 100644
--- a/hal/halx86/generic.cmake
+++ b/hal/halx86/generic.cmake
@@ -8,6 +8,7 @@ list(APPEND HAL_GENERIC_SOURCE
     generic/halinit.c
     generic/memory.c
     generic/misc.c
+    generic/pic.c
     generic/reboot.c
     generic/sysinfo.c
     generic/usage.c)
diff --git a/hal/halx86/generic/pic.c b/hal/halx86/generic/pic.c
new file mode 100644
index 0000000000..fe812e59a1
--- /dev/null
+++ b/hal/halx86/generic/pic.c
@@ -0,0 +1,84 @@
+/*
+ * PROJECT:         ReactOS HAL
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * PURPOSE:         Generic HAL PIC Management Code shared between APIC and 
PIC HAL
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ */
+
+ /* INCLUDES 
*******************************************************************/
+
+#include <hal.h>
+#define NDEBUG
+#include <debug.h>
+
+ /* FUNCTIONS 
******************************************************************/
+
+VOID
+NTAPI
+HalpInitializeLegacyPICs(VOID)
+{
+    I8259_ICW1 Icw1;
+    I8259_ICW2 Icw2;
+    I8259_ICW3 Icw3;
+    I8259_ICW4 Icw4;
+
+    ASSERT(!(__readeflags() & EFLAGS_INTERRUPT_MASK));
+
+    /* Initialize ICW1 for master, interval 8, edge-triggered mode with ICW4 */
+    Icw1.NeedIcw4 = TRUE;
+    Icw1.OperatingMode = Cascade;
+    Icw1.Interval = Interval8;
+    Icw1.InterruptMode = EdgeTriggered;
+    Icw1.Init = TRUE;
+    Icw1.InterruptVectorAddress = 0;
+    __outbyte(PIC1_CONTROL_PORT, Icw1.Bits);
+
+    /* ICW2 - interrupt vector offset */
+    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.SystemMode = New8086Mode;
+    Icw4.EoiMode = NormalEoi;
+    Icw4.BufferedMode = NonBuffered;
+    Icw4.SpecialFullyNestedMode = FALSE;
+    Icw4.Reserved = 0;
+    __outbyte(PIC1_DATA_PORT, Icw4.Bits);
+
+    /* Mask all interrupts */
+    __outbyte(PIC1_DATA_PORT, 0xFF);
+
+    /* Initialize ICW1 for slave, 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.SystemMode = New8086Mode;
+    Icw4.EoiMode = NormalEoi;
+    Icw4.BufferedMode = NonBuffered;
+    Icw4.SpecialFullyNestedMode = FALSE;
+    Icw4.Reserved = 0;
+    __outbyte(PIC2_DATA_PORT, Icw4.Bits);
+
+    /* Mask all interrupts */
+    __outbyte(PIC2_DATA_PORT, 0xFF);
+}
diff --git a/hal/halx86/include/halp.h b/hal/halx86/include/halp.h
index 7967e5973b..8e79f3444e 100644
--- a/hal/halx86/include/halp.h
+++ b/hal/halx86/include/halp.h
@@ -741,6 +741,12 @@ HalpReleaseCmosSpinLock(
     VOID
 );
 
+VOID
+NTAPI
+HalpInitializeLegacyPICs(
+    VOID
+);
+
 NTSTATUS
 NTAPI
 HalpOpenRegistryKey(
diff --git a/hal/halx86/up/pic.c b/hal/halx86/up/pic.c
index 821f071e24..a66526cd50 100644
--- a/hal/halx86/up/pic.c
+++ b/hal/halx86/up/pic.c
@@ -99,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
@@ -216,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
@@ -421,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;
 
@@ -432,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);

Reply via email to