Make fork work, at least for kthreads. Switching still has some issues.

This commit is contained in:
Benno Rice 2002-02-28 03:24:07 +00:00
parent 183439a14a
commit 4eed0cf1be
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=91467
11 changed files with 77 additions and 110 deletions

View File

@ -939,24 +939,6 @@ s_trap:
FRAME_LEAVE(tempsave)
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
*/

View File

@ -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

View File

@ -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;
}
/*

View File

@ -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_ */

View File

@ -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 */
};

View File

@ -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));

View File

@ -939,24 +939,6 @@ s_trap:
FRAME_LEAVE(tempsave)
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
*/

View File

@ -939,24 +939,6 @@ s_trap:
FRAME_LEAVE(tempsave)
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
*/

View File

@ -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

View File

@ -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

View File

@ -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;
}
/*