Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/ia64/ia64 Convert cpu_switchto() from assembly to C...
details: https://anonhg.NetBSD.org/src/rev/0addcbbdf83b
branches: trunk
changeset: 352554:0addcbbdf83b
user: scole <scole%NetBSD.org@localhost>
date: Sat Apr 08 17:38:43 2017 +0000
description:
Convert cpu_switchto() from assembly to C code. Remove comment about
possible cpu_switchto() bug. Actual issue appears to be new processes
using lwp0 instead of own memory, which is still not fixed.
Thanks to <chs> for figuring this out.
diffstat:
sys/arch/ia64/ia64/context.S | 88 +----------------------------------------
sys/arch/ia64/ia64/vm_machdep.c | 49 +++++++++++++++++++---
2 files changed, 43 insertions(+), 94 deletions(-)
diffs (191 lines):
diff -r b2ac6b0b2949 -r 0addcbbdf83b sys/arch/ia64/ia64/context.S
--- a/sys/arch/ia64/ia64/context.S Sat Apr 08 17:04:56 2017 +0000
+++ b/sys/arch/ia64/ia64/context.S Sat Apr 08 17:38:43 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: context.S,v 1.7 2016/12/26 19:46:59 scole Exp $ */
+/* $NetBSD: context.S,v 1.8 2017/04/08 17:38:43 scole Exp $ */
/*
* Copyright (c) 2003 Marcel Moolenaar
@@ -806,93 +806,9 @@
END(restore_high_fp)
/*
- * lwp_t *
- * cpu_switchto(lwp_t *oldlwp, lwp_t *newlwp, bool returning)
- *
- * Switch to the specified next LWP
- * in0 is oldlwp
- * in1 is newlwp
- */
-ENTRY(cpu_switchto, 3)
-{ .mmi
- alloc loc0=ar.pfs,3,2,2,0
-
- /*
- * Save old context, unless the LWP is exiting.
- */
- cmp.eq p6,p0=r0,in0 // p6 = (in0 == 0)
- add r14=PC_CURLWP,r13 // r14 = &ci->ci_curlwp
- ;;
-}
-{ .mii
- add r2=L_PCB,in0 // r2 = lwp_getpcb(&oldlwp)
- add r3=L_PCB,in1 // r3 = lwp_getpcb(&newlwp)
- mov loc1=rp // save rp (loc1 = rp)
- ;;
-}
-{ .mmi
- st8 [r14]=in1 // ci->ci_curlwp = newlwp
- mov r9=in0 // r9 = oldlwp
- nop 0
- ;;
-}
-{ .mmb
- nop 0
- /*
- * Switch to new context, if p6 == true.
- * We assume to return to restorectx_return_here for swapped context.
- */
-(p6) ld8 out0=[r3] // out0 = pcb of &newlwp
-(p6) br.call.sptk.many rp=restorectx // if (p6) restorectx(out0)
- ;;
-}
-{ .mmb
- /*
- * Swap to new context.
- */
- ld8 out0=[r2]
- ld8 out1=[r3]
- br.call.sptk.many rp=swapctx
- ;;
-}
- /*
- * XXX seems to be a bug here...
- *
- * swapctx() and restorectx() (which is called by swapctx())
- * both adjust the bspstore (and hence bsp) registers. When
- * returning to "restorectx_return_here:" the bspstore can
- * be greater than bsp, a state known as an "Incomplete Register Frame".
- *
- * That is not necessarily fatal in itself, but apparently the RSE
- * engine sets bsp=bspstore to adjust, which re-syncs the stacked
- * registers (r32-r127). This clobbers our local registers below
- * (loc0 and loc1) on the br return from swapctx(), and you get all
- * kind of mysterious exceptions depeding on what gets restored from
- * the backing store.
- *
- * Not sure of a proper fix is yet or how cpu_switchto should/can
- * be interacting with restorectx()/swapctx()
- *
- */
-restorectx_return_here:
-{ .mib
- mov r8=r9 // r8(ret0) = oldlwp
- mov rp=loc1
- nop 0
- ;;
-}
-{ .mib
- nop 0
- mov ar.pfs=loc0
- br.ret.sptk.many rp
- ;;
-}
-END(cpu_switchto)
-
-/*
* lwp_trampoline()
*
- * Arrange for a function to be invoked neatly, after a cpu_switch().
+ * Arrange for a function to be invoked neatly, after a cpu_switchto().
*
* Invokes fork_exit() passing in three arguments: a callout function, an
* argument to the callout, and a trapframe pointer. For child processes
diff -r b2ac6b0b2949 -r 0addcbbdf83b sys/arch/ia64/ia64/vm_machdep.c
--- a/sys/arch/ia64/ia64/vm_machdep.c Sat Apr 08 17:04:56 2017 +0000
+++ b/sys/arch/ia64/ia64/vm_machdep.c Sat Apr 08 17:38:43 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vm_machdep.c,v 1.12 2016/08/12 02:08:20 scole Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.13 2017/04/08 17:38:43 scole Exp $ */
/*
* Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -36,6 +36,7 @@
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/systm.h>
+#include <sys/cpu.h>
#include <machine/frame.h>
#include <machine/md_var.h>
@@ -62,11 +63,44 @@
}
/*
+ * The cpu_switchto() function saves the context of the LWP which is
+ * currently running on the processor, and restores the context of the LWP
+ * specified by newlwp. man cpu_switchto(9)
+ */
+lwp_t *
+cpu_switchto(lwp_t *oldlwp, lwp_t *newlwp, bool returning)
+{
+ const struct lwp *l = curlwp;
+ struct pcb *oldpcb = oldlwp ? lwp_getpcb(oldlwp) : NULL;
+ struct pcb *newpcb = lwp_getpcb(newlwp);
+ struct cpu_info *ci = curcpu();
+ register uint64_t reg9 __asm("r9");
+
+ KASSERT(newlwp != NULL);
+
+ ci->ci_curlwp = newlwp;
+
+ /* required for lwp_startup, copy oldlwp into r9, "mov r9=in0" */
+ __asm __volatile("mov %0=%1" : "=r"(reg9) : "r"(oldlwp));
+
+ /* XXX handle RAS eventually */
+
+ if (oldlwp == NULL) {
+ restorectx(newpcb);
+ } else {
+ KASSERT(oldlwp == l);
+ swapctx(oldpcb, newpcb);
+ }
+
+ return (oldlwp);
+}
+
+/*
* Finish a fork operation, with process p2 nearly set up.
* Copy and update the pcb and trap frame, making the child ready to run.
*
* Rig the child's kernel stack so that it will start out in
- * proc_trampoline() and call child_return() with p2 as an
+ * lwp_trampoline() and call child_return() with p2 as an
* argument. This causes the newly-created child process to go
* directly to user level with an apparent return value of 0 from
* fork(), while the parent process returns normally.
@@ -84,18 +118,17 @@
void (*func)(void *), void *arg)
{
struct pcb *pcb1, *pcb2;
- struct trapframe * volatile tf;
-
+ struct trapframe *tf;
+
pcb1 = lwp_getpcb(l1);
pcb2 = lwp_getpcb(l2);
/* Copy pcb from lwp l1 to l2. */
if (l1 == curlwp) {
/* Sync the PCB before we copy it. */
- savectx(pcb1);
-#if 0
- /* ia64_highfp_save(???); */
-#endif
+ if (savectx(pcb1) != 0)
+ panic("unexpected return from savectx");
+ /* ia64_highfp_save(td1); XXX */
} else {
KASSERT(l1 == &lwp0);
}
Home |
Main Index |
Thread Index |
Old Index