summaryrefslogtreecommitdiff
path: root/kc/core/cpu
diff options
context:
space:
mode:
authorAda Christine <adachristine18@gmail.com>2022-02-13 12:26:58 +0000
committerAda Christine <adachristine18@gmail.com>2022-02-13 12:26:58 +0000
commitc1d179d50751d0ce08dc2b009fc5e334d20db11a (patch)
treec24a48ef55fbfe898b58f61a880ae4e3d96e8440 /kc/core/cpu
parent23f4c7eaa0bae30bebbac68950e96d17c6d77c36 (diff)
exception changes
Diffstat (limited to 'kc/core/cpu')
-rw-r--r--kc/core/cpu/cpu.c8
-rw-r--r--kc/core/cpu/exceptions.S85
-rw-r--r--kc/core/cpu/exceptions.h41
3 files changed, 132 insertions, 2 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
+