163 lines
3.3 KiB
C
163 lines
3.3 KiB
C
/**
|
|
* PROJECT: ExectOS
|
|
* COPYRIGHT: See COPYING.md in the top level directory
|
|
* FILE: xtoskrnl/hl/pic.c
|
|
* DESCRIPTION: Programmable Interrupt Controller (PIC) support
|
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
|
* Jozef Nagy <schkwve@gmail.com>
|
|
*/
|
|
|
|
#include <xtos.h>
|
|
|
|
/**
|
|
* Initializes the 8259 PIC.
|
|
*
|
|
* @return This routine does not return any value.
|
|
*
|
|
* @since XT 1.0
|
|
*/
|
|
XTCDECL
|
|
VOID
|
|
HlInitializePic(VOID)
|
|
{
|
|
/* Start in cascade mode */
|
|
HlWritePic(PIC_MASTER_COMMAND, PIC_ICW1_INIT | PIC_ICW1_ICW4);
|
|
HlWritePic(PIC_SLAVE_COMMAND, PIC_ICW1_INIT | PIC_ICW1_ICW4);
|
|
|
|
/* Master PIC Vector offset */
|
|
HlWritePic(PIC_MASTER_DATA, 0x20);
|
|
/* Slave PIC Vector offset */
|
|
HlWritePic(PIC_SLAVE_DATA, 0x28);
|
|
|
|
/* Tell Master PIC that there is a Slave PIC */
|
|
HlWritePic(PIC_MASTER_DATA, 4);
|
|
/* Tell Slave PIC its cascade identity */
|
|
HlWritePic(PIC_SLAVE_DATA, 2);
|
|
|
|
/* Tell Master PIC to use 8086 mode */
|
|
HlWritePic(PIC_MASTER_DATA, PIC_ICW4_8086);
|
|
/* Tell Slave PIC to use 8086 mode */
|
|
HlWritePic(PIC_SLAVE_DATA, PIC_ICW4_8086);
|
|
|
|
/* Mask all IRQs by default */
|
|
for (UCHAR Irq = 0; Irq < 16; Irq++)
|
|
{
|
|
HlSetMaskIrqPic(Irq);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Masks an IRQ in the 8259 PIC.
|
|
*
|
|
* @param Irq
|
|
* Supplies the IRQ number to be masked.
|
|
*
|
|
* @return This routine does not return any value.
|
|
*
|
|
* @since XT 1.0
|
|
*/
|
|
XTCDECL
|
|
VOID
|
|
HlSetMaskIrqPic(UINT Irq)
|
|
{
|
|
UINT Port;
|
|
|
|
if(Irq < 8) {
|
|
Port = PIC_MASTER_DATA;
|
|
} else {
|
|
Port = PIC_SLAVE_DATA;
|
|
Irq -= 8;
|
|
}
|
|
|
|
HlWritePic(Port, HlIoPortInByte(Port) | (1 << Irq));
|
|
}
|
|
|
|
/**
|
|
* Clears an IRQ mask in the 8259 PIC.
|
|
*
|
|
* @param Irq
|
|
* Supplies the IRQ number to be unmasked.
|
|
*
|
|
* @return This routine does not return any value.
|
|
*
|
|
* @since XT 1.0
|
|
*/
|
|
XTCDECL
|
|
VOID
|
|
HlClearMaskIrqPic(UINT Irq)
|
|
{
|
|
UINT Port;
|
|
|
|
if(Irq < 8) {
|
|
Port = PIC_MASTER_DATA;
|
|
} else {
|
|
Port = PIC_SLAVE_DATA;
|
|
Irq -= 8;
|
|
}
|
|
|
|
HlWritePic(Port, HlIoPortInByte(Port) & ~(1 << Irq));
|
|
}
|
|
|
|
/**
|
|
* Disables the 8259 PIC.
|
|
*
|
|
* @return This routine does not return any value.
|
|
*
|
|
* @since XT 1.0
|
|
*/
|
|
XTCDECL
|
|
VOID
|
|
HlDisablePic(VOID)
|
|
{
|
|
HlIoPortOutByte(PIC_MASTER_DATA, 0xFF);
|
|
HlIoPortOutByte(PIC_SLAVE_DATA, 0xFF);
|
|
}
|
|
|
|
XTFASTCALL
|
|
VOID
|
|
HlWritePic(IN UCHAR Register, IN UCHAR Value)
|
|
{
|
|
/* Send data */
|
|
HlIoPortOutByte(Register, Value);
|
|
/* Wait for some time to make sure PIC has processed the data */
|
|
HlIoPortWait();
|
|
}
|
|
|
|
/**
|
|
* Reads from the local APIC register.
|
|
*
|
|
* @param Register
|
|
* Supplies the APIC register to read from.
|
|
*
|
|
* @return This routine returns the value read from the APIC register.
|
|
*
|
|
* @since XT 1.0
|
|
*/
|
|
XTFASTCALL
|
|
ULONG
|
|
HlReadApicRegister(IN APIC_REGISTER Register)
|
|
{
|
|
return RtlReadRegisterLong((PULONG)APIC_BASE + (Register << 4));
|
|
}
|
|
|
|
/**
|
|
* Writes to the local APIC register.
|
|
*
|
|
* @param Register
|
|
* Supplies the APIC register to write to.
|
|
*
|
|
* @param Value
|
|
* Supplies the value to write to the APIC register.
|
|
*
|
|
* @return This routine does not return any value.
|
|
*
|
|
* @since XT 1.0
|
|
*/
|
|
XTFASTCALL
|
|
VOID
|
|
HlWriteApicRegister(IN APIC_REGISTER Register,
|
|
IN ULONG Value)
|
|
{
|
|
RtlWriteRegisterLong((PULONG)APIC_BASE + (Register << 4), Value);
|
|
}
|