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
|
#include "tables.h"
#include "cpu.h"
#include "lib/jove.h"
#include "io/log.h"
PAGEALIGN
static struct InterruptTrapGate s_idtd[48];
static struct Registers *(*s_int_handlers[48])(struct Registers*);
static struct XDTR s_idtr = {
.length = sizeof(s_idtd) - 1,
.address = (uintptr_t)&s_idtd
};
uint64_t __isr_err;
uint64_t __isr_num;
void
int_set_handler(uint8_t code, struct Registers *(*handler)(struct Registers*))
{
if(code >= 48) return;
s_int_handlers[code] = handler;
}
struct Registers*
irq_handle(struct Registers *state)
{
if(__isr_num < 48) {
if(s_int_handlers[__isr_num] != NULL) {
return s_int_handlers[__isr_num](state);
}
}
klogf("Interrupt %i\nerror code %#016X\n", __isr_num, __isr_err);
klogf("IP: %#016X\n", state->ip);
klogf("AX: %#016X\n", state->ax);
klogf("BX: %#016X\n", state->bx);
klogf("CX: %#016X\n", state->cx);
klogf("DX: %#016X\n", state->dx);
klogf("SI: %#016X\n", state->si);
klogf("DI: %#016X\n", state->di);
klogf("BP: %#016X\n", state->bp);
klogf("R8: %#016X\n", state->r8);
klogf("R9: %#016X\n", state->r9);
klogf("R10: %#016X\n", state->r10);
klogf("R11: %#016X\n", state->r11);
klogf("R12: %#016X\n", state->r12);
klogf("R13: %#016X\n", state->r13);
klogf("R14: %#016X\n", state->r14);
klogf("R15: %#016X\n", state->r15);
kpanic("Unhandled exception\n");
return state;
}
extern void x86_64_lidt(struct XDTR *idtr);
void
x86_64_load_idt(void)
{
extern uintptr_t __isr_stubs[22];
for(int i = 0; i < 22; i++)
{
uintptr_t base = __isr_stubs[i];
s_idtd[i] = (struct InterruptTrapGate){
.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
};
klogf("INT %2i : %#016X (%016X)\n", i, base, s_idtd[i]);
}
x86_64_lidt(&s_idtr);
}
|