diff --git a/sys/arch/sparc/sparc/cpu.c b/sys/arch/sparc/sparc/cpu.c index 4a77ba7bf823..94997610f05c 100644 --- a/sys/arch/sparc/sparc/cpu.c +++ b/sys/arch/sparc/sparc/cpu.c @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.75 1998/09/26 20:13:56 pk Exp $ */ +/* $NetBSD: cpu.c,v 1.76 1998/09/30 18:38:57 pk Exp $ */ /* * Copyright (c) 1996 @@ -96,7 +96,6 @@ int ncpu; struct cpu_info *cpus[_MAXNCPU]; #define CPU_MID2CPUNO(mid) ((mid) - 8) -struct proc *fpproc; /* The CPU configuration driver. */ static void cpu_attach __P((struct device *, struct device *, void *)); diff --git a/sys/arch/sparc/sparc/machdep.c b/sys/arch/sparc/sparc/machdep.c index f64c725a4259..68105cc27365 100644 --- a/sys/arch/sparc/sparc/machdep.c +++ b/sys/arch/sparc/sparc/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.130 1998/09/17 02:26:26 thorpej Exp $ */ +/* $NetBSD: machdep.c,v 1.131 1998/09/30 18:38:57 pk Exp $ */ /*- * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. @@ -511,10 +511,13 @@ setregs(p, pack, stack) * 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 == fpproc) { + if (p == cpuinfo.fpproc) { savefpstate(fs); - fpproc = NULL; - } + 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; 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 a305908df689..b841bab2e6b8 100644 --- a/sys/arch/sparc/sparc/trap.c +++ b/sys/arch/sparc/sparc/trap.c @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.73 1998/09/20 20:01:15 pk Exp $ */ +/* $NetBSD: trap.c,v 1.74 1998/09/30 18:38:57 pk Exp $ */ /* * Copyright (c) 1996 @@ -256,7 +256,7 @@ static __inline void share_fpu(p, tf) struct proc *p; struct trapframe *tf; { - if ((tf->tf_psr & PSR_EF) != 0 && fpproc != p) + if ((tf->tf_psr & PSR_EF) != 0 && cpuinfo.fpproc != p) tf->tf_psr &= ~PSR_EF; } @@ -414,11 +414,27 @@ badtrap: fpu_cleanup(p, fs); break; } - if (fpproc != p) { /* we do not have it */ - if (fpproc != NULL) /* someone else had it */ - savefpstate(fpproc->p_md.md_fpstate); + if (cpuinfo.fpproc != p) { /* we do not have it */ + int mid = p->p_md.md_fpumid; + if (cpuinfo.fpproc != NULL) { /* someone else had it*/ + savefpstate(cpuinfo.fpproc->p_md.md_fpstate); + cpuinfo.fpproc->p_md.md_fpumid = -1; + } + /* + * On MP machines, some of the other FPUs might + * still have our state. We can't handle that yet, + * so panic if it happens. Possible solutions: + * (1) send an inter-processor message to have the + * other FPU save the state, or (2) don't do lazy FPU + * context switching at all. + */ + if (mid != -1 && mid != cpuinfo.mid) { + printf("own FPU on module %d\n", mid); + panic("fix this"); + } loadfpstate(fs); - fpproc = p; /* now we do have it */ + cpuinfo.fpproc = p; /* now we do have it */ + p->p_md.md_fpumid = cpuinfo.mid; } tf->tf_psr |= PSR_EF; break; @@ -503,10 +519,10 @@ badtrap: * will not match once fpu_cleanup does its job, so * we must not save again later.) */ - if (p != fpproc) + if (p != cpuinfo.fpproc) panic("fpe without being the FP user"); savefpstate(p->p_md.md_fpstate); - fpproc = NULL; + cpuinfo.fpproc = NULL; /* tf->tf_psr &= ~PSR_EF; */ /* share_fpu will do this */ fpu_cleanup(p, p->p_md.md_fpstate); /* fpu_cleanup posts signals if needed */ diff --git a/sys/arch/sparc/sparc/vm_machdep.c b/sys/arch/sparc/sparc/vm_machdep.c index 1d0e49bcdda7..23823e51e545 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.40 1998/09/09 11:17:31 thorpej Exp $ */ +/* $NetBSD: vm_machdep.c,v 1.41 1998/09/30 18:38:57 pk Exp $ */ /* * Copyright (c) 1996 @@ -201,12 +201,12 @@ vunmapbuf(bp, len) */ void cpu_fork(p1, p2) - register struct proc *p1, *p2; + struct proc *p1, *p2; { - register struct pcb *opcb = &p1->p_addr->u_pcb; - register struct pcb *npcb = &p2->p_addr->u_pcb; - register struct trapframe *tf2; - register struct rwindow *rp; + struct pcb *opcb = &p1->p_addr->u_pcb; + struct pcb *npcb = &p2->p_addr->u_pcb; + struct trapframe *tf2; + struct rwindow *rp; /* * Save all user registers to p1's stack or, in the case of @@ -223,8 +223,10 @@ cpu_fork(p1, p2) opcb->pcb_psr = getpsr(); bcopy((caddr_t)opcb, (caddr_t)npcb, sizeof(struct pcb)); if (p1->p_md.md_fpstate) { - if (p1 == fpproc) + 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); p2->p_md.md_fpstate = malloc(sizeof(struct fpstate), M_SUBPROC, M_WAITOK); bcopy(p1->p_md.md_fpstate, p2->p_md.md_fpstate, @@ -232,6 +234,8 @@ cpu_fork(p1, p2) } else p2->p_md.md_fpstate = NULL; + p2->p_md.md_fpumid = -1; + /* * Setup (kernel) stack frame that will by-pass the child * out of the kernel. (The trap frame invariably resides at @@ -322,12 +326,12 @@ void cpu_exit(p) struct proc *p; { - register struct fpstate *fs; + struct fpstate *fs; if ((fs = p->p_md.md_fpstate) != NULL) { - if (p == fpproc) { + if (p == cpuinfo.fpproc) { savefpstate(fs); - fpproc = NULL; + cpuinfo.fpproc = NULL; } free((void *)fs, M_SUBPROC); } @@ -357,7 +361,7 @@ cpu_coredump(p, vp, cred, chdr) md_core.md_tf = *p->p_md.md_tf; if (p->p_md.md_fpstate) { - if (p == fpproc) + if (p == cpuinfo.fpproc) savefpstate(p->p_md.md_fpstate); md_core.md_fpstate = *p->p_md.md_fpstate; } else