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
|
||||
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user