k-tana-zero/k/idt.c

101 lines
2.6 KiB
C

#include "idt.h"
#include "io.h"
#include "pic/keyboard.h"
#include "pic/pic.h"
#include "pic/pit.h"
#include "stdio.h"
static struct idt idt = { 0 };
static struct idt_entry_info infos[] = {
// Intel-defined (0-20)
{int_de, INTERRUPT_TYPE}, {int_db, INTERRUPT_TYPE},
{int_nmi, INTERRUPT_TYPE}, {int_bp, TRAP_TYPE},
{int_of, TRAP_TYPE}, {int_br, INTERRUPT_TYPE},
{int_ud, INTERRUPT_TYPE}, {int_nm, INTERRUPT_TYPE},
{int_df, INTERRUPT_TYPE}, {0, INTERRUPT_TYPE},
{int_ts, INTERRUPT_TYPE}, {int_np, INTERRUPT_TYPE},
{int_ss, INTERRUPT_TYPE}, {int_gp, INTERRUPT_TYPE},
{int_pf, INTERRUPT_TYPE}, {0, INTERRUPT_TYPE},
{int_mf, INTERRUPT_TYPE}, {int_ac, INTERRUPT_TYPE},
{int_mc, INTERRUPT_TYPE}, {int_xm, INTERRUPT_TYPE},
{int_ve, INTERRUPT_TYPE},
// Intel-reserved (21-31)
{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
// user-defined (32-255)
{pic_pit, INTERRUPT_TYPE}, {pic_keyboard, INTERRUPT_TYPE}
};
void handle_interrupt(struct int_args *args)
{
switch (args->int_code)
{
case 32: // PIT
pit_handler();
outb(MASTER_PORT_A, OCW2_EOI);
return;
case 33: // keyboard
keyboard_handler();
outb(MASTER_PORT_A, OCW2_EOI);
return;
}
printf("INTERRUPT: %d, error code: %d\r\n", args->int_code, args->err_code);
asm volatile("cli; hlt");
}
static struct idt_entry create_idt_entry(uint32_t offset,
struct segment_selector selector,
uint32_t type)
{
struct idt_entry res = { 0 };
res.selector = selector;
res.offset_1 = offset & 0xffff;
res.offset_2 = (offset >> 16) & 0xffff;
res.type = type;
res.size = 1;
res.desc_priv = 0;
res.present = 1;
return res;
}
static void create_idt(void)
{
struct segment_selector selector;
selector.rpl = 0;
selector.table_indicator = 0;
selector.index = KERNEL_CS_INDEX;
for (int i = 0; i < IDT_NB_ENTRIES; ++i)
{
struct idt_entry entry = create_idt_entry((uint32_t)infos[i].isr,
selector,
infos[i].type);
idt.entries[i] = entry;
}
}
static void load_idt(void)
{
struct idt_r idtr;
idtr.addr = (uint32_t)&idt;
idtr.limit = IDT_SIZE - 1;
asm volatile("lidt %0\n"
:
: "m" (idtr)
: "memory");
}
void init_idt(void)
{
create_idt();
load_idt();
}