-/*
+/* $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
*/
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;
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)
{
*/
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;
{
KiDispatchInterrupt();
}
+ CurrentIrql = APC_LEVEL;
if (NewIrql == APC_LEVEL)
{
- CurrentIrql = NewIrql;
return;
}
- CurrentIrql = APC_LEVEL;
if (KeGetCurrentThread() != NULL &&
KeGetCurrentThread()->ApcState.KernelApcPending)
{
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);
* 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,
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;
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;