Date: Tue, 6 Nov 2007 13:18:51 GMT From: Oleksandr Tymoshenko <gonzo@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 128736 for review Message-ID: <200711061318.lA6DIpe6076880@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=128736 Change 128736 by gonzo@gonzo_jeeves on 2007/11/06 13:18:45 o Implement cpu_set_upcall Affected files ... .. //depot/projects/mips2/src/sys/mips/mips/vm_machdep.c#17 edit Differences ... ==== //depot/projects/mips2/src/sys/mips/mips/vm_machdep.c#17 (text+ko) ==== @@ -171,10 +171,52 @@ return ((struct sf_buf *)m); } +/* + * Initialize machine state (pcb and trap frame) for a new thread about to + * upcall. Put enough state in the new thread's PCB to get it to go back + * userret(), where we can intercept it again to set the return (upcall) + * Address and stack, along with those from upcals that are from other sources + * such as those generated in thread_userret() itself. + */ void cpu_set_upcall(struct thread *td, struct thread *td0) { - panic("%s", __func__); + register_t sp; + + /* + * Preserve SP from beeing overwritten. + */ + sp = td->td_pcb->pcb_regs[PCB_REG_SP]; + + bcopy(td0->td_pcb, td->td_pcb, sizeof(struct pcb)); + bcopy(td0->td_frame, td->td_frame, sizeof *td->td_frame); + + /* + * Call fork_trampoline into fork_return via the pcb. + */ + td->td_pcb->pcb_regs[PCB_REG_RA] = (register_t)fork_trampoline; + td->td_pcb->pcb_regs[PCB_REG_S0] = (register_t)fork_return; + td->td_pcb->pcb_regs[PCB_REG_S1] = (register_t)td; + td->td_pcb->pcb_regs[PCB_REG_S2] = (register_t)td->td_frame; + /* + * Restore original stack. + */ + td->td_pcb->pcb_regs[PCB_REG_SP] = sp; + + /* + * DO NOT ENABLE ANY INTERRUPTS HERE: + * after cpu_throw we're supposed to be with td_lock locked + * and this means - no interrupts enabled. + */ + td->td_pcb->pcb_regs[PCB_REG_SR] = 0; + + /* + * Setup to release spin count in fork_exit(). By unlocking + * sched_lock we'll enable interrupts and unmask timer + * interrupt (HW IRQ5) + */ + td->td_md.md_spinlock_count = 1; + td->td_md.md_saved_sr = MIPS_SR_INT_IE | (((1 << 5) << 8) << 2); } void
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200711061318.lA6DIpe6076880>