[HALX86] Deduplicate initialization of legacy PICs and remove EOI in I/O APIC initialization, which causes an unexpected interrupt

This commit is contained in:
Colin Finck 2017-12-17 09:51:37 +01:00 committed by GitHub
parent 0fdb5d9b63
commit 361b6e39e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 96 additions and 136 deletions

View file

@ -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();

View file

@ -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)

84
hal/halx86/generic/pic.c Normal file
View file

@ -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);
}

View file

@ -741,6 +741,12 @@ HalpReleaseCmosSpinLock(
VOID
);
VOID
NTAPI
HalpInitializeLegacyPICs(
VOID
);
NTSTATUS
NTAPI
HalpOpenRegistryKey(

View file

@ -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);