Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/aarch64/aarch64 make them better shape



details:   https://anonhg.NetBSD.org/src/rev/8dcb1cb21f43
branches:  trunk
changeset: 826276:8dcb1cb21f43
user:      nisimura <nisimura%NetBSD.org@localhost>
date:      Fri Aug 25 21:43:49 2017 +0000

description:
make them better shape

diffstat:

 sys/arch/aarch64/aarch64/locore.S |  173 ++++++++++++++++++++++++++++---------
 1 files changed, 131 insertions(+), 42 deletions(-)

diffs (277 lines):

diff -r 834e351d708c -r 8dcb1cb21f43 sys/arch/aarch64/aarch64/locore.S
--- a/sys/arch/aarch64/aarch64/locore.S Fri Aug 25 20:36:16 2017 +0000
+++ b/sys/arch/aarch64/aarch64/locore.S Fri Aug 25 21:43:49 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.S,v 1.2 2017/08/16 22:49:05 nisimura Exp $ */
+/* $NetBSD: locore.S,v 1.3 2017/08/25 21:43:49 nisimura Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -34,10 +34,16 @@
 
 #include "opt_ddb.h"
 
-RCSID("$NetBSD: locore.S,v 1.2 2017/08/16 22:49:05 nisimura Exp $")
+RCSID("$NetBSD: locore.S,v 1.3 2017/08/25 21:43:49 nisimura Exp $")
 
 // XXX:AARCH64
 lr     .req    x30
+       .macro DISABLE_INTERRUPT
+       msr     daifset, #DAIF_I|DAIF_F         /* daif'set */
+       .endm
+       .macro ENABLE_INTERRUPT
+       msr     daifclr, #DAIF_I|DAIF_F         /* daif'clr */
+       .endm
 
 /*
  * At IPL_SCHED:
@@ -50,9 +56,9 @@
        cbz     x0, .Lrestore_lwp
 
        /*
-        * Store the callee saved register on the stack in a trapframe
+        * Store the callee saved register on the stack.
         */
-       sub     sp, sp, #TF_SIZE
+       sub     sp, sp, #TF_SIZE                /* make switchframe */
        stp     x19, x20, [sp, #TF_X19]
        stp     x21, x22, [sp, #TF_X21]
        stp     x23, x24, [sp, #TF_X23]
@@ -61,20 +67,20 @@
        stp     x29, x30, [sp, #TF_X29]
 
        /*
-        * Get the previous trapframe pointer and the user writeable Thread ID
-        * register and save them in the trap frame.
+        * Save the previous trapframe pointer and EL0 thread ID in the
+        * switchframe.
         */
        ldr     x5, [x0, #L_MD_KTF]
        mrs     x4, tpidr_el0
 #if TF_TPIDR + 8 == TF_CHAIN
-       str     x4, x5, [sp, #TF_TPIDR]
+       stp     x4, x5, [sp, #TF_TPIDR]
 #else
        str     x4, [sp, #TF_TPIDR]
        str     x5, [sp, #TF_CHAIN]
 #endif
 
        /*
-        * Get the current stack pointer and the CPACR and save them in
+        * Save the current stack pointer and the CPACR and save them in
         * old lwp md area.
         */
        mov     x4, sp 
@@ -90,48 +96,109 @@
 
 .Lrestore_lwp:
 #if L_MD_KTF + 8 == L_MD_CPACR
-       ldp     x4, x5, [x1, #L_MD_KTF] // get trapframe ptr and cpacr_el1
+       ldp     x4, x5, [x1, #L_MD_KTF] /* get trapframe ptr and cpacr_el1 */
 #else
-       ldr     x4, [x0, #L_MD_KTF]     // get trapframe ptr (aka SP)
-       ldr     x5, [x0, #L_MD_CPACR]   // get cpacr_el1
+       ldr     x4, [x1, #L_MD_KTF]     /* get trapframe ptr (aka SP) */
+       ldr     x5, [x1, #L_MD_CPACR]   /* get cpacr_el1 */
 #endif
-       mov     sp, x4                  // restore stack pointer
-       msr     cpacr_el1, x5           // restore cpacr_el1
+       mov     sp, x4                  /* restore stack pointer */
+       msr     cpacr_el1, x5           /* restore cpacr_el1 */
 
-       ldr     x4, [sp, #TF_TPIDR]     // load user writeable thread ip reg
-       msr     tpidr_el0, x4           // restore it
+       ldr     x4, [sp, #TF_TPIDR]
+       msr     tpidr_el0, x4           /* restore EL0 thread ID */
 
-       mrs     x3, tpidr_el1           // get curcpu
-       str     x1, [x3, #CI_CURLWP]    // show as curlwp
+       mrs     x3, tpidr_el1
+       str     x1, [x3, #CI_CURLWP]    /* switch curlwp to new lwp */
 
        /*
-        * Restore callee save registers
+        * Restore callee save registers.
         */
        ldp     x19, x20, [sp, #TF_X19]
        ldp     x21, x22, [sp, #TF_X21]
        ldp     x23, x24, [sp, #TF_X23]
        ldp     x25, x26, [sp, #TF_X25]
        ldp     x27, x28, [sp, #TF_X27]
-       ldp     x29, x30, [sp, #TF_X29]
-       add     sp, sp, #TF_SIZE        /* pop trapframe from stack */
+       ldp     x29, lr, [sp, #TF_X29]
+       add     sp, sp, #TF_SIZE        /* unwind switchframe */
 
        ret
 END(cpu_switchto)
 
 /*
- *     x0 = lwp
- *     x1 = ipl
+ * void
+ * cpu_switchto_softint(struct lwp *softlwp, int ipl)
+ * {
+ *     build a switchframe on kernel stack.
+ *     craft TF_X30 to have softint_cleanup.
+ *     pinned_lwp = curlwp
+ *     switch to softlwp context.
+ *     call softint_dispatch(pinned_lwp, ipl);
+ *     switch back to pinned_lwp context.
+ *     unwind switchframe made on kernel stack.
+ *     return to caller this time.
+ * }
  */
 ENTRY_NP(cpu_switchto_softint)
-//
-//XXXAARCH64
-//
+       sub     sp, sp, #TF_SIZE        /* make switchframe */
+       adr     x2, softint_cleanup
+       stp     x19, x20, [sp, #TF_X19]
+       stp     x21, x22, [sp, #TF_X21]
+       stp     x23, x24, [sp, #TF_X23]
+       stp     x25, x26, [sp, #TF_X25]
+       stp     x27, x28, [sp, #TF_X27]
+       stp     x29, x2, [sp, #TF_X29]  /* tf->lr = softint_cleanup; */
+
+       mrs     x3, tpidr_el1
+       ldr     x2, [x3, #CI_CURLWP]    /* x2 := curcpu()->ci_curlwp */
+       mov     x4, sp                  /* x4 := sp */
+       DISABLE_INTERRUPT
+       str     x4, [x2, #L_MD_KTF]     /* curlwp->l_md_ktf := sp */
+       str     x0, [x3, #CI_CURLWP]    /* curcpu()->ci_curlwp = softlwp; */
+       ldr     x4, [x0, #L_MD_KTF]     /* switch to softlwp stack */
+       mov     sp, x4                  /* new sp := softlwp->l_md_ktf */
+       ENABLE_INTERRUPT
+       mov     x19, x2                 /* x19 := pinned_lwp */
+       mov     x20, lr                 /* x20 := original lr */
+
+       /* softint_dispatch(pinned_lwp, ipl) */
+       mov     x0, x19
+       bl      _C_LABEL(softint_dispatch)
+
+       mrs     x3, tpidr_el1
+       DISABLE_INTERRUPT
+       str     x19, [x3, #CI_CURLWP]   /* curcpu()->ci_curlwp := x19 */
+       ldr     x4, [x19, #L_MD_KTF]    /* x4 := curlwp->l_md_ktf */
+       mov     sp, x4                  /* restore pinned_lwp sp */
+       ENABLE_INTERRUPT
+       mov     lr, x20                 /* restore pinned_lwp lr */
+       ldp     x19, x20, [sp, #TF_X19] /* restore x19 and x20 */
+       add     sp, sp, #TF_SIZE        /* unwind switchframe */
        ret
 END(cpu_switchto_softint)
 
+/*
+ * void
+ * softint_cleanup(struct lwp *softlwp)
+ * {
+ *     cpu_switchto() bottom half arranges to start this when softlwp.
+ *     kernel thread is to yield CPU for the pinned_lwp in the above.
+ *     curcpu()->ci_mtx_count += 1;
+ *     softlwp->l_ctxswtch = 0;
+ *     this returns as if cpu_switchto_softint finished normally.
+ * }
+ */
+ENTRY_NP(softint_cleanup)
+       mrs     x3, tpidr_el1           /* curcpu() */
+       ldr     w2, [x3, #CI_MTX_COUNT] /* ->ci_mtx_count */
+       add     w2, w2, #1
+       str     w2, [x3, #CI_MTX_COUNT]
+       str     wzr, [x0, #L_CTXSWTCH]  /* softlwp->l_ctxswtch = 0 */
+       add     sp, sp, #TF_SIZE        /* unwind switchframe */
+       ret
+END(softint_cleanup)
 
 /*
- * Called at IPL_SCHED
+ * Called at IPL_SCHED:
  *     x0 = old lwp (from cpu_switchto)
  *     x1 = new lwp (from cpu_switchto)
  *     x27 = func
@@ -161,6 +228,7 @@
  * a syscall return.
  */
 ENTRY_NP(exception_trap_exit)
+       /* XXX critial section guarded by SR.EXL if it was MIPS XXX */
        ldp     x0, x1, [sp, #TF_X0]
        ldp     x2, x3, [sp, #TF_X2]
        ldp     x4, x5, [sp, #TF_X4]
@@ -169,20 +237,18 @@
        ldp     x10, x11, [sp, #TF_X10]
        ldp     x12, x13, [sp, #TF_X12]
        ldp     x14, x15, [sp, #TF_X14]
-exception_syscall_exit:
        ldp     x16, x17, [sp, #TF_X16]
        ldr     x18, [sp, #TF_X18]
 
-#if TF_SP + 8 == TF_PC
-       ldp     x20, x21, [sp, #TF_SP]
-#else
-       ldr     x20, [sp, #TF_SP]
-       ldr     x21, [sp, #TF_PC]
-#endif
-       ldr     x22, [sp, #TF_SPSR]
-       msr     sp_el0, x20
-       msr     elr_el1, x21
-       msr     spsr_el1, x22
+       ldr     x20, [sp, #TF_PC]
+       ldr     x21, [sp, #TF_SPSR]
+       msr     elr_el1, x20            /* exception pc */
+       msr     spsr_el1, x21           /* exception pstate */
+
+       and     x21, x21, #1
+       cbz     x21, .Lkernelexception
+       ldr     x22, [sp, #TF_SP]
+       msr     sp_el0, x22             /* restore EL0 stack */
 
        ldp     x19, x20, [sp, #TF_X19]
        ldp     x21, x22, [sp, #TF_X21]
@@ -190,11 +256,16 @@
        ldp     x25, x26, [sp, #TF_X25]
        ldp     x27, x28, [sp, #TF_X27]
        ldp     x29, x30, [sp, #TF_X29]
-
-       /*
-        * Don't adjust the stack for the trapframe since we would
-        * just add subtract it again upon exception entry.
-        */
+       /* EL1 sp stays at l_md_utf */
+       eret
+ .Lkernelexception:
+       ldp     x19, x20, [sp, #TF_X19]
+       ldp     x21, x22, [sp, #TF_X21]
+       ldp     x23, x24, [sp, #TF_X23]
+       ldp     x25, x26, [sp, #TF_X25]
+       ldp     x27, x28, [sp, #TF_X27]
+       ldp     x29, x30, [sp, #TF_X29]
+       add     sp, sp, #TF_SIZE        /* unwind trapframe on stack */
        eret
 END(exception_trap_exit)
 
@@ -205,6 +276,24 @@
 END(cpu_Debugger)
 #endif /* DDB */
 
+#ifdef MULTIPROCESSOR
+/*
+ * void
+ * cpu_spinup_trampoline(int cpu_index)
+ * {
+ *      ci := tp == cpu_info[cpu_index]
+ *      ci->ci_curlwp = ci->ci_data.ci_idlelwp;
+ *      sp := ci->ci_curlwp->l_addr + USPACE - sizeof(struct trapframe)
+ *      cpu_hatch(ci);
+ *      jump to idle_loop() to join the cpu pool.
+ * }
+ */
+ENTRY(cpu_spinup_trampoline)
+       bl      _C_LABEL(cpu_hatch)
+       b       _C_LABEL(cpu_idle)
+END(cpu_spinup_trampoline)
+#endif
+
 /*
  * int cpu_set_onfault(struct faultbuf *fb, register_t retval)
  */



Home | Main Index | Thread Index | Old Index