diff options
author | Ian Moffett <ian@osmora.org> | 2024-06-04 20:43:41 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-06-04 20:43:41 -0400 |
commit | 31e9919ced2c577e601d17ec02a3d7886f793469 (patch) | |
tree | 02b7eae801c3128dfd1c43dad5e8735e70d4179f /sys/arch | |
parent | 8d545ea74f1387c7c99b88ee12ed26fe84bf6061 (diff) |
kernel/amd64: trap: Add logging for debugging
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/amd64/amd64/trap.c | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c index dcae075..2d479ee 100644 --- a/sys/arch/amd64/amd64/trap.c +++ b/sys/arch/amd64/amd64/trap.c @@ -27,12 +27,69 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include <sys/param.h> +#include <sys/cdefs.h> #include <sys/reboot.h> +#include <sys/panic.h> +#include <sys/syslog.h> #include <machine/trap.h> #include <machine/frame.h> +#define pr_error(fmt, ...) kprintf("trap: " fmt, ##__VA_ARGS__) + +static const char *trap_type[] = { + [TRAP_BREAKPOINT] = "breakpoint", + [TRAP_ARITH_ERR] = "arithmetic error", + [TRAP_OVERFLOW] = "overflow", + [TRAP_BOUND_RANGE] = "bound range exceeded", + [TRAP_INVLOP] = "invalid opcode", + [TRAP_DOUBLE_FAULT] = "double fault", + [TRAP_INVLTSS] = "invalid TSS", + [TRAP_SEGNP] = "segment not present", + [TRAP_PROTFLT] = "general protection", + [TRAP_PAGEFLT] = "page fault", + [TRAP_NMI] = "non-maskable interrupt", + [TRAP_SS] = "stack-segment fault" +}; + +static inline uintptr_t +pf_faultaddr(void) +{ + uintptr_t cr2; + __ASMV("mov %%cr2, %0\n" : "=r" (cr2) :: "memory"); + return cr2; +} + +static void +regdump(struct trapframe *tf) +{ + uintptr_t cr3, cr2 = pf_faultaddr(); + + __ASMV("mov %%cr3, %0\n" + : "=r" (cr3) + : + : "memory" + ); + + kprintf(OMIT_TIMESTAMP + "RAX=%p RCX=%p RDX=%p\n" + "RBX=%p RSI=%p RDI=%p\n" + "RFL=%p CR2=%p CR3=%p\n" + "RBP=%p RSP=%p RIP=%p\n", + tf->rax, tf->rcx, tf->rdx, + tf->rbx, tf->rsi, tf->rdi, + tf->rflags, cr2, cr3, + tf->rbp, tf->rsp, tf->rip); +} + void trap_handler(struct trapframe *tf) { - cpu_reboot(REBOOT_HALT); + if (tf->trapno >= NELEM(trap_type)) { + panic("Got unknown trap %d\n", tf->trapno); + } + + pr_error("Got %s\n", trap_type[tf->trapno]); + regdump(tf); + panic("Fatal trap - halting\n"); } |