adjust exec_param to keep track of sp_el0, fix incorrect use sys regs
authorLunaixsky <lunaixsky@qq.com>
Wed, 2 Oct 2024 16:38:42 +0000 (17:38 +0100)
committerLunaixsky <lunaixsky@qq.com>
Wed, 2 Oct 2024 16:42:07 +0000 (17:42 +0100)
* rename BITS to BITFIELD for better clarity
* allow architecturally optimisation to override the default BITS ops
* implement the trace utility for arm64

12 files changed:
lunaix-os/arch/aarch64/LBuild
lunaix-os/arch/aarch64/exception/context.S
lunaix-os/arch/aarch64/exception/handler.c
lunaix-os/arch/aarch64/fault.c [new file with mode: 0644]
lunaix-os/arch/aarch64/includes/asm/aa64_exception.h
lunaix-os/arch/aarch64/includes/asm/aa64_spsr.h
lunaix-os/arch/aarch64/includes/asm/abi.h
lunaix-os/arch/aarch64/includes/asm/bits.h [new file with mode: 0644]
lunaix-os/arch/aarch64/includes/asm/hart.h
lunaix-os/arch/aarch64/trace.c [new file with mode: 0644]
lunaix-os/arch/generic/includes/asm-generic/bits.h [new file with mode: 0644]
lunaix-os/includes/lunaix/bits.h

index 7526610d39c8ef4c367fe4cb66aa58ce0ad0ab69..52b347958737924c9024662c08589a3d8ee48f0b 100644 (file)
@@ -11,6 +11,11 @@ sources([
     "exception/handler.c"
 ])
 
+sources([
+    "fault.c",
+    "trace.c"
+])
+
 compile_opts([
     "-mlittle-endian",
     "-mgeneral-regs-only",
index cbb7cf4a823cd4873893542eb88faad5eba0f61e..fd8584991b6ce274f50e8c2832ef1098c06b5bf6 100644 (file)
@@ -8,8 +8,10 @@
     .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]
index ab2b80674c7d0e773ed562f1d254904fc41d2c2e..0c861bbc6e4c2b33c79938ae3c5577ef41db13d8 100644 (file)
@@ -1,5 +1,7 @@
 #include <lunaix/process.h>
 #include <asm/hart.h>
+#include <asm/aa64_exception.h>
+
 
 static inline void
 update_thread_context(struct hart_state* state)
@@ -10,18 +12,56 @@ 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
diff --git a/lunaix-os/arch/aarch64/fault.c b/lunaix-os/arch/aarch64/fault.c
new file mode 100644 (file)
index 0000000..e551d68
--- /dev/null
@@ -0,0 +1,9 @@
+#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
index 5ed810410abbddb0bd6e9f8747e671154d5489c1..db74b8869cf4e00aca66491e3af782d0eca0317d 100644 (file)
@@ -1,22 +1,20 @@
 #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
index 07a807a58afb5a016a752c421986b3a3350420e5..8b5b46fae92cb6cbb2785470211932204fbbbfa5 100644 (file)
@@ -4,7 +4,7 @@
 #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
index c5dc081b4973a9633c218a00a4d6c351e1d7c591..7f8d83d545563075799cacee0f7a52b65b92324c 100644 (file)
@@ -4,7 +4,7 @@
 #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() {
diff --git a/lunaix-os/arch/aarch64/includes/asm/bits.h b/lunaix-os/arch/aarch64/includes/asm/bits.h
new file mode 100644 (file)
index 0000000..a30f254
--- /dev/null
@@ -0,0 +1,31 @@
+#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 */
index 89a2e9ae881574564f2d36e4fa09f44107676f72..ae84ddd13c70c373f7bda587d324f626ff522784 100644 (file)
@@ -6,7 +6,7 @@
 #include <lunaix/bits.h>
 #include <asm/aa64_spsr.h>
 
-#define SYNDROME_ETYPE  BITS(63, 56)
+#define SYNDROME_ETYPE  BITFIELD(63, 56)
 
 struct hart_state;
 
diff --git a/lunaix-os/arch/aarch64/trace.c b/lunaix-os/arch/aarch64/trace.c
new file mode 100644 (file)
index 0000000..1930003
--- /dev/null
@@ -0,0 +1,76 @@
+#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
diff --git a/lunaix-os/arch/generic/includes/asm-generic/bits.h b/lunaix-os/arch/generic/includes/asm-generic/bits.h
new file mode 100644 (file)
index 0000000..430e395
--- /dev/null
@@ -0,0 +1,13 @@
+#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 */
index 1029bb08bfd314e97cf74678efb748499fe2ef9b..ddc28004945fac665a3182a3f3190d09749a168b 100644 (file)
@@ -2,13 +2,16 @@
 #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 */