summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorTakuya ASADA <syuu@cvs.openbsd.org>2010-01-08 01:35:53 +0000
committerTakuya ASADA <syuu@cvs.openbsd.org>2010-01-08 01:35:53 +0000
commit00c362481c438c6cc4b467504aa317a13d015c5f (patch)
tree0143ec6d0b75e1c17b0b7e54139645685227be4c /sys/arch
parent1241b457a2c904c3d40e20a5070cdbb0a70a341d (diff)
MP-safe FPU handling. ok miod@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/mips64/include/cpu.h8
-rw-r--r--sys/arch/mips64/mips64/context.S6
-rw-r--r--sys/arch/mips64/mips64/cpu.c50
-rw-r--r--sys/arch/mips64/mips64/genassym.cf3
-rw-r--r--sys/arch/mips64/mips64/lcore_float.S10
-rw-r--r--sys/arch/mips64/mips64/process_machdep.c26
-rw-r--r--sys/arch/mips64/mips64/sendsig.c20
-rw-r--r--sys/arch/mips64/mips64/trap.c15
-rw-r--r--sys/arch/mips64/mips64/vm_machdep.c30
-rw-r--r--sys/arch/sgi/sgi/machdep.c8
10 files changed, 99 insertions, 77 deletions
diff --git a/sys/arch/mips64/include/cpu.h b/sys/arch/mips64/include/cpu.h
index 57d14b39b81..cb2d70e10d1 100644
--- a/sys/arch/mips64/include/cpu.h
+++ b/sys/arch/mips64/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.50 2009/12/30 01:17:59 syuu Exp $ */
+/* $OpenBSD: cpu.h,v 1.51 2010/01/08 01:35:52 syuu Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -370,6 +370,7 @@ struct cpu_info {
struct cpu_info *ci_next; /* next cpu */
struct proc *ci_curproc;
struct user *ci_curprocpaddr;
+ struct proc *ci_fpuproc; /* pointer to last proc to use FP */
struct schedstate_percpu
ci_schedstate;
@@ -602,8 +603,9 @@ int tlb_update(vaddr_t, unsigned);
void tlb_read(int, struct tlb_entry *);
void savectx(struct user *, int);
-void MipsSaveCurFPState(struct proc *);
-void MipsSaveCurFPState16(struct proc *);
+
+void enable_fpu(struct proc *);
+void save_fpu(void);
int guarded_read_4(paddr_t, uint32_t *);
int guarded_write_4(paddr_t, uint32_t);
diff --git a/sys/arch/mips64/mips64/context.S b/sys/arch/mips64/mips64/context.S
index bf022f1f407..43c263a3e4a 100644
--- a/sys/arch/mips64/mips64/context.S
+++ b/sys/arch/mips64/mips64/context.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: context.S,v 1.37 2010/01/07 20:24:15 miod Exp $ */
+/* $OpenBSD: context.S,v 1.38 2010/01/08 01:35:52 syuu Exp $ */
/*
* Copyright (c) 2002-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -87,9 +87,9 @@ LEAF(cpu_idle_cycle, 0)
END(cpu_idle_cycle)
/*
- * cpu_switchto(struct proc *oldproc, struct proc *newproc)
+ * cpu_switchto_asm(struct proc *oldproc, struct proc *newproc)
*/
-NON_LEAF(cpu_switchto, FRAMESZ(CF_SZ), ra)
+NON_LEAF(cpu_switchto_asm, FRAMESZ(CF_SZ), ra)
GET_CPU_INFO(t1, t3)
PTR_L t3, CI_CURPROCPADDR(t1)
REG_S sp, PCB_CONTEXT+8*REGSZ(t3) # save old sp
diff --git a/sys/arch/mips64/mips64/cpu.c b/sys/arch/mips64/mips64/cpu.c
index 7edde7625f5..0dd44178805 100644
--- a/sys/arch/mips64/mips64/cpu.c
+++ b/sys/arch/mips64/mips64/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.22 2009/12/28 06:55:27 syuu Exp $ */
+/* $OpenBSD: cpu.c,v 1.23 2010/01/08 01:35:52 syuu Exp $ */
/*
* Copyright (c) 1997-2004 Opsycon AB (www.opsycon.se)
@@ -313,6 +313,54 @@ cpuattach(struct device *parent, struct device *dev, void *aux)
#endif
}
+extern void cpu_switchto_asm(struct proc *, struct proc *);
+extern void MipsSaveCurFPState(struct proc *);
+extern void MipsSaveCurFPState16(struct proc *);
+extern void MipsSwitchFPState(struct proc *, struct trap_frame *);
+extern void MipsSwitchFPState16(struct proc *, struct trap_frame *);
+
+void
+cpu_switchto(struct proc *oldproc, struct proc *newproc)
+{
+ struct cpu_info *ci = curcpu();
+ if (ci->ci_fpuproc)
+ save_fpu();
+
+ cpu_switchto_asm(oldproc, newproc);
+}
+
+void
+enable_fpu(struct proc *p)
+{
+ struct cpu_info *ci = curcpu();
+
+ KASSERT(!ci->ci_fpuproc);
+
+
+ if (p->p_md.md_regs->sr & SR_FR_32)
+ MipsSwitchFPState(NULL, p->p_md.md_regs);
+ else
+ MipsSwitchFPState16(NULL, p->p_md.md_regs);
+
+ ci->ci_fpuproc = p;
+ p->p_md.md_regs->sr |= SR_COP_1_BIT;
+ p->p_md.md_flags |= MDP_FPUSED;
+}
+
+void
+save_fpu(void)
+{
+ struct cpu_info *ci = curcpu();
+ struct proc *p;
+
+ KASSERT(ci->ci_fpuproc);
+ p = ci->ci_fpuproc;
+ if (p->p_md.md_regs->sr & SR_FR_32)
+ MipsSaveCurFPState(p);
+ else
+ MipsSaveCurFPState16(p);
+}
+
#ifdef MULTIPROCESSOR
void
cpu_boot_secondary_processors(void)
diff --git a/sys/arch/mips64/mips64/genassym.cf b/sys/arch/mips64/mips64/genassym.cf
index e87b1f3f3fc..8630c50414e 100644
--- a/sys/arch/mips64/mips64/genassym.cf
+++ b/sys/arch/mips64/mips64/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.2 2010/01/05 06:44:58 syuu Exp $
+# $OpenBSD: genassym.cf,v 1.3 2010/01/08 01:35:52 syuu Exp $
#
# Copyright (c) 1997 Per Fogelstrom / Opsycon AB
#
@@ -59,6 +59,7 @@ member pcb_segtab
struct cpu_info
member ci_curproc
member ci_curprocpaddr
+member ci_fpuproc
member ci_ipl
export CKSEG0_BASE
diff --git a/sys/arch/mips64/mips64/lcore_float.S b/sys/arch/mips64/mips64/lcore_float.S
index dad6f45e1b0..c15db784cc6 100644
--- a/sys/arch/mips64/mips64/lcore_float.S
+++ b/sys/arch/mips64/mips64/lcore_float.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: lcore_float.S,v 1.18 2010/01/01 15:04:00 miod Exp $ */
+/* $OpenBSD: lcore_float.S,v 1.19 2010/01/08 01:35:52 syuu Exp $ */
/*
* Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -279,7 +279,7 @@ END(MipsSwitchFPState16)
* None.
*
* Side effects:
- * machFPCurProcPtr is cleared.
+ * curcpu()->ci_fpuproc is cleared.
*
*----------------------------------------------------------------------------
*/
@@ -289,7 +289,8 @@ LEAF(MipsSaveCurFPState, 0)
or t0, t1, SR_COP_1_BIT|SR_FR_32 # enable the coprocessor
mtc0 t0, COP_0_STATUS_REG
ITLBNOPFIX
- PTR_S zero, machFPCurProcPtr # indicate state has been saved
+ GET_CPU_INFO(t2, t3)
+ PTR_S zero, CI_FPUPROC(t2) # indicate state has been saved
/*
* First read out the status register to make sure that all FP operations
* have completed.
@@ -349,7 +350,8 @@ LEAF(MipsSaveCurFPState16, 0)
or t0, t1, SR_COP_1_BIT # enable the coprocessor
mtc0 t0, COP_0_STATUS_REG
ITLBNOPFIX
- PTR_S zero, machFPCurProcPtr # indicate state has been saved
+ GET_CPU_INFO(t2, t3)
+ PTR_S zero, CI_FPUPROC(t2) # indicate state has been saved
/*
* First read out the status register to make sure that all FP operations
* have completed.
diff --git a/sys/arch/mips64/mips64/process_machdep.c b/sys/arch/mips64/mips64/process_machdep.c
index 93e66d282c0..fbbbeec1222 100644
--- a/sys/arch/mips64/mips64/process_machdep.c
+++ b/sys/arch/mips64/mips64/process_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: process_machdep.c,v 1.12 2010/01/01 19:26:31 miod Exp $ */
+/* $OpenBSD: process_machdep.c,v 1.13 2010/01/08 01:35:52 syuu Exp $ */
/*
* Copyright (c) 1994 Adam Glass
@@ -40,7 +40,7 @@
* From:
* Id: procfs_i386.c,v 4.1 1993/12/17 10:47:45 jsp Rel
*
- * $Id: process_machdep.c,v 1.12 2010/01/01 19:26:31 miod Exp $
+ * $Id: process_machdep.c,v 1.13 2010/01/08 01:35:52 syuu Exp $
*/
/*
@@ -85,14 +85,11 @@ process_read_regs(p, regs)
struct proc *p;
struct reg *regs;
{
- extern struct proc *machFPCurProcPtr;
+ struct cpu_info *ci = curcpu();
+
+ if (p == ci->ci_fpuproc)
+ save_fpu();
- if (p == machFPCurProcPtr) {
- if (p->p_md.md_regs->sr & SR_FR_32)
- MipsSaveCurFPState(p);
- else
- MipsSaveCurFPState16(p);
- }
bcopy(&p->p_md.md_regs->ast, &regs->r_regs[AST], REGSIZE);
regs->r_regs[ZERO] = 0;
return (0);
@@ -105,15 +102,12 @@ process_write_regs(p, regs)
struct proc *p;
struct reg *regs;
{
+ struct cpu_info *ci = curcpu();
register_t sr, ic, ipl;
- extern struct proc *machFPCurProcPtr;
- if (p == machFPCurProcPtr) {
- if (p->p_md.md_regs->sr & SR_FR_32)
- MipsSaveCurFPState(p);
- else
- MipsSaveCurFPState16(p);
- }
+ if (p == ci->ci_fpuproc)
+ save_fpu();
+
sr = p->p_md.md_regs->sr;
ic = p->p_md.md_regs->ic;
ipl = p->p_md.md_regs->ipl;
diff --git a/sys/arch/mips64/mips64/sendsig.c b/sys/arch/mips64/mips64/sendsig.c
index 474591aad89..8f8a924e4fd 100644
--- a/sys/arch/mips64/mips64/sendsig.c
+++ b/sys/arch/mips64/mips64/sendsig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sendsig.c,v 1.10 2008/05/04 09:57:47 martin Exp $ */
+/* $OpenBSD: sendsig.c,v 1.11 2010/01/08 01:35:52 syuu Exp $ */
/*
* Copyright (c) 1990 The Regents of the University of California.
@@ -104,6 +104,7 @@ sendsig(catcher, sig, mask, code, type, val)
int type;
union sigval val;
{
+ struct cpu_info *ci = curcpu();
struct proc *p = curproc;
struct sigframe *fp;
struct trap_frame *regs;
@@ -152,15 +153,10 @@ sendsig(catcher, sig, mask, code, type, val)
sizeof(ksc.sc_regs) - sizeof(register_t));
ksc.sc_fpused = p->p_md.md_flags & MDP_FPUSED;
if (ksc.sc_fpused) {
- extern struct proc *machFPCurProcPtr;
-
/* if FPU has current state, save it first */
- if (p == machFPCurProcPtr) {
- if (regs->sr & SR_FR_32)
- MipsSaveCurFPState(p);
- else
- MipsSaveCurFPState16(p);
- }
+ if (p == ci->ci_fpuproc)
+ save_fpu();
+
bcopy((caddr_t)&p->p_md.md_regs->f0, (caddr_t)ksc.sc_fpregs,
sizeof(ksc.sc_fpregs));
}
@@ -220,6 +216,7 @@ sys_sigreturn(p, v, retval)
void *v;
register_t *retval;
{
+ struct cpu_info *ci = curcpu();
struct sys_sigreturn_args /* {
syscallarg(struct sigcontext *) sigcntxp;
} */ *uap = v;
@@ -227,7 +224,6 @@ sys_sigreturn(p, v, retval)
struct trap_frame *regs;
struct sigcontext ksc;
int error;
- extern struct proc *machFPCurProcPtr;
scp = SCARG(uap, sigcntxp);
#ifdef DEBUG
@@ -265,8 +261,8 @@ sys_sigreturn(p, v, retval)
regs->mullo = scp->mullo;
regs->mulhi = scp->mulhi;
regs->sr &= ~SR_COP_1_BIT; /* Zap current FP state */
- if (p == machFPCurProcPtr)
- machFPCurProcPtr = NULL;
+ if (p == ci->ci_fpuproc)
+ ci->ci_fpuproc = NULL;
bcopy((caddr_t)&scp->sc_regs[1], (caddr_t)&regs->ast,
sizeof(scp->sc_regs) - sizeof(register_t));
if (scp->sc_fpused)
diff --git a/sys/arch/mips64/mips64/trap.c b/sys/arch/mips64/mips64/trap.c
index e1b7309e1c3..f6a1de4982f 100644
--- a/sys/arch/mips64/mips64/trap.c
+++ b/sys/arch/mips64/mips64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.56 2010/01/07 20:51:04 miod Exp $ */
+/* $OpenBSD: trap.c,v 1.57 2010/01/08 01:35:52 syuu Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -88,8 +88,6 @@
#define USERMODE(ps) (((ps) & SR_KSU_MASK) == SR_KSU_USER)
-struct proc *machFPCurProcPtr; /* pointer to last proc to use FP */
-
const char *trap_type[] = {
"external interrupt",
"TLB modification",
@@ -136,8 +134,6 @@ int kdbpeek(void *);
extern int kdb_trap(int, db_regs_t *);
#endif
-extern void MipsSwitchFPState(struct proc *, struct trap_frame *);
-extern void MipsSwitchFPState16(struct proc *, struct trap_frame *);
extern void MipsFPTrap(u_int, u_int, u_int, union sigval);
void ast(void);
@@ -764,14 +760,7 @@ printf("SIG-BUSB @%p pc %p, ra %p\n", trapframe->badvaddr, trapframe->pc, trapfr
break;
}
- if (p->p_md.md_regs->sr & SR_FR_32)
- MipsSwitchFPState(machFPCurProcPtr, p->p_md.md_regs);
- else
- MipsSwitchFPState16(machFPCurProcPtr, p->p_md.md_regs);
-
- machFPCurProcPtr = p;
- p->p_md.md_regs->sr |= SR_COP_1_BIT;
- p->p_md.md_flags |= MDP_FPUSED;
+ enable_fpu(p);
goto out;
case T_FPE:
diff --git a/sys/arch/mips64/mips64/vm_machdep.c b/sys/arch/mips64/mips64/vm_machdep.c
index 94352a1bad0..06ee454cb67 100644
--- a/sys/arch/mips64/mips64/vm_machdep.c
+++ b/sys/arch/mips64/mips64/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.21 2009/12/07 19:01:06 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.22 2010/01/08 01:35:52 syuu Exp $ */
/*
* Copyright (c) 1988 University of Utah.
* Copyright (c) 1992, 1993
@@ -68,13 +68,11 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
void (*func)(void *);
void *arg;
{
+ struct cpu_info *ci = curcpu();
struct pcb *pcb;
#if UPAGES == 1
paddr_t pa;
-#endif
- extern struct proc *machFPCurProcPtr;
-#if UPAGES == 1
/* replace p_addr with a direct translation address */
p2->p_md.md_uarea = (vaddr_t)p2->p_addr;
pmap_extract(pmap_kernel(), p2->p_md.md_uarea, &pa);
@@ -85,12 +83,8 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
/*
* If we own the FPU, save its state before copying the PCB.
*/
- if (p1 == machFPCurProcPtr) {
- if (p1->p_addr->u_pcb.pcb_regs.sr & SR_FR_32)
- MipsSaveCurFPState(p1);
- else
- MipsSaveCurFPState16(p1);
- }
+ if (p1 == ci->ci_fpuproc)
+ save_fpu();
p2->p_md.md_flags = p1->p_md.md_flags & MDP_FORKSAVE;
@@ -140,10 +134,10 @@ void
cpu_exit(p)
struct proc *p;
{
- extern struct proc *machFPCurProcPtr;
+ struct cpu_info *ci = curcpu();
- if (machFPCurProcPtr == p)
- machFPCurProcPtr = (struct proc *)0;
+ if (ci->ci_fpuproc == p)
+ ci->ci_fpuproc = NULL;
pmap_deactivate(p);
#if UPAGES == 1
@@ -163,10 +157,10 @@ cpu_coredump(p, vp, cred, chdr)
struct ucred *cred;
struct core *chdr;
{
+ struct cpu_info *ci = curcpu();
int error;
/*register struct user *up = p->p_addr;*/
struct coreseg cseg;
- extern struct proc *machFPCurProcPtr;
CORE_SETMAGIC(*chdr, COREMAGIC, MID_MIPS, 0);
chdr->c_hdrsize = ALIGN(sizeof(*chdr));
@@ -177,12 +171,8 @@ cpu_coredump(p, vp, cred, chdr)
* Copy floating point state from the FP chip if this process
* has state stored there.
*/
- if (p == machFPCurProcPtr) {
- if (p->p_md.md_regs->sr & SR_FR_32)
- MipsSaveCurFPState(p);
- else
- MipsSaveCurFPState16(p);
- }
+ if (p == ci->ci_fpuproc)
+ save_fpu();
CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MIPS, CORE_CPU);
cseg.c_addr = 0;
diff --git a/sys/arch/sgi/sgi/machdep.c b/sys/arch/sgi/sgi/machdep.c
index 185c4d2d9ef..11015429434 100644
--- a/sys/arch/sgi/sgi/machdep.c
+++ b/sys/arch/sgi/sgi/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.94 2009/12/12 20:07:10 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.95 2010/01/08 01:35:52 syuu Exp $ */
/*
* Copyright (c) 2003-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -821,7 +821,7 @@ setregs(p, pack, stack, retval)
u_long stack;
register_t *retval;
{
- extern struct proc *machFPCurProcPtr;
+ struct cpu_info *ci = curcpu();
bzero((caddr_t)p->p_md.md_regs, sizeof(struct trap_frame));
p->p_md.md_regs->sp = stack;
@@ -836,8 +836,8 @@ setregs(p, pack, stack, retval)
p->p_md.md_regs->sr |= idle_mask & SR_INT_MASK;
p->p_md.md_regs->ic = (idle_mask << 8) & IC_INT_MASK;
p->p_md.md_flags &= ~MDP_FPUSED;
- if (machFPCurProcPtr == p)
- machFPCurProcPtr = (struct proc *)0;
+ if (ci->ci_fpuproc == p)
+ ci->ci_fpuproc = (struct proc *)0;
p->p_md.md_ss_addr = 0;
p->p_md.md_pc_ctrl = 0;
p->p_md.md_watch_1 = 0;