mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/hal/x86/irql.c
|
* FILE: ntoskrnl/hal/x86/irql.c
|
||||||
|
@ -26,16 +27,28 @@
|
||||||
*/
|
*/
|
||||||
static KIRQL CurrentIrql = HIGH_LEVEL;
|
static KIRQL CurrentIrql = HIGH_LEVEL;
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
USHORT both;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
BYTE master;
|
||||||
|
BYTE slave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PIC_MASK;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PURPOSE: - Mask for HalEnableSystemInterrupt and HalDisableSystemInterrupt
|
* PURPOSE: - Mask for HalEnableSystemInterrupt and HalDisableSystemInterrupt
|
||||||
* - At startup enable timer and cascade
|
* - 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
|
* 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;
|
extern IMPORTED ULONG DpcQueueSize;
|
||||||
|
|
||||||
|
@ -76,13 +89,35 @@ VOID HalpInitPICs(VOID)
|
||||||
WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1);
|
WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1);
|
||||||
WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1);
|
WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1);
|
||||||
/* Enable interrupts */
|
/* Enable interrupts */
|
||||||
WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask & 0xFF);
|
WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master);
|
||||||
WRITE_PORT_UCHAR((PUCHAR)0xa1, (pic_mask >> 8) & 0xFF);
|
WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave);
|
||||||
|
|
||||||
/* We can now enable interrupts */
|
/* We can now enable interrupts */
|
||||||
__asm__ __volatile__ ("sti\n\t");
|
__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
|
VOID STATIC
|
||||||
HalpExecuteIrqs(KIRQL NewIrql)
|
HalpExecuteIrqs(KIRQL NewIrql)
|
||||||
{
|
{
|
||||||
|
@ -96,26 +131,29 @@ HalpExecuteIrqs(KIRQL NewIrql)
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < IrqLimit; i++)
|
for (i = 0; i < IrqLimit; i++)
|
||||||
{
|
{
|
||||||
|
if (HalpPendingInterruptCount[i] > 0)
|
||||||
|
{
|
||||||
|
CurrentIrql = IRQ_TO_DIRQL(i);
|
||||||
|
|
||||||
while (HalpPendingInterruptCount[i] > 0)
|
while (HalpPendingInterruptCount[i] > 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* For each deferred interrupt execute all the handlers at DIRQL.
|
* For each deferred interrupt execute all the handlers at DIRQL.
|
||||||
*/
|
*/
|
||||||
CurrentIrql = IRQ_TO_DIRQL(i);
|
|
||||||
KiInterruptDispatch2(i, NewIrql);
|
KiInterruptDispatch2(i, NewIrql);
|
||||||
HalpPendingInterruptCount[i]--;
|
HalpPendingInterruptCount[i]--;
|
||||||
if (HalpPendingInterruptCount[i] == 0)
|
}
|
||||||
{
|
CurrentIrql--;
|
||||||
HalEndSystemInterrupt(CurrentIrql, 0);
|
HalpEndSystemInterrupt(CurrentIrql);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID STATIC
|
VOID STATIC
|
||||||
HalpLowerIrql(KIRQL NewIrql)
|
HalpLowerIrql(KIRQL NewIrql)
|
||||||
{
|
{
|
||||||
if (NewIrql > PROFILE_LEVEL)
|
if (NewIrql >= PROFILE_LEVEL)
|
||||||
{
|
{
|
||||||
CurrentIrql = NewIrql;
|
CurrentIrql = NewIrql;
|
||||||
return;
|
return;
|
||||||
|
@ -131,12 +169,11 @@ HalpLowerIrql(KIRQL NewIrql)
|
||||||
{
|
{
|
||||||
KiDispatchInterrupt();
|
KiDispatchInterrupt();
|
||||||
}
|
}
|
||||||
|
CurrentIrql = APC_LEVEL;
|
||||||
if (NewIrql == APC_LEVEL)
|
if (NewIrql == APC_LEVEL)
|
||||||
{
|
{
|
||||||
CurrentIrql = NewIrql;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CurrentIrql = APC_LEVEL;
|
|
||||||
if (KeGetCurrentThread() != NULL &&
|
if (KeGetCurrentThread() != NULL &&
|
||||||
KeGetCurrentThread()->ApcState.KernelApcPending)
|
KeGetCurrentThread()->ApcState.KernelApcPending)
|
||||||
{
|
{
|
||||||
|
@ -325,16 +362,16 @@ HalBeginSystemInterrupt (ULONG Vector,
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
irq = Vector - IRQ_BASE;
|
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)
|
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);
|
WRITE_PORT_UCHAR((PUCHAR)0x20, 0x20);
|
||||||
}
|
}
|
||||||
else
|
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 */
|
/* Send EOI to the PICs */
|
||||||
WRITE_PORT_UCHAR((PUCHAR)0x20,0x20);
|
WRITE_PORT_UCHAR((PUCHAR)0x20,0x20);
|
||||||
WRITE_PORT_UCHAR((PUCHAR)0xa0,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.
|
* FUNCTION: Finish a system interrupt and restore the specified irq level.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULONG mask;
|
|
||||||
|
|
||||||
HalpLowerIrql(Irql);
|
HalpLowerIrql(Irql);
|
||||||
|
HalpEndSystemInterrupt(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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN STDCALL HalDisableSystemInterrupt (ULONG Vector,
|
BOOLEAN STDCALL HalDisableSystemInterrupt (ULONG Vector,
|
||||||
|
@ -391,14 +407,14 @@ BOOLEAN STDCALL HalDisableSystemInterrupt (ULONG Vector,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
irq = Vector - IRQ_BASE;
|
irq = Vector - IRQ_BASE;
|
||||||
pic_mask |= (1 << irq);
|
pic_mask.both |= (1 << irq);
|
||||||
if (irq < 8)
|
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
|
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;
|
return TRUE;
|
||||||
|
@ -415,14 +431,14 @@ BOOLEAN STDCALL HalEnableSystemInterrupt (ULONG Vector,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
irq = Vector - IRQ_BASE;
|
irq = Vector - IRQ_BASE;
|
||||||
pic_mask &= ~(1 << irq);
|
pic_mask.both &= ~(1 << irq);
|
||||||
if (irq < 8)
|
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
|
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;
|
return TRUE;
|
||||||
|
|
Loading…
Reference in a new issue