diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2005-10-09 14:52:13 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2005-10-09 14:52:13 +0000 |
commit | cf0567ecdec309b2995b80d2a634b5fb25391e0f (patch) | |
tree | bc38d65ad3667eccbc895186a0bfb6ba0c5e524d /sys/arch | |
parent | a802e1ffc6da9faf0266f5e2bac875f6c8bd5e67 (diff) |
Subtle changes to the powerpc fpu handling, basically fpuproc is handled
in a non-raceable manner inside save_fpu and enable_fpu so that the
eventual SMP case will not grab a half loaded fpu context.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/macppc/macppc/machdep.c | 3 | ||||
-rw-r--r-- | sys/arch/powerpc/include/fpu.h | 4 | ||||
-rw-r--r-- | sys/arch/powerpc/powerpc/fpu.c | 28 | ||||
-rw-r--r-- | sys/arch/powerpc/powerpc/process_machdep.c | 6 | ||||
-rw-r--r-- | sys/arch/powerpc/powerpc/trap.c | 14 | ||||
-rw-r--r-- | sys/arch/powerpc/powerpc/vm_machdep.c | 8 |
6 files changed, 37 insertions, 26 deletions
diff --git a/sys/arch/macppc/macppc/machdep.c b/sys/arch/macppc/macppc/machdep.c index 713f346e033..f1b741f673f 100644 --- a/sys/arch/macppc/macppc/machdep.c +++ b/sys/arch/macppc/macppc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.76 2005/10/09 14:17:32 drahn Exp $ */ +/* $OpenBSD: machdep.c,v 1.77 2005/10/09 14:52:12 drahn Exp $ */ /* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */ /* @@ -93,7 +93,6 @@ */ struct pcb *curpcb; struct pmap *curpm; -struct proc *fpuproc; extern struct user *proc0paddr; struct pool ppc_vecpl; diff --git a/sys/arch/powerpc/include/fpu.h b/sys/arch/powerpc/include/fpu.h index b845691b37a..82cd06facb3 100644 --- a/sys/arch/powerpc/include/fpu.h +++ b/sys/arch/powerpc/include/fpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fpu.h,v 1.5 2001/09/01 15:49:05 drahn Exp $ */ +/* $OpenBSD: fpu.h,v 1.6 2005/10/09 14:52:12 drahn Exp $ */ /*- * Copyright (C) 1996 Wolfgang Solfrank. @@ -67,5 +67,5 @@ #define FPCSR_RN 0x00000003 void enable_fpu(struct proc *p); -void save_fpu(struct proc *p); +void save_fpu(void); #endif /* _POWERPC_FPU_H_ */ diff --git a/sys/arch/powerpc/powerpc/fpu.c b/sys/arch/powerpc/powerpc/fpu.c index 8b09ff065da..c5672584c62 100644 --- a/sys/arch/powerpc/powerpc/fpu.c +++ b/sys/arch/powerpc/powerpc/fpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fpu.c,v 1.8 2003/10/15 02:43:09 drahn Exp $ */ +/* $OpenBSD: fpu.c,v 1.9 2005/10/09 14:52:12 drahn Exp $ */ /* $NetBSD: fpu.c,v 1.1 1996/09/30 16:34:44 ws Exp $ */ /* @@ -45,13 +45,12 @@ enable_fpu(struct proc *p) struct pcb *pcb = &p->p_addr->u_pcb; struct trapframe *tf = trapframe(p); - tf->srr1 |= PSL_FP; if (!(pcb->pcb_flags & PCB_FPU)) { bzero(&pcb->pcb_fpu, sizeof pcb->pcb_fpu); pcb->pcb_flags |= PCB_FPU; } msr = ppc_mfmsr(); - ppc_mtmsr(msr | PSL_FP); + ppc_mtmsr((msr & ~PSL_EE) | PSL_FP); __asm volatile("isync"); asm volatile ("lfd 0,0(%0); mtfsf 0xff,0" :: "b"(&pcb->pcb_fpu.fpcsr)); @@ -87,23 +86,32 @@ enable_fpu(struct proc *p) "lfd 29,232(%0);" "lfd 30,240(%0);" "lfd 31,248(%0)" :: "b"(&pcb->pcb_fpu.fpr[0])); + fpuproc = p; + tf->srr1 |= PSL_FP; ppc_mtmsr(msr); __asm volatile("isync"); } void -save_fpu(struct proc *p) +save_fpu() { int msr; struct pcb *pcb; + struct proc *p; + struct trapframe *tf; + + msr = ppc_mfmsr(); + ppc_mtmsr((msr & ~PSL_EE) | PSL_FP); + + p = fpuproc; - if (p == NULL) + if (p == NULL) { + ppc_mtmsr(msr); return; + } pcb = &p->p_addr->u_pcb; - msr = ppc_mfmsr(); - ppc_mtmsr(msr | PSL_FP); __asm volatile("isync"); asm ("stfd 0,0(%0);" @@ -139,6 +147,12 @@ save_fpu(struct proc *p) "stfd 30,240(%0);" "stfd 31,248(%0)" :: "b"(&pcb->pcb_fpu.fpr[0])); asm volatile ("mffs 0; stfd 0,0(%0)" :: "b"(&pcb->pcb_fpu.fpcsr)); + asm ("lfd 0,0(%0);" :: "b"(&pcb->pcb_fpu.fpr[0])); + + tf = trapframe(fpuproc); + tf->srr1 &= ~PSL_FP; + fpuproc = NULL; + ppc_mtmsr(msr); __asm volatile("isync"); } diff --git a/sys/arch/powerpc/powerpc/process_machdep.c b/sys/arch/powerpc/powerpc/process_machdep.c index 8c5ea10bb46..b7815091c3d 100644 --- a/sys/arch/powerpc/powerpc/process_machdep.c +++ b/sys/arch/powerpc/powerpc/process_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: process_machdep.c,v 1.9 2005/06/20 20:02:04 kettenis Exp $ */ +/* $OpenBSD: process_machdep.c,v 1.10 2005/10/09 14:52:12 drahn Exp $ */ /* $NetBSD: process_machdep.c,v 1.1 1996/09/30 16:34:53 ws Exp $ */ /* @@ -54,7 +54,7 @@ process_read_regs(struct proc *p, struct reg *regs) bzero(regs->fpr, sizeof(regs->fpr)); } else { if (p == fpuproc) - save_fpu(fpuproc); + save_fpu(); bcopy(pcb->pcb_fpu.fpr, regs->fpr, sizeof(regs->fpr)); } @@ -104,7 +104,7 @@ process_write_regs(struct proc *p, struct reg *regs) bcopy(regs->gpr, tf->fixreg, sizeof(regs->gpr)); if (p == fpuproc) { /* release the fpu */ - save_fpu(fpuproc); + save_fpu(); fpuproc = NULL; } diff --git a/sys/arch/powerpc/powerpc/trap.c b/sys/arch/powerpc/powerpc/trap.c index 575da48d5a7..c1592769f57 100644 --- a/sys/arch/powerpc/powerpc/trap.c +++ b/sys/arch/powerpc/powerpc/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.69 2005/09/15 21:09:29 miod Exp $ */ +/* $OpenBSD: trap.c,v 1.70 2005/10/09 14:52:12 drahn Exp $ */ /* $NetBSD: trap.c,v 1.3 1996/10/13 03:31:37 christos Exp $ */ /* @@ -73,6 +73,7 @@ void trap(struct trapframe *frame); volatile int want_resched; struct proc *ppc_vecproc; +struct proc *fpuproc; #ifdef DDB void ppc_dumpbt(struct trapframe *frame); @@ -523,8 +524,7 @@ syscall_bad: case EXC_FPU|EXC_USER: if (fpuproc) - save_fpu(fpuproc); - fpuproc = p; + save_fpu(); uvmexp.fpswtch++; enable_fpu(p); break; @@ -675,8 +675,6 @@ for (i = 0; i < errnum; i++) { */ if (p != ppc_vecproc) frame->srr1 &= ~PSL_VEC; - else - frame->srr1 |= PSL_VEC; #endif /* ALTIVEC */ } @@ -755,21 +753,21 @@ fix_unaligned(struct proc *p, struct trapframe *frame) */ if (fpuproc != p) { if (fpuproc) - save_fpu(fpuproc); + save_fpu(); enable_fpu(p); } - save_fpu(p); + save_fpu(); if (indicator == EXC_ALI_LFD) { if (copyin((void *)frame->dar, fpr, sizeof(double)) != 0) return -1; - enable_fpu(p); } else { if (copyout(fpr, (void *)frame->dar, sizeof(double)) != 0) return -1; } + enable_fpu(p); return 0; } break; diff --git a/sys/arch/powerpc/powerpc/vm_machdep.c b/sys/arch/powerpc/powerpc/vm_machdep.c index dfc77a82d2f..c3ff197a4ad 100644 --- a/sys/arch/powerpc/powerpc/vm_machdep.c +++ b/sys/arch/powerpc/powerpc/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.38 2004/06/24 22:35:56 drahn Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.39 2005/10/09 14:52:12 drahn Exp $ */ /* $NetBSD: vm_machdep.c,v 1.1 1996/09/30 16:34:57 ws Exp $ */ /* @@ -61,7 +61,7 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, struct pcb *pcb = &p2->p_addr->u_pcb; if (p1 == fpuproc) - save_fpu(p1); + save_fpu(); *pcb = p1->p_addr->u_pcb; #ifdef ALTIVEC @@ -170,8 +170,8 @@ cpu_exit(struct proc *p) struct pcb *pcb = &p->p_addr->u_pcb; #endif /* ALTIVEC */ - if (p == fpuproc) /* release the fpu */ - fpuproc = 0; + if (p == fpuproc) /* release the fpu */ + fpuproc = NULL; #ifdef ALTIVEC if (p == ppc_vecproc) |