mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
Splited HalEndSystemInterrupt in two functions. HalEndSystemInterrupt,
HalpLowerIrql and HalpExecuteIrqs was called recursively. svn path=/trunk/; revision=3921
This commit is contained in:
parent
e7cbcafe30
commit
4af2b6bcb7
1 changed files with 66 additions and 50 deletions
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue