exectos/xtoskrnl/hl/pic.c
2023-11-26 10:31:31 +01:00

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);
}