mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 18:52:57 +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
|
||||
.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:
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue