107 lines
3.8 KiB
C
107 lines
3.8 KiB
C
#include "idt.h"
|
|
#include "stdio.h"
|
|
#include "pic/pic.h"
|
|
#include "pic/keyboard.h"
|
|
#include "pic/pit.h"
|
|
#include "io.h"
|
|
|
|
static struct idt idt = { 0 };
|
|
|
|
static struct idt_entry_descriptor idt_entries_descriptors[IDT_NB_ENTRIES] = {
|
|
{(uint32_t)&isr_divide, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 0
|
|
{(uint32_t)&isr_debug, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 1
|
|
{(uint32_t)&isr_nmi, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 2
|
|
{(uint32_t)&isr_breakpoint, KERNEL_CS_SEGMENT_SELECTOR, TRAP_TYPE}, // 3
|
|
{(uint32_t)&isr_overflow, KERNEL_CS_SEGMENT_SELECTOR, TRAP_TYPE}, // 4
|
|
{(uint32_t)&isr_bound_range_exceeded, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 5
|
|
{(uint32_t)&isr_invalid_opcode, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 6
|
|
{(uint32_t)&isr_device_not_available, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 7
|
|
{(uint32_t)&isr_double_fault, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 8
|
|
{(uint32_t)&isr_coprocessor_segment_overrun, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 9
|
|
{(uint32_t)&isr_invalid_tss, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 10
|
|
{(uint32_t)&isr_segment_not_present, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 11
|
|
{(uint32_t)&isr_stack_segment_fault, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 12
|
|
{(uint32_t)&isr_general_protection, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 13
|
|
{(uint32_t)&isr_page_fault, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 14
|
|
{0, {0, 0, 0}, 0}, // 15
|
|
{(uint32_t)&isr_fpu_floating_point_error, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 16
|
|
{(uint32_t)&isr_alignment_check, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 17
|
|
{(uint32_t)&isr_machine_check, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 18
|
|
{(uint32_t)&isr_simd_floating_point_exception, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 19
|
|
{(uint32_t)&isr_virtualization_exception, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 20
|
|
{(uint32_t)&isr_control_protection_exception, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 21
|
|
{0, {0, 0, 0}, 0}, // 22
|
|
{0, {0, 0, 0}, 0}, // 23
|
|
{0, {0, 0, 0}, 0}, // 24
|
|
{0, {0, 0, 0}, 0}, // 25
|
|
{0, {0, 0, 0}, 0}, // 26
|
|
{0, {0, 0, 0}, 0}, // 27
|
|
{0, {0, 0, 0}, 0}, // 28
|
|
{0, {0, 0, 0}, 0}, // 29
|
|
{0, {0, 0, 0}, 0}, // 30
|
|
{0, {0, 0, 0}, 0}, // 31
|
|
{(uint32_t)&isr_pit, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 32
|
|
{(uint32_t)&isr_keyboard, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE} // 33
|
|
};
|
|
|
|
void interrupt_handler(struct isr_param *isr_param)
|
|
{
|
|
switch (isr_param->int_vector)
|
|
{
|
|
case PIT_INT_VECTOR:
|
|
pit_handler();
|
|
break;
|
|
case KEYBOARD_INT_VECTOR:
|
|
keyboard_handler();
|
|
break;
|
|
}
|
|
|
|
if (isr_param->int_vector >= IDT_RESERVED_ENTRIES
|
|
&& isr_param->int_vector < IDT_RESERVED_ENTRIES + 16)
|
|
acknowledge(isr_param->int_vector);
|
|
}
|
|
|
|
struct idt_entry create_idt_entry(struct idt_entry_descriptor descriptor)
|
|
{
|
|
struct idt_entry res = { 0 };
|
|
|
|
res.selector = descriptor.selector;
|
|
res.offset_1 = descriptor.offset & 0xffff;
|
|
res.offset_2 = (descriptor.offset >> 16) & 0xffff;
|
|
|
|
res.type = descriptor.type;
|
|
res.size = 1;
|
|
res.desc_priv = 0;
|
|
res.present = 1;
|
|
|
|
return res;
|
|
}
|
|
|
|
static void create_idt(void)
|
|
{
|
|
for (int i = 0; i < IDT_NB_ENTRIES; ++i)
|
|
{
|
|
struct idt_entry entry = create_idt_entry(idt_entries_descriptors[i]);
|
|
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();
|
|
}
|