#include "handlers.h" #include "../arch/core_cr.h" #include "../arch/idt.h" #include "../arch/lapic.h" #include "../arch/system.h" #include "../debug/kernelpanic.h" #include "../debug/output.h" #include "../device/ps2controller.h" #include "../sync/ticketlock.h" #include "epilogues.h" #include "guard.h" Key kout_key = Key(); void printContext(const InterruptContext *context) { DBG << "ip: " << hex << context->cs << ':' << context->ip << " sp: " << context->ss << ':' << context->sp << " flags" << bin << context->flags << endl; } [[gnu::interrupt]] void handle_invalid_opcode(InterruptContext *context) { DBG << "Invalid opcode encoutered" << endl; printContext(context); kernelpanic("Invalid opcode!"); } [[gnu::interrupt]] void handle_double_fault(InterruptContext *context, uint64_t error) { (void)error; DBG << "Double fault encoutered" << endl; printContext(context); kernelpanic("Double fault!"); } [[gnu::interrupt]] void handle_invalid_tss(InterruptContext *context, uint64_t error) { DBG << "Invalid tss encoutered. Offending selector idx: " << dec << error << endl; printContext(context); kernelpanic("Invalid TSS!"); } [[gnu::interrupt]] void handle_general_protection_fault( InterruptContext *context, uint64_t error) { DBG << "General protection fault encoutered. Error code: " << dec << error << endl; printContext(context); kernelpanic("General protection fault!"); } enum PAGE_FAULT_ERROR { PF_ERR_PRESENT = 0x1, PF_ERR_WRITE = 0x2, PF_ERR_USER = 0x4, PF_ERR_RESERVED = 0x8, PF_ERR_IFETCH = 0x10, }; [[gnu::interrupt]] void handle_page_fault(InterruptContext *context, uint64_t error) { (void)error; DBG << "Page fault encoutered at linear address " << hex << Core::CR<2>::read() << endl << (error & PF_ERR_PRESENT ? "present" : "non-present") << " page|" << (error & PF_ERR_WRITE ? "write" : "read") << " access|" << (error & PF_ERR_USER ? "user" : "supervisor") << "|" << (error & PF_ERR_RESERVED ? "reserved bit int pte" : "") << "|" << (error & PF_ERR_IFETCH ? "instrution" : "data") << " fetch|" << endl; printContext(context); kernelpanic("Page fault!"); } extern Ticketlock koutlock; extern Vault keyboard_vault; void handle_keyboard() { //Key key = Key(); if (PS2Controller::fetch(kout_key)) { LAPIC::endOfInterrupt(); if (kout_key.ctrl() && kout_key.alt() && kout_key.scancode == Key::KEY_DEL) System::reboot(); Guard::relay(Epilogues::keyboard); //koutlock.lock(); //kout << key.ascii() << endl << flush ; //koutlock.unlock(); } else LAPIC::endOfInterrupt(); } [[gnu::interrupt]] void handle_panic(InterruptContext *context) { DBG << "Generic KernelPanic triggered"<< endl; printContext(context); kernelpanic("Generic Panic Triggerd"); } [[gnu::interrupt]] void handle_timer(InterruptContext *context) { (void)context; } [[gnu::interrupt]] void handle_assassin(InterruptContext *context) { (void)context; } [[gnu::interrupt]] void handle_wakeup(InterruptContext *context) { (void)context; } void initInterruptHandlers() { // Some handlers that are useful for debugging IDT::set(Core::Interrupt::Vector::INVALID_OPCODE, IDT::InterruptDescriptor::Returning(handle_invalid_opcode)); IDT::set(Core::Interrupt::Vector::DOUBLE_FAULT, IDT::InterruptDescriptor::DivergingWithError(handle_double_fault)); IDT::set(Core::Interrupt::Vector::INVALID_TSS, IDT::InterruptDescriptor::ReturningWithError(handle_invalid_tss)); IDT::set(Core::Interrupt::Vector::GENERAL_PROTECTION_FAULT, IDT::InterruptDescriptor::ReturningWithError( handle_general_protection_fault)); IDT::set(Core::Interrupt::Vector::PAGE_FAULT, IDT::InterruptDescriptor::ReturningWithError(handle_page_fault)); // TODO: Add more handlers here IDT::set(Core::Interrupt::Vector::KEYBOARD, IDT::InterruptDescriptor::Returning(handle_keyboard_asm)); // Load the idt pointer IDT::load(); }