#include "exception.h" #include "cpu_context.h" #include "idt.h" #include "interrupt.h" #include "irq.h" #include "klibc.h" #include "process.h" #include "thread.h" #include "types.h" #include "uaddrspace.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) { struct thread *current = getCurrentThread(); struct uAddrSpace *as = processGetAddrSpace(current->process); vaddr_t faultAddr = cpu_context_get_EX_faulting_vaddr(frame); if(!uAddrSpaceCheckNAlloc(as, faultAddr)) return; printf("page fault while in thread [%s] at 0x%x when trying to access 0x%x err_code 0x%x\n", current->name, cpu_context_get_PC(frame), faultAddr, cpu_context_get_EX_err(frame)); if (cpu_context_is_in_user_mode(frame)) { printf("Killing User Thread\n"); threadExit(); } 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; }