diff options
author | benno <benno@FreeBSD.org> | 2002-02-28 03:24:07 +0000 |
---|---|---|
committer | benno <benno@FreeBSD.org> | 2002-02-28 03:24:07 +0000 |
commit | a0268a06222fcbb69243c6e67fe1741ac3a77194 (patch) | |
tree | b7f558b1545ed5a0d8ad186ce6dba3e85f00a3dc /sys/powerpc | |
parent | 778f777d9dcd70311e383a7b20a4b32a146a6790 (diff) | |
download | FreeBSD-src-a0268a06222fcbb69243c6e67fe1741ac3a77194.zip FreeBSD-src-a0268a06222fcbb69243c6e67fe1741ac3a77194.tar.gz |
Make fork work, at least for kthreads. Switching still has some issues.
Diffstat (limited to 'sys/powerpc')
-rw-r--r-- | sys/powerpc/aim/locore.S | 18 | ||||
-rw-r--r-- | sys/powerpc/aim/swtch.S | 11 | ||||
-rw-r--r-- | sys/powerpc/aim/vm_machdep.c | 30 | ||||
-rw-r--r-- | sys/powerpc/include/frame.h | 13 | ||||
-rw-r--r-- | sys/powerpc/include/pcb.h | 21 | ||||
-rw-r--r-- | sys/powerpc/powerpc/genassym.c | 6 | ||||
-rw-r--r-- | sys/powerpc/powerpc/locore.S | 18 | ||||
-rw-r--r-- | sys/powerpc/powerpc/locore.s | 18 | ||||
-rw-r--r-- | sys/powerpc/powerpc/swtch.S | 11 | ||||
-rw-r--r-- | sys/powerpc/powerpc/swtch.s | 11 | ||||
-rw-r--r-- | sys/powerpc/powerpc/vm_machdep.c | 30 |
11 files changed, 77 insertions, 110 deletions
diff --git a/sys/powerpc/aim/locore.S b/sys/powerpc/aim/locore.S index 76fc3aa..79c575d 100644 --- a/sys/powerpc/aim/locore.S +++ b/sys/powerpc/aim/locore.S @@ -940,24 +940,6 @@ s_trap: rfi /* - * Child comes here at the end of a fork. - * Mostly similar to the above. - */ - .globl fork_trampoline -fork_trampoline: - xor 3,3,3 -#if 0 /* XXX */ - bl lcsplx -#endif - mtlr 31 - mr 3,30 - blrl /* jump indirect to r31 */ - mr 3,30 - bl ast - FRAME_LEAVE(tempsave) - rfi - -/* * DSI second stage fault handler */ s_dsitrap: diff --git a/sys/powerpc/aim/swtch.S b/sys/powerpc/aim/swtch.S index 00bdbb3..828c6cd 100644 --- a/sys/powerpc/aim/swtch.S +++ b/sys/powerpc/aim/swtch.S @@ -121,3 +121,14 @@ ENTRY(savectx) mfcr %r4 /* Save the condition register */ stw %r4,PCB_CONTEXT(%r3) blr + +/* + * fork_trampoline() + * Set up the return from cpu_fork() + */ +ENTRY(fork_trampoline) + lwz %r3,CF_FUNC(1) + lwz %r4,CF_ARG0(1) + lwz %r5,CF_ARG1(1) + bl fork_exit + rfi diff --git a/sys/powerpc/aim/vm_machdep.c b/sys/powerpc/aim/vm_machdep.c index 6958373..36345ec 100644 --- a/sys/powerpc/aim/vm_machdep.c +++ b/sys/powerpc/aim/vm_machdep.c @@ -128,7 +128,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) struct switchframe *sf; struct pcb *pcb; - KASSERT(td1 == curthread || td1 == thread0, + KASSERT(td1 == curthread || td1 == &thread0, ("cpu_fork: p1 not curproc and not proc0")); CTR3(KTR_PROC, "cpu_fork: called td1=%08x p2=%08x flags=%x", (u_int)td1, (u_int)p2, flags); @@ -137,8 +137,8 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) p1 = td1->td_proc; - pcb = (struct pcb *)(td2->td_kstack + KSTACK_PAGES * PAGE_SIZE - - sizeof(struct pcb)); + pcb = (struct pcb *)((td2->td_kstack + KSTACK_PAGES * PAGE_SIZE - + sizeof(struct pcb)) & ~0x2fU); td2->td_pcb = pcb; /* Copy the pcb */ @@ -149,7 +149,6 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) * Copy the trap frame for the return to user mode as if from a * syscall. This copies most of the user mode register values. */ - tf = (struct trapframe *)pcb - 1; bcopy(td1->td_frame, tf, sizeof(*tf)); @@ -157,18 +156,13 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) td2->td_frame = tf; - /* - * There happens to be a callframe, too. - */ cf = (struct callframe *)tf - 1; - cf->lr = (int)fork_trampoline; + cf->cf_func = (register_t)fork_return; + cf->cf_arg0 = (register_t)td2; + cf->cf_arg1 = (register_t)tf; - /* - * Below that, we allocate the switch frame. - */ - sf = (struct switchframe *)cf - 1; - sf->sp = (int)cf; - pcb->pcb_sp = (int)sf; + pcb->pcb_sp = (register_t)cf; + pcb->pcb_lr = (register_t)fork_trampoline; /* * Now cpu_switch() can schedule the new process. @@ -187,17 +181,15 @@ cpu_set_fork_handler(td, func, arg) void (*func) __P((void *)); void *arg; { - struct switchframe *sf; struct callframe *cf; CTR3(KTR_PROC, "cpu_set_fork_handler: called with td=%08x func=%08x arg=%08x", (u_int)td, (u_int)func, (u_int)arg); - sf = (struct switchframe *)td->td_pcb->pcb_sp; - cf = (struct callframe *)sf->sp; + cf = (struct callframe *)td->td_pcb->pcb_sp; - cf->r31 = (register_t)func; - cf->r30 = (register_t)arg; + cf->cf_func = (register_t)func; + cf->cf_arg0 = (register_t)arg; } /* diff --git a/sys/powerpc/include/frame.h b/sys/powerpc/include/frame.h index 3865de4..72dbd9f 100644 --- a/sys/powerpc/include/frame.h +++ b/sys/powerpc/include/frame.h @@ -67,9 +67,9 @@ struct trapframe { struct switchframe { register_t sp; - int fill; - int user_sr; - int cr; + register_t fill; + register_t user_sr; + register_t cr; register_t fixreg2; register_t fixreg[19]; /* R13-R31 */ }; @@ -85,10 +85,9 @@ struct clockframe { * Call frame for PowerPC used during fork. */ struct callframe { - register_t sp; - register_t lr; - register_t r30; - register_t r31; + register_t cf_func; + register_t cf_arg0; + register_t cf_arg1; }; #endif /* _MACHINE_FRAME_H_ */ diff --git a/sys/powerpc/include/pcb.h b/sys/powerpc/include/pcb.h index 98b6fa9..fbd7cbf 100644 --- a/sys/powerpc/include/pcb.h +++ b/sys/powerpc/include/pcb.h @@ -38,18 +38,19 @@ typedef int faultbuf[23]; struct pcb { - u_int32_t pcb_context[18]; /* non-volatile r14-r31 */ - u_int32_t pcb_cr; /* Condition register */ - struct pmap *pcb_pm; /* pmap of our vmspace */ - struct pmap *pcb_pmreal; /* real address of above */ - register_t pcb_sp; /* saved SP */ - int pcb_spl; /* saved SPL */ - faultbuf *pcb_onfault; /* For use during copyin/copyout */ - int pcb_flags; + register_t pcb_context[18]; /* non-volatile r14-r31 */ + register_t pcb_cr; /* Condition register */ + register_t pcb_sp; /* stack pointer */ + register_t pcb_lr; /* link register */ + struct pmap *pcb_pm; /* pmap of our vmspace */ + struct pmap *pcb_pmreal; /* real address of above */ + faultbuf *pcb_onfault; /* For use during + copyin/copyout */ + int pcb_flags; #define PCB_FPU 1 /* Process had FPU initialized */ struct fpu { - double fpr[32]; - double fpscr; /* FPSCR stored as double for easier access */ + double fpr[32]; + double fpscr; /* FPSCR stored as double for easier access */ } pcb_fpu; /* Floating point processor */ }; diff --git a/sys/powerpc/powerpc/genassym.c b/sys/powerpc/powerpc/genassym.c index f0b28d4..c8a484b 100644 --- a/sys/powerpc/powerpc/genassym.c +++ b/sys/powerpc/powerpc/genassym.c @@ -86,11 +86,15 @@ ASSYM(FRAME_EXC, offsetof(struct trapframe, exc)); ASSYM(SFRAMELEN, roundup(sizeof(struct switchframe), 16)); +ASSYM(CF_FUNC, offsetof(struct callframe, cf_func)); +ASSYM(CF_ARG0, offsetof(struct callframe, cf_arg0)); +ASSYM(CF_ARG1, offsetof(struct callframe, cf_arg1)); + ASSYM(PCB_CONTEXT, offsetof(struct pcb, pcb_context)); ASSYM(PCB_CR, offsetof(struct pcb, pcb_cr)); ASSYM(PCB_PMR, offsetof(struct pcb, pcb_pmreal)); ASSYM(PCB_SP, offsetof(struct pcb, pcb_sp)); -ASSYM(PCB_SPL, offsetof(struct pcb, pcb_spl)); +ASSYM(PCB_LR, offsetof(struct pcb, pcb_lr)); ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault)); ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags)); diff --git a/sys/powerpc/powerpc/locore.S b/sys/powerpc/powerpc/locore.S index 76fc3aa..79c575d 100644 --- a/sys/powerpc/powerpc/locore.S +++ b/sys/powerpc/powerpc/locore.S @@ -940,24 +940,6 @@ s_trap: rfi /* - * Child comes here at the end of a fork. - * Mostly similar to the above. - */ - .globl fork_trampoline -fork_trampoline: - xor 3,3,3 -#if 0 /* XXX */ - bl lcsplx -#endif - mtlr 31 - mr 3,30 - blrl /* jump indirect to r31 */ - mr 3,30 - bl ast - FRAME_LEAVE(tempsave) - rfi - -/* * DSI second stage fault handler */ s_dsitrap: diff --git a/sys/powerpc/powerpc/locore.s b/sys/powerpc/powerpc/locore.s index 76fc3aa..79c575d 100644 --- a/sys/powerpc/powerpc/locore.s +++ b/sys/powerpc/powerpc/locore.s @@ -940,24 +940,6 @@ s_trap: rfi /* - * Child comes here at the end of a fork. - * Mostly similar to the above. - */ - .globl fork_trampoline -fork_trampoline: - xor 3,3,3 -#if 0 /* XXX */ - bl lcsplx -#endif - mtlr 31 - mr 3,30 - blrl /* jump indirect to r31 */ - mr 3,30 - bl ast - FRAME_LEAVE(tempsave) - rfi - -/* * DSI second stage fault handler */ s_dsitrap: diff --git a/sys/powerpc/powerpc/swtch.S b/sys/powerpc/powerpc/swtch.S index 00bdbb3..828c6cd 100644 --- a/sys/powerpc/powerpc/swtch.S +++ b/sys/powerpc/powerpc/swtch.S @@ -121,3 +121,14 @@ ENTRY(savectx) mfcr %r4 /* Save the condition register */ stw %r4,PCB_CONTEXT(%r3) blr + +/* + * fork_trampoline() + * Set up the return from cpu_fork() + */ +ENTRY(fork_trampoline) + lwz %r3,CF_FUNC(1) + lwz %r4,CF_ARG0(1) + lwz %r5,CF_ARG1(1) + bl fork_exit + rfi diff --git a/sys/powerpc/powerpc/swtch.s b/sys/powerpc/powerpc/swtch.s index 00bdbb3..828c6cd 100644 --- a/sys/powerpc/powerpc/swtch.s +++ b/sys/powerpc/powerpc/swtch.s @@ -121,3 +121,14 @@ ENTRY(savectx) mfcr %r4 /* Save the condition register */ stw %r4,PCB_CONTEXT(%r3) blr + +/* + * fork_trampoline() + * Set up the return from cpu_fork() + */ +ENTRY(fork_trampoline) + lwz %r3,CF_FUNC(1) + lwz %r4,CF_ARG0(1) + lwz %r5,CF_ARG1(1) + bl fork_exit + rfi diff --git a/sys/powerpc/powerpc/vm_machdep.c b/sys/powerpc/powerpc/vm_machdep.c index 6958373..36345ec 100644 --- a/sys/powerpc/powerpc/vm_machdep.c +++ b/sys/powerpc/powerpc/vm_machdep.c @@ -128,7 +128,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) struct switchframe *sf; struct pcb *pcb; - KASSERT(td1 == curthread || td1 == thread0, + KASSERT(td1 == curthread || td1 == &thread0, ("cpu_fork: p1 not curproc and not proc0")); CTR3(KTR_PROC, "cpu_fork: called td1=%08x p2=%08x flags=%x", (u_int)td1, (u_int)p2, flags); @@ -137,8 +137,8 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) p1 = td1->td_proc; - pcb = (struct pcb *)(td2->td_kstack + KSTACK_PAGES * PAGE_SIZE - - sizeof(struct pcb)); + pcb = (struct pcb *)((td2->td_kstack + KSTACK_PAGES * PAGE_SIZE - + sizeof(struct pcb)) & ~0x2fU); td2->td_pcb = pcb; /* Copy the pcb */ @@ -149,7 +149,6 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) * Copy the trap frame for the return to user mode as if from a * syscall. This copies most of the user mode register values. */ - tf = (struct trapframe *)pcb - 1; bcopy(td1->td_frame, tf, sizeof(*tf)); @@ -157,18 +156,13 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) td2->td_frame = tf; - /* - * There happens to be a callframe, too. - */ cf = (struct callframe *)tf - 1; - cf->lr = (int)fork_trampoline; + cf->cf_func = (register_t)fork_return; + cf->cf_arg0 = (register_t)td2; + cf->cf_arg1 = (register_t)tf; - /* - * Below that, we allocate the switch frame. - */ - sf = (struct switchframe *)cf - 1; - sf->sp = (int)cf; - pcb->pcb_sp = (int)sf; + pcb->pcb_sp = (register_t)cf; + pcb->pcb_lr = (register_t)fork_trampoline; /* * Now cpu_switch() can schedule the new process. @@ -187,17 +181,15 @@ cpu_set_fork_handler(td, func, arg) void (*func) __P((void *)); void *arg; { - struct switchframe *sf; struct callframe *cf; CTR3(KTR_PROC, "cpu_set_fork_handler: called with td=%08x func=%08x arg=%08x", (u_int)td, (u_int)func, (u_int)arg); - sf = (struct switchframe *)td->td_pcb->pcb_sp; - cf = (struct callframe *)sf->sp; + cf = (struct callframe *)td->td_pcb->pcb_sp; - cf->r31 = (register_t)func; - cf->r30 = (register_t)arg; + cf->cf_func = (register_t)func; + cf->cf_arg0 = (register_t)arg; } /* |