diff options
author | Takuya ASADA <syuu@cvs.openbsd.org> | 2010-01-08 01:35:53 +0000 |
---|---|---|
committer | Takuya ASADA <syuu@cvs.openbsd.org> | 2010-01-08 01:35:53 +0000 |
commit | 00c362481c438c6cc4b467504aa317a13d015c5f (patch) | |
tree | 0143ec6d0b75e1c17b0b7e54139645685227be4c /sys/arch | |
parent | 1241b457a2c904c3d40e20a5070cdbb0a70a341d (diff) |
MP-safe FPU handling. ok miod@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/mips64/include/cpu.h | 8 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/context.S | 6 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/cpu.c | 50 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/genassym.cf | 3 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/lcore_float.S | 10 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/process_machdep.c | 26 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/sendsig.c | 20 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/trap.c | 15 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/vm_machdep.c | 30 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/machdep.c | 8 |
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, ®s->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)®s->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; |