Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/mips/mips cpu_lwp_fork (MIPS): replace l_addr with ...
details: https://anonhg.NetBSD.org/src/rev/9d0d3af4b840
branches: trunk
changeset: 749411:9d0d3af4b840
user: rmind <rmind%NetBSD.org@localhost>
date: Sun Nov 29 04:11:51 2009 +0000
description:
cpu_lwp_fork (MIPS): replace l_addr with uvm_lwp_getuarea(), clean up a little.
diffstat:
sys/arch/mips/mips/vm_machdep.c | 92 ++++++++++++++++++----------------------
1 files changed, 41 insertions(+), 51 deletions(-)
diffs (166 lines):
diff -r 76c7df8ef43f -r 9d0d3af4b840 sys/arch/mips/mips/vm_machdep.c
--- a/sys/arch/mips/mips/vm_machdep.c Sun Nov 29 04:09:35 2009 +0000
+++ b/sys/arch/mips/mips/vm_machdep.c Sun Nov 29 04:11:51 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vm_machdep.c,v 1.127 2009/11/21 17:40:28 rmind Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.128 2009/11/29 04:11:51 rmind Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.127 2009/11/21 17:40:28 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.128 2009/11/29 04:11:51 rmind Exp $");
#include "opt_ddb.h"
@@ -104,22 +104,15 @@
paddr_t kvtophys(vaddr_t); /* XXX */
/*
- * Finish a fork operation, with process p2 nearly set up.
- * Copy and update the pcb and trap frame, making the child ready to run.
+ * cpu_lwp_fork: finish a new LWP (l2) operation.
*
- * Rig the child's kernel stack so that it will start out in
- * 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.
- *
- * p1 is the process being forked; if p1 == &proc0, we are creating
- * a kernel thread, and the return path and argument are specified with
- * `func' and `arg'.
+ * First LWP (l1) is the process being forked. If it is &lwp0, then we
+ * are creating a kthread, where return path and argument are specified
+ * with `func' and `arg'.
*
* If an alternate user-level stack is requested (with non-zero values
- * in both the stack and stacksize args), set up the user stack pointer
- * accordingly.
+ * in both the stack and stacksize arguments), then set up the user stack
+ * pointer accordingly.
*/
void
cpu_lwp_fork(struct lwp *l1, struct lwp *l2, void *stack, size_t stacksize,
@@ -127,6 +120,9 @@
{
struct pcb *pcb1, *pcb2;
struct frame *f;
+ vaddr_t uv;
+
+ KASSERT(l1 == curlwp || l1 == &lwp0);
pcb1 = lwp_getpcb(l1);
pcb2 = lwp_getpcb(l2);
@@ -135,28 +131,22 @@
l2->l_md.md_ss_instr = 0;
l2->l_md.md_astpending = 0;
-#ifdef DIAGNOSTIC
- /*
- * If l1 != curlwp && l1 == &lwp0, we're creating a kernel thread.
- */
- if (l1 != curlwp && l1 != &lwp0)
- panic("cpu_lwp_fork: curlwp");
-#endif
+ /* If parent LWP was using FPU, then save the FPU h/w state. */
if ((l1->l_md.md_flags & MDP_FPUSED) && l1 == fpcurlwp)
savefpregs(l1);
+ /* Copy the PCB from parent. */
+ memcpy(pcb2, pcb1, sizeof(struct pcb));
+
/*
- * Copy pcb from proc p1 to p2.
- * Copy p1 trapframe atop on p2 stack space, so return to user mode
+ * Copy the trapframe from parent, so that return to userspace
* will be to right address, with correct registers.
*/
- memcpy(pcb2, pcb1, sizeof(struct pcb));
- f = (struct frame *)((char *)l2->l_addr + USPACE) - 1;
+ uv = uvm_lwp_getuarea(l2);
+ f = (struct frame *)(uv + USPACE) - 1;
memcpy(f, l1->l_md.md_regs, sizeof(struct frame));
- /*
- * If specified, give the child a different stack.
- */
+ /* If specified, set a different user stack for a child. */
if (stack != NULL)
f->f_regs[_R_SP] = (uintptr_t)stack + stacksize;
@@ -164,49 +154,49 @@
l2->l_md.md_flags = l1->l_md.md_flags & MDP_FPUSED;
#if USPACE > PAGE_SIZE
{
+ const int x = (MIPS_HAS_R4K_MMU) ?
+ (MIPS3_PG_G | MIPS3_PG_RO | MIPS3_PG_WIRED) : MIPS1_PG_G;
+ pt_entry_t *pte = kvtopte(uv);
size_t i;
- const int x = (MIPS_HAS_R4K_MMU) ?
- (MIPS3_PG_G | MIPS3_PG_RO | MIPS3_PG_WIRED) :
- MIPS1_PG_G;
- pt_entry_t *pte = kvtopte(l2->l_addr);
+
for (i = 0; i < UPAGES; i++)
l2->l_md.md_upte[i] = pte[i].pt_entry &~ x;
}
#endif
-
- pcb2->pcb_context[0] = (intptr_t)func; /* S0 */
- pcb2->pcb_context[1] = (intptr_t)arg; /* S1 */
+ /*
+ * Rig kernel stack so that it would start out in lwp_trampoline()
+ * and call child_return() with l2 as an argument. This causes the
+ * newly-created child process to go directly to user level with a
+ * parent return value of 0 from fork(), while the parent process
+ * returns normally.
+ */
+ pcb2->pcb_context[0] = (intptr_t)func; /* S0 */
+ pcb2->pcb_context[1] = (intptr_t)arg; /* S1 */
pcb2->pcb_context[MIPS_CURLWP_CARD - 16] = (intptr_t)l2;/* S? */
- pcb2->pcb_context[8] = (intptr_t)f; /* SP */
- pcb2->pcb_context[10] = (intptr_t)lwp_trampoline;/* RA */
+ pcb2->pcb_context[8] = (intptr_t)f; /* SP */
+ pcb2->pcb_context[10] = (intptr_t)lwp_trampoline; /* RA */
#ifdef IPL_ICU_MASK
- pcb2->pcb_ppl = 0; /* machine dependent interrupt mask */
+ /* Machine depenedend interrupt mask. */
+ pcb2->pcb_ppl = 0;
#endif
}
-/*
- * Set the given LWP to start at the given function via the
- * lwp_trampoline.
- */
void
cpu_setfunc(struct lwp *l, void (*func)(void *), void *arg)
{
- struct pcb *pcb;
- struct frame *f;
+ struct pcb *pcb = lwp_getpcb(l);
+ struct frame *f = l->l_md.md_regs;
- f = (struct frame *)((char *)l->l_addr + USPACE) - 1;
- KASSERT(l->l_md.md_regs == f);
-
- pcb = lwp_getpcb(l);
pcb->pcb_context[0] = (intptr_t)func; /* S0 */
pcb->pcb_context[1] = (intptr_t)arg; /* S1 */
pcb->pcb_context[MIPS_CURLWP_CARD - 16] = (intptr_t)l; /* S? */
pcb->pcb_context[8] = (intptr_t)f; /* SP */
pcb->pcb_context[10] = (intptr_t)setfunc_trampoline; /* RA */
#ifdef IPL_ICU_MASK
- pcb->pcb_ppl = 0; /* machine depenedend interrupt mask */
+ /* Machine depenedend interrupt mask. */
+ pcb->pcb_ppl = 0;
#endif
-}
+}
void
cpu_lwp_free(struct lwp *l, int proc)
Home |
Main Index |
Thread Index |
Old Index