#include using namespace mercury::kernel; struct [[gnu::packed]] exception_info_t { uint64_t rax; uint64_t rbx; uint64_t rcx; uint64_t rdx; uint64_t rdi; uint64_t rsi; uint64_t rbp; uint64_t rsp; uint64_t r8; uint64_t r9; uint64_t r10; uint64_t r11; uint64_t r12; uint64_t r13; uint64_t r14; uint64_t r15; uint64_t cr2; uint64_t cr3; uint64_t rip; uint64_t rflags; uint64_t error; uint8_t has_error;//0 or 1 uint8_t exception_number; }; extern exception_info_t exception_info; const char *exception_types[] = { "division error", "", "non-maskable interrupt", "", "", "", "invalid opcode", "", "double fault (uh oh)", "", "", "", "stack fault", "general protection fault", "page fault", "" }; const char *flag_names[] = { " cf", "", " pf", "", " af", "", " zf", " sf", " tf", " if", " df", " of", "", "", " nt", " md" }; void print_line(const char *r1, const char *r2, uint64_t r1v, uint64_t r2v) { terminal::put_string_sz("\n "); terminal::put_string_sz(r1); terminal::put_string_sz(": 0x"); terminal::put_int_hex(r1v, 16); terminal::put_string_sz(" "); terminal::put_string_sz(r2); terminal::put_string_sz(": 0x"); terminal::put_int_hex(r2v, 16); } extern "C" [[noreturn]] void print_exception() { terminal::put_string_sz("exception handler:\n type: "); terminal::put_string_sz(exception_types[exception_info.exception_number]); terminal::put_string_sz(" (0x"); terminal::put_int_hex(exception_info.exception_number, 2); terminal::put_char(')'); if (exception_info.has_error == 1) { terminal::put_string_sz("\n error code: 0x"); terminal::put_int_hex(exception_info.error, 16); } terminal::put_string_sz("\n flags:"); if (exception_info.rflags == 0) terminal::put_string_sz(" [none]"); else for (int i = 0; i < 16; ++i) if (((exception_info.rflags >> i) & 1) == 1) terminal::put_string_sz(flag_names[i]); if (exception_info.exception_number == 0x0e) { terminal::put_string_sz("\n cr2: 0x"); terminal::put_int_hex(exception_info.cr2, 16); } print_line("cr3", "rip", exception_info.cr3, exception_info.rip); print_line("rax", "rbx", exception_info.rax, exception_info.rbx); print_line("rcx", "rdx", exception_info.rcx, exception_info.rdx); print_line("rdi", "rsi", exception_info.rdi, exception_info.rsi); print_line("rbp", "rsp", exception_info.rbp, exception_info.rsp); print_line("r8 ", "r9 ", exception_info.r8 , exception_info.r9 ); print_line("r10", "r11", exception_info.r10, exception_info.r11); print_line("r12", "r13", exception_info.r12, exception_info.r13); print_line("r14", "r15", exception_info.r14, exception_info.r15); while (1) asm ("hlt"); }