Module Name:    src
Committed By:   scole
Date:           Wed Nov 14 21:10:59 UTC 2018

Modified Files:
        src/sys/arch/ia64/ia64: locore.S machdep.c syscall.c vm_machdep.c
        src/sys/arch/ia64/include: md_var.h proc.h

Log Message:
- When forking, use own register stack for each thread
- For UAREA, arrange layout same as FreeBSD for now to hopefully
  ease porting woes.  add some related macros
  locore.S is incorrectly assuming same layout and seems painful
  to change bspstore in startup
- use ia64_init_return same as FreeBSD
- change some "printf" to "panic" for incompleted items

context switching is still broken but maybe less so


To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/ia64/ia64/locore.S
cvs rdiff -u -r1.38 -r1.39 src/sys/arch/ia64/ia64/machdep.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/ia64/ia64/syscall.c
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/ia64/ia64/vm_machdep.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/ia64/include/md_var.h
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/ia64/include/proc.h

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/locore.S
diff -u src/sys/arch/ia64/ia64/locore.S:1.7 src/sys/arch/ia64/ia64/locore.S:1.8
--- src/sys/arch/ia64/ia64/locore.S:1.7	Sat Apr  8 17:45:22 2017
+++ src/sys/arch/ia64/ia64/locore.S	Wed Nov 14 21:10:59 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.S,v 1.7 2017/04/08 17:45:22 scole Exp $	*/
+/*	$NetBSD: locore.S,v 1.8 2018/11/14 21:10:59 scole Exp $	*/
 	
 /*-
  * Copyright (c) 1998 Doug Rabson
@@ -94,6 +94,22 @@ ENTRY_NOPROFILE(start, 1)
 	;;
 	br.call.sptk.many rp=ia64_init
 	;;
+        /* We have the new bspstore in r8 and the new sp in r9.
+           Switch onto the new stack and call mi_startup(). */
+{       .mmi
+        mov     ar.rsc = 0
+        ;;
+        mov     ar.bspstore = r8
+        mov     sp = r9
+        ;;
+}
+{       .mmi
+        loadrs
+        ;;
+        mov     ar.rsc = 3
+        nop     0
+        ;;
+}	
 	br.call.sptk.many rp=main
 	;;
 	/* NOTREACHED */

Index: src/sys/arch/ia64/ia64/machdep.c
diff -u src/sys/arch/ia64/ia64/machdep.c:1.38 src/sys/arch/ia64/ia64/machdep.c:1.39
--- src/sys/arch/ia64/ia64/machdep.c:1.38	Sat Apr  8 17:46:01 2017
+++ src/sys/arch/ia64/ia64/machdep.c	Wed Nov 14 21:10:59 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.38 2017/04/08 17:46:01 scole Exp $	*/
+/*	$NetBSD: machdep.c,v 1.39 2018/11/14 21:10:59 scole Exp $	*/
 
 /*-
  * Copyright (c) 2003,2004 Marcel Moolenaar
@@ -152,7 +152,7 @@ extern uint64_t ia64_gateway_page[];
 uint64_t pa_bootinfo;
 struct bootinfo bootinfo;
 
-
+extern vaddr_t kstack, kstack_top;
 extern vaddr_t kernel_text, end;
 
 struct fpswa_iface *fpswa_iface;
@@ -377,9 +377,10 @@ calculate_frequencies(void)
 
 /* XXXX: Don't allocate 'ci' on stack. */
 register struct cpu_info *ci __asm__("r13");
-void
+struct ia64_init_return
 ia64_init(void)
 {
+	struct ia64_init_return ret;
 	paddr_t kernstartpfn, kernendpfn, pfn0, pfn1;
 	struct pcb *pcb0;
 	struct efi_md *md;
@@ -620,33 +621,15 @@ ia64_init(void)
 	 * Set the kernel sp, reserving space for an (empty) trapframe,
 	 * and make lwp0's trapframe pointer point to it for sanity.
 	 */
+	lwp0.l_md.md_tf = (struct trapframe *)(v + UAREA_TF_OFFSET);
 
-	/*
-	 * Process u-area is organised as follows:
-	 *
-	 *  -----------------------------------------------------------
-	 * |  P  |                  |                    | 16Bytes | T |
-	 * |  C  | Register Stack   |      Memory Stack  | <-----> | F |
-	 * |  B  | ------------->   |       <----------  |         |   |
-	 *  -----------------------------------------------------------
-	 *        ^                                      ^
-	 *        |___ bspstore                          |___ sp
-	 *
-	 *                 --------------------------->
-         *                       Higher Addresses
-	 *
-	 *	PCB: struct pcb;    TF: struct trapframe;
-	 */
-
-
-	lwp0.l_md.md_tf = (struct trapframe *)(v + USPACE) - 1;
-
+	lwp0.l_md.user_stack = NULL;
+	lwp0.l_md.user_stack_size = 0;
+	
 	pcb0 = lwp_getpcb(&lwp0);
-
-	/* 16 bytes is the scratch area defined by the ia64 ABI. */
-	pcb0->pcb_special.sp = (vaddr_t)lwp0.l_md.md_tf - 16;
-	pcb0->pcb_special.bspstore = v + 1;
-
+	pcb0->pcb_special.sp = v + UAREA_SP_OFFSET;
+	pcb0->pcb_special.bspstore = v + UAREA_BSPSTORE_OFFSET;
+	
 	mutex_init(&pcb0->pcb_fpcpu_slock, MUTEX_DEFAULT, 0);
 
 	/*
@@ -684,8 +667,10 @@ ia64_init(void)
 	 * sane) context as the initial context for new threads that are
 	 * forked from us.
 	 */
+#if 0	/* XXX */
 	if (savectx(pcb0))
 		panic("savectx failed");
+#endif
 
 	/*
 	 * Initialize debuggers, and break into them if appropriate.
@@ -699,6 +684,11 @@ ia64_init(void)
 	if (boothowto & RB_KDB)
 		Debugger();
 #endif
+
+	ret.bspstore = pcb0->pcb_special.bspstore;
+	ret.sp = pcb0->pcb_special.sp;
+	
+	return (ret);
 }
 
 uint64_t

Index: src/sys/arch/ia64/ia64/syscall.c
diff -u src/sys/arch/ia64/ia64/syscall.c:1.6 src/sys/arch/ia64/ia64/syscall.c:1.7
--- src/sys/arch/ia64/ia64/syscall.c:1.6	Mon Nov  5 15:14:34 2012
+++ src/sys/arch/ia64/ia64/syscall.c	Wed Nov 14 21:10:59 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: syscall.c,v 1.6 2012/11/05 15:14:34 chs Exp $ */
+/* $NetBSD: syscall.c,v 1.7 2018/11/14 21:10:59 scole Exp $ */
 
 /*
  * Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.6 2012/11/05 15:14:34 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.7 2018/11/14 21:10:59 scole Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -61,14 +61,14 @@ syscall_intern(struct proc *p)
 void
 syscall_plain(struct lwp *l, u_int64_t code, struct trapframe *framep)
 {
-printf("%s: not yet\n", __func__);
+	panic("XXX %s: not implemented\n", __func__);
 	return;
 }
 
 void
 syscall_fancy(struct lwp *l, u_int64_t code, struct trapframe *framep)
 {
-printf("%s: not yet\n", __func__);
+	panic("XXX %s: not implemented\n", __func__);
 	return;
 }
 
@@ -78,7 +78,7 @@ printf("%s: not yet\n", __func__);
 void
 child_return(void *arg)
 {
-printf("%s: not yet\n", __func__);
+	panic("XXX %s: not implemented\n", __func__);
 	return;
 }
 

Index: src/sys/arch/ia64/ia64/vm_machdep.c
diff -u src/sys/arch/ia64/ia64/vm_machdep.c:1.14 src/sys/arch/ia64/ia64/vm_machdep.c:1.15
--- src/sys/arch/ia64/ia64/vm_machdep.c:1.14	Sat Apr 14 19:58:20 2018
+++ src/sys/arch/ia64/ia64/vm_machdep.c	Wed Nov 14 21:10:59 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: vm_machdep.c,v 1.14 2018/04/14 19:58:20 scole Exp $	*/
+/*	$NetBSD: vm_machdep.c,v 1.15 2018/11/14 21:10:59 scole Exp $	*/
 
 /*
  * Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -117,47 +117,67 @@ void
 cpu_lwp_fork(struct lwp *l1, struct lwp *l2, void *stack, size_t stacksize,
     void (*func)(void *), void *arg)
 {
-	struct pcb *pcb1, *pcb2;
+	vaddr_t ua1 = uvm_lwp_getuarea(l1);
+	vaddr_t ua2 = uvm_lwp_getuarea(l2);
+	struct pcb *pcb1 = lwp_getpcb(l1);
+	struct pcb *pcb2 = lwp_getpcb(l2);
+
 	struct trapframe *tf;
-	
-	pcb1 = lwp_getpcb(l1);
-	pcb2 = lwp_getpcb(l2);
+	uint64_t ndirty;
 
-	/* Copy pcb from lwp l1 to l2. */
+	/*
+	 * Save the preserved registers and the high FP registers in the
+	 * PCB if we're the parent (ie l1 == curlwp) so that we have
+	 * a valid PCB. This also causes a RSE flush. We don't have to
+	 * do that otherwise, because there wouldn't be anything important
+	 * to save.
+	 *
+	 * Copy pcb from lwp l1 to l2.
+	 */
 	if (l1 == curlwp) {
 		/* Sync the PCB before we copy it. */
 		if (savectx(pcb1) != 0)
-			panic("unexpected return from savectx");
+			panic("unexpected return from savectx()");
 		/* ia64_highfp_save(td1); XXX */
 	} else {
 		KASSERT(l1 == &lwp0);
 	}
 
 	/*
-	 * XXX this seems incomplete, each thread apparently needs its
-	 * own stack and bspstore, and to re-adjust the RSE "ndirty"
-	 * registers.  See
-	 * http://fxr.watson.org/fxr/source/ia64/ia64/vm_machdep.c?v=FREEBSD10#L262
-	 * Also should verify u-area usage is consistent, which may be
-	 * different than freebsd.
+	 * create the child's kernel stack and backing store. We basicly
+	 * create an image of the parent's stack and backing store and
+	 * adjust where necessary.
 	 */
 	*pcb2 = *pcb1;
 
 	l2->l_md.md_flags = l1->l_md.md_flags;
-	l2->l_md.md_tf = (struct trapframe *)(uvm_lwp_getuarea(l2) + USPACE) - 1;
+	l2->l_md.md_tf = (struct trapframe *)(ua2 + UAREA_TF_OFFSET);
 	l2->l_md.md_astpending = 0;
-
+	l2->l_md.user_stack = NULL;
+	l2->l_md.user_stack_size = 0;
+	
         /*
 	 * Copy the trapframe.
 	 */
 	tf = l2->l_md.md_tf;
 	*tf = *l1->l_md.md_tf;
 
+	/* XXX need something like this, but still not correct */
+	ndirty = tf->tf_special.ndirty + (tf->tf_special.bspstore & 0x1ffUL);
+	memcpy((void *)(ua2 + UAREA_BSPSTORE_OFFSET),
+	       (void *)(ua1 + UAREA_BSPSTORE_OFFSET), ndirty);
+
         /*
 	 * If specified, give the child a different stack.
 	 */
-	if (stack != NULL)
-		tf->tf_special.sp = (unsigned long)stack + stacksize;
+	if (stack != NULL) {
+		l2->l_md.user_stack = stack;
+		l2->l_md.user_stack_size = stacksize;
+		tf->tf_special.sp = (unsigned long)stack + UAREA_SP_OFFSET;
+		tf->tf_special.bspstore = (unsigned long)stack + UAREA_BSPSTORE_OFFSET;
+
+		memcpy(stack, (void *)(ua1 + UAREA_BSPSTORE_OFFSET), ndirty);
+	}
 
 	/* Set-up the return values as expected by the fork() libc stub. */
 	if (tf->tf_special.psr & IA64_PSR_IS) {
@@ -171,8 +191,10 @@ cpu_lwp_fork(struct lwp *l1, struct lwp 
 
 	tf->tf_scratch.gr2 = (unsigned long)FDESC_FUNC(func);
 	tf->tf_scratch.gr3 = (unsigned long)arg;
-	pcb2->pcb_special.sp = (unsigned long)tf - 16;
+
+	pcb2->pcb_special.sp = ua2 + UAREA_SP_OFFSET;
 	pcb2->pcb_special.rp = (unsigned long)FDESC_FUNC(lwp_trampoline);
+	pcb2->pcb_special.bspstore = ua2 + UAREA_BSPSTORE_OFFSET + ndirty;
 	pcb2->pcb_special.pfs = 0;
 
 	return;
@@ -186,7 +208,7 @@ cpu_lwp_fork(struct lwp *l1, struct lwp 
 int
 vmapbuf(struct buf *bp, vsize_t len)
 {
-printf("%s: not yet\n", __func__);
+	panic("XXX %s implement", __func__);
 	return 0;
 }
 
@@ -196,6 +218,6 @@ printf("%s: not yet\n", __func__);
 void
 vunmapbuf(struct buf *bp, vsize_t len)
 {
-printf("%s: not yet\n", __func__);
+	panic("XXX %s implement", __func__);
 	return;
 }

Index: src/sys/arch/ia64/include/md_var.h
diff -u src/sys/arch/ia64/include/md_var.h:1.2 src/sys/arch/ia64/include/md_var.h:1.3
--- src/sys/arch/ia64/include/md_var.h:1.2	Sat Apr  8 18:02:55 2017
+++ src/sys/arch/ia64/include/md_var.h	Wed Nov 14 21:10:59 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: md_var.h,v 1.2 2017/04/08 18:02:55 scole Exp $	*/
+/*	$NetBSD: md_var.h,v 1.3 2018/11/14 21:10:59 scole Exp $	*/
 
 /*-
  * Copyright (c) 1998 Doug Rabson
@@ -68,6 +68,14 @@ struct reg;
 struct thread;
 struct trapframe;
 
+/*
+ * Return value from ia64_init. Describes stack to switch to.
+ */
+struct ia64_init_return {
+        uint64_t        bspstore;
+        uint64_t        sp;
+};
+
 void	busdma_swi(void);
 int	copyout_regstack(struct thread *, uint64_t *, uint64_t *);
 void	cpu_mp_add(u_int, u_int, u_int);
@@ -78,7 +86,7 @@ void	ia64_flush_dirty(struct thread *, s
 uint64_t ia64_get_hcdp(void);
 int	ia64_highfp_drop(struct thread *);
 int	ia64_highfp_save(struct thread *);
-void	ia64_init(void);
+struct ia64_init_return ia64_init(void);
 void	ia64_probe_sapics(void);
 int	interrupt(uint64_t, struct trapframe *);
 void	map_gateway_page(void);

Index: src/sys/arch/ia64/include/proc.h
diff -u src/sys/arch/ia64/include/proc.h:1.6 src/sys/arch/ia64/include/proc.h:1.7
--- src/sys/arch/ia64/include/proc.h:1.6	Fri Jan 14 02:06:27 2011
+++ src/sys/arch/ia64/include/proc.h	Wed Nov 14 21:10:59 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: proc.h,v 1.6 2011/01/14 02:06:27 rmind Exp $	*/
+/*	$NetBSD: proc.h,v 1.7 2018/11/14 21:10:59 scole Exp $	*/
 
 #ifndef _IA64_PROC_H_
 #define _IA64_PROC_H_
@@ -6,12 +6,25 @@
 #include <machine/frame.h>
 
 /*
+ * Process u-area is organised as follows:
+ *
+ *   ------------------------------------------- 
+ *  |                      |         |    |     |
+ *  |  bspstore       sp   | 16bytes | TF | PCB |
+ *  |  ---->        <---   |         |    |     |
+ *   -------------------------------------------
+ *              -----> Higher Addresses
+ */
+
+/*
  * Machine-dependent part of the lwp structure for ia64
  */
 struct mdlwp {
 	u_long	md_flags;
 	struct	trapframe *md_tf;	/* trap/syscall registers */
 	__volatile int md_astpending;	/* AST pending for this process */
+	void *user_stack;
+	uint64_t user_stack_size;
 };
 
 /*
@@ -26,4 +39,11 @@ struct mdproc {
 					/* Syscall handling function */
 };
 
+#define UAREA_PCB_OFFSET	(USPACE - sizeof(struct pcb))
+#define UAREA_TF_OFFSET		(UAREA_PCB_OFFSET - sizeof(struct trapframe))
+#define UAREA_SP_OFFSET		(UAREA_TF_OFFSET -16 -sizeof(uint64_t))
+#define UAREA_BSPSTORE_OFFSET	(0)
+#define UAREA_STACK_SIZE	(USPACE - 16 - sizeof(struct trapframe) - \
+				 sizeof(struct PCB))
+
 #endif /* _IA64_PROC_H_ */

Reply via email to