summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2005-10-09 14:52:13 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2005-10-09 14:52:13 +0000
commitcf0567ecdec309b2995b80d2a634b5fb25391e0f (patch)
treebc38d65ad3667eccbc895186a0bfb6ba0c5e524d /sys/arch
parenta802e1ffc6da9faf0266f5e2bac875f6c8bd5e67 (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.c3
-rw-r--r--sys/arch/powerpc/include/fpu.h4
-rw-r--r--sys/arch/powerpc/powerpc/fpu.c28
-rw-r--r--sys/arch/powerpc/powerpc/process_machdep.c6
-rw-r--r--sys/arch/powerpc/powerpc/trap.c14
-rw-r--r--sys/arch/powerpc/powerpc/vm_machdep.c8
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)