diff options
Diffstat (limited to 'kc/core')
| -rw-r--r-- | kc/core/cpu/exceptions.S | 21 | ||||
| -rw-r--r-- | kc/core/cpu/exceptions.h | 68 | ||||
| -rw-r--r-- | kc/core/memory/memory.c | 19 |
3 files changed, 79 insertions, 29 deletions
diff --git a/kc/core/cpu/exceptions.S b/kc/core/cpu/exceptions.S index 087cf12..8aa109e 100644 --- a/kc/core/cpu/exceptions.S +++ b/kc/core/cpu/exceptions.S @@ -1,32 +1,26 @@ #include "exceptions.h" #include "interrupt.h" -.macro EXCEPTION_BEGIN vec:req, code=0 +.macro EXCEPTION_BEGIN vec:req, code // just in case something tried to be clever before - cld + pushq $\vec + .ifb \code + pushq $0 + .endif // push param registers ISR_STORE_PARAM_REGS - // store certain parameters - movb $\vec,%dil - .if \code - movq ISR_PARAM_REGS_SIZE(%rsp), %rsi - .else - xor %rsi, %rsi - .endif // caller-saved registers ISR_STORE_CALLER_REGS // callee-saved registers ISR_STORE_CALLEE_REGS .endm -.macro EXCEPTION_END vec:req, code=0 +.macro EXCEPTION_END vec:req, code // restore all the registers ISR_RESTORE_CALLEE_REGS ISR_RESTORE_CALLER_REGS ISR_RESTORE_PARAM_REGS - .if \code - add $8, %rsp - .endif + add $16, %rsp iretq .endm @@ -37,6 +31,7 @@ .else EXCEPTION_BEGIN \vec .endif + movq %rsp, %rdi ISR_CALL \name\()_handler .if \vec > 9 && \vec < 15 || \vec == 17 || \vec == 21 || \vec > 28 && \vec < 31 EXCEPTION_END \vec, 1 diff --git a/kc/core/cpu/exceptions.h b/kc/core/cpu/exceptions.h index c35c8ca..a43ba23 100644 --- a/kc/core/cpu/exceptions.h +++ b/kc/core/cpu/exceptions.h @@ -21,10 +21,70 @@ #ifndef __ASSEMBLER__ -void general_protection_isr(); -void general_protection_handler(); -void page_fault_isr(); -void page_fault_handler(); +#include "kprint.h" + +struct isr_context_param_regs +{ + uint64_t r9, r8, rcx, rdx, rsi, rdi; +}; + +struct isr_context_caller_regs +{ + uint64_t r11, r10, rax; +}; + +struct isr_context_callee_regs +{ + uint64_t r15, r14, r13, r12, rbp, rbx; +}; + +struct isr_context_entry_state +{ + uint64_t vector, code, rip, cs, rflags; +}; + +struct isr_context +{ + struct isr_context_callee_regs callee_regs; + struct isr_context_caller_regs caller_regs; + struct isr_context_param_regs param_regs; + struct isr_context_entry_state entry_state; +}; + +static inline void print_exception_context(struct isr_context *context) +{ + kprintf( + "exception %#hhx:%x context:\n" + "interrupt entry state:\n" + "rip: %#hx:%p rflags: %#x\n" + "parameter registers:\n" + "rdi: %#lx rsi: %#lx rdx: %lx\n" + "rcx: %#lx r8: %#lx r9: %#lx\n" + "caller registers:\n" + "rax: %#lx r10: %#lx r11: %#lx\n" + "callee registers:\n" + "rbx: %#lx rbp: %#lx r12: %lx\n" + "r13: %#lx r14: %#lx r15: %#lx\n", + context->entry_state.vector, context->entry_state.code, + context->entry_state.cs, context->entry_state.rip, + context->entry_state.rflags, + + context->param_regs.rdi, context->param_regs.rsi, + context->param_regs.rdx, context->param_regs.rcx, + context->param_regs.r8,context->param_regs.r9, + + context->caller_regs.rax, context->caller_regs.r10, + context->caller_regs.r11, + + context->callee_regs.rbx, context->callee_regs.rbp, + context->callee_regs.r12, context->callee_regs.r13, + context->callee_regs.r14, context->callee_regs.r15); +} + +void general_protection_isr(void); +void general_protection_handler(struct isr_context *context); +void page_fault_isr(void); +void page_fault_handler(struct isr_context *context); void exceptions_init(void); diff --git a/kc/core/memory/memory.c b/kc/core/memory/memory.c index 1a33629..0fbc941 100644 --- a/kc/core/memory/memory.c +++ b/kc/core/memory/memory.c @@ -15,6 +15,7 @@ #include "panic.h" #include "vm_object.h" #include "cpu/mmu.h" +#include "cpu/exceptions.h" #include <stdint.h> @@ -589,10 +590,8 @@ int anonymous_page_handler( return 0; } -int page_fault_handler(uint8_t vector, uint32_t code) +void page_fault_handler(struct isr_context *context) { - (void)vector; - void *address; __asm__ volatile ("movq %%cr2, %0" : "=r"(address)); @@ -601,28 +600,24 @@ int page_fault_handler(uint8_t vector, uint32_t code) if (!node) { - kprintf("error: page fault in unmanaged address %#lx\n", - address); + print_exception_context(context); + kprintf("error: page fault in unmanaged address %#lx\n", address); PANIC(UNHANDLED_FAULT); } if (!node->object->handler) { + print_exception_context(context); kprintf("error: vm object at %p has no fault handler\n"); PANIC(UNHANDLED_FAULT); } - - return node->object->handler(node, code, address); } -int general_protection_handler(uint8_t vector, uint32_t code) +void general_protection_handler(struct isr_context *context) { //TODO: implement #gp handler - (void)vector; - (void)code; - kputs("general protection violation\n"); + print_exception_context(context); PANIC(UNHANDLED_FAULT); - return 0; } |
