Splited HalEndSystemInterrupt in two functions. HalEndSystemInterrupt,

HalpLowerIrql and HalpExecuteIrqs was called recursively.

svn path=/trunk/; revision=3921
This commit is contained in:
Hartmut Birr 2003-01-02 16:07:49 +00:00
parent e7cbcafe30
commit 4af2b6bcb7

View file

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