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++
		
	
			
		
		
	
	
			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();
 | |
| }
 |