blob: b8086251b844e6a0ea3fbed4015470a64d7450e0 (
plain)
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
|
#include "idt.hpp"
#include "libs/string.hpp"
IDT_REGISTER IDTR = {
IDT_GATE_SIZE*IDT_MAX_ENTRIES,
IDT_ADDR
};
extern u64 INT_DEFAULT,INT_0,INT_14;
void idt_enable_interrupt(void){
IDT_DESCRIPTOR d;
d.ign=0;
d.ist=0;
d.selector=0x08;
d.options=IDT_OPT_P|IDT_OPT_PRVL_0|IDT_OPT_TYPE_INT;
// Write idt entries
for(u16 i=0;i<IDT_MAX_ENTRIES;i++){
if(i==0){ // Zero-division
d.offset=(u64)&INT_0;
idt_write_descriptor(d, i);
}
else if(i==14){ // Page fault
d.offset=(u64)&INT_14;
idt_write_descriptor(d, i);
}
else {
d.offset=(u64)&INT_DEFAULT;
idt_write_descriptor(d, i);
}
}
// Enable interrupts
asm(
"lidt (IDTR) \n\t"
"sti \n\t"
);
}
void idt_write_descriptor(IDT_DESCRIPTOR desc, u16 index){
u32 desc0_31=(desc.selector << 16) | desc.offset&0xFFFF;
u32 desc32_63=desc.ist | desc.options | (desc.offset&0xFFFF0000);
u32 desc64_95=desc.offset>>32;
u32 desc96_127=desc.ign;
u32* dst=(u32*)(IDTR.base+index*IDT_GATE_SIZE);
*dst=desc0_31;
*(dst+1)=desc32_63;
*(dst+2)=desc64_95;
*(dst+3)=desc96_127;
}
|