#include "memory/pagefault.h" #include "arch/core.h" #include "arch/core_interrupt.h" #include "arch/idt.h" #include "debug/output.h" #include "memory/config.h" namespace PageFault { union ErrorCode { uint32_t value; struct { uint32_t present : 1; ///< was the page present? uint32_t write : 1; ///< was the access a write? uint32_t usermode : 1; ///< was it in user mode? uint32_t reserved : 1; ///< reserved bit violation uint32_t instruction : 1; ///< was it caused by instruction fetch? uint32_t : 0; } __attribute__((packed)); explicit ErrorCode(uint32_t value) : value(value) {} }; assert_size(ErrorCode, 4); [[gnu::interrupt]] static void pagefault_handler(InterruptContext *context, uint64_t err) { PageFault::ErrorCode error(err); // Get the faulting address uintptr_t virt = 0; asm volatile("mov %%cr2, %0" : "=r"(virt)); DBG << "Page fault at " << hex << virt << dec << endl; // show page fault message DBG << "PAGEFAULT: " << hex << virt << ":" << dec << error.present << error.write << error.usermode << error.reserved << error.instruction << " @ " << hex << context->ip << endl; Core::die(); } void init() { IDT::set(Core::Interrupt::Vector::PAGE_FAULT, IDT::InterruptDescriptor::ReturningWithError(pagefault_handler)); } } // namespace PageFault