* Copyright (c) 1990 W. Jolitz
* @(#)npx.c 1.3 (Berkeley) %G%
#include "machine/isa/isa_device.h"
* 387 and 287 Numeric Coprocessor Extension (NPX) Driver.
int npxprobe(), npxattach(), npxintr();
struct isa_driver npxdriver
= {
npxprobe
, npxattach
, "npx",
struct proc
*npxproc
; /* process who owns device, otherwise zero */
extern struct user npxutl
; /* owners user structure */
extern struct pte Npxmap
[]; /* kernel ptes mapping owner's user structure */
* Probe routine - look device, otherwise set emulator bit
{ static status
, control
;
asm(" fninit "); /* put device in known state */
/* check for a proper status of zero */
asm (" fnstsw %0 " : "=m" (status
) : "m" (status
) );
/* good, now check for a proper control word */
asm (" fnstcw %0 " : "=m" (control
) : "m" (control
));
if ((control
&0x103f) == 0x3f) {
/* then we have a numeric coprocessor */
/* XXX should force an exception here to generate an intr */
* Attach routine - announce which it is, and wire into system
/* check for ET bit to decide 387/287 */
/*outb(0xb1,0); /* reset processor */
* Initialize floating point unit, usually after an error
asm(" fldcw %0" : : "g" (control
));
* Load floating point context and record ownership to suite
if (npxproc
) panic ("npxload");
uaccess(npxproc
, Npxmap
, &npxutl
);
asm(" frstor %0 " : : "g" (u
.u_pcb
.pcb_savefpu
) );
* Unload floating point context and relinquish ownership
if (npxproc
== 0) panic ("npxunload");
asm(" fsave %0 " : : "g" (npxutl
.u_pcb
.pcb_savefpu
) );
* Record information needed in processing an exception and clear status word
/* save state in appropriate user structure */
if (npxproc
== 0) panic ("npxexcept");
asm (" fsave %0 " : : "g" (npxutl
.u_pcb
.pcb_savefpu
) );
* encode the appropriate u_code for detailed information
/* signal appropriate process */
psignal (npxproc
, SIGFPE
);
/* clear the exception so we can catch others like it */
* Catch AT/386 interrupt used to signal exception, and simulate trap()
* Implement device not available (DNA) exception