Date: Mon, 17 Jul 2006 19:20:40 GMT From: Oleksandr Tymoshenko <gonzo@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 101788 for review Message-ID: <200607171920.k6HJKejF030199@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 <machine/asm.h> #include <machine/asmacros.h> +#include <machine/cpuregs.h> __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 <vm/uma.h> #include <vm/uma_int.h> +/* + * 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607171920.k6HJKejF030199>