mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 19:03:00 +00:00
[HAL]: Implement HalEnableSystemInterrupt and HalDisableSystemInterrupt in C instead of ASM.
svn path=/trunk/; revision=45236
This commit is contained in:
parent
9c976d58e7
commit
f79bc2e7f0
2 changed files with 79 additions and 120 deletions
|
@ -210,126 +210,6 @@ AfterCall:
|
||||||
ret
|
ret
|
||||||
.endfunc
|
.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
|
.globl _HalBeginSystemInterrupt@12
|
||||||
.func HalBeginSystemInterrupt@12
|
.func HalBeginSystemInterrupt@12
|
||||||
_HalBeginSystemInterrupt@12:
|
_HalBeginSystemInterrupt@12:
|
||||||
|
|
|
@ -341,3 +341,82 @@ HalClearSoftwareInterrupt(IN KIRQL Irql)
|
||||||
/* Mask out the requested bit */
|
/* Mask out the requested bit */
|
||||||
KeGetPcr()->IRR &= ~(1 << Irql);
|
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();
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue