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/e97960a220e4
branches: trunk
changeset: 355975:e97960a220e4
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 9c76914b8697 -r e97960a220e4 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