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.

103 lines
3.3 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"
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!");
}
void handle_keyboard() {}
[[gnu::interrupt]] void handle_panic(InterruptContext *context) {
(void)context;
}
[[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
// Load the idt pointer
IDT::load();
}