82 lines
1.5 KiB
C++
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();
|
|
} |