93 lines
2.0 KiB
C
93 lines
2.0 KiB
C
// 8259 Programmable interrupt controller routines...
|
|
// The usual computer will switch to IOAPIC later on, once ACPI is fully
|
|
// initialized and the driver/module system is active.
|
|
|
|
// I could probably try to do without interrupts until I get in C++-land but
|
|
// you never know - also, paging without interrupts is pointless, especiallly
|
|
// if I want a good heap implementation, which is more-or-less indispensable
|
|
// if I want to ever reach Tier1 in a sane way.
|
|
|
|
// tl;dr - This code isn't going to be running all the time
|
|
|
|
#include "types.h"
|
|
#include "Tier0/kstdio.h"
|
|
#include "Tier0/pic.h"
|
|
|
|
#define PIC_COMMAND_EOI 0x20
|
|
|
|
// Initialisation "words".
|
|
#define PIC_ICW1_INIT 0x10
|
|
#define PIC_ICW1_ICW4 0x01
|
|
#define PIC_ICW4_8086 0x01
|
|
|
|
void pic_init(u8 *OldMask1, u8 *OldMask2)
|
|
{
|
|
if (OldMask1 != 0)
|
|
*OldMask1 = kinb(PIC_1_DATA);
|
|
|
|
if (OldMask2 != 0)
|
|
*OldMask2 = kinb(PIC_2_DATA);
|
|
|
|
koutb(PIC_1_ADDR, PIC_ICW1_INIT | PIC_ICW1_ICW4);
|
|
kio_wait();
|
|
|
|
koutb(PIC_2_ADDR, PIC_ICW1_INIT | PIC_ICW1_ICW4);
|
|
kio_wait();
|
|
|
|
// ICW2
|
|
koutb(PIC_1_DATA, PIC_1_START);
|
|
kio_wait();
|
|
|
|
koutb(PIC_2_DATA, PIC_2_START);
|
|
kio_wait();
|
|
|
|
// ICW3
|
|
koutb(PIC_1_DATA, 4);
|
|
kio_wait();
|
|
|
|
koutb(PIC_2_DATA, 2);
|
|
kio_wait();
|
|
|
|
// ICW4
|
|
koutb(PIC_1_DATA, PIC_ICW4_8086);
|
|
kio_wait();
|
|
|
|
koutb(PIC_2_DATA, PIC_ICW4_8086);
|
|
kio_wait();
|
|
|
|
//We don't support ANYTHING
|
|
koutb(PIC_1_DATA, 0xFF);
|
|
koutb(PIC_2_DATA, 0xFF);
|
|
}
|
|
|
|
void pic_eoi(u8 IRQ)
|
|
{
|
|
if (IRQ > 7)
|
|
koutb(PIC_2_ADDR, PIC_COMMAND_EOI);
|
|
|
|
koutb(PIC_1_ADDR, PIC_COMMAND_EOI);
|
|
}
|
|
|
|
void pic_unmask_irq(u8 IRQ)
|
|
{
|
|
if (IRQ > 7)
|
|
{
|
|
u8 Bit = 0;
|
|
Bit |= 1 << (IRQ - 8);
|
|
|
|
u8 CurrentMask = kinb(PIC_2_DATA);
|
|
u8 NewMask = ~((~CurrentMask) | Bit);
|
|
|
|
koutb(PIC_2_DATA, NewMask);
|
|
}
|
|
else
|
|
{
|
|
u8 Bit = 0;
|
|
Bit |= 1 << (IRQ);
|
|
|
|
u8 CurrentMask = kinb(PIC_1_DATA);
|
|
u8 NewMask = ~((~CurrentMask) | Bit);
|
|
koutb(PIC_1_DATA, NewMask);
|
|
}
|
|
}
|