aboutsummaryrefslogtreecommitdiff
path: root/src/core/idt.c
blob: 861927a8753d147d7e75532b0719d68745e31e92 (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
#include "idt.h"

struct IDT_REGISTER IDTR={
    8*IDT_MAX_ENTRY,
    0x0 // IDT is located at physical address 0
};

// Interrupt functions (cf int.S)
extern u32
INT_DEFAULT,
INT_PAGE_FAULT,
INT_CLOCK,
INT_KEYPRESS,
INT_SYSCALL;


void idt_init(){
    // Map entries, note that first 32 entries are used by the CPU
    // and should be mapped to a function (INT_DEFAULT here)
    for(int i=0;i<IDT_MAX_ENTRY;i++){
        idt_write_entry((IDT_ENTRY){0x08,(u32)&INT_DEFAULT,IDT_INT_GATE|IDT_P},i);
        if(i==14)
            idt_write_entry((IDT_ENTRY){0x08,(u32)&INT_PAGE_FAULT,IDT_INT_GATE|IDT_P},i);
        if(i==32)
            idt_write_entry((IDT_ENTRY){0x08,(u32)&INT_CLOCK,IDT_INT_GATE|IDT_P},i);
        if(i==33)
            idt_write_entry((IDT_ENTRY){0x08,(u32)&INT_KEYPRESS,IDT_INT_GATE|IDT_P},i);
        if(i==48)
            idt_write_entry((IDT_ENTRY){0x08,(u32)&INT_SYSCALL,IDT_INT_GATE|IDT_P|IDT_PRVL_3},i);
    }
    // Load IDT
    asm("lidtl (IDTR)");
}

void idt_write_entry(IDT_ENTRY entry, int id){
    int descriptor[2];
    descriptor[0]=entry.offset & 0xFFFF | entry.segment << 16;
    descriptor[1]=entry.type & 0xFFFF | entry.offset & 0xFFFF0000;
    memcpy((void*)descriptor, (void *)(IDTR.base+(id*8)),8);
}