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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
#include <stdbool.h>
#include <idt.h>
#include <vga.h>
#include <mem.h>
extern void idt_load();
struct idt_entry {
uint16_t offset_low;
uint16_t sel;
uint8_t ist;
uint8_t flags;
uint16_t offset_middle;
uint32_t offset_high;
uint32_t reserved;
} __attribute__((packed));
struct idt {
uint16_t limit;
uint64_t base;
} __attribute__((packed));
struct idt_entry idt[256];
struct idt idt_ptr;
static void (*handlers[256])(uint64_t, uint64_t) = { 0 };
static const char *exception_msg[] = {
"Division By Zero Exception",
"Debug Exception",
"Non Maskable Interrupt Exception",
"Breakpoint Exception",
"Into Detected Overflow Exception",
"Out of Bounds Exception",
"Invalid Opcode Exception",
"No Coprocessor Exception",
"Double Fault Exception",
"Coprocessor Segment Overrun Exception",
"Bad TSS Exception",
"Segment Not Present Exception",
"Stack Fault Exception",
"General Protection Fault Exception",
"Page Fault Exception",
"Unknown Interrupt Exception",
"Coprocessor Fault Exception",
"Alignment Check Exception (486+)",
"Machine Check Exception (Pentium/586+)",
"Reserved Exceptions",
"Reserved Exceptions",
"Reserved Exceptions",
"Reserved Exceptions",
"Reserved Exceptions",
"Reserved Exceptions",
"Reserved Exceptions",
"Reserved Exceptions",
"Reserved Exceptions",
"Reserved Exceptions",
"Reserved Exceptions",
"Reserved Exceptions",
"Reserved Exceptions",
};
void exception_handler(uint64_t num, uint64_t error) {
vga_puts("\n\neto bleh: ");
vga_puts(exception_msg[num]);
vga_puts("\nerror info: ");
vga_putx(error);
while (1);
}
void interrupt_handler(uint64_t num, uint64_t data) {
handlers[num](num, data);
}
void idt_set_isr(uint8_t num, uint64_t offset, uint16_t sel, uint8_t flags) {
idt[num] = (struct idt_entry) {
.offset_low = offset & 0xFFFF,
.offset_middle = (offset >> 16) & 0xFFFF,
.offset_high = (offset >> 32) & 0xFFFFFFFF,
.sel = sel,
.ist = 0,
.flags = flags,
.reserved = 0,
};
}
void idt_init() {
idt_ptr.limit = (sizeof(struct idt_entry) * 256) - 1;
idt_ptr.base = (uint64_t) &idt;
memset(idt, 0, (sizeof(struct idt_entry) * 256));
idt_load();
for (size_t i = 0; i < 32; i++) {
idt_set_isr(i, isr_table[i], 0x08, 0x8E);
handlers[i] = exception_handler;
}
}
bool idt_register_isr(size_t num, void (*func)(uint64_t, uint64_t)) {
if (handlers[num])
return false;
handlers[num] = func;
return true;
}
bool idt_remove_isr(size_t num, void (*func)(uint64_t, uint64_t)) {
if (handlers[num] != func)
return false;
handlers[num] = NULL;
return true;
}
|