diff options
Diffstat (limited to 'stage3')
-rw-r--r-- | stage3/debug.c | 193 | ||||
-rw-r--r-- | stage3/debug.h | 9 | ||||
-rw-r--r-- | stage3/interrupts.c | 186 | ||||
-rw-r--r-- | stage3/interrupts.h | 8 | ||||
-rw-r--r-- | stage3/main.c | 10 |
5 files changed, 214 insertions, 192 deletions
diff --git a/stage3/debug.c b/stage3/debug.c new file mode 100644 index 0000000..0621dbd --- /dev/null +++ b/stage3/debug.c @@ -0,0 +1,193 @@ +#include "fs.h" +#include "font.h" +#include "string.h" +#include "halt.h" +#include "debug.h" + +static str dbg_map = NILS; +static str dbg_disas = NILS; + +static str exception[32] = { + S("Division Error"), + S("Debug"), + S("Non-maskable Interrupt"), + S("Breakpoint"), + S("Overflow"), + S("Bound Range Exceeded"), + S("Invalid Opcode"), + S("Device Not Available"), + S("Double Fault"), + S("Coprocessor Segment Overrun"), + S("Invalid TSS"), + S("Segment Not Present"), + S("Stack-Segment Fault"), + S("General Protection Fault"), + S("Page Fault"), + NILS, + S("x87 Floating-Point Exception"), + S("Alignment Check"), + S("Machine Check"), + S("SIMD Floating-Point Exception"), + S("Virtualization Exception"), + S("Control Protection Exception"), + NILS, NILS, NILS, NILS, NILS, NILS, + S("Hypervisor Injection Exception"), + S("VMM Communication Exception"), + S("Security Exception"), + NILS, +}; + +static void dump_frame(interrupt_frame *frame) +{ + 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 < LEN(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(ss, cs) + +#undef REG +#undef REGS +} + +void debug_exception(interrupt_frame *frame) +{ + // TODO: possible race condition due to printing here + // when exception happens in printing code itself + + if (exception[frame->which].data == nil) { + print(S("Unknown Exception ")); + print_dec(frame->which); + } else { + print(exception[frame->which]); + } + print_char('\n'); + + if (frame->which == 14) { + str bits[8] = { + S("present"), + S("write"), + S("user"), + S("reserved_write"), + S("instruction_fetch"), + S("protection_key"), + S("shadow_stack"), + S("software_guard_extensions"), + }; + + u8 err = frame->error_code; + + for (int i = 0; i < 8; i++) { + print(bits[i]); print(S(" = ")); print((err & 1) ? S("true\n") : S("false\n")); + err >>= 1; + } + } else { + print(S("error_code = ")); print_dec(frame->error_code); print_char('\n'); + } + + dump_frame(frame); + freeze(); +} + +void debug_init() +{ + print(S("loading kernel debug info...\n")); + dbg_map = fs_read(S("dbg/kernel.map")); + dbg_disas = fs_read(S("dbg/kernel.dis.asm")); +} diff --git a/stage3/debug.h b/stage3/debug.h new file mode 100644 index 0000000..97bce2b --- /dev/null +++ b/stage3/debug.h @@ -0,0 +1,9 @@ +#ifndef DEBUG_H +#define DEBUG_H + +#include "interrupts.h" + +void debug_init(); +void debug_exception(interrupt_frame *frame); + +#endif diff --git a/stage3/interrupts.c b/stage3/interrupts.c index e2dd148..2bb64f1 100644 --- a/stage3/interrupts.c +++ b/stage3/interrupts.c @@ -7,193 +7,14 @@ #include "thread.h" #include "io.h" #include "string.h" +#include "debug.h" -extern str dbg_map, dbg_disas; extern u64 idt_entries[256]; // isr.asm -typedef struct __attribute__((packed)) { - 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; - -static str exception[32] = { - S("Division Error"), - S("Debug"), - S("Non-maskable Interrupt"), - S("Breakpoint"), - S("Overflow"), - S("Bound Range Exceeded"), - S("Invalid Opcode"), - S("Device Not Available"), - S("Double Fault"), - S("Coprocessor Segment Overrun"), - S("Invalid TSS"), - S("Segment Not Present"), - S("Stack-Segment Fault"), - S("General Protection Fault"), - S("Page Fault"), - NILS, - S("x87 Floating-Point Exception"), - S("Alignment Check"), - S("Machine Check"), - S("SIMD Floating-Point Exception"), - S("Virtualization Exception"), - S("Control Protection Exception"), - NILS, NILS, NILS, NILS, NILS, NILS, - S("Hypervisor Injection Exception"), - S("VMM Communication Exception"), - S("Security Exception"), - NILS, -}; - -static void dump_frame(interrupt_frame *frame) -{ - 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 < LEN(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(ss, cs) - -#undef REG -#undef REGS -} - void interrupt_handler(interrupt_frame *frame) { if (frame->which < 32) { - // TODO: possible race condition due to printing here - // when exception happens in printing code itself - - if (exception[frame->which].data == nil) { - print(S("Unknown Exception ")); - print_dec(frame->which); - } else { - print(exception[frame->which]); - } - print_char('\n'); - - if (frame->which == 14) { - str bits[8] = { - S("present"), - S("write"), - S("user"), - S("reserved_write"), - S("instruction_fetch"), - S("protection_key"), - S("shadow_stack"), - S("software_guard_extensions"), - }; - - u8 err = frame->error_code; - - for (int i = 0; i < 8; i++) { - print(bits[i]); print(S(" = ")); print((err & 1) ? S("true\n") : S("false\n")); - err >>= 1; - } - } else { - print(S("error_code = ")); print_dec(frame->error_code); print_char('\n'); - } - - dump_frame(frame); - freeze(); + debug_exception(frame); } else if (frame->which-32 < 16) { u64 irq = frame->which-32; @@ -221,9 +42,6 @@ void interrupt_handler(interrupt_frame *frame) } ack_irq(irq); - } else { - // print(S("Spurious Interrupt ")); print_num(frame->which, 10); print(S("\n")); - // dump_frame(frame); } } diff --git a/stage3/interrupts.h b/stage3/interrupts.h index 333aca0..595ed22 100644 --- a/stage3/interrupts.h +++ b/stage3/interrupts.h @@ -1,6 +1,14 @@ #ifndef INTERRUPTS_H #define INTERRUPTS_H +#include "def.h" + +typedef struct __attribute__((packed)) { + 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; + void interrupts_init(); #endif diff --git a/stage3/main.c b/stage3/main.c index abbd33b..eec822a 100644 --- a/stage3/main.c +++ b/stage3/main.c @@ -16,6 +16,7 @@ #include "gfx.h" #include "clock.h" #include "rng.h" +#include "debug.h" char keymap[256] = { '\0' }; @@ -57,9 +58,6 @@ void keyboard_handler() } } -str dbg_map = NILS; -str dbg_disas = NILS; - void kmain() { heap_init(); @@ -132,13 +130,9 @@ void kmain() interrupts_init(); pic_init(); thread_init(); - ata_init(); ps2_init(); - - print(S("loading kernel debug info...\n")); - dbg_map = fs_read(S("dbg/kernel.map")); - dbg_disas = fs_read(S("dbg/kernel.dis.asm")); + debug_init(); shell_run_cmd(S("run init")); |