[HAL]: Implement HalEnableSystemInterrupt and HalDisableSystemInterrupt in C instead of ASM.

svn path=/trunk/; revision=45236
This commit is contained in:
Sir Richard 2010-01-24 23:21:36 +00:00
parent 9c976d58e7
commit f79bc2e7f0
2 changed files with 79 additions and 120 deletions

View file

@ -210,126 +210,6 @@ AfterCall:
ret
.endfunc
.globl _HalDisableSystemInterrupt@8
.func HalDisableSystemInterrupt@8
_HalDisableSystemInterrupt@8:
/* Convert to vector */
movzx ecx, byte ptr [esp+4]
sub ecx, PRIMARY_VECTOR_BASE
/* Disable interrupts and set the new IDR */
mov edx, 1
shl edx, cl
cli
or PCR[KPCR_IDR], edx
/* Get the current mask */
xor eax, eax
in al, 0xA1
shl eax, 8
in al, 0x21
/* Mask off the interrupt and write the new mask */
or eax, edx
out 0x21, al
shr eax, 8
out 0xA1, al
/* Return with interrupts enabled */
in al, 0xA1
sti
ret 8
.endfunc
.globl _HalEnableSystemInterrupt@12
.func HalEnableSystemInterrupt@12
_HalEnableSystemInterrupt@12:
/* Get the vector and validate it */
movzx ecx, byte ptr [esp+4]
sub ecx, PRIMARY_VECTOR_BASE
jb Invalid
cmp ecx, CLOCK2_LEVEL
jnb Invalid
#if 0
/* Is PCI IRQ Routing enabled? */
cmp byte ptr _HalpIrqMiniportInitialized, 0
jz NoMiniport
/* UNHANDLED */
UNHANDLED_PATH
NoMiniport:
/* Check if this is an EISA IRQ */
bt _HalpEisaIrqIgnore, ecx
jb IgnoredIrq
/* Clear the EISA Edge/Level Control Register */
btr _HalpEisaELCR, ecx
/* Get the interrupt type */
mov al, [esp+12]
cmp al, 0
jnz Latched
/* Check the register again */
bt _HalpEisaELCR, ecx
jb Dismiss
/* Check if the miniport is active */
cmp byte ptr _HalpIrqMiniportInitialized, 0
jz Dismiss
/* Update the EISA Edge/Level Control Register */
bts _HalpEisaELCR, ecx
Dismiss:
/* Use the level hardware interrupt handler */
mov dword ptr SWInterruptHandlerTableHardware[ecx*4], offset _HalpHardwareInterruptLevel
mov edx, HalpSpecialDismissLevelTable[ecx*4]
mov HalpSpecialDismissTable[ecx*4], edx
Latched:
/* Is PCI IRQ Routing enabled? */
cmp byte ptr _HalpIrqMiniportInitialized, 0
jz IgnoredIrq
/* UNHANDLED */
UNHANDLED_PATH
#endif
IgnoredIrq:
/* Calculate the new IDR */
mov eax, 1
shl eax, cl
not eax
cli
and PCR[KPCR_IDR], eax
/* Get the current IRQL and mask the IRQs in the PIC */
mov eax, PCR[KPCR_IRQL]
mov eax, KiI8259MaskTable[eax*4]
or eax, PCR[KPCR_IDR]
out 0x21, al
shr eax, 8
out 0xA1, al
/* Enable interrupts and return TRUE */
sti
mov eax, 1
ret 12
Invalid:
/* Fail, invalid IRQ */
#if DBG
int 3
#endif
xor eax, eax
ret 12
.endfunc
.globl _HalBeginSystemInterrupt@12
.func HalBeginSystemInterrupt@12
_HalBeginSystemInterrupt@12:

View file

@ -341,3 +341,82 @@ HalClearSoftwareInterrupt(IN KIRQL Irql)
/* Mask out the requested bit */
KeGetPcr()->IRR &= ~(1 << Irql);
}
/* SYSTEM INTERRUPTS **********************************************************/
/*
* @implemented
*/
BOOLEAN
NTAPI
HalEnableSystemInterrupt(IN UCHAR Vector,
IN KIRQL Irql,
IN KINTERRUPT_MODE InterruptMode)
{
ULONG Irq;
PKPCR Pcr = KeGetPcr();
PIC_MASK PicMask;
/* Validate the IRQ */
Irq = Vector - PRIMARY_VECTOR_BASE;
if (Irq >= CLOCK2_LEVEL) return FALSE;
#ifdef PCI_IRQ_MP
/* Check if there is a PCI IRQ Routing Miniport Driver */
if (HalpIrqMiniportInitialized)
{
UNIMPLEMENTED;
while (TRUE);
}
#endif
/* Disable interrupts */
_disable();
/* Update software IDR */
Pcr->IDR &= ~(1 << Irq);
/* Set new PIC mask */
PicMask.Both = KiI8259MaskTable[Pcr->Irql] | Pcr->IDR;
__outbyte(PIC1_DATA_PORT, PicMask.Master);
__outbyte(PIC2_DATA_PORT, PicMask.Slave);
/* Enable interrupts and exit */
_enable();
return TRUE;
}
/*
* @implemented
*/
VOID
NTAPI
HalDisableSystemInterrupt(IN UCHAR Vector,
IN KIRQL Irql)
{
ULONG IrqMask;
PIC_MASK PicMask;
/* Compute new combined IRQ mask */
IrqMask = 1 << (Vector - PRIMARY_VECTOR_BASE);
/* Disable interrupts */
_disable();
/* Update software IDR */
KeGetPcr()->IDR |= IrqMask;
/* Read current interrupt mask */
PicMask.Master = __inbyte(PIC1_DATA_PORT);
PicMask.Slave = __inbyte(PIC2_DATA_PORT);
/* Add the new disabled interrupt */
PicMask.Both |= IrqMask;
/* Write new interrupt mask */
__outbyte(PIC1_DATA_PORT, PicMask.Master);
__outbyte(PIC2_DATA_PORT, PicMask.Slave);
/* Bring interrupts back */
_enable();
}