From owner-p4-projects@FreeBSD.ORG Mon Jul 17 19:20:41 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 25C9616A506; Mon, 17 Jul 2006 19:20:41 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id DC78616A501 for ; Mon, 17 Jul 2006 19:20:40 +0000 (UTC) (envelope-from gonzo@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7747743D5C for ; Mon, 17 Jul 2006 19:20:40 +0000 (GMT) (envelope-from gonzo@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k6HJKegG030206 for ; Mon, 17 Jul 2006 19:20:40 GMT (envelope-from gonzo@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k6HJKejF030199 for perforce@freebsd.org; Mon, 17 Jul 2006 19:20:40 GMT (envelope-from gonzo@FreeBSD.org) Date: Mon, 17 Jul 2006 19:20:40 GMT Message-Id: <200607171920.k6HJKejF030199@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to gonzo@FreeBSD.org using -f From: Oleksandr Tymoshenko To: Perforce Change Reviews Cc: Subject: PERFORCE change 101788 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 17 Jul 2006 19:20:41 -0000 http://perforce.freebsd.org/chv.cgi?CH=101788 Change 101788 by gonzo@gonzo_hq on 2006/07/17 19:20:21 o fork/context switching routines merged from juli's sources. Affected files ... .. //depot/projects/mips2/src/sys/mips/mips/swtch.S#3 edit .. //depot/projects/mips2/src/sys/mips/mips/vm_machdep.c#4 edit Differences ... ==== //depot/projects/mips2/src/sys/mips/mips/swtch.S#3 (text+ko) ==== @@ -30,24 +30,86 @@ #include #include +#include __FBSDID("$FreeBSD$"); /* - * XXXMIPS: Implement these routines + * a0: struct thread *old + * a1: struct thread *new */ +ENTRY(cpu_throw) + subu sp, 8 + sw a1, 0(sp) + move a0, a1 + jal pmap_activate + nop + lw t3, 0(sp) + addu sp, 8 + .set at + lw t2, pcpup + .set noat + sw t3, PC_CURTHREAD(t2) + lw t0, TD_PCB(t3) + sw t0, PC_CURPCB(t2) + lw s0, PCB_REG_S0(t0) + lw s1, PCB_REG_S1(t0) + lw s2, PCB_REG_S2(t0) + lw s3, PCB_REG_S3(t0) + lw s4, PCB_REG_S4(t0) + lw s5, PCB_REG_S5(t0) + lw s6, PCB_REG_S6(t0) + lw s7, PCB_REG_S7(t0) + lw s8, PCB_REG_S8(t0) + lw sp, PCB_REG_SP(t0) + lw ra, PCB_REG_RA(t0) + lw t0, PCB_REG_SR(t0) + /* Copy s0-s3 into a0-s3 so we can just pass args. */ + move a0, s0 + move a1, s1 + move a2, s2 + move a3, s3 + mtc0 t0, MIPS_COP_0_STATUS + li v0, 1 + jr ra + nop -ENTRY(cpu_throw) - break END(cpu_throw) -ENTRY(cpu_switch) - break -END(cpu_switch) +/* + * a0: struct pcb *pcb + */ +ENTRY(savectx) + mfc0 t0, MIPS_COP_0_STATUS + sw s0, PCB_REG_S0(a0) + sw s1, PCB_REG_S1(a0) + sw s2, PCB_REG_S2(a0) + sw s3, PCB_REG_S3(a0) + sw s4, PCB_REG_S4(a0) + sw s5, PCB_REG_S5(a0) + sw s6, PCB_REG_S6(a0) + sw s7, PCB_REG_S7(a0) + sw s8, PCB_REG_S8(a0) + sw sp, PCB_REG_SP(a0) + sw t0, PCB_REG_SR(a0) + sw ra, PCB_REG_RA(a0) + li v0, 0 + jr ra + nop -ENTRY(savectx) - break END(savectx) +/* + * s0: Routine to call. + * s1: a0 for said routine. + * s2: a1 for said routine. + * These need passed to fork_exit as a0, a1, a2 respectively. + */ + ENTRY(fork_trampoline) - break + move a0, s0 + move a1, s1 + move a2, s2 + j fork_exit + nop + END(fork_trampoline) ==== //depot/projects/mips2/src/sys/mips/mips/vm_machdep.c#4 (text+ko) ==== @@ -58,11 +58,53 @@ #include #include +/* + * Finish a fork operation, with process p2 nearly set up. + * Copy and update the pcb, set up the stack so that the child + * ready to run and return to user mode. + */ void -cpu_fork(register struct thread *td1, register struct proc *p2, +cpu_fork(register struct thread *td, register struct proc *p2, struct thread *td2, int flags) { - panic("%s", __func__); + if ((flags & RFPROC) == 0) + return; + + cpu_thread_setup(td2); + + /* Copy the pcb */ + bcopy(td->td_pcb, td2->td_pcb, sizeof(struct pcb)); + + /* + * Copy the trap frame for the return to user mode as if from a + * syscall. This copies most of the user mode register values. + */ + bcopy(td->td_frame, td2->td_frame, sizeof *td2->td_frame); + + /* + * Call fork_trampoline into fork_return via the pcb. + */ + td2->td_pcb->pcb_regs[PCB_REG_RA] = (register_t)fork_trampoline; + td2->td_pcb->pcb_regs[PCB_REG_S0] = (register_t)fork_return; + td2->td_pcb->pcb_regs[PCB_REG_S1] = (register_t)td2; + td2->td_pcb->pcb_regs[PCB_REG_S2] = (register_t)td2->td_frame; + + /* + * Now cpu_switch() can schedule the new process. + */ + + /* Setup to release sched_lock in fork_exit(). */ + td2->td_md.md_spinlock_count = 1; +} + +void +cpu_switch(struct thread *old, struct thread *new) +{ + if (!savectx(old->td_pcb)) { + pmap_deactivate(old); + cpu_throw(old, new); + panic("%s: should not be reached", __func__); + } } void @@ -143,7 +185,8 @@ void cpu_set_fork_handler(struct thread *td, void (*func)(void *), void *arg) { - panic("%s", __func__); + td->td_pcb->pcb_regs[PCB_REG_S0] = (register_t)func; + td->td_pcb->pcb_regs[PCB_REG_S1] = (register_t)arg; } void