blob: b2251bdf40d7e6c858f9b654aa9efa0438cd6965 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
#include "idt.h"
#include "smp.h"
#include "gdt.h"
#include "jove.h"
#include "lib/printf.h"
ALIGN(8)
static struct idt_entry s_idt[IDT_ENTRIES];
typedef void (*isr_t)(void);
extern isr_t __isrs[IDT_ENTRIES];
typedef struct int_stackframe *(*int_handler_t)(struct int_stackframe*);
int_handler_t __int_handles[IDT_ENTRIES];
static struct int_stackframe*
s_int_handle_stub(struct int_stackframe* frame)
{
kprintf("Unhandled interrupt %i at %p\n", frame->int_num, frame->int_rip);
hcf();
}
void
idt_init(void)
{
for(size_t i = 0; i < IDT_ENTRIES; i++) {
uintptr_t isr = (uintptr_t)(__isrs[i]);
s_idt[i] = (struct idt_entry) {
.offset_0_15 = (uint16_t)(isr & 0xFFFF),
.segment_selector = GDT_KERNEL_CODE * 8,
.ist = 0,
.type = IDT_INTERRUPT_GATE,
.dpl = 0,
.p = 1,
.offset_16_31 = (uint16_t)((isr >> 16) & 0xFFFF),
.offset_32_63 = (uint32_t)(isr >> 32)
};
__int_handles[i] = s_int_handle_stub;
}
}
void
idt_setup(processor_t *processor)
{
struct idt_descriptor idtr = (struct idt_descriptor) {
.limit = sizeof(struct idt_entry) * IDT_ENTRIES - 1,
.base = (uint64_t)&s_idt
};
__asm__ volatile("lidt %0":: "m"(idtr));
}
|