Make the current FPU owner (`fpproc') a per-CPU entity. Unresolved issue
as yet: lazy FPU context switching may require co-operation from other CPUs.
This commit is contained in:
parent
7f233b2f7a
commit
4826aac9cf
@ -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 *));
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user