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
|
#include "idt.h"
#define outb(port, value) asm volatile("out %b0,%w1" : : "a" (value), "d" (port));
#define isr_panic(num) void isr_ ## num(); \
asm( \
".globl isr_" #num "\n" \
"isr_" #num ":\n" \
"push $" #num "\n" \
"call panic\n" \
"iret\n" \
)
char* panic_msg[] = {
[0] = "Divide error.",
[8] = "Double fault.",
[14] = "Page fault."
};
isr_panic(0);
isr_panic(8);
isr_panic(14);
void panic(uint32_t num) {
char* str = panic_msg[num];
while(*str) {
outb(0x3f8, *str++);
}
outb(0x3f8, '\r');
outb(0x3f8, '\n');
asm volatile(
"cli\n"
"hlt\n"
);
while(1);
}
idt_entry idt[] = {
{.base_low = 1}, // Keep IDT in .data.
[1 ... 255] = idt_entry_null
};
idt_ptr idtr = {
.base = idt,
.limit = sizeof(idt) - 1
};
void idt_set_gate(uint8_t num, uint32_t base, uint16_t segment, uint16_t flags) {
idt[num].base_low = base & 0xffff;
idt[num].base_high = base >> 16 & 0xffff;
idt[num].segment = segment;
idt[num].flags = flags;
}
void idt_init() {
idt_set_gate(0, (uint32_t)isr_0, 0x08, 0x8e00);
idt_set_gate(8, (uint32_t)isr_8, 0x08, 0x8e00);
idt_set_gate(14, (uint32_t)isr_14, 0x08, 0x8e00);
asm volatile(
"lidt (%0)\n"
: : "r" (&idtr)
);
}
|