102 lines
2.1 KiB
C
102 lines
2.1 KiB
C
// Interrupt Requests setup
|
|
// Author: xamidev
|
|
// Licensed under the Unlicense. See the repo below.
|
|
// https://github.com/xamidev/blankos
|
|
|
|
#include "system.h"
|
|
#include "io.h"
|
|
#include "idt.h"
|
|
#include "../libc/stdio.h"
|
|
|
|
extern void irq0();
|
|
extern void irq1();
|
|
extern void irq2();
|
|
extern void irq3();
|
|
extern void irq4();
|
|
extern void irq5();
|
|
extern void irq6();
|
|
extern void irq7();
|
|
extern void irq8();
|
|
extern void irq9();
|
|
extern void irq10();
|
|
extern void irq11();
|
|
extern void irq12();
|
|
extern void irq13();
|
|
extern void irq14();
|
|
extern void irq15();
|
|
|
|
extern void syscall_common_stub();
|
|
|
|
void *irq_routines[16] =
|
|
{
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
|
|
void irq_install_handler(int irq, void (*handler)(struct regs *r))
|
|
{
|
|
irq_routines[irq] = handler;
|
|
}
|
|
|
|
void irq_uninstall_handler(int irq)
|
|
{
|
|
irq_routines[irq] = 0;
|
|
}
|
|
|
|
void irq_remap(void)
|
|
{
|
|
outb(0x20, 0x11);
|
|
outb(0xA0, 0x11);
|
|
outb(0x21, 0x20);
|
|
outb(0xA1, 0x28);
|
|
outb(0x21, 0x04);
|
|
outb(0xA1, 0x02);
|
|
outb(0x21, 0x01);
|
|
outb(0xA1, 0x01);
|
|
outb(0x21, 0x0);
|
|
outb(0xA1, 0x0);
|
|
}
|
|
|
|
void irq_install()
|
|
{
|
|
irq_remap();
|
|
|
|
idt_set_gate(32, (unsigned)irq0, 0x08, 0x8E);
|
|
idt_set_gate(33, (unsigned)irq1, 0x08, 0x8E);
|
|
idt_set_gate(34, (unsigned)irq2, 0x08, 0x8E);
|
|
idt_set_gate(35, (unsigned)irq3, 0x08, 0x8E);
|
|
idt_set_gate(36, (unsigned)irq4, 0x08, 0x8E);
|
|
idt_set_gate(37, (unsigned)irq5, 0x08, 0x8E);
|
|
idt_set_gate(38, (unsigned)irq6, 0x08, 0x8E);
|
|
idt_set_gate(39, (unsigned)irq7, 0x08, 0x8E);
|
|
idt_set_gate(40, (unsigned)irq8, 0x08, 0x8E);
|
|
idt_set_gate(41, (unsigned)irq9, 0x08, 0x8E);
|
|
idt_set_gate(42, (unsigned)irq10, 0x08, 0x8E);
|
|
idt_set_gate(43, (unsigned)irq11, 0x08, 0x8E);
|
|
idt_set_gate(44, (unsigned)irq12, 0x08, 0x8E);
|
|
idt_set_gate(45, (unsigned)irq13, 0x08, 0x8E);
|
|
idt_set_gate(46, (unsigned)irq14, 0x08, 0x8E);
|
|
idt_set_gate(47, (unsigned)irq15, 0x08, 0x8E);
|
|
printf("[kernel] installed irq 0-15\n");
|
|
|
|
idt_set_gate(0x80, (unsigned long)syscall_common_stub, 0x08, 0x8E);
|
|
}
|
|
|
|
void irq_handler(struct regs *r)
|
|
{
|
|
void (*handler)(struct regs *r);
|
|
|
|
handler = irq_routines[r->int_no-32];
|
|
if (handler)
|
|
{
|
|
handler(r);
|
|
}
|
|
|
|
if (r->int_no >= 40)
|
|
{
|
|
outb(0xA0, 0x20);
|
|
}
|
|
|
|
outb(0x20, 0x20);
|
|
}
|