diff options
Diffstat (limited to 'arch/x86_64/idt.c')
-rw-r--r-- | arch/x86_64/idt.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/arch/x86_64/idt.c b/arch/x86_64/idt.c new file mode 100644 index 0000000..99e1da1 --- /dev/null +++ b/arch/x86_64/idt.c @@ -0,0 +1,46 @@ +#include "arch/x86_64/tables.h" +#include "arch/x86_64/idt.h" + +__attribute__((aligned(4096))) +interrupt_gate_t s_idtd[256]; + +int64_t __isr_err; +int64_t __isr_num; + +void +isr_handle(ivt_state_t* state) +{ + kpanic_state(state, "Unhandled interrupt %i", __isr_num); +} + +void +ivt_setup(void) +{ + extern uintptr_t __ivt[256]; + for(int i = 0; i < 256; i++) { + uintptr_t base = __ivt[i]; + s_idtd[i] = (interrupt_gate_t) { + .base_0_15 = (base & 0xFFFF), + .segment_selector = 0x8, + .ist = 0, + .zero_0 = 0, + .type = 0xE, + .zero_1 = 0, + .dpl = 0, + .p = 1, + .base_16_31 = (base >> 16) & 0xFFFF, + .base_32_63 = (base >> 32) & 0xFFFFFFFF, + .resv = 0 + }; + } +} + +void +idt_setup(processor_t *processor) +{ + processor->idtr.base = (uintptr_t)&s_idtd; + processor->idtr.length = sizeof(s_idtd) - 1; + + extern void idt_load(void* idtr); + idt_load(&processor->idtr); +} |