#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) { DBG << "Double fault encountered. Error code: " << dec << error << 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) { DBG << "Page fault encountered 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!"); } 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); } 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; LAPIC::endOfInterrupt(); Guard::relay(Epilogues::timer); } [[gnu::interrupt]] void handle_assassin(InterruptContext *context) { (void)context; LAPIC::endOfInterrupt(); Guard::relay(Epilogues::assassin); } [[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)); IDT::set(Core::Interrupt::Vector::TIMER, IDT::InterruptDescriptor::Returning(handle_timer)); // TODO: Add more handlers here IDT::set(Core::Interrupt::Vector::KEYBOARD, IDT::InterruptDescriptor::Returning(handle_keyboard_asm)); IDT::set(Core::Interrupt::Vector::TIMER, IDT::InterruptDescriptor::Returning(handle_timer)); IDT::set(Core::Interrupt::Vector::ASS, IDT::InterruptDescriptor::Returning(handle_assassin)); // Load the idt pointer IDT::load(); }