summaryrefslogblamecommitdiffstats
path: root/arch/x86_64/idt.c
blob: 05dcf438ebd19e1d88b0091e5742d3a991545d20 (plain) (tree)
1
2
3
4
5
6
7
8






                                           
                                                                  







                                 






                                                                              




                                               
                                                    






























                                                                     

                                               
                                    






                                                

                                                    
          
                                                                


                         
#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);
}