FreeBSD/sys/arm/arm/vm_machdep.c
/*
 * 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.
 */
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.
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,
    struct thread *td2, int flags)
{
	struct pcb *pcb2;
	struct trapframe *tf;
	struct mdproc *mdp2;
	if ((flags & RFPROC) == 0)
		return;
	pcb2 = (struct pcb *)
	    (td2->td_kstack + td2->td_kstack_pages * PAGE_SIZE) - 1;
#ifdef __XSCALE__
#ifndef CPU_XSCALE_CORE3
	pmap_use_minicache(td2->td_kstack, td2->td_kstack_pages * PAGE_SIZE);
#endif
#endif
	td2->td_pcb = pcb2;
	bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
	mdp2 = &p2->p_md;
	bcopy(&td1->td_proc->p_md, mdp2, sizeof(*mdp2));
	td2->td_frame = (struct trapframe *)pcb2 - 1;
	*td2->td_frame = *td1->td_frame;
	pmap_set_pcb_pagedir(vmspace_pmap(p2->p_vmspace), pcb2);
	pcb2->pcb_regs.sf_r4 = (register_t)fork_return;
	pcb2->pcb_regs.sf_r5 = (register_t)td2;
	pcb2->pcb_regs.sf_lr = (register_t)fork_trampoline;
	pcb2->pcb_regs.sf_sp = STACKALIGN(td2->td_frame);
	pcb2->pcb_vfpcpu = -1;
	pcb2->pcb_vfpstate.fpscr = initial_fpscr;
	tf = td2->td_frame;
	tf->tf_spsr &= ~PSR_C;
	tf->tf_r0 = 0;
	tf->tf_r1 = 0;
	td2->td_md.md_spinlock_count = 1;
	td2->td_md.md_saved_cspr = PSR_SVC32_MODE;
#if __ARM_ARCH >= 6
	td2->td_md.md_tp = td1->td_md.md_tp;
#else
	td2->td_md.md_tp = *(register_t *)ARM_TP_ADDRESS;
#endif
}
void cpu_fork ( register struct thread * td1 , register struct proc * p2 , struct thread * td2 , int flags ) { struct pcb * pcb2 ; struct trapframe * tf ; struct mdproc * mdp2 ; if ( ( flags & RFPROC ) == 0 ) return ; pcb2 = ( struct pcb * ) ( td2 -> td_kstack + td2 -> td_kstack_pages * PAGE_SIZE ) - 1 ; #ifdef __XSCALE__ #ifndef CPU_XSCALE_CORE3 pmap_use_minicache ( td2 -> td_kstack , td2 -> td_kstack_pages * PAGE_SIZE ) ; #endif #endif td2 -> td_pcb = pcb2 ; bcopy ( td1 -> td_pcb , pcb2 , sizeof ( * pcb2 ) ) ; mdp2 = & p2 -> p_md ; bcopy ( & td1 -> td_proc -> p_md , mdp2 , sizeof ( * mdp2 ) ) ; td2 -> td_frame = ( struct trapframe * ) pcb2 - 1 ; * td2 -> td_frame = * td1 -> td_frame ; pmap_set_pcb_pagedir ( vmspace_pmap ( p2 -> p_vmspace ) , pcb2 ) ; pcb2 -> pcb_regs . sf_r4 = ( register_t ) fork_return ; pcb2 -> pcb_regs . sf_r5 = ( register_t ) td2 ; pcb2 -> pcb_regs . sf_lr = ( register_t ) fork_trampoline ; pcb2 -> pcb_regs . sf_sp = STACKALIGN ( td2 -> td_frame ) ; pcb2 -> pcb_vfpcpu = -1 ; pcb2 -> pcb_vfpstate . fpscr = initial_fpscr ; tf = td2 -> td_frame ; tf -> tf_spsr &= ~ PSR_C ; tf -> tf_r0 = 0 ; tf -> tf_r1 = 0 ; td2 -> td_md . md_spinlock_count = 1 ; td2 -> td_md . md_saved_cspr = PSR_SVC32_MODE ; #if __ARM_ARCH >= 6 td2 -> td_md . md_tp = td1 -> td_md . md_tp ; #else td2 -> td_md . md_tp = * ( register_t * ) ARM_TP_ADDRESS ; #endif }
Finish a fork operation, with process p2 nearly set up.
Finish a fork operation with process p2 nearly set up .
/* Point the pcb to the top of the stack */ /* Clone td1's pcb */ /* Point to mdproc and then copy over td1's contents */ /* Point the frame to the stack in front of pcb and copy td1's frame */ /*
	 * Create a new fresh stack for the new process.
	 * Copy the trap frame for the return to user mode as if from a
	 * syscall.  This copies most of the user mode register values.
	 */ /* Setup to release spin count in fork_exit(). */