Luna/kernel/src/io/PIC.cpp

82 lines
1.5 KiB
C++

#define MODULE "pic"
#include "io/PIC.h"
#include "io/IO.h"
#include "log/Log.h"
#define PIC1_COMMAND 0x20
#define PIC1_DATA 0x21
#define PIC2_COMMAND 0xA0
#define PIC2_DATA 0xA1
#define PIC_EOI 0x20
#define ICW1_INIT 0x10
#define ICW1_ICW4 0x01
#define ICW4_8086 0x01
void PIC::remap()
{
kdbgln("Remapping PIC");
uint8_t a1, a2;
a1 = IO::inb(PIC1_DATA);
IO::delay();
a2 = IO::inb(PIC2_DATA);
IO::delay();
IO::outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4);
IO::delay();
IO::outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
IO::delay();
kdbgln("Remapping master PIC to ISRs 32-39");
IO::outb(PIC1_DATA, 0x20);
IO::delay();
kdbgln("Remapping slave PIC to ISRs 40-47");
IO::outb(PIC2_DATA, 0x28);
IO::delay();
IO::outb(PIC1_DATA, 4);
IO::delay();
IO::outb(PIC2_DATA, 2);
IO::delay();
IO::outb(PIC1_DATA, ICW4_8086);
IO::delay();
IO::outb(PIC2_DATA, ICW4_8086);
IO::delay();
IO::outb(PIC1_DATA, a1);
IO::delay();
IO::outb(PIC2_DATA, a2);
}
void PIC::enable_master(uint8_t mask)
{
kdbgln("Setting mask of master PIC to 0x%x", mask);
IO::outb(PIC1_DATA, mask);
}
void PIC::enable_slave(uint8_t mask)
{
kdbgln("Setting mask of slave PIC to 0x%x", mask);
IO::outb(PIC2_DATA, mask);
}
void PIC::end_master()
{
IO::outb(PIC1_COMMAND, PIC_EOI);
}
void PIC::end_slave()
{
IO::outb(PIC2_COMMAND, PIC_EOI);
IO::outb(PIC1_COMMAND, PIC_EOI);
}
void PIC::send_eoi(unsigned char irq)
{
if (irq >= 8) end_slave();
else
end_master();
}