Merged sys/i386/isa/npx.c 1.110, 1.111, 1.112 KSE
Reviewed by: julian, bde, jhb
This commit is contained in:
parent
8b8a72ee71
commit
58be6f3ff5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=83429
@ -133,23 +133,23 @@ void stop_emulating __P((void));
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#ifdef CPU_ENABLE_SSE
|
||||
#define GET_FPU_CW(proc) \
|
||||
#define GET_FPU_CW(thread) \
|
||||
(cpu_fxsr ? \
|
||||
(proc)->p_addr->u_pcb.pcb_save.sv_xmm.sv_env.en_cw : \
|
||||
(proc)->p_addr->u_pcb.pcb_save.sv_87.sv_env.en_cw)
|
||||
#define GET_FPU_SW(proc) \
|
||||
(thread)->td_pcb->pcb_save.sv_xmm.sv_env.en_cw : \
|
||||
(thread)->td_pcb->pcb_save.sv_87.sv_env.en_cw)
|
||||
#define GET_FPU_SW(thread) \
|
||||
(cpu_fxsr ? \
|
||||
(proc)->p_addr->u_pcb.pcb_save.sv_xmm.sv_env.en_sw : \
|
||||
(proc)->p_addr->u_pcb.pcb_save.sv_87.sv_env.en_sw)
|
||||
(thread)->td_pcb->pcb_save.sv_xmm.sv_env.en_sw : \
|
||||
(thread)->td_pcb->pcb_save.sv_87.sv_env.en_sw)
|
||||
#define GET_FPU_EXSW_PTR(pcb) \
|
||||
(cpu_fxsr ? \
|
||||
&(pcb)->pcb_save.sv_xmm.sv_ex_sw : \
|
||||
&(pcb)->pcb_save.sv_87.sv_ex_sw)
|
||||
#else /* CPU_ENABLE_SSE */
|
||||
#define GET_FPU_CW(proc) \
|
||||
(proc->p_addr->u_pcb.pcb_save.sv_87.sv_env.en_cw)
|
||||
#define GET_FPU_SW(proc) \
|
||||
(proc->p_addr->u_pcb.pcb_save.sv_87.sv_env.en_sw)
|
||||
#define GET_FPU_CW(thread) \
|
||||
(thread->td_pcb->pcb_save.sv_87.sv_env.en_cw)
|
||||
#define GET_FPU_SW(thread) \
|
||||
(thread->td_pcb->pcb_save.sv_87.sv_env.en_sw)
|
||||
#define GET_FPU_EXSW_PTR(pcb) \
|
||||
(&(pcb)->pcb_save.sv_87.sv_ex_sw)
|
||||
#endif /* CPU_ENABLE_SSE */
|
||||
@ -255,7 +255,7 @@ static void
|
||||
npx_intr(dummy)
|
||||
void *dummy;
|
||||
{
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
|
||||
/*
|
||||
* The BUSY# latch must be cleared in all cases so that the next
|
||||
@ -268,22 +268,22 @@ npx_intr(dummy)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* npxproc is normally non-null here. In that case, schedule an
|
||||
* npxthread is normally non-null here. In that case, schedule an
|
||||
* AST to finish the exception handling in the correct context
|
||||
* (this interrupt may occur after the process has entered the
|
||||
* (this interrupt may occur after the thread has entered the
|
||||
* kernel via a syscall or an interrupt). Otherwise, the npx
|
||||
* state of the process that caused this interrupt must have been
|
||||
* pushed to the process' pcb, and clearing of the busy latch
|
||||
* state of the thread that caused this interrupt must have been
|
||||
* pushed to the thread's pcb, and clearing of the busy latch
|
||||
* above has finished the (essentially null) handling of this
|
||||
* interrupt. Control will eventually return to the instruction
|
||||
* that caused it and it will repeat. We will eventually (usually
|
||||
* soon) win the race to handle the interrupt properly.
|
||||
*/
|
||||
p = PCPU_GET(npxproc);
|
||||
if (p != NULL) {
|
||||
p->p_addr->u_pcb.pcb_flags |= PCB_NPXTRAP;
|
||||
td = PCPU_GET(npxthread);
|
||||
if (td != NULL) {
|
||||
td->td_pcb->pcb_flags |= PCB_NPXTRAP;
|
||||
mtx_lock_spin(&sched_lock);
|
||||
p->p_sflag |= PS_ASTPENDING;
|
||||
td->td_kse->ke_flags |= KEF_ASTPENDING;
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
}
|
||||
}
|
||||
@ -623,7 +623,7 @@ npxinit(control)
|
||||
/*
|
||||
* fninit has the same h/w bugs as fnsave. Use the detoxified
|
||||
* fnsave to throw away any junk in the fpu. npxsave() initializes
|
||||
* the fpu and sets npxproc = NULL as important side effects.
|
||||
* the fpu and sets npxthread = NULL as important side effects.
|
||||
*/
|
||||
savecrit = critical_enter();
|
||||
npxsave(&dummy);
|
||||
@ -639,13 +639,13 @@ npxinit(control)
|
||||
* Free coprocessor (if we have it).
|
||||
*/
|
||||
void
|
||||
npxexit(p)
|
||||
struct proc *p;
|
||||
npxexit(td)
|
||||
struct thread *td;
|
||||
{
|
||||
critical_t savecrit;
|
||||
|
||||
savecrit = critical_enter();
|
||||
if (p == PCPU_GET(npxproc))
|
||||
if (td == PCPU_GET(npxthread))
|
||||
npxsave(&PCPU_GET(curpcb)->pcb_save);
|
||||
critical_exit(savecrit);
|
||||
#ifdef NPX_DEBUG
|
||||
@ -660,8 +660,9 @@ npxexit(p)
|
||||
*/
|
||||
if (masked_exceptions & 0x0d)
|
||||
log(LOG_ERR,
|
||||
"pid %d (%s) exited with masked floating point exceptions 0x%02x\n",
|
||||
p->p_pid, p->p_comm, masked_exceptions);
|
||||
"pid %d (%s) exited with masked floating"
|
||||
" point exceptions 0x%02x\n",
|
||||
td->td_proc->p_pid, td->td_proc->p_comm, masked_exceptions);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -862,8 +863,8 @@ npxtrap()
|
||||
u_long *exstat;
|
||||
|
||||
if (!npx_exists) {
|
||||
printf("npxtrap: npxproc = %p, curproc = %p, npx_exists = %d\n",
|
||||
PCPU_GET(npxproc), curproc, npx_exists);
|
||||
printf("npxtrap: npxthread = %p, curthread = %p, npx_exists = %d\n",
|
||||
PCPU_GET(npxthread), curthread, npx_exists);
|
||||
panic("npxtrap from nowhere");
|
||||
}
|
||||
savecrit = critical_enter();
|
||||
@ -873,18 +874,18 @@ npxtrap()
|
||||
* state to memory. Fetch the relevant parts of the state from
|
||||
* wherever they are.
|
||||
*/
|
||||
if (PCPU_GET(npxproc) != curproc) {
|
||||
control = GET_FPU_CW(curproc);
|
||||
status = GET_FPU_SW(curproc);
|
||||
if (PCPU_GET(npxthread) != curthread) {
|
||||
control = GET_FPU_CW(curthread);
|
||||
status = GET_FPU_SW(curthread);
|
||||
} else {
|
||||
fnstcw(&control);
|
||||
fnstsw(&status);
|
||||
}
|
||||
|
||||
exstat = GET_FPU_EXSW_PTR(&curproc->p_addr->u_pcb);
|
||||
exstat = GET_FPU_EXSW_PTR(curthread->td_pcb);
|
||||
*exstat = status;
|
||||
if (PCPU_GET(npxproc) != curproc)
|
||||
GET_FPU_SW(curproc) &= ~0x80bf;
|
||||
if (PCPU_GET(npxthread) != curthread)
|
||||
GET_FPU_SW(curthread) &= ~0x80bf;
|
||||
else
|
||||
fnclex();
|
||||
critical_exit(savecrit);
|
||||
@ -894,7 +895,7 @@ npxtrap()
|
||||
/*
|
||||
* Implement device not available (DNA) exception
|
||||
*
|
||||
* It would be better to switch FP context here (if curproc != npxproc)
|
||||
* It would be better to switch FP context here (if curthread != npxthread)
|
||||
* and not necessarily for every context switch, but it is too hard to
|
||||
* access foreign pcb's.
|
||||
*/
|
||||
@ -906,9 +907,9 @@ npxdna()
|
||||
|
||||
if (!npx_exists)
|
||||
return (0);
|
||||
if (PCPU_GET(npxproc) != NULL) {
|
||||
printf("npxdna: npxproc = %p, curproc = %p\n",
|
||||
PCPU_GET(npxproc), curproc);
|
||||
if (PCPU_GET(npxthread) != NULL) {
|
||||
printf("npxdna: npxthread = %p, curthread = %p\n",
|
||||
PCPU_GET(npxthread), curthread);
|
||||
panic("npxdna");
|
||||
}
|
||||
s = critical_enter();
|
||||
@ -916,7 +917,7 @@ npxdna()
|
||||
/*
|
||||
* Record new context early in case frstor causes an IRQ13.
|
||||
*/
|
||||
PCPU_SET(npxproc, CURPROC);
|
||||
PCPU_SET(npxthread, curthread);
|
||||
|
||||
exstat = GET_FPU_EXSW_PTR(PCPU_GET(curpcb));
|
||||
*exstat = 0;
|
||||
@ -948,13 +949,13 @@ npxdna()
|
||||
* after the process has entered the kernel. It may even be delivered after
|
||||
* the fnsave here completes. A spurious IRQ13 for the fnsave is handled in
|
||||
* the same way as a very-late-arriving non-spurious IRQ13 from user mode:
|
||||
* it is normally ignored at first because we set npxproc to NULL; it is
|
||||
* it is normally ignored at first because we set npxthread to NULL; it is
|
||||
* normally retriggered in npxdna() after return to user mode.
|
||||
*
|
||||
* npxsave() must be called with interrupts disabled, so that it clears
|
||||
* npxproc atomically with saving the state. We require callers to do the
|
||||
* npxthread atomically with saving the state. We require callers to do the
|
||||
* disabling, since most callers need to disable interrupts anyway to call
|
||||
* npxsave() atomically with checking npxproc.
|
||||
* npxsave() atomically with checking npxthread.
|
||||
*
|
||||
* A previous version of npxsave() went to great lengths to excecute fnsave
|
||||
* with interrupts enabled in case executing it froze the CPU. This case
|
||||
@ -970,7 +971,7 @@ npxsave(addr)
|
||||
fpusave(addr);
|
||||
|
||||
start_emulating();
|
||||
PCPU_SET(npxproc, NULL);
|
||||
PCPU_SET(npxthread, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1057,7 +1058,7 @@ static devclass_t npx_devclass;
|
||||
DRIVER_MODULE(npx, nexus, npx_driver, npx_devclass, 0, 0);
|
||||
|
||||
/*
|
||||
* This sucks up the legacy ISA support assignments from PNPBIOS.
|
||||
* This sucks up the legacy ISA support assignments from PNPBIOS/ACPI.
|
||||
*/
|
||||
static struct isa_pnp_id npxisa_ids[] = {
|
||||
{ 0x040cd041, "Legacy ISA coprocessor support" }, /* PNP0C04 */
|
||||
@ -1101,4 +1102,5 @@ static driver_t npxisa_driver = {
|
||||
static devclass_t npxisa_devclass;
|
||||
|
||||
DRIVER_MODULE(npxisa, isa, npxisa_driver, npxisa_devclass, 0, 0);
|
||||
DRIVER_MODULE(npxisa, acpi, npxisa_driver, npxisa_devclass, 0, 0);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user