mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[HALX86] Deduplicate initialization of legacy PICs and remove EOI in I/O APIC initialization, which causes an unexpected interrupt
This commit is contained in:
parent
0fdb5d9b63
commit
361b6e39e3
5 changed files with 96 additions and 136 deletions
|
@ -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();
|
||||
|
|
|
@ -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
84
hal/halx86/generic/pic.c
Normal 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);
|
||||
}
|
|
@ -741,6 +741,12 @@ HalpReleaseCmosSpinLock(
|
|||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalpInitializeLegacyPICs(
|
||||
VOID
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HalpOpenRegistryKey(
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue