summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-06-19 00:53:55 -0400
committerIan Moffett <ian@osmora.org>2025-06-19 00:53:55 -0400
commitcaad8df87d20c5949ef4c1190bc5a63ccf75dc05 (patch)
tree9aa3abd04a4797dfbeb1a82820a2367bfb5a9371 /sys
parent1a3e39cd28f90754c3927dabe32a37836db3f8d5 (diff)
kernel/aarch64: Add exception code + frame fixups
- Add handle_exception() as higher level logic to handle the exceptions - Simplify frame.h - Call C handler in vector.S - Clean up stack after creating frame - Add register dump on exception Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/aarch64/aarch64/exception.c128
-rw-r--r--sys/arch/aarch64/aarch64/vector.S51
-rw-r--r--sys/include/arch/aarch64/exception.h54
-rw-r--r--sys/include/arch/aarch64/frame.h80
-rw-r--r--sys/include/arch/aarch64/frameasm.h21
5 files changed, 249 insertions, 85 deletions
diff --git a/sys/arch/aarch64/aarch64/exception.c b/sys/arch/aarch64/aarch64/exception.c
new file mode 100644
index 0000000..d6f1f97
--- /dev/null
+++ b/sys/arch/aarch64/aarch64/exception.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/syslog.h>
+#include <sys/param.h>
+#include <sys/cdefs.h>
+#include <machine/cdefs.h>
+#include <machine/exception.h>
+
+#define pr_trace(fmt, ...) kprintf("exception: " fmt, ##__VA_ARGS__)
+#define pr_error(...) pr_trace(__VA_ARGS__)
+
+static inline void
+log_esr_class(uint8_t class)
+{
+ switch (class) {
+ case EC_WF:
+ pr_error("trapped WF\n");
+ break;
+ case EC_MCRMRC:
+ pr_error("trapped MCR/MRC\n");
+ break;
+ case EC_MCRRC:
+ pr_trace("trapped MCRR/MRRC\n");
+ break;
+ case EC_LDCSTC:
+ pr_error("trapped LDC/STC\n");
+ break;
+ case EC_SVE:
+ pr_trace("trapped SVE/SIMD/FP operation\n");
+ break;
+ case EC_BRE:
+ pr_error("ibt: bad branch target\n");
+ break;
+ case EC_ILLX:
+ pr_error("illegal execution state\n");
+ break;
+ case EC_SVC64:
+ /* TODO */
+ pr_error("supervisor call (TODO)!!\n");
+ break;
+ case EC_PCALIGN:
+ pr_error("PC alignment fault\n");
+ break;
+ case EC_DABORT:
+ case EC_EDABORT:
+ pr_error("data abort\n");
+ break;
+ case EC_SPALIGN:
+ pr_error("SP alignment fault\n");
+ break;
+ case EC_SERR:
+ pr_error("system error\n");
+ break;
+ default:
+ pr_error("unknown exception\n");
+ }
+}
+
+static void
+regdump(struct trapframe *tf, uint64_t elr)
+{
+ kprintf(OMIT_TIMESTAMP
+ "X0=%p X1=%p X2=%p\n"
+ "X3=%p X4=%p X5=%p\n"
+ "X6=%p X7=%p X8=%p\n"
+ "X9=%p X10=%p X11=%p\n"
+ "X12=%p X13=%p X14=%p\n"
+ "X15=%p X16=%p X17=%p\n"
+ "X18=%p X19=%p X20=%p\n"
+ "X21=%p X22=%p X23=%p\n"
+ "X24=%p X25=%p X26=%p\n"
+ "X27=%p X28=%p X29=%p\n"
+ "X30=%p\n"
+ "ELR=%p\n",
+ tf->x0, tf->x1, tf->x2, tf->x3,
+ tf->x4, tf->x5, tf->x6, tf->x7,
+ tf->x8, tf->x9, tf->x10, tf->x11,
+ tf->x12, tf->x13, tf->x14, tf->x15,
+ tf->x16, tf->x17, tf->x18, tf->x19,
+ tf->x20, tf->x21, tf->x22, tf->x23,
+ tf->x24, tf->x25, tf->x26, tf->x27,
+ tf->x28, tf->x29, tf->x30, elr);
+}
+
+/*
+ * Handle an exception
+ *
+ * @esr: Copy of the Exception Syndrome Register
+ */
+void
+handle_exception(struct trapframe *tf)
+{
+ uint8_t class;
+
+ class = (tf->esr >> 26) & 0x3F;
+ log_esr_class(class);
+ regdump(tf, tf->elr);
+ for (;;) {
+ md_hlt();
+ }
+}
diff --git a/sys/arch/aarch64/aarch64/vector.S b/sys/arch/aarch64/aarch64/vector.S
index f38f24e..c8f77ca 100644
--- a/sys/arch/aarch64/aarch64/vector.S
+++ b/sys/arch/aarch64/aarch64/vector.S
@@ -36,54 +36,37 @@
b \label
.endm
- .section .data
-error:
- .ascii "got exception, halting\n\0"
-
.text
x_sync_elx:
- PUSH_XFRAME(TRAPNO_XSYNC)
- ldr x0, =error
- bl kprintf
- POP_XFRAME()
-1:
- hlt #0
+ PUSH_XFRAME(TRAPNO_XSYNC) // Synchronous: sp+top @ X0
+ bl handle_exception // Handle the exception
+ POP_XFRAME() // Pop the trapframe
+1: hlt #0 // TODO
b 1b
x_irq_elx:
- PUSH_XFRAME(TRAPNO_XSYNC)
- ldr x0, =error
- bl kprintf
- POP_XFRAME()
-1:
- hlt #0
+ PUSH_XFRAME(TRAPNO_XIRQ) // IRQ: sp+top @ X0
+ bl handle_exception // Handle the exception
+ POP_XFRAME() // Pop the trapframe
+1: hlt #0 // TODO
b 1b
x_fiq_elx:
- PUSH_XFRAME(TRAPNO_XSYNC)
- ldr x0, =error
- bl kprintf
- POP_XFRAME()
-1:
- hlt #0
+ PUSH_XFRAME(TRAPNO_XFIQ) // FIQ: sp+top @ X0
+ bl handle_exception // Handle the exception
+ POP_XFRAME() // Pop the trapframe
+1: hlt #0
b 1b
x_serr_elx:
- PUSH_XFRAME(TRAPNO_XSYNC)
- ldr x0, =error
- bl kprintf
- POP_XFRAME()
-1:
- hlt #0
+ PUSH_XFRAME(TRAPNO_XSERR) // SERR: sp+top @ X0
+ bl handle_exception // Handle the exception
+ POP_XFRAME() // Pop the trapframe
+1: hlt #0 // TODO
b 1b
x_unimpl:
- PUSH_XFRAME(TRAPNO_XSYNC)
- ldr x0, =error
- bl kprintf
- POP_XFRAME()
-1:
- hlt #0
+1: hlt #0
b 1b
.align 11 // Table aligned @ 2 KiB
diff --git a/sys/include/arch/aarch64/exception.h b/sys/include/arch/aarch64/exception.h
new file mode 100644
index 0000000..9e89c81
--- /dev/null
+++ b/sys/include/arch/aarch64/exception.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_EXCEPTION_H_
+#define _MACHINE_EXCEPTION_H_
+
+#include <sys/types.h>
+#include <machine/frame.h>
+
+/* Exception class */
+#define EC_UNKNOWN 0x00 /* Unknown type */
+#define EC_WF 0x01 /* Trapped WF instruction */
+#define EC_MCRMRC 0x03 /* Trapped MCR/MRC */
+#define EC_MCRRC 0x04 /* Trapped MCRR/MRRC */
+#define EC_LDCSTC 0x06 /* Trapped LDC/STC */
+#define EC_SVE 0x07 /* Trapped SVE/SIMD/FP op */
+#define EC_BRE 0x0D /* Branch target exception */
+#define EC_ILLX 0x0E /* Illegal execution state */
+#define EC_SVC64 0x15 /* AARCH64 SVC */
+#define EC_PCALIGN 0x22 /* PC alignment fault */
+#define EC_DABORT 0x24 /* Data abort (w/o ELx change) */
+#define EC_EDABORT 0x25 /* Data abort (w/ ELx change) */
+#define EC_SPALIGN 0x26 /* SP alignment fault */
+#define EC_SERR 0x2F /* System error (what the fuck!) */
+
+void handle_exception(struct trapframe *tf);
+
+#endif /* !_MACHINE_EXCEPTION_H_ */
diff --git a/sys/include/arch/aarch64/frame.h b/sys/include/arch/aarch64/frame.h
index f14fa01..143f4d0 100644
--- a/sys/include/arch/aarch64/frame.h
+++ b/sys/include/arch/aarch64/frame.h
@@ -31,46 +31,11 @@
#define _MACHINE_FRAME_H_
#include <sys/types.h>
+#include <sys/cdefs.h>
typedef uint64_t lreg_t;
typedef uint64_t frament_t;
-/* General purpose registers */
-struct gpregs {
- frament_t trapno;
- lreg_t x0;
- lreg_t x1;
- lreg_t x2;
- lreg_t x3;
- lreg_t x4;
- lreg_t x5;
- lreg_t x6;
- lreg_t x7;
- lreg_t x8;
- lreg_t x9;
- lreg_t x10;
- lreg_t x11;
- lreg_t x12;
- lreg_t x13;
- lreg_t x14;
- lreg_t x15;
- lreg_t x16;
- lreg_t x17;
- lreg_t x18;
- lreg_t x19;
- lreg_t x20;
- lreg_t x21;
- lreg_t x22;
- lreg_t x23;
- lreg_t x24;
- lreg_t x25;
- lreg_t x26;
- lreg_t x27;
- lreg_t x28;
- lreg_t x29;
- lreg_t x30;
-};
-
/* Stack regs */
struct sregs {
lreg_t sp_el0;
@@ -85,14 +50,41 @@ struct pstat {
lreg_t spsr_el3;
};
-struct trapframe {
- struct gpregs gp;
- struct sregs stack;
- struct pstat status;
- lreg_t elr_el1;
- lreg_t elr_el2;
- lreg_t elr_el3;
- lreg_t pc;
+struct __aligned(16) trapframe {
+ lreg_t x30;
+ lreg_t x29;
+ lreg_t x28;
+ lreg_t x27;
+ lreg_t x26;
+ lreg_t x25;
+ lreg_t x24;
+ lreg_t x23;
+ lreg_t x22;
+ lreg_t x21;
+ lreg_t x20;
+ lreg_t x19;
+ lreg_t x18;
+ lreg_t x17;
+ lreg_t x16;
+ lreg_t x15;
+ lreg_t x14;
+ lreg_t x13;
+ lreg_t x12;
+ lreg_t x11;
+ lreg_t x10;
+ lreg_t x9;
+ lreg_t x8;
+ lreg_t x7;
+ lreg_t x6;
+ lreg_t x5;
+ lreg_t x4;
+ lreg_t x3;
+ lreg_t x2;
+ lreg_t x1;
+ lreg_t x0;
+ lreg_t elr;
+ lreg_t esr;
+ frament_t trapno;
};
#define TF_IP(TFP) ((TFP)->pc)
diff --git a/sys/include/arch/aarch64/frameasm.h b/sys/include/arch/aarch64/frameasm.h
index 5664ff5..ca7f81a 100644
--- a/sys/include/arch/aarch64/frameasm.h
+++ b/sys/include/arch/aarch64/frameasm.h
@@ -31,13 +31,14 @@
#define _MACHINE_FRAMEASM_H_
/* XXX: Must be 16-byte aligned!!! */
-#define XFRAME_STACK_SIZE (34 * 8)
+#define XFRAME_STACK_SIZE (38 * 8)
/* Trap numbers */
-#define TRAPNO_XSYNC #0 /* Synchronous */
-#define TRAPNO_XIRQ #1 /* IRQ */
-#define TRAPNO_XFIQ #2 /* FIQ */
-#define TRAPNO_XSERR #3 /* System error */
+#define TRAPNO_UNKNOWN #0
+#define TRAPNO_XSYNC #1 /* Synchronous */
+#define TRAPNO_XIRQ #2 /* IRQ */
+#define TRAPNO_XFIQ #3 /* FIQ */
+#define TRAPNO_XSERR #4 /* System error */
#define PUSH_XFRAME(TRAPNO) \
sub sp, sp, #XFRAME_STACK_SIZE ; \
@@ -57,11 +58,16 @@
stp x4, x3, [sp, #(26 * 8)] ; \
stp x2, x1, [sp, #(28 * 8)] ; \
str x0, [sp, #(30 * 8)] ; \
+ ; \
+ mrs x0, elr_el1 ; \
+ str x0, [sp, #(31 * 8)] ; \
+ mrs x0, esr_el1 ; \
+ str x0, [sp, #(32 * 8)] ; \
mov x0, TRAPNO ; \
- str x0, [sp, #(31 * 8)]
+ str x0, [sp, #(33 * 8)] ; \
+ mov x0, sp
#define POP_XFRAME() \
- add sp, sp, #8 ; \
ldr x0, [sp, #(30 * 8)] ; \
ldp x2, x1, [sp, #(28 * 8)] ; \
ldp x4, x3, [sp, #(26 * 8)] ; \
@@ -78,5 +84,6 @@
ldp x26, x25, [sp, #(4 * 8)] ; \
ldp x28, x27, [sp, #(2 * 8)] ; \
ldp x30, x29, [sp, #(0 * 8)] ; \
+ add sp, sp, #XFRAME_STACK_SIZE
#endif /* !_MACHINE_FRAMEASM_H_ */