cleaning pass, removed dead code, updated comments, found boners
[unix-history] / usr / src / sys / i386 / isa / npx.c
CommitLineData
d4a75cc0
KB
1/*-
2 * Copyright (c) 1990 William Jolitz.
3 * Copyright (c) 1991 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * %sccs.include.redist.c%
7 *
a9096eab 8 * @(#)npx.c 7.2 (Berkeley) %G%
4686adac
BJ
9 */
10#include "npx.h"
d4a75cc0 11#if NNPX > 0
4686adac
BJ
12
13#include "param.h"
14#include "systm.h"
15#include "conf.h"
16#include "file.h"
8dfab1b8 17#include "proc.h"
a9096eab 18#include "machine/cpu.h"
8dfab1b8 19#include "machine/pcb.h"
a9096eab 20#include "machine/trap.h"
8dfab1b8
WN
21#include "ioctl.h"
22#include "machine/specialreg.h"
23#include "i386/isa/isa_device.h"
4686adac 24#include "icu.h"
33822afd
BJ
25/*
26 * 387 and 287 Numeric Coprocessor Extension (NPX) Driver.
33822afd
BJ
27 */
28
29int npxprobe(), npxattach(), npxintr();
4686adac 30struct isa_driver npxdriver = {
33822afd
BJ
31 npxprobe, npxattach, "npx",
32};
33
a9096eab
WN
34struct proc *npxproc; /* process who owns device, otherwise zero */
35struct pcb *npxpcb; /* owners context structure */
8dfab1b8
WN
36static npxexists;
37extern long npx0mask;
33822afd
BJ
38
39/*
40 * Probe routine - look device, otherwise set emulator bit
41 */
42npxprobe(dvp)
4686adac
BJ
43 struct isa_device *dvp;
44{ static status, control;
33822afd
BJ
45
46#ifdef lint
47 npxintr();
48#endif
4686adac
BJ
49
50 /* insure EM bit off */
51 asm(" fninit "); /* put device in known state */
33822afd
BJ
52
53 /* check for a proper status of zero */
54 status = 0xa5a5;
4686adac 55 asm (" fnstsw %0 " : "=m" (status) : "m" (status) );
33822afd
BJ
56
57 if (status == 0) {
33822afd
BJ
58
59 /* good, now check for a proper control word */
60 control = 0xa5a5;
4686adac 61 asm (" fnstcw %0 " : "=m" (control) : "m" (control));
33822afd 62
4686adac 63 if ((control&0x103f) == 0x3f) {
33822afd
BJ
64 /* then we have a numeric coprocessor */
65 /* XXX should force an exception here to generate an intr */
66 return (1);
67 }
68 }
69
70/* insure EM bit on */
71 return (0);
72}
73
74/*
75 * Attach routine - announce which it is, and wire into system
76 */
77npxattach(dvp)
4686adac 78 struct isa_device *dvp;
33822afd 79{
33822afd 80
4686adac 81 npxinit(0x262);
33822afd 82 /* check for ET bit to decide 387/287 */
33822afd 83 /*outb(0xb1,0); /* reset processor */
8dfab1b8
WN
84 npxexists++;
85 npx0mask = dvp->id_irq;
33822afd
BJ
86}
87
88/*
89 * Initialize floating point unit, usually after an error
90 */
4686adac 91npxinit(control) {
33822afd 92
8dfab1b8
WN
93 if (npxexists == 0) return;
94
95
96 load_cr0(rcr0() & ~CR0_EM); /* stop emulating */
97#ifdef INTEL_COMPAT
98 asm (" finit");
4686adac 99 asm(" fldcw %0" : : "g" (control));
a9096eab 100 asm(" fnsave %0 " : : "g" (curpcb->pcb_savefpu) );
8dfab1b8
WN
101#else
102 asm("fninit");
a9096eab 103 asm(" fnsave %0 " : : "g" (curpcb->pcb_savefpu) );
8dfab1b8
WN
104#endif
105 load_cr0(rcr0() | CR0_EM); /* start emulating */
33822afd
BJ
106
107}
108
109/*
110 * Load floating point context and record ownership to suite
111 */
112npxload() {
113
114 if (npxproc) panic ("npxload");
8dfab1b8 115 npxproc = curproc;
a9096eab
WN
116 npxpcb = curpcb;
117 asm(" frstor %0 " : : "g" (curpcb->pcb_savefpu) );
33822afd
BJ
118}
119
120/*
121 * Unload floating point context and relinquish ownership
122 */
123npxunload() {
124
125 if (npxproc == 0) panic ("npxunload");
a9096eab 126 asm(" fsave %0 " : : "g" (npxpcb->pcb_savefpu) );
33822afd
BJ
127 npxproc = 0 ;
128}
129
130/*
131 * Record information needed in processing an exception and clear status word
132 */
a9096eab
WN
133npxintr(frame) struct intrframe frame; {
134 struct trapframe tf;
8dfab1b8
WN
135
136 outb(0xf0,0); /* reset processor */
33822afd 137
a9096eab 138 /* sync state in process context structure, in advance of debugger/process looking for it */
8dfab1b8 139 if (npxproc == 0 || npxexists == 0) panic ("npxintr");
a9096eab
WN
140 asm (" fnsave %0 " : : "g" (npxpcb->pcb_savefpu) );
141
142 /*
143 * Prepair a trap frame for our generic exception processing routine, trap()
144 */
145 bcopy(&frame.if_es, &tf, sizeof(tf));
146 tf.tf_trapno = T_ARITHTRAP;
8dfab1b8 147#ifdef notyet
a9096eab
WN
148 /* encode the appropriate code for detailed information on this exception */
149 tf.tf_err = ???;
8dfab1b8 150#endif
a9096eab 151 trap(tf);
33822afd
BJ
152
153 /*
a9096eab 154 * Restore with any changes to superior frame
33822afd 155 */
a9096eab 156 bcopy(&tf, &frame.if_es, sizeof(tf));
33822afd
BJ
157
158 /* clear the exception so we can catch others like it */
159 asm (" fnclex");
160}
161
33822afd
BJ
162/*
163 * Implement device not available (DNA) exception
164 */
165npxdna() {
8dfab1b8
WN
166
167 if (npxexists == 0) return(0);
a9096eab
WN
168 if (!(curpcb->pcb_flags & FP_WASUSED)
169 ||(curpcb->pcb_flags & FP_NEEDSRESTORE)) {
8dfab1b8 170 load_cr0(rcr0() & ~CR0_EM); /* stop emulating */
a9096eab
WN
171 asm(" frstor %0 " : : "g" (curpcb->pcb_savefpu));
172 curpcb->pcb_flags |= FP_WASUSED | FP_NEEDSSAVE;
173 curpcb->pcb_flags &= ~FP_NEEDSRESTORE;
8dfab1b8 174 npxproc = curproc;
a9096eab 175 npxpcb = curpcb;
8dfab1b8
WN
176
177 return(1);
178 }
179 return (0);
33822afd 180}
4686adac 181#endif