diff options
Diffstat (limited to 'stage3/interrupts.c')
-rw-r--r-- | stage3/interrupts.c | 117 |
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"), |