date and time created 90/11/08 20:01:31 by bill
authorBill Joy <bill@ucbvax.Berkeley.EDU>
Fri, 9 Nov 1990 12:01:31 +0000 (04:01 -0800)
committerBill Joy <bill@ucbvax.Berkeley.EDU>
Fri, 9 Nov 1990 12:01:31 +0000 (04:01 -0800)
SCCS-vsn: sys/i386/isa/npx.c 1.1

usr/src/sys/i386/isa/npx.c [new file with mode: 0644]

diff --git a/usr/src/sys/i386/isa/npx.c b/usr/src/sys/i386/isa/npx.c
new file mode 100644 (file)
index 0000000..8ad0283
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * 387 and 287 Numeric Coprocessor Extension (NPX) Driver.
+ * @(#)npx.c   1.1 (Berkeley) %G%
+ */
+
+int    npxprobe(), npxattach(), npxintr();
+struct driver npxdriver = {
+       npxprobe, npxattach, "npx",
+};
+
+struct proc    *npxproc;       /* process who owns device, otherwise zero */
+struct user    *npxutl;        /* owners user structure */
+struct pte     *Npxmap;        /* kernel ptes mapping owner's user structure */
+
+/*
+ * Probe routine - look device, otherwise set emulator bit
+ */
+npxprobe(dvp)
+       struct device *dvp;
+{
+       register status;
+
+#ifdef lint
+       npxintr();
+#endif
+/* insure EM bit off */
+       asm("   fninit");       /* put device in known state */
+
+       /* check for a proper status of zero */
+       status = 0xa5a5;        
+       asm("   movw    %1,%%ax ; fnstsw %%ax ;  movw %%ax, %0"
+               : "=g" (status) : "g" (status) : "ax");
+
+       if (status == 0) {
+               register control;
+
+               /* good, now check for a proper control word */
+               control = 0xa5a5;       
+               asm("   movw    %1,%%ax ; fnstcw %%ax ;  movw %%ax, %0"
+                       : "=g" (control) : "g" (control) : "ax");
+
+               if (control&0x103f == 0x3f) {
+                       /* then we have a numeric coprocessor */
+               /* XXX should force an exception here to generate an intr */
+                       return (1);
+               }
+       }
+
+/* insure EM bit on */
+       return (0);
+}
+
+/*
+ * Attach routine - announce which it is, and wire into system
+ */
+npxattach(dvp)
+       struct device *dvp;
+{
+       int unit = dvp->unit;
+
+       npxinit();
+       /* check for ET bit to decide 387/287 */
+       INTREN(IRQ13);
+       /*outb(0xb1,0);         /* reset processor */
+}
+
+/*
+ * Initialize floating point unit, usually after an error
+ */
+npxinit() {
+       register control;
+
+       asm ("  fninit");
+       control = XXX;
+       asm("   movw    %0,%%ax ; fldcw %%ax "
+                       : "g" (control) : "ax");
+
+}
+
+/*
+ * Load floating point context and record ownership to suite
+ */
+npxload() {
+
+       if (npxproc) panic ("npxload");
+       npxproc = u.u_procp;
+       uaccess(npxproc, Npxmap, &npxutl);
+       asm("   frstor %0 " : "g" (u.u_pcb.pcb_savefpu) );
+}
+
+/*
+ * Unload floating point context and relinquish ownership
+ */
+npxunload() {
+
+       if (npxproc == 0) panic ("npxunload");
+       asm("   fsave %0 " : "g" (npxutl.u_pcb.pcb_savefpu) );
+       npxproc = 0 ;
+}
+
+/*
+ * Record information needed in processing an exception and clear status word
+ */
+npxexcept() {
+
+       /* 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
+         * on this exception
+        */
+
+       /* signal appropriate process */
+       psignal (npxproc, SIGFPE);
+
+       /* clear the exception so we can catch others like it */
+       asm ("  fnclex");
+}
+
+/*
+ * Catch AT/386 interrupt used to signal exception, and simulate trap()
+ */
+npxintr() {
+       outb(0xf0,0);
+       pg("npxintr");
+}
+
+/*
+ * Implement device not available (DNA) exception
+ */
+npxdna() {
+}