k-chow/k/events/idt.c
Julien CLEMENT f6cdc3005d feat(pit): add pit initialization and handler
Signed-off-by: Julien CLEMENT <julien.clement@epita.fr>
2021-07-26 14:15:21 +02:00

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();
}