diff options
| -rw-r--r-- | kc/core/cpu/cpu.c | 8 | ||||
| -rw-r--r-- | kc/core/cpu/exceptions.S | 85 | ||||
| -rw-r--r-- | kc/core/cpu/exceptions.h | 41 | ||||
| -rw-r--r-- | kc/core/exceptions.S | 84 | ||||
| -rw-r--r-- | kc/core/exceptions.h | 10 | ||||
| -rw-r--r-- | kc/core/memory.c | 14 |
6 files changed, 141 insertions, 101 deletions
diff --git a/kc/core/cpu/cpu.c b/kc/core/cpu/cpu.c index 6e8e8b6..28b69ff 100644 --- a/kc/core/cpu/cpu.c +++ b/kc/core/cpu/cpu.c @@ -257,8 +257,12 @@ void cpu_init(void) void exceptions_init(void) { - isr_install(GENERAL_PROTECTION_VECTOR, &general_protection_isr, 0, 0); - isr_install(PAGE_FAULT_VECTOR, &page_fault_isr, 0, 0); + isr_install( + GENERAL_PROTECTION_EXCEPTION, + &general_protection_isr, + 0, + 0); + isr_install(PAGE_FAULT_EXCEPTION, &page_fault_isr, 0, 0); } void isr_install(int vec, void (*isr)(void), int trap, unsigned ist) diff --git a/kc/core/cpu/exceptions.S b/kc/core/cpu/exceptions.S new file mode 100644 index 0000000..8a19c8c --- /dev/null +++ b/kc/core/cpu/exceptions.S @@ -0,0 +1,85 @@ +#include "exceptions.h" + +.macro EXCEPTION_BEGIN vec:req, code=0 + // just in case something tried to be clever before + cld + // push param registers + push %rdi + // store certain parameters + movb $\vec,%dil + push %rsi + .if \code + movq 16(%rsp), %rsi + .else + xor %rsi, %rsi + .endif + push %rdx + push %rcx + push %r8 + push %r9 + // caller-saved registers + push %rax + push %r10 + push %r11 + // callee-saved registers + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 +.endm + +.macro EXCEPTION_END vec:req, code=0 + // restore all the registers + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %r11 + pop %r10 + pop %rax + pop %r9 + pop %r8 + pop %rcx + pop %rdx + pop %rsi + pop %rdi + .if \code + add $8, %rsp + .endif + iretq +.endm + +.macro EXCEPTION_CALL func + // align the stack for the call to the handler function + mov %rsp, %rbp + and $-16, %rsp + call \func + // restore stack pointer, possibly unaligned + mov %rbp, %rsp +.endm + +.macro EXCEPTION_DEFINE name:req, vec:req +\name\()_isr: + .if \vec > 9 && \vec < 15 || \vec == 17 || \vec == 21 || \vec > 28 && \vec < 31 + EXCEPTION_BEGIN \vec, 1 + .else + EXCEPTION_BEGIN \vec + .endif + EXCEPTION_CALL \name\()_handler + .if \vec > 9 && \vec < 15 || \vec == 17 || \vec == 21 || \vec > 28 && \vec < 31 + EXCEPTION_END \vec, 1 + .else + EXCEPTION_END \vec + .endif +.size \name\()_isr, . - \name\()_isr +.endm + +EXCEPTION_DECLARE page_fault PAGE_FAULT_EXCEPTION +EXCEPTION_DECLARE general_protection GENERAL_PROTECTION_EXCEPTION +EXCEPTION_DEFINE page_fault, PAGE_FAULT_EXCEPTION +EXCEPTION_DEFINE general_protection, GENERAL_PROTECTION_EXCEPTION + diff --git a/kc/core/cpu/exceptions.h b/kc/core/cpu/exceptions.h new file mode 100644 index 0000000..c35c8ca --- /dev/null +++ b/kc/core/cpu/exceptions.h @@ -0,0 +1,41 @@ +#pragma once + +#define DIVIDE_ZER0_EXCEPTION 0x0 +#define DEBUG_EXCEPTION 0x1 +#define NONMASKABLE_EXCEPTION 0x2 +#define BREAKPOINT_EXCEPTION 0x3 +#define OVERFLOW_EXCEPTION 0x4 +#define BOUND_RANGE_EXCEPTION 0x5 +#define INVALID_OPCODE_EXCEPTION 0x6 +#define DEVICE_NOT_AVAILABLE_EXCEPTION 0x7 +#define DOUBLE_FAULT_EXCEPTION 0x8 +#define INVALID_TSS_EXCEPTION 0x10 +#define SEGMENT_NOT_PRESENT_EXCEPTION 0x11 +#define STACK_EXCEPTION 0xc +#define GENERAL_PROTECTION_EXCEPTION 0xd +#define PAGE_FAULT_EXCEPTION 0xe +#define X87_FLOAT_EXCEPTION 0x10 +#define ALIGNMENT_CHECK_EXCEPTION 0x11 +#define MACHINE_CHECK_EXCEPTION 0x12 +#define SIMD_FLOAT_EXCEPTION 0x13 + +#ifndef __ASSEMBLER__ + +void general_protection_isr(); +void general_protection_handler(); +void page_fault_isr(); +void page_fault_handler(); + +void exceptions_init(void); + +#else + +.macro EXCEPTION_DECLARE name:req, vec:req +.hidden \name\()_isr +.global \name\()_isr +.extern \name\()_handler +.type \name\()_isr, @function +.endm + +#endif + diff --git a/kc/core/exceptions.S b/kc/core/exceptions.S deleted file mode 100644 index 0a5b760..0000000 --- a/kc/core/exceptions.S +++ /dev/null @@ -1,84 +0,0 @@ -.extern page_fault_handler -.extern general_protection_handler - -.macro ISR_STORE_REGISTERS - /* just in case something tried to be clever before */ - cld - /* push param registers */ - push %rdi - push %rsi - push %rdx - push %rcx - push %r8 - push %r9 - /* caller-saved registers */ - push %rax - push %r10 - push %r11 - /* callee-saved registers */ - push %rbx - push %rbp - push %r12 - push %r13 - push %r14 - push %r15 -.endm - -.macro ISR_RESTORE_REGISTERS - // restore all the registers - pop %r15 - pop %r14 - pop %r13 - pop %r12 - pop %rbp - pop %rbx - pop %r11 - pop %r10 - pop %rax - pop %r9 - pop %r8 - pop %rcx - pop %rdx - pop %rsi - pop %rdi -.endm - -.macro ISR_CALL func - // align the stack for the call to the handler function - mov %rsp, %rbp - and $-16, %rsp - call \func - // restore stack pointer, possibly unaligned - mov %rbp, %rsp -.endm - -.hidden page_fault_isr -.global page_fault_isr -.type page_fault_isr, @function -page_fault_isr: - ISR_STORE_REGISTERS - /* collect parameters for page fault handler */ - mov 120(%rsp), %rdi /* error code is first parameter */ - mov %cr2, %rsi /* PFLA is next parameter */ - /* stack has to be aligned */ - ISR_CALL page_fault_handler - /* TODO: test for error code here and panic() */ - ISR_RESTORE_REGISTERS - /* unwind the error code from the stack */ - add $8, %rsp - /* leave the isr */ - iretq -.size page_fault_isr, . - page_fault_isr - -.hidden general_protection_isr -.global general_protection_isr -.type general_protection_isr, @function -general_protection_isr: - ISR_STORE_REGISTERS - // TODO: parameters? - ISR_CALL general_protection_handler - add $8, %rsp - ISR_RESTORE_REGISTERS - iretq -.size general_protection_isr, . - general_protection_isr - diff --git a/kc/core/exceptions.h b/kc/core/exceptions.h deleted file mode 100644 index 11696d5..0000000 --- a/kc/core/exceptions.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -extern void page_fault_isr(void); -extern void general_protection_isr(void); - -#define GENERAL_PROTECTION_VECTOR 0xd -#define PAGE_FAULT_VECTOR 0xe - -void exceptions_init(void); - diff --git a/kc/core/memory.c b/kc/core/memory.c index 634c3b3..7571f0d 100644 --- a/kc/core/memory.c +++ b/kc/core/memory.c @@ -31,7 +31,7 @@ struct page uint32_t used: 1; }; -static struct page *const page_array = (struct page *)0xffffffd800000000; +static struct page * const page_array = (struct page *)0xffffffd800000000; static int first_free_page_index = -1; static size_t page_array_entries = 0; static size_t free_pages = 0; @@ -593,10 +593,12 @@ int anonymous_page_handler(uint32_t code, void *address) return 0; } -int page_fault_handler(uint32_t code, void *address) +int page_fault_handler(uint8_t vector, uint32_t code) { - (void)code; - kputs("page fault\n"); + (void)vector; + void *address; + __asm__ volatile ("movq %%cr2, %0" : "=r"(address)); + kprintf("page fault code=%d, pfla=%#lx\n", code, address); struct vm_object *o = vmt_get_object(&core_vm_tree, address); int result = 1; if (o) @@ -620,10 +622,12 @@ int page_fault_handler(uint32_t code, void *address) return 0; } -int general_protection_handler(uint32_t code) +int general_protection_handler(uint8_t vector, uint32_t code) { //TODO: implement #gp handler + (void)vector; (void)code; + kputs("general protection violation\n"); panic(UNHANDLED_FAULT); return 0; } |
