Finish FPU context switching on SMP systems.
This commit is contained in:
parent
7f468ee029
commit
ff451161e2
@ -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
|
* Copyright (c) 1992, 1993
|
||||||
@ -51,7 +51,7 @@ struct mdproc {
|
|||||||
struct trapframe *md_tf; /* trap/syscall registers */
|
struct trapframe *md_tf; /* trap/syscall registers */
|
||||||
struct fpstate *md_fpstate; /* fpu state, if any; always resident */
|
struct fpstate *md_fpstate; /* fpu state, if any; always resident */
|
||||||
u_long md_flags;
|
u_long md_flags;
|
||||||
int md_fpumid; /* Module ID of last FPU used */
|
struct cpu_info *md_fpu; /* Module holding FPU state */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* md_flags */
|
/* md_flags */
|
||||||
|
@ -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.
|
* 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);
|
psr = tf->tf_psr & (PSR_S | PSR_CWP);
|
||||||
if ((fs = p->p_md.md_fpstate) != NULL) {
|
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
|
* 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.
|
* to save it. In any case, get rid of our FPU state.
|
||||||
*/
|
*/
|
||||||
if (p == cpuinfo.fpproc) {
|
if ((cpi = p->p_md.md_fpu) != NULL) {
|
||||||
savefpstate(fs);
|
if (cpi->fpproc != p)
|
||||||
cpuinfo.fpproc = NULL;
|
panic("FPU(%d): fpproc %p",
|
||||||
} else if (p->p_md.md_fpumid != -1)
|
cpi->ci_cpuid, cpi->fpproc);
|
||||||
panic("setreg: own FPU on module %d; fix this",
|
if (p == cpuinfo.fpproc)
|
||||||
p->p_md.md_fpumid);
|
savefpstate(fs);
|
||||||
p->p_md.md_fpumid = -1;
|
#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);
|
free((void *)fs, M_SUBPROC);
|
||||||
p->p_md.md_fpstate = NULL;
|
p->p_md.md_fpstate = NULL;
|
||||||
}
|
}
|
||||||
|
@ -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
|
* Copyright (c) 1996
|
||||||
@ -468,34 +468,32 @@ badtrap:
|
|||||||
KERNEL_PROC_UNLOCK(p);
|
KERNEL_PROC_UNLOCK(p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if notyet
|
#if 1
|
||||||
simple_lock(&cpuinfo.fplock);
|
|
||||||
if (cpuinfo.fpproc != p) { /* we do not have it */
|
if (cpuinfo.fpproc != p) { /* we do not have it */
|
||||||
|
struct cpu_info *cpi;
|
||||||
if (cpuinfo.fpproc != NULL) { /* someone else had it*/
|
if (cpuinfo.fpproc != NULL) { /* someone else had it*/
|
||||||
savefpstate(cpuinfo.fpproc->p_md.md_fpstate);
|
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
|
* On MP machines, some of the other FPUs might
|
||||||
* still have our state. Tell the owning processor
|
* still have our state. Tell the owning processor
|
||||||
* to save the process' FPU state.
|
* to save the process' FPU state.
|
||||||
*/
|
*/
|
||||||
cpi = p->p_md.md_fpumid;
|
if ((cpi = p->p_md.md_fpu) != NULL) {
|
||||||
if (cpi != NULL) {
|
if (cpi->ci_cpuid == cpuinfo.ci_cpuid)
|
||||||
if (cpi->mid == cpuinfo.mid)
|
panic("FPU(%d): state for %p",
|
||||||
panic("FPU on module %d", mid);
|
cpi->ci_cpuid, p);
|
||||||
LOCK_XPMSG();
|
#if defined(MULTIPROCESSOR)
|
||||||
simple_lock(&cpi->fplock);
|
xcall((xcall_func_t)savefpstate,
|
||||||
simple_lock(&cpi->msg.lock);
|
(int)fs, 0, 0, 0, 1 << cpi->ci_cpuid);
|
||||||
cpi->msg.tag = XPMSG_SAVEFPU;
|
#endif
|
||||||
raise_ipi_wait_and_unlock(cpi);
|
cpi->fpproc = NULL;
|
||||||
UNLOCK_XPMSG();
|
|
||||||
}
|
}
|
||||||
loadfpstate(fs);
|
loadfpstate(fs);
|
||||||
cpuinfo.fpproc = p; /* now we do have it */
|
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
|
#else
|
||||||
if (cpuinfo.fpproc != p) { /* we do not have it */
|
if (cpuinfo.fpproc != p) { /* we do not have it */
|
||||||
int mid;
|
int mid;
|
||||||
@ -808,7 +806,7 @@ mem_access_fault(type, ser, v, pc, psr, tf)
|
|||||||
if (cpuinfo.fpproc != p)
|
if (cpuinfo.fpproc != p)
|
||||||
panic("FPU enabled but wrong proc (1)");
|
panic("FPU enabled but wrong proc (1)");
|
||||||
savefpstate(p->p_md.md_fpstate);
|
savefpstate(p->p_md.md_fpstate);
|
||||||
p->p_md.md_fpumid = -1;
|
p->p_md.md_fpu = NULL;
|
||||||
cpuinfo.fpproc = NULL;
|
cpuinfo.fpproc = NULL;
|
||||||
tf->tf_psr &= ~PSR_EF;
|
tf->tf_psr &= ~PSR_EF;
|
||||||
setpsr(getpsr() & ~PSR_EF);
|
setpsr(getpsr() & ~PSR_EF);
|
||||||
@ -984,7 +982,7 @@ mem_access_fault4m(type, sfsr, sfva, tf)
|
|||||||
if (cpuinfo.fpproc != p)
|
if (cpuinfo.fpproc != p)
|
||||||
panic("FPU enabled but wrong proc (2)");
|
panic("FPU enabled but wrong proc (2)");
|
||||||
savefpstate(p->p_md.md_fpstate);
|
savefpstate(p->p_md.md_fpstate);
|
||||||
p->p_md.md_fpumid = -1;
|
p->p_md.md_fpu = NULL;
|
||||||
cpuinfo.fpproc = NULL;
|
cpuinfo.fpproc = NULL;
|
||||||
tf->tf_psr &= ~PSR_EF;
|
tf->tf_psr &= ~PSR_EF;
|
||||||
setpsr(getpsr() & ~PSR_EF);
|
setpsr(getpsr() & ~PSR_EF);
|
||||||
|
@ -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
|
* Copyright (c) 1996
|
||||||
@ -231,11 +231,21 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bcopy((caddr_t)opcb, (caddr_t)npcb, sizeof(struct pcb));
|
bcopy((caddr_t)opcb, (caddr_t)npcb, sizeof(struct pcb));
|
||||||
if (p1->p_md.md_fpstate) {
|
if (p1->p_md.md_fpstate != NULL) {
|
||||||
if (p1 == cpuinfo.fpproc)
|
struct cpu_info *cpi;
|
||||||
savefpstate(p1->p_md.md_fpstate);
|
if ((cpi = p1->p_md.md_fpu) != NULL) {
|
||||||
else if (p1->p_md.md_fpumid != -1)
|
if (cpi->fpproc != p1)
|
||||||
panic("FPU on module %d; fix this", p1->p_md.md_fpumid);
|
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),
|
p2->p_md.md_fpstate = malloc(sizeof(struct fpstate),
|
||||||
M_SUBPROC, M_WAITOK);
|
M_SUBPROC, M_WAITOK);
|
||||||
bcopy(p1->p_md.md_fpstate, p2->p_md.md_fpstate,
|
bcopy(p1->p_md.md_fpstate, p2->p_md.md_fpstate,
|
||||||
@ -243,7 +253,7 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
|
|||||||
} else
|
} else
|
||||||
p2->p_md.md_fpstate = NULL;
|
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
|
* Setup (kernel) stack frame that will by-pass the child
|
||||||
@ -303,9 +313,19 @@ cpu_exit(p)
|
|||||||
struct fpstate *fs;
|
struct fpstate *fs;
|
||||||
|
|
||||||
if ((fs = p->p_md.md_fpstate) != NULL) {
|
if ((fs = p->p_md.md_fpstate) != NULL) {
|
||||||
if (p == cpuinfo.fpproc) {
|
struct cpu_info *cpi;
|
||||||
savefpstate(fs);
|
if ((cpi = p->p_md.md_fpu) != NULL) {
|
||||||
cpuinfo.fpproc = 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);
|
free((void *)fs, M_SUBPROC);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user