summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAda Christine <adachristine18@gmail.com>2022-02-24 16:48:53 +0000
committerAda Christine <adachristine18@gmail.com>2022-02-24 16:48:53 +0000
commit9fcd505ab3106e9fbf586e6d16e53e3e44936215 (patch)
treeadd54829625e90c27a1c11a160e9deb5e5877ae1
parent1923e47fd296399180eaf19b990d5e951d71ccd2 (diff)
context struct for ISRs rather than using param registers; second-stage handlers should deal with that i think
-rw-r--r--kc/core/cpu/exceptions.S21
-rw-r--r--kc/core/cpu/exceptions.h68
-rw-r--r--kc/core/memory/memory.c19
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;
}