diff options
author | Freya Murphy <freya@freyacat.org> | 2024-02-03 00:50:07 -0500 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2024-02-03 00:53:58 -0500 |
commit | 90a6065691beee52bf5309916fba98f7580d27be (patch) | |
tree | 0b5375d20c189f62d394c473d371f7bf7f1d3fc5 /src/arch/amd64/cpu | |
parent | improved debugger, refactored (diff) | |
download | corn-90a6065691beee52bf5309916fba98f7580d27be.tar.gz corn-90a6065691beee52bf5309916fba98f7580d27be.tar.bz2 corn-90a6065691beee52bf5309916fba98f7580d27be.zip |
refactor, new arch dirs, (wip) page alloc on write, hsv screen (convert to userspace later), other fixes
Diffstat (limited to 'src/arch/amd64/cpu')
-rw-r--r-- | src/arch/amd64/cpu/backtrace.c | 45 | ||||
-rw-r--r-- | src/arch/amd64/cpu/debugger.c | 414 | ||||
-rw-r--r-- | src/arch/amd64/cpu/debugger.h | 9 | ||||
-rw-r--r-- | src/arch/amd64/cpu/idt.S | 207 | ||||
-rw-r--r-- | src/arch/amd64/cpu/idt.c | 160 | ||||
-rw-r--r-- | src/arch/amd64/cpu/idt.h | 29 |
6 files changed, 864 insertions, 0 deletions
diff --git a/src/arch/amd64/cpu/backtrace.c b/src/arch/amd64/cpu/backtrace.c new file mode 100644 index 0000000..9e1c9d7 --- /dev/null +++ b/src/arch/amd64/cpu/backtrace.c @@ -0,0 +1,45 @@ +#include <backtrace.h> +#include <lib.h> + +struct stackframe { + struct stackframe *rbp; + void *rip; +}; + +size_t backtrace(void **dst, size_t len) { + struct stackframe *rbp; + __asm__ volatile ("mov %%rbp, %0" : "=r"(rbp)); + return backtrace_ex(dst, len, rbp->rip, rbp->rbp); +} + +size_t backtrace_ex(void **dst, size_t len, void *ip, void *bp) { + struct stackframe *frame = bp; + __asm__ volatile ("mov %%rbp, %0" : "=r"(frame)); + if (len > 0) { + dst[0] = ip; + } + size_t i; + for (i = 1; frame && i < len; i++) { + dst[i] = frame->rip; + frame = frame->rbp; + } + return i; +} + +void log_backtrace() { + struct stackframe *rbp; + __asm__ volatile ("mov %%rbp, %0" : "=r"(rbp)); + log_backtrace_ex(rbp->rip, rbp->rbp); +} + + +void log_backtrace_ex(void *ip, void *bp) { + struct stackframe *frame = bp; + kputs("Stack trace:\n"); + kprintf(" %#lx\n", (size_t)ip); + while (frame) { + kprintf(" %#lx\n", (size_t)frame->rip); + frame = frame->rbp; + } + +} diff --git a/src/arch/amd64/cpu/debugger.c b/src/arch/amd64/cpu/debugger.c new file mode 100644 index 0000000..4d9d3c3 --- /dev/null +++ b/src/arch/amd64/cpu/debugger.c @@ -0,0 +1,414 @@ +#include <lib.h> +#include <stddef.h> +#include <backtrace.h> +#include <serial.h> + +#include "debugger.h" + +struct dr6 { + uint64_t b0 : 1, + b1 : 1, + b2 : 1, + b3 : 1, + : 7, + bld : 1, + : 1, + bd : 1, + bs : 1, + bt : 1, + rtm : 1, + : 47; +}; + +struct dr7 { + uint64_t l0 : 1, + g0 : 1, + l1 : 1, + g1 : 1, + l2 : 1, + g2 : 1, + l3 : 1, + g3 : 1, + : 8, + rw0 : 2, + len0 : 2, + rw1 : 2, + len1 : 2, + rw2 : 2, + len2 : 2, + rw3 : 2, + len3 : 2, + : 32; +}; + +struct rflags { + uint64_t cf : 1, + : 1, + pf : 1, + : 1, + af : 1, + : 1, + zf : 1, + sf : 1, + + tf : 1, + if_ : 1, + df : 1, + of : 1, + iopl : 2, + nt : 1, + md : 1, + + rf : 1, + vm : 1, + ac : 1, + vif : 1, + vip : 1, + id : 1, + : 42; +}; + +struct breakpoint { + uint64_t addr; + uint8_t len; + uint8_t rw; + uint8_t used; + uint8_t enable; + uint8_t instr_len; +}; + +static int dbg_steps = 0; +static int dbg_continue = 0; +static struct breakpoint bkps[4] = {{0}, {0}, {0}, {0}}; + +static size_t debugger_read(char *buf, size_t len) { + char *p = buf; + size_t result; + while (p < buf + len - 1) { + char ch = serial_in(); + switch (ch) { + case '\r': + goto end; + case '\x7f': + if (p > buf) { + p--; + kputs("\x08 \x08"); + } + break; + default: + kputc(ch); + *p++ = ch; + } + } +end: + result = p - buf; + kputc('\n'); + for(; p < buf + len; p++) { + *p = 0; + } + return result; +} + +static void debugger_msg(int cause, struct dr6 dr6) { + switch (cause) { + case DEBUG_INT3: + kputs("dbg: reached int3"); + break; + case DEBUG_FAULT: + kputs("dbg: a fault occured"); + break; + case DEBUG_DBG: + if (dr6.bs) + kputs("dbg: finished steps"); + if (dr6.b0) + kputs("dbg: reached breakpoint 0"); + else if (dr6.b1) + kputs("dbg: reached breakpoint 1"); + else if (dr6.b2) + kputs("dbg: reached breakpoint 2"); + else if (dr6.b3) + kputs("dbg: reached breakpoint 3"); + } + if (dbg_steps > 0) { + kprintf(" (%d steps left)", dbg_steps); + } + if (dbg_continue > 0) { + kputs(" (paused continue)"); + } + kputs("\n"); +} + +static void debugger_print_regs(struct isr_regs *state) { + kprintf("rax: %#016lx (%lu)\n", state->rax, state->rax); + kprintf("rbx: %#016lx (%lu)\n", state->rbx, state->rbx); + kprintf("rcx: %#016lx (%lu)\n", state->rcx, state->rcx); + kprintf("rdx: %#016lx (%lu)\n", state->rdx, state->rdx); + kprintf("rsi: %#016lx (%lu)\n", state->rsi, state->rsi); + kprintf("rdi: %#016lx (%lu)\n", state->rdi, state->rdi); + kprintf("rsp: %#016lx (%lu)\n", state->rsp, state->rsp); + kprintf("rbp: %#016lx (%lu)\n", state->rbp, state->rbp); + kprintf("r8 : %#016lx (%lu)\n", state->r8 , state->r8 ); + kprintf("r9 : %#016lx (%lu)\n", state->r9 , state->r9 ); + kprintf("r10: %#016lx (%lu)\n", state->r10, state->r10); + kprintf("r11: %#016lx (%lu)\n", state->r11, state->r11); + kprintf("r12: %#016lx (%lu)\n", state->r12, state->r12); + kprintf("r13: %#016lx (%lu)\n", state->r13, state->r13); + kprintf("r14: %#016lx (%lu)\n", state->r14, state->r14); + kprintf("r15: %#016lx (%lu)\n", state->r15, state->r15); + kputs("---\n"); + kprintf("rip: %#016lx (%lu)\n", state->rip, state->rip); + kputs("---\n"); + kprintf("rflags: %#016lx (%lu)\n", state->rflags, state->rflags); + struct rflags *rflags = (struct rflags *)state->rflags; + kputs("rflags: "); + if(rflags->cf) kputs("CF "); + if(rflags->pf) kputs("PF "); + if(rflags->af) kputs("AF "); + if(rflags->zf) kputs("ZF "); + if(rflags->sf) kputs("SF "); + if(rflags->tf) kputs("TF "); + if(rflags->if_) kputs("IF "); + if(rflags->df) kputs("DF "); + if(rflags->of) kputs("OF "); + if(rflags->iopl) kputs("IOPL "); + if(rflags->nt) kputs("NT "); + if(rflags->md) kputs("MD "); + if(rflags->rf) kputs("RF "); + if(rflags->vm) kputs("VM "); + if(rflags->ac) kputs("AC "); + if(rflags->vif) kputs("VIF "); + if(rflags->vip) kputs("VIP "); + if(rflags->id) kputs("ID "); + kputs("\n"); +} + +#define PROMPT_LEN 60 + +static int debugger_handle_bkp_cmd(char *msg) { + if (msg[0] == 'l') { + // list breakpoints + for (int i = 0; i < 4; i++) { + struct breakpoint bkp = bkps[i]; + if(!bkp.used) { + kprintf("breakpoint %d: unset\n", i); + continue; + } + const char *lenstrs[] = {"1", "2", "8", "4"}; + const char *rwstrs[] = {"x ", "w ", "io", "rw"}; + kprintf( + "breakpoint %d: %#016lx len=%s trigger=%s instrlen=%01d %s\n", + i, + bkp.addr, + lenstrs[bkp.len], + rwstrs[bkp.rw], + bkp.instr_len, + bkp.enable ? " enabled" : " disabled" + ); + } + return 1; + } else if (msg[0] == 'd') { + // disable breakpoints + bkps[0].enable = 0; + bkps[1].enable = 0; + bkps[2].enable = 0; + bkps[3].enable = 0; + kputs("disabled breakpoints\n"); + return 1; + } else if (msg[0] == 'c') { + // clear breakpoints + bkps[0].used = 0; + bkps[1].used = 0; + bkps[2].used = 0; + bkps[3].used = 0; + kputs("cleared breakpoints\n"); + return 1; + } else if (msg[0] <= '0' && msg[0] >= '3') { + kputs("invalid breakpoint command\n"); + return 1; + } + char buf[64]; + int id = msg[0] - '0'; + switch (msg[1]) { + case 'e': + bkps[id].enable = bkps[id].used; + kprintf("enabled breakpoint %d\n", id); + return 1; + case 'd': + bkps[id].enable = 0; + kprintf("disabled breakpoint %d\n", id); + return 1; + case 'c': + bkps[id].used = 0; + kprintf("cleared breakpoint %d\n", id); + return 1; + case 'a': + kputs("addr> 0x"); + debugger_read(buf, 64); + bkps[id].addr = strtoll(buf, NULL, 16); + kputs("len (1/2/4/8)> "); + debugger_read(buf, 64); + switch (buf[0]) { + case '1': bkps[id].len = 0x0; break; + case '2': bkps[id].len = 0x1; break; + case '8': bkps[id].len = 0x2; break; + case '4': bkps[id].len = 0x3; break; + default: bkps[id].len = 0x0; break; + } + kputs("cond (x/w/io/rw)> "); + debugger_read(buf, 64); + switch ((int)buf[0] * 256 + (int)buf[1]) { + case (int)'x'*256 + (int)0: bkps[id].rw = 0x0; break; + case (int)'w'*256 + (int)0: bkps[id].rw = 0x1; break; + case (int)'i'*256 + (int)'o': bkps[id].rw = 0x2; break; + case (int)'r'*256 + (int)'w': bkps[id].rw = 0x3; break; + default: bkps[id].len = 0x0; break; + } + kputs("instr len (1..15)> "); + debugger_read(buf, 64); + bkps[id].instr_len = strtoi(buf, NULL, 10); + kputs("enable (y/n)> "); + debugger_read(buf, 64); + bkps[id].used = 1; + bkps[id].enable = !(buf[0] == 'n' || buf[0] == 'N'); + kprintf("added breakpoint %d\n", id); + return 1; + default: + kputs("invalid breakpoint command\n"); + return 1; + } +} + +static void debugger_load_bkps() { + struct dr7 dr7; + __asm__ volatile ("mov %%dr7, %0" : "=r"(dr7)); + dr7.g0 = bkps[0].enable & bkps[0].used; + dr7.g1 = bkps[1].enable & bkps[1].used; + dr7.g2 = bkps[2].enable & bkps[2].used; + dr7.g3 = bkps[3].enable & bkps[3].used; + dr7.l0 = 0; + dr7.l1 = 0; + dr7.l2 = 0; + dr7.l3 = 0; + dr7.rw0 = bkps[0].rw; + dr7.rw1 = bkps[1].rw; + dr7.rw2 = bkps[2].rw; + dr7.rw3 = bkps[3].rw; + dr7.len0 = bkps[0].len; + dr7.len1 = bkps[1].len; + dr7.len2 = bkps[2].len; + dr7.len3 = bkps[3].len; + __asm__ volatile ("mov %0, %%dr7" : : "r"(dr7)); + __asm__ volatile ("mov %0, %%dr0" : : "r"(bkps[0].addr)); + __asm__ volatile ("mov %0, %%dr1" : : "r"(bkps[1].addr)); + __asm__ volatile ("mov %0, %%dr2" : : "r"(bkps[2].addr)); + __asm__ volatile ("mov %0, %%dr3" : : "r"(bkps[3].addr)); +} + +static int debugger_prompt(struct isr_regs *state) { + kputs("dbg> "); + char buf[64]; + debugger_read(buf, 64); + + struct rflags *rflags = (struct rflags *)&state->rflags; + + switch (buf[0]) { + case '\0': // nothing entered + return 1; + case 'h': // help + kputs("see debugger.c for help information\n"); + return 1; + case 'q': // quit + return 0; + case 'c': // continue + rflags->tf = 1; + dbg_continue = 1; + return 0; + case 'r': // print registers + debugger_print_regs(state); + return 1; + case 'k': // backtrace + log_backtrace_ex((void *)state->rip, (void *)state->rbp); + return 1; + case 's': // step (n) + rflags->tf = 1; + dbg_steps = atol(buf + 1) - 1; + //if (dbg_steps < 0) dbg_steps = 0; + return 0; + case 'm': // memory + { + kputs("addr> 0x"); + debugger_read(buf, 64); + uint64_t start = (~0xF) & strtoll(buf, NULL, 16); + + kputs("len> 0x"); + debugger_read(buf, 64); + uint64_t len = (~0xF) & strtoll(buf, NULL, 16); + + for (uint64_t a = start; a <= start + len; a += 0x10) { + kprintf("%08lx: ", a); + for (uint64_t b = 0; b < 0x10; b++) { + kprintf("%02x ", *(uint8_t *)(a + b)); + if (b % 0x08 == 7) { + kputc(' '); + } + } + kputs("|"); + for (uint64_t b = 0; b < 0x10; b++) { + uint8_t ch = *(uint8_t *)(a + b); + if (ch < 0x20 || ch >= 0x7f) { + ch = '.'; + } + kputc(ch); + } + kputs("|\n"); + } + return 1; + } + case 'b': // breakpoints + { + int res = debugger_handle_bkp_cmd(buf+1); + debugger_load_bkps(); + return res; + } + default: + kputs("unknown command\n"); + return 1; + } +} + +void debugger(struct isr_regs *state, int cause) { + struct dr6 dr6; + __asm__ volatile ("mov %%dr6, %0" : "=r"(dr6)); + + if (!(dr6.b0 || dr6.b1 || dr6.b2 || dr6.b3)) { + if (dr6.bs && dbg_steps > 0) { + dbg_steps--; + return; + } + + if (dr6.bs && dbg_continue) { + return; + } + } + + debugger_msg(cause, dr6); + + kputs("hi\n"); + + dbg_steps = 0; + dbg_continue = 0; + + ((struct rflags *)&state->rflags)->tf = 0; + + if (dr6.b0) { + state->rip += bkps[0].instr_len; + } else if (dr6.b1) { + state->rip += bkps[1].instr_len; + } else if (dr6.b2) { + state->rip += bkps[2].instr_len; + } else if (dr6.b3) { + state->rip += bkps[3].instr_len; + } + + while (debugger_prompt(state)); +} diff --git a/src/arch/amd64/cpu/debugger.h b/src/arch/amd64/cpu/debugger.h new file mode 100644 index 0000000..14f73bf --- /dev/null +++ b/src/arch/amd64/cpu/debugger.h @@ -0,0 +1,9 @@ +#pragma once + +#include "idt.h" + +#define DEBUG_INT3 0x00 +#define DEBUG_DBG 0x01 +#define DEBUG_FAULT 0x02 + +void debugger(struct isr_regs *state, int cause); diff --git a/src/arch/amd64/cpu/idt.S b/src/arch/amd64/cpu/idt.S new file mode 100644 index 0000000..cd8783e --- /dev/null +++ b/src/arch/amd64/cpu/idt.S @@ -0,0 +1,207 @@ +extern idt_exception_handler +global isr_stub_table + +extern idt_pic_timer +extern idt_pic_keyboard +extern idt_pic_mouse +extern idt_pic_eoi + +%macro PUSHALL 0 + push rax + push rbx + push rcx + push rdx + push rsi + push rdi + push rbp + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 +%endmacro + +%macro POPALL 0 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rbp + pop rdi + pop rsi + pop rdx + pop rcx + pop rbx + pop rax +%endmacro + +; call the exception handler with the interrupt number +; args: interrupt number +%macro ISRException 1 +align 8 +isr_stub_%+%1: + PUSHALL + cld + mov rdi, %1 ; exception number + mov rsi, 0 ; placeholder error code + mov rdx, rsp ; top of stack + call idt_exception_handler + POPALL + iretq +%endmacro + +; call the exception handler with the interrupt number +; these exceptions also put an error code on the stack +; args: interrupt number +%macro ISRExceptionCode 1 +align 8 +isr_stub_%+%1: + ; retrieve the error code without corrupting registers + mov [isr_tmp], rax + pop rax + mov [isr_err_code], rax + mov rax, [isr_tmp] + PUSHALL + cld + mov rdi, %1 ; exception number + mov rsi, [isr_err_code] ; error code + mov rdx, rsp ; top of stack + call idt_exception_handler + POPALL + iretq +%endmacro + +%macro PICGeneric 1 +isr_stub_%+%1: + PUSHALL + cld + mov rdi, %1 + call idt_pic_eoi + POPALL + iretq +%endmacro + +%macro PICTimer 1 +isr_stub_%+%1: + PUSHALL + cld + call idt_pic_timer + mov rdi, %1 + call idt_pic_eoi + POPALL + iretq +%endmacro + +%macro PICKeyboard 1 +isr_stub_%+%1: + PUSHALL + cld + call idt_pic_keyboard + mov rdi, %1 + call idt_pic_eoi + POPALL + iretq +%endmacro + +%macro PICMouse 1 +isr_stub_%+%1: + PUSHALL + cld + call idt_pic_mouse + mov rdi, %1 + call idt_pic_eoi + POPALL + iretq +%endmacro + +; do nothing +; args: interrupt number +%macro ISRIgnore 1 +align 8 +isr_stub_%+%1: + iretq +%endmacro + +; isr stubs +section .text +bits 64 + +ISRException 0 +ISRException 1 +ISRException 2 +ISRException 3 +ISRException 4 +ISRException 5 +ISRException 6 +ISRException 7 +ISRExceptionCode 8 +ISRException 9 +ISRExceptionCode 10 +ISRExceptionCode 11 +ISRExceptionCode 12 +ISRExceptionCode 13 +ISRExceptionCode 14 +ISRException 15 +ISRException 16 +ISRExceptionCode 17 +ISRException 18 +ISRException 19 +ISRException 20 +ISRExceptionCode 21 +ISRException 22 +ISRException 23 +ISRException 24 +ISRException 25 +ISRException 26 +ISRException 27 +ISRException 28 +ISRExceptionCode 29 +ISRExceptionCode 30 +ISRException 31 + +PICTimer 32 ; 0 +PICKeyboard 33 ; 1 +PICGeneric 34 ; 2 +PICGeneric 35 ; 3 +PICGeneric 36 ; 4 +PICGeneric 37 ; 5 +PICGeneric 38 ; 6 +PICGeneric 39 ; 7 +PICGeneric 40 ; 8 +PICGeneric 41 ; 9 +PICGeneric 42 ; 10 +PICGeneric 43 ; 11 +PICMouse 44 ; 12 +PICGeneric 45 ; 13 +PICGeneric 46 ; 14 +PICGeneric 47 ; 15 + +; ignore other interrupts +%assign i 48 +%rep 256 - i + ISRIgnore i + %assign i i+1 +%endrep + +section .data +isr_tmp: dq 0 +isr_err_code: dq 0 + +; isr stub table +section .rodata +bits 64 +align 16 + +isr_stub_table: +%assign i 0 +%rep 256 + dq isr_stub_%+i +%assign i i+1 +%endrep diff --git a/src/arch/amd64/cpu/idt.c b/src/arch/amd64/cpu/idt.c new file mode 100644 index 0000000..053f614 --- /dev/null +++ b/src/arch/amd64/cpu/idt.c @@ -0,0 +1,160 @@ +#include <stdint.h> +#include <stddef.h> +#include <lib.h> +#include <panic.h> +#include "idt.h" +#include "debugger.h" +#include "../paging.h" +#include "../drivers/pic.h" + +#define IDT_SIZE 256 + +struct idt_entry { + uint16_t isr_low; // low 16 bits of isr + uint16_t kernel_cs; // kernel segment selector + uint8_t ist; // interrupt stack table + uint8_t flags; // gate type, privilege level, present bit + uint16_t isr_mid; // middle 16 bits of isr + uint32_t isr_high; // high 32 bits of isr + uint32_t reserved; +} __attribute__((packed)); + +struct idtr { + uint16_t size; + uint64_t address; +} __attribute__((packed)); + +// interrupt gate +#define GATE_64BIT_INT 0x0E +// trap gate +#define GATE_64BIT_TRAP 0x0F + +// privilege ring allowed to call interrupt +#define RING0 0x00 +#define RING1 0x20 +#define RING2 0x40 +#define RING3 0x60 + +// interrupt is present in IDT +#define PRESENT 0x80 + +__attribute__((aligned(0x10))) +static struct idt_entry idt[256]; + +static struct idtr idtr; +// from idt.S +extern void *isr_stub_table[]; + +// initialize and load the IDT +void idt_init(void) { + // initialize idtr + idtr.address = (uint64_t)&idt; + idtr.size = (uint16_t)sizeof(struct idt_entry) * IDT_SIZE - 1; + + // initialize idt + for (size_t vector = 0; vector < IDT_SIZE; vector++) { + struct idt_entry *entry = &idt[vector]; + + uint64_t isr = (uint64_t)isr_stub_table[vector]; + // interrupts before 0x20 are for cpu exceptions + uint8_t gate_type = (vector < 0x20) ? GATE_64BIT_TRAP : GATE_64BIT_INT; + + entry->kernel_cs = 0x08; // offset of 1 into GDT + entry->ist = 0; + entry->flags = PRESENT | RING0 | gate_type; + entry->isr_low = isr & 0xffff; + entry->isr_mid = (isr >> 16) & 0xffff; + entry->isr_high = (isr >> 32) & 0xffffffff; + entry->reserved = 0; + } + + __asm__ volatile ("lidt %0" : : "m"(idtr)); +} + +// Intel manual vol 3 ch 6.3.1 +char *EXCEPTIONS[] = { + "Division Error", + "Debug", + "NMI", + "Breakpoint", + "Overflow", + "BOUND Range Exceeded", + "Invalid Opcode", + "Device Not Available", + "Double Fault", + "Coprocessor Segment Overrun", + "Invalid TSS", + "Segment Not Present", + "Stack-Segment Fault", + "General Protection Fault", + "Page Fault", + "Reserved", + "x87 Floating-Point Error", + "Alignment Check", + "Machine Check", + "SIMD Floaing-Point Exception", + "Virtualization Exception", + "Control Protection Exception", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Hypervisor Injection Exception", + "VMM Communication Exception", + "Security Exception", + "Reserved", +}; + +void idt_exception_handler(uint64_t exception, uint64_t code, struct isr_regs *state) { + switch (exception) { + case 0x01: // debug + debugger(state, DEBUG_DBG); + return; + case 0x03: // breakpoint + debugger(state, DEBUG_INT3); + return; + } + + char custom[64]; + *custom = '\0'; + + // page faults store the offending address in cr2 + if (exception == 0x0E) { + strcat(custom, "\nPage fault address: 0x"); + uint64_t cr2; + __asm__ volatile ("mov %%cr2, %0" : "=r"(cr2)); + ultoa((size_t)cr2, custom + 23, 16); + } + + panic_interrupt( + (void *)state->rip, + (void *)state->rbp, + "Exception %s\nError code 0x%lu%s", + EXCEPTIONS[exception], + code, + custom + ); +} + +void idt_pic_eoi(uint8_t exception) { + pic_eoi(exception - PIC_REMAP_OFFSET); +} + +int counter = 0; + +void idt_pic_timer(void) { + // print a message once we know the timer works + // but avoid spamming the logs + if (counter == 3) { + //kputs("pic timer!\n"); + } + if (counter <= 3) { + counter++; + } +} + +void idt_pic_keyboard(void) {} + +void idt_pic_mouse(void) {} diff --git a/src/arch/amd64/cpu/idt.h b/src/arch/amd64/cpu/idt.h new file mode 100644 index 0000000..89a9dab --- /dev/null +++ b/src/arch/amd64/cpu/idt.h @@ -0,0 +1,29 @@ +#pragma once + +#include <stdint.h> + +struct isr_regs { + uint64_t r15; + uint64_t r14; + uint64_t r13; + uint64_t r12; + uint64_t r11; + uint64_t r10; + uint64_t r9; + uint64_t r8; + uint64_t rbp; + uint64_t rdi; + uint64_t rsi; + uint64_t rdx; + uint64_t rcx; + uint64_t rbx; + uint64_t rax; + + uint64_t rip; + uint64_t cs; + uint64_t rflags; + uint64_t rsp; + uint64_t ss; +}; + +void idt_init(); |