summaryrefslogtreecommitdiff
path: root/stage3/interrupts.c
diff options
context:
space:
mode:
authorLizzy Fleckenstein <lizzy@vlhl.dev>2023-12-19 09:19:43 +0100
committerLizzy Fleckenstein <lizzy@vlhl.dev>2023-12-19 09:24:31 +0100
commit3102878c86c810c0bf877d72aceefeb28a44271d (patch)
treeb6232392ff6dc2903567a79828b4a713ababc76f /stage3/interrupts.c
parenta6b460d3b1b0909e0c7b388f1a55365bf24c6b7b (diff)
downloadcuddles-3102878c86c810c0bf877d72aceefeb28a44271d.tar.xz
improve debugging
Diffstat (limited to 'stage3/interrupts.c')
-rw-r--r--stage3/interrupts.c117
1 files changed, 110 insertions, 7 deletions
diff --git a/stage3/interrupts.c b/stage3/interrupts.c
index 2713cfa..edfe431 100644
--- a/stage3/interrupts.c
+++ b/stage3/interrupts.c
@@ -5,11 +5,13 @@
#include "pic.h"
#include "thread.h"
#include "io.h"
+#include "string.h"
+extern str dbg_map, dbg_disas;
extern u64 idt_entries[256]; // isr.asm
typedef struct __attribute__((packed)) {
- u64 rax, rdx, rcx, rsi, rdi, r8, r9, r10, r11;
+ u64 rax, rbx, rcx, rdx, rbp, rdi, rsi, r8, r9, r10, r11, r12, r13, r14, r15;
u64 which, error_code;
u64 rip, cs, rflags, rsp, ss;
} interrupt_frame;
@@ -46,11 +48,112 @@ static str exception[32] = {
static void dump_frame(interrupt_frame *frame)
{
- print(S("rip = ")); print_hex(frame->rip); print_char('\n');
- print(S("cs = ")); print_hex(frame->cs); print_char('\n');
- print(S("rflags = ")); print_hex(frame->rflags); print_char('\n');
- print(S("rsp = ")); print_hex(frame->rsp); print_char('\n');
- print(S("ss = ")); print_hex(frame->ss); print_char('\n');
+ print(S("rip = "));
+ print_hex(frame->rip);
+
+ if (dbg_map.data != nil) {
+ str entry = NILS;
+ str iter = dbg_map;
+ while (iter.len > 0) {
+ str line = str_walk(&iter, S("\n"));
+ line = str_eat(line, S(" "));
+ if (!str_start(line, S("0x")))
+ continue;
+ line = str_advance(line, 2);
+
+ u64 addr;
+ usize adv = str_parse_num(line, 16, &addr);
+ if (adv == 0)
+ continue;
+ line = str_advance(line, adv);
+
+ if (addr > frame->rip)
+ break;
+
+ line = str_eat(line, S(" "));
+ if (line.len > 0)
+ entry = line;
+ }
+
+ if (entry.len > 0) {
+ print(S(" in "));
+ print(entry);
+ }
+ }
+
+ if (dbg_disas.data != nil) {
+ str iter = dbg_disas;
+ while (iter.len > 0) {
+ str line = str_walk(&iter, S("\n"));
+ u64 addr;
+ if (!str_parse_num(str_eat(line, S(" ")), 16, &addr))
+ continue;
+ if (addr == frame->rip) {
+ print(S("\n"));
+ print(line);
+ break;
+ }
+ }
+ }
+
+ print(S("\n"));
+
+ struct {
+ u8 bit;
+ str name;
+ } flags[] = {
+ { 0, S("CF") },
+ { 2, S("PF") },
+ { 4, S("AF") },
+ { 6, S("ZF") },
+ { 7, S("SF") },
+ { 8, S("TF") },
+ { 9, S("IF") },
+ { 10, S("DF") },
+ { 11, S("OF") },
+ { 16, S("RF") },
+ { 17, S("VM") },
+ { 18, S("AC") },
+ { 19, S("VIF") },
+ { 20, S("ID") },
+ };
+
+ print(S("rflags = "));
+
+ usize f = 0;
+ for (usize i = 0; i < 63; i++) {
+ bool has_name = f < sizeof flags / sizeof *flags && flags[f].bit == i;
+
+ if (frame->rflags & ((u64) 1 << i)) {
+ if (has_name)
+ print(flags[f].name);
+ else
+ print_dec(i);
+ print(S(" "));
+ }
+
+ if (has_name)
+ f++;
+ }
+
+ print(S("\n"));
+
+#define REG(X) print(S(#X)); if (S(#X).len == 2) print(S(" ")); print(S(" = ")); print_num_pad(frame->X, 16, 16, ' ');
+#define REGS(A, B) REG(A) print(S(" ")); REG(B) print(S("\n"));
+
+ REGS(rax, rbx)
+ REGS(rcx, rdx)
+ REGS(rsp, rbp)
+ REGS(rdi, rsi)
+ REGS(r8, r9)
+ REGS(r10, r11)
+ REGS(r12, r13)
+ REGS(r14, r15)
+ REGS(r14, r15)
+ REGS(ss, cs)
+
+#undef REG
+#undef REGS
}
void interrupt_handler(interrupt_frame *frame)
@@ -67,7 +170,7 @@ void interrupt_handler(interrupt_frame *frame)
}
print_char('\n');
- if (frame->which == 13) {
+ if (frame->which == 14) {
str bits[8] = {
S("present"),
S("write"),