https://git.reactos.org/?p=reactos.git;a=commitdiff;h=361b6e39e3ce4c582db302...
commit 361b6e39e3ce4c582db3026c44d3d8d7e442dca7 Author: Colin Finck colin@reactos.org 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);