aboutsummaryrefslogtreecommitdiff
path: root/src/core/idt.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/idt.cc')
-rw-r--r--src/core/idt.cc51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/core/idt.cc b/src/core/idt.cc
new file mode 100644
index 0000000..b808625
--- /dev/null
+++ b/src/core/idt.cc
@@ -0,0 +1,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;
+} \ No newline at end of file