You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
4.2 KiB
C++
131 lines
4.2 KiB
C++
#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!");
|
|
}
|
|
|
|
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));
|
|
IDT::set(Core::Interrupt::Vector::Timer,
|
|
IDT::InterruptDescriptor::Returning(handle_timer));
|
|
// Load the idt pointer
|
|
IDT::load();
|
|
}
|