/* This file is part of Fennix Kernel. Fennix Kernel is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Fennix Kernel is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Fennix Kernel. If not, see . */ #include "../../crashhandler.hpp" #include "../chfcts.hpp" #include #include #include #include #include #if defined(a64) #include "../../../arch/amd64/cpu/gdt.hpp" #elif defined(a32) #elif defined(aa64) #endif #include "../../../kernel.h" static const char *PagefaultDescriptions[8] = { "Supervisory process tried to read a non-present page entry\n", "Supervisory process tried to read a page and caused a protection fault\n", "Supervisory process tried to write to a non-present page entry\n", "Supervisory process tried to write a page and caused a protection fault\n", "User process tried to read a non-present page entry\n", "User process tried to read a page and caused a protection fault\n", "User process tried to write to a non-present page entry\n", "User process tried to write a page and caused a protection fault\n"}; namespace CrashHandler { nsa void DisplayMainScreen(CRData data) { CPU::TrapFrame *Frame = data.Frame; /* _______ ___ ___ _______ _______ _______ _______ ______ ______ _______ _______ _______ _______ _____ | __| | | __|_ _| ___| | | | | __ \ _ | __| | | ___| \ |__ |\ /|__ | | | | ___| | | ---| < |__ | | ___| -- | |_______| |___| |_______| |___| |_______|__|_|__| |______|___|__|___|___|_______|___|___|_______|_____/ */ EHPrint("\eFF5500 _______ ___ ___ _______ _______ _______ _______ ______ ______ _______ _______ _______ _______ _____ \n"); EHPrint("| __| | | __|_ _| ___| | | | | __ \\ _ | __| | | ___| \\ \n"); EHPrint("|__ |\\ /|__ | | | | ___| | | ---| < |__ | | ___| -- |\n"); EHPrint("|_______| |___| |_______| |___| |_______|__|_|__| |______|___|__|___|___|_______|___|___|_______|_____/ \n\eFAFAFA"); switch (Frame->InterruptNumber) { case CPU::x86::DivideByZero: { EHPrint("Exception: Divide By Zero\n"); EHPrint("The processor attempted to divide a number by zero.\n"); break; } case CPU::x86::Debug: { EHPrint("Exception: Debug\n"); EHPrint("A debug exception has occurred.\n"); break; } case CPU::x86::NonMaskableInterrupt: { EHPrint("Exception: Non-Maskable Interrupt\n"); EHPrint("A non-maskable interrupt was received.\n"); break; } case CPU::x86::Breakpoint: { EHPrint("Exception: Breakpoint\n"); EHPrint("The processor encountered a breakpoint.\n"); break; } case CPU::x86::Overflow: { EHPrint("Exception: Overflow\n"); EHPrint("The processor attempted to add a number to a number that was too large.\n"); break; } case CPU::x86::BoundRange: { EHPrint("Exception: Bound Range\n"); EHPrint("The processor attempted to access an array element that is out of bounds.\n"); break; } case CPU::x86::InvalidOpcode: { EHPrint("Exception: Invalid Opcode\n"); EHPrint("The processor attempted to execute an invalid opcode.\n"); break; } case CPU::x86::DeviceNotAvailable: { EHPrint("Exception: Device Not Available\n"); EHPrint("The processor attempted to use a device that is not available.\n"); break; } case CPU::x86::DoubleFault: { EHPrint("Exception: Double Fault\n"); EHPrint("The processor encountered a double fault.\n"); break; } case CPU::x86::CoprocessorSegmentOverrun: { EHPrint("Exception: Coprocessor Segment Overrun\n"); EHPrint("The processor attempted to access a segment that is not available.\n"); break; } case CPU::x86::InvalidTSS: { EHPrint("Exception: Invalid TSS\n"); EHPrint("The processor attempted to access a task state segment that is not available or valid.\n"); CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode}; EHPrint("External? %s\n", SelCode.External ? "Yes" : "No"); EHPrint("GDT IDT LDT IDT\n"); switch (SelCode.Table) { case 0b00: { EHPrint(" ^ \n"); EHPrint(" | \n"); EHPrint(" %ld\n", SelCode.Idx); break; } case 0b01: { EHPrint(" ^ \n"); EHPrint(" | \n"); EHPrint(" %ld\n", SelCode.Idx); break; } case 0b10: { EHPrint(" ^ \n"); EHPrint(" | \n"); EHPrint(" %ld\n", SelCode.Idx); break; } case 0b11: { EHPrint(" ^ \n"); EHPrint(" | \n"); EHPrint(" %ld\n", SelCode.Idx); break; } default: { EHPrint(" ? \n"); EHPrint(" ? \n"); EHPrint(" %ld\n", SelCode.Idx); break; } } break; } case CPU::x86::SegmentNotPresent: { EHPrint("Exception: Segment Not Present\n"); EHPrint("The processor attempted to access a segment that is not present.\n"); CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode}; EHPrint("External? %s\n", SelCode.External ? "Yes" : "No"); EHPrint("GDT IDT LDT IDT\n"); switch (SelCode.Table) { case 0b00: { EHPrint(" ^ \n"); EHPrint(" | \n"); EHPrint(" %ld\n", SelCode.Idx); break; } case 0b01: { EHPrint(" ^ \n"); EHPrint(" | \n"); EHPrint(" %ld\n", SelCode.Idx); break; } case 0b10: { EHPrint(" ^ \n"); EHPrint(" | \n"); EHPrint(" %ld\n", SelCode.Idx); break; } case 0b11: { EHPrint(" ^ \n"); EHPrint(" | \n"); EHPrint(" %ld\n", SelCode.Idx); break; } default: { EHPrint(" ? \n"); EHPrint(" ? \n"); EHPrint(" %ld\n", SelCode.Idx); break; } } break; } case CPU::x86::StackSegmentFault: { EHPrint("Exception: Stack Segment Fault\n"); CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode}; EHPrint("External? %s\n", SelCode.External ? "Yes" : "No"); EHPrint("GDT IDT LDT IDT\n"); switch (SelCode.Table) { case 0b00: { EHPrint(" ^ \n"); EHPrint(" | \n"); EHPrint(" %ld\n", SelCode.Idx); break; } case 0b01: { EHPrint(" ^ \n"); EHPrint(" | \n"); EHPrint(" %ld\n", SelCode.Idx); break; } case 0b10: { EHPrint(" ^ \n"); EHPrint(" | \n"); EHPrint(" %ld\n", SelCode.Idx); break; } case 0b11: { EHPrint(" ^ \n"); EHPrint(" | \n"); EHPrint(" %ld\n", SelCode.Idx); break; } default: { EHPrint(" ? \n"); EHPrint(" ? \n"); EHPrint(" %ld\n", SelCode.Idx); break; } } break; } case CPU::x86::GeneralProtectionFault: { EHPrint("Exception: General Protection Fault\n"); EHPrint("Kernel performed an illegal operation.\n"); CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode}; EHPrint("External? %s\n", SelCode.External ? "Yes" : "No"); EHPrint("GDT IDT LDT IDT\n"); switch (SelCode.Table) { case 0b00: { EHPrint(" ^ \n"); EHPrint(" | \n"); EHPrint(" %ld\n", SelCode.Idx); break; } case 0b01: { EHPrint(" ^ \n"); EHPrint(" | \n"); EHPrint(" %ld\n", SelCode.Idx); break; } case 0b10: { EHPrint(" ^ \n"); EHPrint(" | \n"); EHPrint(" %ld\n", SelCode.Idx); break; } case 0b11: { EHPrint(" ^ \n"); EHPrint(" | \n"); EHPrint(" %ld\n", SelCode.Idx); break; } default: { EHPrint(" ? \n"); EHPrint(" ? \n"); EHPrint(" %ld\n", SelCode.Idx); break; } } break; } case CPU::x86::PageFault: { EHPrint("Exception: Page Fault\n"); EHPrint("The processor attempted to access a page that is not present/accessible.\n"); CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode}; #if defined(a64) EHPrint("At \e8888FF%#lx \eFAFAFAby \e8888FF%#lx\eFAFAFA\n", PageFaultAddress, Frame->rip); #elif defined(a32) EHPrint("At \e8888FF%#lx \eFAFAFAby \e8888FF%#lx\eFAFAFA\n", PageFaultAddress, Frame->eip); #elif defined(aa64) #endif EHPrint("Page: %s\eFAFAFA\n", params.P ? "\e058C19Present" : "\eE85230Not Present"); EHPrint("Write Operation: \e8888FF%s\eFAFAFA\n", params.W ? "Read-Only" : "Read-Write"); EHPrint("Processor Mode: \e8888FF%s\eFAFAFA\n", params.U ? "User-Mode" : "Kernel-Mode"); EHPrint("CPU Reserved Bits: %s\eFAFAFA\n", params.R ? "\eE85230Reserved" : "\e058C19Unreserved"); EHPrint("Caused By An Instruction Fetch: %s\eFAFAFA\n", params.I ? "\eE85230Yes" : "\e058C19No"); EHPrint("Caused By A Protection-Key Violation: %s\eFAFAFA\n", params.PK ? "\eE85230Yes" : "\e058C19No"); EHPrint("Caused By A Shadow Stack Access: %s\eFAFAFA\n", params.SS ? "\eE85230Yes" : "\e058C19No"); EHPrint("Caused By An SGX Violation: %s\eFAFAFA\n", params.SGX ? "\eE85230Yes" : "\e058C19No"); EHPrint("More Info: \e8888FF"); if (Frame->ErrorCode & 0x00000008) EHPrint("One or more page directory entries contain reserved bits which are set to 1.\n"); else EHPrint(PagefaultDescriptions[Frame->ErrorCode & 0b111]); EHPrint("\eFAFAFA"); break; } case CPU::x86::x87FloatingPoint: { EHPrint("Exception: x87 Floating Point\n"); EHPrint("The x87 FPU generated an error.\n"); break; } case CPU::x86::AlignmentCheck: { EHPrint("Exception: Alignment Check\n"); EHPrint("The CPU detected an unaligned memory access.\n"); break; } case CPU::x86::MachineCheck: { EHPrint("Exception: Machine Check\n"); EHPrint("The CPU detected a hardware error.\n"); break; } case CPU::x86::SIMDFloatingPoint: { EHPrint("Exception: SIMD Floating Point\n"); EHPrint("The CPU detected an error in the SIMD unit.\n"); break; } case CPU::x86::Virtualization: { EHPrint("Exception: Virtualization\n"); EHPrint("The CPU detected a virtualization error.\n"); break; } case CPU::x86::Security: { EHPrint("Exception: Security\n"); EHPrint("The CPU detected a security violation.\n"); break; } default: { EHPrint("Exception: Unknown\n"); EHPrint("The CPU generated an unknown exception.\n"); break; } } #if defined(a64) EHPrint("The exception happened at \e8888FF%#lx\eFAFAFA\n", Frame->rip); #elif defined(a32) EHPrint("The exception happened at \e8888FF%#lx\eFAFAFA\n", Frame->eip); #elif defined(aa64) #endif } }