diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2008-04-27 16:01:48 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2008-04-27 16:01:48 +0000 |
commit | bd03abea783aaa8400341d61a5af3f6f0f8f7bf2 (patch) | |
tree | 97a90dc24f46b4ea4de2ae57eaab17ac9523e52b | |
parent | 5788a8af1750cfa41066856b1ecabf16211465dc (diff) |
FPU/Altivec cleanup and prep for SMP.
-rw-r--r-- | sys/arch/powerpc/include/pcb.h | 4 | ||||
-rw-r--r-- | sys/arch/powerpc/powerpc/fpu.c | 9 | ||||
-rw-r--r-- | sys/arch/powerpc/powerpc/trap.c | 17 |
3 files changed, 24 insertions, 6 deletions
diff --git a/sys/arch/powerpc/include/pcb.h b/sys/arch/powerpc/include/pcb.h index 7560dee7b17..e6672182033 100644 --- a/sys/arch/powerpc/include/pcb.h +++ b/sys/arch/powerpc/include/pcb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pcb.h,v 1.11 2007/10/10 15:53:52 art Exp $ */ +/* $OpenBSD: pcb.h,v 1.12 2008/04/27 16:01:47 drahn Exp $ */ /* $NetBSD: pcb.h,v 1.1 1996/09/30 16:34:29 ws Exp $ */ /*- @@ -57,6 +57,8 @@ struct pcb { double fpcsr; /* FPCSR stored as double for easier access */ } pcb_fpu; /* Floating point processor */ struct vreg *pcb_vr; /* Vector unit */ + struct cpu_info *pcb_fpcpu; + struct cpu_info *pcb_veccpu; }; struct md_coredump { diff --git a/sys/arch/powerpc/powerpc/fpu.c b/sys/arch/powerpc/powerpc/fpu.c index 7b40ea97df6..b4d01c1b1d3 100644 --- a/sys/arch/powerpc/powerpc/fpu.c +++ b/sys/arch/powerpc/powerpc/fpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fpu.c,v 1.10 2007/03/20 20:59:53 kettenis Exp $ */ +/* $OpenBSD: fpu.c,v 1.11 2008/04/27 16:01:47 drahn Exp $ */ /* $NetBSD: fpu.c,v 1.1 1996/09/30 16:34:44 ws Exp $ */ /* @@ -50,6 +50,11 @@ enable_fpu(struct proc *p) bzero(&pcb->pcb_fpu, sizeof pcb->pcb_fpu); pcb->pcb_flags |= PCB_FPU; } + + if (pcb->pcb_fpcpu != NULL || ci->ci_fpuproc != NULL) { + printf("attempting to restore fpu state when in use pcb %x" + " fpproc %x\n", pcb->pcb_fpcpu, ci->ci_fpuproc); + } msr = ppc_mfmsr(); ppc_mtmsr((msr & ~PSL_EE) | PSL_FP); __asm volatile("isync"); @@ -88,6 +93,7 @@ enable_fpu(struct proc *p) "lfd 30,240(%0);" "lfd 31,248(%0)" :: "b"(&pcb->pcb_fpu.fpr[0])); ci->ci_fpuproc = p; + pcb->pcb_fpcpu = ci; tf->srr1 |= PSL_FP; ppc_mtmsr(msr); __asm volatile("isync"); @@ -154,6 +160,7 @@ save_fpu() tf = trapframe(ci->ci_fpuproc); tf->srr1 &= ~PSL_FP; ci->ci_fpuproc = NULL; + pcb->pcb_fpcpu = NULL; ppc_mtmsr(msr); __asm volatile("isync"); diff --git a/sys/arch/powerpc/powerpc/trap.c b/sys/arch/powerpc/powerpc/trap.c index b418ccc42ed..6ceff97cb4b 100644 --- a/sys/arch/powerpc/powerpc/trap.c +++ b/sys/arch/powerpc/powerpc/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.80 2008/04/27 15:59:49 drahn Exp $ */ +/* $OpenBSD: trap.c,v 1.81 2008/04/27 16:01:47 drahn Exp $ */ /* $NetBSD: trap.c,v 1.3 1996/10/13 03:31:37 christos Exp $ */ /* @@ -118,7 +118,7 @@ save_vec(struct proc *p) * in kernel mode */ oldmsr = ppc_mfmsr(); - msr = oldmsr | PSL_VEC; + msr = (oldmsr & ~PSL_EE) | PSL_VEC; ppc_mtmsr(msr); __asm__ volatile ("sync;isync"); @@ -163,6 +163,9 @@ save_vec(struct proc *p) __asm__ volatile ("mfvscr 0"); SAVE_VEC_REG(0,&pcb_vr->vscr); + curcpu()->ci_vecproc = NULL; + pcb->pcb_veccpu = NULL; + /* fix kernel msr back */ ppc_mtmsr(oldmsr); } @@ -175,6 +178,7 @@ enable_vec(struct proc *p) { struct pcb *pcb = &p->p_addr->u_pcb; struct vreg *pcb_vr = pcb->pcb_vr; + struct cpu_info *ci = curcpu(); u_int32_t oldmsr, msr; /* If this is the very first altivec instruction executed @@ -185,13 +189,19 @@ enable_vec(struct proc *p) bzero(pcb->pcb_vr, sizeof *(pcb->pcb_vr)); } + if (curcpu()->ci_vecproc != NULL || pcb->pcb_veccpu != NULL) + printf("attempting to restore vector in use vecproc %x" + " veccpu %x\n", curcpu()->ci_vecproc, pcb->pcb_veccpu); + /* first we enable vector so that we dont throw an exception * in kernel mode */ oldmsr = ppc_mfmsr(); - msr = oldmsr | PSL_VEC; + msr = (oldmsr & ~PSL_EE) | PSL_VEC; ppc_mtmsr(msr); __asm__ volatile ("sync;isync"); + ci->ci_vecproc = p; + pcb->pcb_veccpu = ci; #define LOAD_VEC_REG(reg, addr) \ __asm__ volatile ("lvxl %0, 0, %1" :: "n"(reg), "r" (addr)); @@ -643,7 +653,6 @@ for (i = 0; i < errnum; i++) { if (ci->ci_vecproc) save_vec(ci->ci_vecproc); - ci->ci_vecproc = p; enable_vec(p); break; #else /* ALTIVEC */ |