#include "exception.h" #include "cpu_context.h" #include "idt.h" #include "interrupt.h" #include "irq.h" #include "klibc.h" #include "kthread.h" #include "vga.h" exception_handler exception_handler_array[EXCEPTION_NUM] = { NULL, }; extern vaddr_t exception_handler_wrapper_array[EXCEPTION_NUM]; void exception_handler_wrap(int intr, struct cpu_state *frame) { if (0 > intr || EXCEPTION_NUM <= intr) { pr_err("Trying to handle unknow exception %d\n", intr); return; } if (exception_handler_array[intr] != NULL) exception_handler_array[intr](frame, intr); } int exceptionSetRoutine(int exception, exception_handler handler) { uint32_t flags; if ((exception < 0) || exception >= EXCEPTION_NUM) return -1; disable_IRQs(flags); exception_handler_array[exception] = handler; idt_set_handler(EXCEPTION_INTERRUPT_BASE_ADDRESS + exception, (unsigned int)exception_handler_wrapper_array[exception], 0); restore_IRQs(flags); return 0; } void print_handler(struct cpu_state *frame, ulong intr) { int intNbInt = intr; VGAPrintf(RED, BLACK, 0, VGA_HEIGHT - 1, "EXCEPTION %d %d", intNbInt, intr); printf("Exception %d (Err %d) at 0x%x\n", intr, intr, cpu_context_get_PC(frame)); asm("hlt"); } void pagefault_handler(struct cpu_state *frame, ulong intr) { // A page fault has occurred. // The faulting address is stored in the CR2 register. uint32_t faulting_address; asm volatile("mov %%cr2, %0" : "=r"(faulting_address)); struct kthread *current = getCurrentThread(); printf("page fault while in thread %s at 0x%x 0x%x\n", current->name, faulting_address, cpu_context_get_PC(frame)); VGAPrintf(RED, BLACK, 0, VGA_HEIGHT - 1, "PAGE FAULT %d", intr); (void)intr; for (;;) continue; } int exceptionSetup() { for (int i = 0; i < EXCEPTION_NUM; i++) { exceptionSetRoutine(i, print_handler); } exceptionSetRoutine(EXCEPTION_PAGE_FAULT, pagefault_handler); return 0; }