-/*
+/* $Id$
+ *
* 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 PIC_MASK pic_mask = {.both = 0xFFFA};
+
+
+/*
+ * PURPOSE: Mask for disabling of acknowledged interrupts
+ */
+static PIC_MASK pic_mask_intr = {.both = 0x0000};
+
extern IMPORTED ULONG DpcQueueSize;
static ULONG HalpPendingInterruptCount[NR_IRQS];
/* 8086 mode */
WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1);
WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1);
- /* Enable all interrupts from PICs */
- WRITE_PORT_UCHAR((PUCHAR)0x21, 0x0);
- WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x0);
+ /* Enable interrupts */
+ 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]--;
+ 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)
{
KIRQL Irql,
PKIRQL OldIrql)
{
- if (Vector < IRQ_BASE || Vector > IRQ_BASE + NR_IRQS)
+ ULONG irq;
+ if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
{
return(FALSE);
}
-
- /* Send EOI to the PICs */
- WRITE_PORT_UCHAR((PUCHAR)0x20,0x20);
- if ((Vector-IRQ_BASE)>=8)
- {
- WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20);
- }
+ irq = Vector - IRQ_BASE;
+ pic_mask_intr.both |= ((1 << irq) & 0xfffe); // do not disable the timer interrupt
+
+ if (irq < 8)
+ {
+ 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.slave|pic_mask_intr.slave);
+ /* Send EOI to the PICs */
+ WRITE_PORT_UCHAR((PUCHAR)0x20,0x20);
+ WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20);
+ }
if (CurrentIrql >= Irql)
{
- HalpPendingInterruptCount[Vector - IRQ_BASE]++;
+ HalpPendingInterruptCount[irq]++;
return(FALSE);
}
*OldIrql = CurrentIrql;
*/
{
HalpLowerIrql(Irql);
+ HalpEndSystemInterrupt(Irql);
}
-
+
BOOLEAN STDCALL HalDisableSystemInterrupt (ULONG Vector,
ULONG Unknown2)
{
ULONG irq;
- if (Vector < IRQ_BASE || Vector > IRQ_BASE + NR_IRQS)
+ if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
return FALSE;
irq = Vector - IRQ_BASE;
+ pic_mask.both |= (1 << irq);
if (irq < 8)
{
- WRITE_PORT_UCHAR((PUCHAR)0x21,
- READ_PORT_UCHAR((PUCHAR)0x21)|(1<<irq));
+ WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master|pic_mask_intr.slave);
}
else
{
- WRITE_PORT_UCHAR((PUCHAR)0xa1,
- READ_PORT_UCHAR((PUCHAR)0xa1)|(1<<(irq-8)));
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave|pic_mask_intr.slave);
}
return TRUE;
{
ULONG irq;
- if (Vector < IRQ_BASE || Vector > IRQ_BASE + NR_IRQS)
+ if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
return FALSE;
irq = Vector - IRQ_BASE;
+ pic_mask.both &= ~(1 << irq);
if (irq < 8)
{
- WRITE_PORT_UCHAR((PUCHAR)0x21,
- READ_PORT_UCHAR((PUCHAR)0x21)&(~(1<<irq)));
+ WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master|pic_mask_intr.master);
}
else
{
- WRITE_PORT_UCHAR((PUCHAR)0xa1,
- READ_PORT_UCHAR((PUCHAR)0xa1)&(~(1<<(irq-8))));
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave|pic_mask_intr.slave);
}
return TRUE;