diff options
| author | Loic Guegan <manzerbredes@mailbox.org> | 2021-04-21 18:54:50 +0200 |
|---|---|---|
| committer | Loic Guegan <manzerbredes@mailbox.org> | 2021-04-21 18:54:50 +0200 |
| commit | 99019721a9e147c49becc466c5427609b937aca8 (patch) | |
| tree | 3b187d90bdb606a9c27760cd6e187aeb995fd956 /src/core | |
| parent | 2f712d027b38bebd571e4fa673f0d642b59e3c98 (diff) | |
Enable interrupts
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/idt.cc | 51 | ||||
| -rw-r--r-- | src/core/idt.hpp | 33 | ||||
| -rw-r--r-- | src/core/int.S | 33 |
3 files changed, 117 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 diff --git a/src/core/idt.hpp b/src/core/idt.hpp new file mode 100644 index 0000000..f2aca43 --- /dev/null +++ b/src/core/idt.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include "types.hpp" +#include "libs/stdio.hpp" + +#define IDT_GATE_SIZE 16 +#define IDT_MAX_ENTRIES 50 +#define IDT_ADDR 0x200000 + +#define IDT_OPT_P (1 << 15) +#define IDT_OPT_TYPE_INT 0xE << 8 +#define IDT_OPT_PRVL_0 0 +#define IDT_OPT_PRVL_1 (1 << 13) +#define IDT_OPT_PRVL_2 (2 << 13) +#define IDT_OPT_PRVL_3 (3 << 13) + + + +typedef struct IDT_REGISTER { + u16 limit; + u64 base; +} __attribute__((packed)) IDT_REGISTER; + +typedef struct IDT_DESCRIPTOR { + u64 offset; + u16 selector; + u16 options; + u8 ist; + u32 ign; +} __attribute__((packed)) IDT_DESCRIPTOR; + +void idt_enable_interrupt(void); +void idt_write_descriptor(IDT_DESCRIPTOR desc, u16 index);
\ No newline at end of file diff --git a/src/core/int.S b/src/core/int.S new file mode 100644 index 0000000..d5ad643 --- /dev/null +++ b/src/core/int.S @@ -0,0 +1,33 @@ +.extern printk + +.macro call_printk msg + mov \msg, %rdi + mov $0, %eax # Required for variadic functions + call printk +.endm + +.globl INT_DEFAULT +INT_DEFAULT: + iretq + +.globl INT_0 +INT_0: + call_printk $MSG_INT_0 + INT_0_INFINITE: + jmp INT_0_INFINITE + iretq + +.globl INT_14 +INT_14: + call_printk $MSG_INT_14 + mov $0, %eax + call printk + INT_14_INFINITE: + jmp INT_14_INFINITE + iretq + + +MSG_INT_0: +.asciz "Zero Division error!" +MSG_INT_14: +.asciz "Page fault!" |
