Module Name:    src
Committed By:   scole
Date:           Sat Apr  8 17:38:44 UTC 2017

Modified Files:
        src/sys/arch/ia64/ia64: context.S vm_machdep.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/ia64/ia64/context.S
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/ia64/ia64/vm_machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/ia64/ia64/context.S
diff -u src/sys/arch/ia64/ia64/context.S:1.7 src/sys/arch/ia64/ia64/context.S:1.8
--- src/sys/arch/ia64/ia64/context.S:1.7	Mon Dec 26 19:46:59 2016
+++ src/sys/arch/ia64/ia64/context.S	Sat Apr  8 17:38:43 2017
@@ -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 @@ ENTRY(restore_high_fp, 1)
 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

Index: src/sys/arch/ia64/ia64/vm_machdep.c
diff -u src/sys/arch/ia64/ia64/vm_machdep.c:1.12 src/sys/arch/ia64/ia64/vm_machdep.c:1.13
--- src/sys/arch/ia64/ia64/vm_machdep.c:1.12	Fri Aug 12 02:08:20 2016
+++ src/sys/arch/ia64/ia64/vm_machdep.c	Sat Apr  8 17:38:43 2017
@@ -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 @@ cpu_lwp_free2(struct lwp *l)
 }
 
 /*
+ * 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 @@ cpu_lwp_fork(struct lwp *l1, struct lwp 
     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);
 	}

Reply via email to