119 lines
2.6 KiB
C++
119 lines
2.6 KiB
C++
#include <mercury/kernel/terminal.hpp>
|
|
|
|
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 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]);
|
|
|
|
print_line("rip", "cr3", exception_info.rip, exception_info.cr3);
|
|
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");
|
|
|
|
}
|