diff --git a/reactos/hal/halx86/irql.c b/reactos/hal/halx86/irql.c index acd655ce1df..0e46e7661b0 100644 --- a/reactos/hal/halx86/irql.c +++ b/reactos/hal/halx86/irql.c @@ -1,4 +1,5 @@ -/* +/* $Id: irql.c,v 1.8 2003/01/02 16:07:49 hbirr Exp $ + * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/hal/x86/irql.c @@ -26,16 +27,28 @@ */ static KIRQL CurrentIrql = HIGH_LEVEL; +typedef union +{ + USHORT both; + struct + { + BYTE master; + BYTE slave; + } +} +PIC_MASK; + /* * PURPOSE: - Mask for HalEnableSystemInterrupt and HalDisableSystemInterrupt * - At startup enable timer and cascade */ -static USHORT pic_mask = 0xFFFA; +static PIC_MASK pic_mask = {.both = 0xFFFA}; + /* * PURPOSE: Mask for disabling of acknowledged interrupts */ -static USHORT pic_mask_intr = 0x0000; +static PIC_MASK pic_mask_intr = {.both = 0x0000}; extern IMPORTED ULONG DpcQueueSize; @@ -76,13 +89,35 @@ VOID HalpInitPICs(VOID) WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1); WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1); /* Enable interrupts */ - WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask & 0xFF); - WRITE_PORT_UCHAR((PUCHAR)0xa1, (pic_mask >> 8) & 0xFF); + WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master); + WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave); /* We can now enable interrupts */ __asm__ __volatile__ ("sti\n\t"); } +VOID HalpEndSystemInterrupt(KIRQL Irql) +/* + * FUNCTION: Enable all irqs with higher priority. + */ +{ + const USHORT mask[] = + { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0xc000, 0xe000, 0xf000, + 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, 0xffc0, 0xffe0, 0xfff0, + 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + }; + + /* Interrupts should be disable while enabling irqs of both pics */ + __asm__("pushf\n\t"); + __asm__("cli\n\t"); + pic_mask_intr.both &= mask[Irql]; + WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master|pic_mask_intr.master); + WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave|pic_mask_intr.slave); + __asm__("popf\n\t"); +} + VOID STATIC HalpExecuteIrqs(KIRQL NewIrql) { @@ -96,26 +131,29 @@ HalpExecuteIrqs(KIRQL NewIrql) */ for (i = 0; i < IrqLimit; i++) { - while (HalpPendingInterruptCount[i] > 0) + if (HalpPendingInterruptCount[i] > 0) { - /* - * For each deferred interrupt execute all the handlers at DIRQL. - */ - CurrentIrql = IRQ_TO_DIRQL(i); - KiInterruptDispatch2(i, NewIrql); - HalpPendingInterruptCount[i]--; - if (HalpPendingInterruptCount[i] == 0) - { - HalEndSystemInterrupt(CurrentIrql, 0); - } + CurrentIrql = IRQ_TO_DIRQL(i); + + while (HalpPendingInterruptCount[i] > 0) + { + /* + * For each deferred interrupt execute all the handlers at DIRQL. + */ + KiInterruptDispatch2(i, NewIrql); + HalpPendingInterruptCount[i]--; + } + CurrentIrql--; + HalpEndSystemInterrupt(CurrentIrql); } } + } VOID STATIC HalpLowerIrql(KIRQL NewIrql) { - if (NewIrql > PROFILE_LEVEL) + if (NewIrql >= PROFILE_LEVEL) { CurrentIrql = NewIrql; return; @@ -131,12 +169,11 @@ HalpLowerIrql(KIRQL NewIrql) { KiDispatchInterrupt(); } + CurrentIrql = APC_LEVEL; if (NewIrql == APC_LEVEL) { - CurrentIrql = NewIrql; return; } - CurrentIrql = APC_LEVEL; if (KeGetCurrentThread() != NULL && KeGetCurrentThread()->ApcState.KernelApcPending) { @@ -325,16 +362,16 @@ HalBeginSystemInterrupt (ULONG Vector, return(FALSE); } irq = Vector - IRQ_BASE; - pic_mask_intr |= (1 << irq); + pic_mask_intr.both |= ((1 << irq) & 0xfffe); // do not disable the timer interrupt if (irq < 8) { - WRITE_PORT_UCHAR((PUCHAR)0x21, (pic_mask|pic_mask_intr) & 0xff); + WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master|pic_mask_intr.master); WRITE_PORT_UCHAR((PUCHAR)0x20, 0x20); } else { - WRITE_PORT_UCHAR((PUCHAR)0xa1, ((pic_mask|pic_mask_intr) >> 8) & 0xff); + WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave|pic_mask_intr.slave); /* Send EOI to the PICs */ WRITE_PORT_UCHAR((PUCHAR)0x20,0x20); WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20); @@ -357,29 +394,8 @@ VOID STDCALL HalEndSystemInterrupt (KIRQL Irql, ULONG Unknown2) * FUNCTION: Finish a system interrupt and restore the specified irq level. */ { - ULONG mask; - HalpLowerIrql(Irql); - - if (Irql > PROFILE_LEVEL) - { - mask = 0xffff; - } - else if (Irql > PROFILE_LEVEL - NR_IRQS) - { - mask = ~((1 << (PROFILE_LEVEL - Irql + 1)) - 1); - } - else - { - mask = 0; - } - /* Interrupts should be disable while enabling irqs of both pics */ - __asm__("pushf\n\t"); - __asm__("cli\n\t"); - pic_mask_intr &= mask; - WRITE_PORT_UCHAR((PUCHAR)0x21, (pic_mask|pic_mask_intr) & 0xff); - WRITE_PORT_UCHAR((PUCHAR)0xa1, ((pic_mask|pic_mask_intr) >> 8) & 0xff); - __asm__("popf\n\t"); + HalpEndSystemInterrupt(Irql); } BOOLEAN STDCALL HalDisableSystemInterrupt (ULONG Vector, @@ -391,14 +407,14 @@ BOOLEAN STDCALL HalDisableSystemInterrupt (ULONG Vector, return FALSE; irq = Vector - IRQ_BASE; - pic_mask |= (1 << irq); + pic_mask.both |= (1 << irq); if (irq < 8) { - WRITE_PORT_UCHAR((PUCHAR)0x21, (pic_mask|pic_mask_intr) & 0xff); + WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master|pic_mask_intr.slave); } else { - WRITE_PORT_UCHAR((PUCHAR)0xa1, ((pic_mask|pic_mask_intr) >> 8) & 0xff); + WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave|pic_mask_intr.slave); } return TRUE; @@ -415,14 +431,14 @@ BOOLEAN STDCALL HalEnableSystemInterrupt (ULONG Vector, return FALSE; irq = Vector - IRQ_BASE; - pic_mask &= ~(1 << irq); + pic_mask.both &= ~(1 << irq); if (irq < 8) { - WRITE_PORT_UCHAR((PUCHAR)0x21, (pic_mask|pic_mask_intr) & 0xff); + WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master|pic_mask_intr.master); } else { - WRITE_PORT_UCHAR((PUCHAR)0xa1, ((pic_mask|pic_mask_intr) >> 8) & 0xff); + WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave|pic_mask_intr.slave); } return TRUE;