diff --git a/sys/arch/sparc/include/proc.h b/sys/arch/sparc/include/proc.h index f72be5112383..d534f7071247 100644 --- a/sys/arch/sparc/include/proc.h +++ b/sys/arch/sparc/include/proc.h @@ -1,4 +1,4 @@ -/* $NetBSD: proc.h,v 1.7 2000/05/26 21:20:16 thorpej Exp $ */ +/* $NetBSD: proc.h,v 1.8 2003/01/03 15:12:02 pk Exp $ */ /* * Copyright (c) 1992, 1993 @@ -51,7 +51,7 @@ struct mdproc { struct trapframe *md_tf; /* trap/syscall registers */ struct fpstate *md_fpstate; /* fpu state, if any; always resident */ u_long md_flags; - int md_fpumid; /* Module ID of last FPU used */ + struct cpu_info *md_fpu; /* Module holding FPU state */ }; /* md_flags */ diff --git a/sys/arch/sparc/sparc/machdep.c b/sys/arch/sparc/sparc/machdep.c index cf95567851f6..eb028c8107f0 100644 --- a/sys/arch/sparc/sparc/machdep.c +++ b/sys/arch/sparc/sparc/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.211 2003/01/03 11:57:47 mrg Exp $ */ +/* $NetBSD: machdep.c,v 1.212 2003/01/03 15:12:02 pk Exp $ */ /*- * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. @@ -407,18 +407,26 @@ setregs(p, pack, stack) */ psr = tf->tf_psr & (PSR_S | PSR_CWP); if ((fs = p->p_md.md_fpstate) != NULL) { + struct cpu_info *cpi; /* - * We hold an FPU state. If we own *the* FPU chip state + * We hold an FPU state. If we own *some* FPU chip state * we must get rid of it, and the only way to do that is * to save it. In any case, get rid of our FPU state. */ - if (p == cpuinfo.fpproc) { - savefpstate(fs); - cpuinfo.fpproc = NULL; - } else if (p->p_md.md_fpumid != -1) - panic("setreg: own FPU on module %d; fix this", - p->p_md.md_fpumid); - p->p_md.md_fpumid = -1; + if ((cpi = p->p_md.md_fpu) != NULL) { + if (cpi->fpproc != p) + panic("FPU(%d): fpproc %p", + cpi->ci_cpuid, cpi->fpproc); + if (p == cpuinfo.fpproc) + savefpstate(fs); +#if defined(MULTIPROCESSOR) + else + xcall((xcall_func_t)savefpstate, + (int)fs, 0, 0, 0, 1 << cpi->ci_cpuid); +#endif + cpi->fpproc = NULL; + } + p->p_md.md_fpu = NULL; free((void *)fs, M_SUBPROC); p->p_md.md_fpstate = NULL; } diff --git a/sys/arch/sparc/sparc/trap.c b/sys/arch/sparc/sparc/trap.c index d8e3be6a1a66..9bdfe33de0d7 100644 --- a/sys/arch/sparc/sparc/trap.c +++ b/sys/arch/sparc/sparc/trap.c @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.119 2002/12/31 13:17:23 pk Exp $ */ +/* $NetBSD: trap.c,v 1.120 2003/01/03 15:12:03 pk Exp $ */ /* * Copyright (c) 1996 @@ -468,34 +468,32 @@ badtrap: KERNEL_PROC_UNLOCK(p); break; } -#if notyet - simple_lock(&cpuinfo.fplock); +#if 1 if (cpuinfo.fpproc != p) { /* we do not have it */ + struct cpu_info *cpi; if (cpuinfo.fpproc != NULL) { /* someone else had it*/ savefpstate(cpuinfo.fpproc->p_md.md_fpstate); - cpuinfo.fpproc->p_md.md_fpumid = -1; + cpuinfo.fpproc->p_md.md_fpu = NULL; } /* * On MP machines, some of the other FPUs might * still have our state. Tell the owning processor * to save the process' FPU state. */ - cpi = p->p_md.md_fpumid; - if (cpi != NULL) { - if (cpi->mid == cpuinfo.mid) - panic("FPU on module %d", mid); - LOCK_XPMSG(); - simple_lock(&cpi->fplock); - simple_lock(&cpi->msg.lock); - cpi->msg.tag = XPMSG_SAVEFPU; - raise_ipi_wait_and_unlock(cpi); - UNLOCK_XPMSG(); + if ((cpi = p->p_md.md_fpu) != NULL) { + if (cpi->ci_cpuid == cpuinfo.ci_cpuid) + panic("FPU(%d): state for %p", + cpi->ci_cpuid, p); +#if defined(MULTIPROCESSOR) + xcall((xcall_func_t)savefpstate, + (int)fs, 0, 0, 0, 1 << cpi->ci_cpuid); +#endif + cpi->fpproc = NULL; } loadfpstate(fs); cpuinfo.fpproc = p; /* now we do have it */ - p->p_md.md_fpumid = cpuinfo.mid; + p->p_md.md_fpu = curcpu(); } - simple_unlock(&cpuinfo.fplock); #else if (cpuinfo.fpproc != p) { /* we do not have it */ int mid; @@ -808,7 +806,7 @@ mem_access_fault(type, ser, v, pc, psr, tf) if (cpuinfo.fpproc != p) panic("FPU enabled but wrong proc (1)"); savefpstate(p->p_md.md_fpstate); - p->p_md.md_fpumid = -1; + p->p_md.md_fpu = NULL; cpuinfo.fpproc = NULL; tf->tf_psr &= ~PSR_EF; setpsr(getpsr() & ~PSR_EF); @@ -984,7 +982,7 @@ mem_access_fault4m(type, sfsr, sfva, tf) if (cpuinfo.fpproc != p) panic("FPU enabled but wrong proc (2)"); savefpstate(p->p_md.md_fpstate); - p->p_md.md_fpumid = -1; + p->p_md.md_fpu = NULL; cpuinfo.fpproc = NULL; tf->tf_psr &= ~PSR_EF; setpsr(getpsr() & ~PSR_EF); diff --git a/sys/arch/sparc/sparc/vm_machdep.c b/sys/arch/sparc/sparc/vm_machdep.c index 0d8a1ea1fad9..15c72e8ed8ef 100644 --- a/sys/arch/sparc/sparc/vm_machdep.c +++ b/sys/arch/sparc/sparc/vm_machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: vm_machdep.c,v 1.64 2002/12/16 16:59:13 pk Exp $ */ +/* $NetBSD: vm_machdep.c,v 1.65 2003/01/03 15:12:03 pk Exp $ */ /* * Copyright (c) 1996 @@ -231,11 +231,21 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) #endif bcopy((caddr_t)opcb, (caddr_t)npcb, sizeof(struct pcb)); - if (p1->p_md.md_fpstate) { - if (p1 == cpuinfo.fpproc) - savefpstate(p1->p_md.md_fpstate); - else if (p1->p_md.md_fpumid != -1) - panic("FPU on module %d; fix this", p1->p_md.md_fpumid); + if (p1->p_md.md_fpstate != NULL) { + struct cpu_info *cpi; + if ((cpi = p1->p_md.md_fpu) != NULL) { + if (cpi->fpproc != p1) + panic("FPU(%d): fpproc %p", + cpi->ci_cpuid, cpi->fpproc); + if (p1 == cpuinfo.fpproc) + savefpstate(p1->p_md.md_fpstate); +#if defined(MULTIPROCESSOR) + else + xcall((xcall_func_t)savefpstate, + (int)p1->p_md.md_fpstate, 0, 0, 0, + 1 << cpi->ci_cpuid); +#endif + } p2->p_md.md_fpstate = malloc(sizeof(struct fpstate), M_SUBPROC, M_WAITOK); bcopy(p1->p_md.md_fpstate, p2->p_md.md_fpstate, @@ -243,7 +253,7 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) } else p2->p_md.md_fpstate = NULL; - p2->p_md.md_fpumid = -1; + p2->p_md.md_fpu = NULL; /* * Setup (kernel) stack frame that will by-pass the child @@ -303,9 +313,19 @@ cpu_exit(p) struct fpstate *fs; if ((fs = p->p_md.md_fpstate) != NULL) { - if (p == cpuinfo.fpproc) { - savefpstate(fs); - cpuinfo.fpproc = NULL; + struct cpu_info *cpi; + if ((cpi = p->p_md.md_fpu) != NULL) { + if (cpi->fpproc != p) + panic("FPU(%d): fpproc %p", + cpi->ci_cpuid, cpi->fpproc); + if (p == cpuinfo.fpproc) + savefpstate(fs); +#if defined(MULTIPROCESSOR) + else + xcall((xcall_func_t)savefpstate, + (int)fs, 0, 0, 0, 1 << cpi->ci_cpuid); +#endif + cpi->fpproc = NULL; } free((void *)fs, M_SUBPROC); }