mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 12:29:56 +00:00
Fixed handling for level triggered interrupts.
svn path=/trunk/; revision=3850
This commit is contained in:
parent
4386afd7cb
commit
c657e69cc6
1 changed files with 68 additions and 24 deletions
|
@ -26,6 +26,17 @@
|
||||||
*/
|
*/
|
||||||
static KIRQL CurrentIrql = HIGH_LEVEL;
|
static KIRQL CurrentIrql = HIGH_LEVEL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PURPOSE: - Mask for HalEnableSystemInterrupt and HalDisableSystemInterrupt
|
||||||
|
* - At startup enable timer and cascade
|
||||||
|
*/
|
||||||
|
static USHORT pic_mask = 0xFFFA;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PURPOSE: Mask for disabling of acknowledged interrupts
|
||||||
|
*/
|
||||||
|
static USHORT pic_mask_intr = 0x0000;
|
||||||
|
|
||||||
extern IMPORTED ULONG DpcQueueSize;
|
extern IMPORTED ULONG DpcQueueSize;
|
||||||
|
|
||||||
static ULONG HalpPendingInterruptCount[NR_IRQS];
|
static ULONG HalpPendingInterruptCount[NR_IRQS];
|
||||||
|
@ -64,9 +75,9 @@ VOID HalpInitPICs(VOID)
|
||||||
/* 8086 mode */
|
/* 8086 mode */
|
||||||
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 all interrupts from PICs */
|
/* Enable interrupts */
|
||||||
WRITE_PORT_UCHAR((PUCHAR)0x21, 0x0);
|
WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask & 0xFF);
|
||||||
WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x0);
|
WRITE_PORT_UCHAR((PUCHAR)0xa1, (pic_mask >> 8) & 0xFF);
|
||||||
|
|
||||||
/* We can now enable interrupts */
|
/* We can now enable interrupts */
|
||||||
__asm__ __volatile__ ("sti\n\t");
|
__asm__ __volatile__ ("sti\n\t");
|
||||||
|
@ -93,6 +104,10 @@ HalpExecuteIrqs(KIRQL NewIrql)
|
||||||
CurrentIrql = IRQ_TO_DIRQL(i);
|
CurrentIrql = IRQ_TO_DIRQL(i);
|
||||||
KiInterruptDispatch2(i, NewIrql);
|
KiInterruptDispatch2(i, NewIrql);
|
||||||
HalpPendingInterruptCount[i]--;
|
HalpPendingInterruptCount[i]--;
|
||||||
|
if (HalpPendingInterruptCount[i] == 0)
|
||||||
|
{
|
||||||
|
HalEndSystemInterrupt(CurrentIrql, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -304,21 +319,30 @@ HalBeginSystemInterrupt (ULONG Vector,
|
||||||
KIRQL Irql,
|
KIRQL Irql,
|
||||||
PKIRQL OldIrql)
|
PKIRQL OldIrql)
|
||||||
{
|
{
|
||||||
if (Vector < IRQ_BASE || Vector > IRQ_BASE + NR_IRQS)
|
ULONG irq;
|
||||||
|
if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
|
||||||
{
|
{
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
irq = Vector - IRQ_BASE;
|
||||||
|
pic_mask_intr |= (1 << irq);
|
||||||
|
|
||||||
/* Send EOI to the PICs */
|
if (irq < 8)
|
||||||
WRITE_PORT_UCHAR((PUCHAR)0x20,0x20);
|
{
|
||||||
if ((Vector-IRQ_BASE)>=8)
|
WRITE_PORT_UCHAR((PUCHAR)0x21, (pic_mask|pic_mask_intr) & 0xff);
|
||||||
{
|
WRITE_PORT_UCHAR((PUCHAR)0x20, 0x20);
|
||||||
WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20);
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
WRITE_PORT_UCHAR((PUCHAR)0xa1, ((pic_mask|pic_mask_intr) >> 8) & 0xff);
|
||||||
|
/* Send EOI to the PICs */
|
||||||
|
WRITE_PORT_UCHAR((PUCHAR)0x20,0x20);
|
||||||
|
WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20);
|
||||||
|
}
|
||||||
|
|
||||||
if (CurrentIrql >= Irql)
|
if (CurrentIrql >= Irql)
|
||||||
{
|
{
|
||||||
HalpPendingInterruptCount[Vector - IRQ_BASE]++;
|
HalpPendingInterruptCount[irq]++;
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
*OldIrql = CurrentIrql;
|
*OldIrql = CurrentIrql;
|
||||||
|
@ -333,7 +357,29 @@ 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);
|
||||||
|
|
||||||
|
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,
|
||||||
|
@ -341,19 +387,18 @@ BOOLEAN STDCALL HalDisableSystemInterrupt (ULONG Vector,
|
||||||
{
|
{
|
||||||
ULONG irq;
|
ULONG irq;
|
||||||
|
|
||||||
if (Vector < IRQ_BASE || Vector > IRQ_BASE + NR_IRQS)
|
if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
irq = Vector - IRQ_BASE;
|
irq = Vector - IRQ_BASE;
|
||||||
|
pic_mask |= (1 << irq);
|
||||||
if (irq < 8)
|
if (irq < 8)
|
||||||
{
|
{
|
||||||
WRITE_PORT_UCHAR((PUCHAR)0x21,
|
WRITE_PORT_UCHAR((PUCHAR)0x21, (pic_mask|pic_mask_intr) & 0xff);
|
||||||
READ_PORT_UCHAR((PUCHAR)0x21)|(1<<irq));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WRITE_PORT_UCHAR((PUCHAR)0xa1,
|
WRITE_PORT_UCHAR((PUCHAR)0xa1, ((pic_mask|pic_mask_intr) >> 8) & 0xff);
|
||||||
READ_PORT_UCHAR((PUCHAR)0xa1)|(1<<(irq-8)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -366,19 +411,18 @@ BOOLEAN STDCALL HalEnableSystemInterrupt (ULONG Vector,
|
||||||
{
|
{
|
||||||
ULONG irq;
|
ULONG irq;
|
||||||
|
|
||||||
if (Vector < IRQ_BASE || Vector > IRQ_BASE + NR_IRQS)
|
if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
irq = Vector - IRQ_BASE;
|
irq = Vector - IRQ_BASE;
|
||||||
|
pic_mask &= ~(1 << irq);
|
||||||
if (irq < 8)
|
if (irq < 8)
|
||||||
{
|
{
|
||||||
WRITE_PORT_UCHAR((PUCHAR)0x21,
|
WRITE_PORT_UCHAR((PUCHAR)0x21, (pic_mask|pic_mask_intr) & 0xff);
|
||||||
READ_PORT_UCHAR((PUCHAR)0x21)&(~(1<<irq)));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WRITE_PORT_UCHAR((PUCHAR)0xa1,
|
WRITE_PORT_UCHAR((PUCHAR)0xa1, ((pic_mask|pic_mask_intr) >> 8) & 0xff);
|
||||||
READ_PORT_UCHAR((PUCHAR)0xa1)&(~(1<<(irq-8))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
Loading…
Reference in a new issue