"exception/handler.c"
])
+sources([
+ "fault.c",
+ "trace.c"
+])
+
compile_opts([
"-mlittle-endian",
"-mgeneral-regs-only",
.globl _aa64_switch_task
_aa64_evec_prehandle:
- stp xzr, elr, [sp, #-16]! # push {xzr , elr}
- stp spsr, xzr, [sp, #-16]! # push {spsr, xzr}
+ # reservation for struct exec_param
+ sub sp, sp, #8 # push sp_el1
+ sub sp, sp, #16 # push {sp_el0, link}
+ sub sp, sp, #16 # push {spsr, parent_hart}
stp lr, fp, [sp, #-16]! # push {x31-x1}
stp x28, x27, [sp, #-16]!
mrs x0, SP_EL0
str x0, [x1, #execp_spel0_saved]
+
+ mrs x0, ELR_E1
+ str x0, [x1, #execp_link]
+
+ mrs x0, SPSR_EL1
+ str x0, [x1, #execp_spsr]
sub x0, sp, #hart_end
str x0, [x1, #execp_spel1_saved]
#include <lunaix/process.h>
#include <asm/hart.h>
+#include <asm/aa64_exception.h>
+
static inline void
update_thread_context(struct hart_state* state)
struct hart_state* parent = current_thread->hstate;
hart_push_state(parent, state);
+
current_thread->hstate = state;
+ current_thread->ustack_top = state->execp.sp_el0;
if (parent) {
state->depth = parent->depth + 1;
}
}
+extern void
+handle_mm_abort(struct hart_state* state);
+
+static void
+handle_sync_exception(struct hart_state* hstate)
+{
+ unsigned int ec;
+
+ ec = esr_ec(hstate->execp.syndrome);
+
+ switch (ec)
+ {
+ case EC_I_ABORT:
+ case EC_D_ABORT:
+ case EC_I_ABORT_EL:
+ case EC_D_ABORT_EL:
+ handle_mm_abort(hstate);
+ break;
+
+ default:
+ fail("unhandled exception (synced)");
+ break;
+ }
+}
+
+static void
+handle_async_exception(struct hart_state* hstate)
+{
+
+}
struct hart_state*
handle_exception(struct hart_state* hstate)
{
update_thread_context(hstate);
+ if (hart_vector_stamp(hstate) == EXCEPTION_SYNC) {
+ handle_sync_exception(hstate);
+ } else {
+ handle_async_exception(hstate);
+ }
+
return hstate;
}
\ No newline at end of file
--- /dev/null
+#include <lunaix/mm/fault.h>
+#include <asm/aa64_exception.h>
+#include <asm/hart.h>
+
+void
+handle_mm_abort(struct hart_state* state)
+{
+ // TODO
+}
\ No newline at end of file
#ifndef __LUNAIX_AA64_ESR_H
#define __LUNAIX_AA64_ESR_H
-#ifdef __ASM__
-
#define EXCEPTION_SYNC 0
-#define EXCEPTION_IFQ 1
+#define EXCEPTION_FIQ 1
#define EXCEPTION_IRQ 2
#define EXCEPTION_SERR 3
-#else
+#ifndef __ASM__
#include <lunaix/bits.h>
#include <lunaix/types.h>
-#define ESR_ISS2 BITS(55, 32)
-#define ESR_EC BITS(31, 26)
+#define ESR_ISS2 BITFIELD(55, 32)
+#define ESR_EC BITFIELD(31, 26)
#define ESR_IL BIT(25)
-#define ESR_ISS BITS(24, 0)
+#define ESR_ISS BITFIELD(24, 0)
#define EC_UNKNOWN 0b000000
#define EC_WF 0b000001
#include <lunaix/types.h>
#include <lunaix/bits.h>
-#define SPSR_EL BITS(3, 2)
+#define SPSR_EL BITFIELD(3, 2)
#define SPSR_SP BIT(0)
static inline bool
#include <lunaix/types.h>
#ifndef __ASM__
-#define align_stack(ptr) ((ptr) & stack_alignment)
+#define align_stack(ptr) ((ptr) & ~15)
static inline void must_inline noret
switch_context() {
--- /dev/null
+#ifndef __LUNAIX_ARCH_BITS_H
+#define __LUNAIX_ARCH_BITS_H
+
+#include <asm-generic/bits.h>
+
+#undef _BITS_EXTRACT
+#undef _BITS_INSERT
+
+#define _BITS_EXTRACT(from, h, l) \
+ ({ \
+ unsigned long _r; \
+ asm ("ubfm %0, %1, %2, %3" \
+ : "=r"(_r) \
+ : "r"(from) \
+ "i"(l) "i"(h)); \
+ _r; \
+ })
+
+#define _BITS_INSERT(to, from, h, l) \
+ ({ \
+ unsigned long _r = to; \
+ asm ("bfi %0, %1, %2, %3" \
+ : "=r"(_r) \
+ : "r"(from) \
+ "i"(l) \
+ "i"(h - l + 1)); \
+ _r; \
+ })
+
+
+#endif /* __LUNAIX_ARCH_BITS_H */
#include <lunaix/bits.h>
#include <asm/aa64_spsr.h>
-#define SYNDROME_ETYPE BITS(63, 56)
+#define SYNDROME_ETYPE BITFIELD(63, 56)
struct hart_state;
--- /dev/null
+#include <lunaix/trace.h>
+#include <asm/aa64_exception.h>
+#include <sys-generic/trace_arch.h>
+
+static inline char*
+__type_name(reg_t syndrome)
+{
+ switch (hart_vector_stamp(syndrome))
+ {
+ case EXCEPTION_SYNC:
+ return "sync";
+ case EXCEPTION_IRQ:
+ return "async (irq)";
+ case EXCEPTION_FIQ:
+ return "async (fiq)";
+ case EXCEPTION_SERR:
+ return "async (serr)";
+ }
+
+ return "unknwon";
+}
+
+void
+trace_print_transistion_short(struct hart_state* hstate)
+{
+ struct exec_param* execp;
+ reg_t syndrome;
+
+ execp = &hstate->execp;
+ syndrome = execp->syndrome;
+
+ trace_log("%s from EL%d: ec=%04x, iss=%08lx, il=%d",
+ __type_name(syndrome), !spsr_from_el0(execp->syndrome),
+ esr_ec(syndrome), esr_iss(syndrome), esr_inst32(syndrome));
+}
+
+void
+trace_print_transition_full(struct hart_state* hstate)
+{
+ struct exec_param* execp;
+ reg_t syndrome;
+
+ execp = &hstate->execp;
+ syndrome = execp->syndrome;
+
+ trace_log("exception %s from EL%d",
+ __type_name(syndrome), !spsr_from_el0(execp->syndrome));
+ trace_log(" ec=0x%08lx, iss=0x%08lx, il=%d",
+ esr_ec(syndrome), esr_iss(syndrome), esr_inst32(syndrome));
+ trace_log(" esr=0x%016lx, spsr=0x%016lx",
+ syndrome, execp->spsr);
+ trace_log(" sp_el0=0x%016lx, sp_el1=0x%016lx",
+ execp->sp_el0, execp->sp_el1);
+ trace_log(" pc=0x%016lx", execp->link);
+}
+
+void
+trace_dump_state(struct hart_state* hstate)
+{
+ struct regcontext* r;
+
+ r = &hstate->registers;
+
+ trace_log("hart state dump (depth=%d)", hstate->depth);
+
+ for (int i = 0; i < 30; i+=3)
+ {
+ trace_log(" x%02d=0x%016lx x%02d=0x%016lx x%02d=0x%016lx",
+ i, r->x[i],
+ i + 1, r->x[i + 1],
+ i + 2, r->x[i + 2]);
+ }
+
+ trace_log(" x30=0x%016lx x31=0x%016lx (sp)",
+ r->x[30], hart_sp(hstate));
+}
\ No newline at end of file
--- /dev/null
+#ifndef __LUNAIX_ARCH_GENERIC_BITS_H
+#define __LUNAIX_ARCH_GENERIC_BITS_H
+
+#define _BITS_GENMASK(h, l) \
+ (((1UL << ((h) + 1)) - 1) ^ ((1UL << (l)) - 1))
+
+#define _BITS_EXTRACT(from, h, l) \
+ (((from) & (((1UL << (h + 1)) - 1) ^ ((1UL << l) - 1))) >> l)
+
+#define _BITS_INSERT(to, from, h, l) \
+ (((to) & ~_BITS_GENMASK(h, l)) | (((from) << l) & _BITS_GENMASK(h, l)))
+
+#endif /* __LUNAIX_ARCH_BITS_H */
#define __LUNAIX_BITS_H
#include <lunaix/compiler.h>
+#include <asm/bits.h>
-#define BITS(h, l) (((1UL << ((h) + 1)) - 1) ^ ((1UL << (l)) - 1))
-#define BIT(p) BITS(p, p)
+#define BITFIELD(h, l) (h), (l)
-#define BITS_GET(from, bits) (((from) & (bits)) >> ctzl(bits))
+#define BIT(p) BITFIELD(p, p)
-#define BITS_SET(to, bits, val) \
- (((to) & ~(bits)) | (((val) << ctzl(bits)) & (bits)))
+#define BITS_GENMASK(bits) _BITS_GENMASK(bits)
+
+#define BITS_GET(from, bits) _BITS_EXTRACT(from, bits)
+
+#define BITS_SET(to, bits, val) _BITS_INSERT(to, val, bits)
#endif /* __LUNAIX_BITS_H */