|
|
1.1 root 1: /*-
2: * Copyright (c) 1990 William Jolitz.
3: * Copyright (c) 1991 The Regents of the University of California.
4: * All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: * 3. All advertising materials mentioning features or use of this software
15: * must display the following acknowledgement:
16: * This product includes software developed by the University of
17: * California, Berkeley and its contributors.
18: * 4. Neither the name of the University nor the names of its contributors
19: * may be used to endorse or promote products derived from this software
20: * without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32: * SUCH DAMAGE.
33: *
34: * @(#)npx.c 7.2 (Berkeley) 5/12/91
35: */
36: #include "npx.h"
37: #if NNPX > 0
38:
39: #include "param.h"
40: #include "systm.h"
41: #include "conf.h"
42: #include "file.h"
43: #include "proc.h"
44: #include "machine/cpu.h"
45: #include "machine/pcb.h"
46: #include "machine/trap.h"
47: #include "ioctl.h"
48: #include "machine/specialreg.h"
49: #include "i386/isa/isa_device.h"
50: #include "icu.h"
51: /*
52: * 387 and 287 Numeric Coprocessor Extension (NPX) Driver.
53: */
54:
55: int npxprobe(), npxattach(), npxintr();
56: struct isa_driver npxdriver = {
57: npxprobe, npxattach, "npx",
58: };
59:
60: struct proc *npxproc; /* process who owns device, otherwise zero */
61: struct pcb *npxpcb; /* owners context structure */
62: static npxexists;
63: extern long npx0mask;
64:
65: /*
66: * Probe routine - look device, otherwise set emulator bit
67: */
68: npxprobe(dvp)
69: struct isa_device *dvp;
70: { static status, control;
71:
72: #ifdef lint
73: npxintr();
74: #endif
75:
76: /* insure EM bit off */
77: asm(" fninit "); /* put device in known state */
78:
79: /* check for a proper status of zero */
80: status = 0xa5a5;
81: asm (" fnstsw %0 " : "=m" (status) : "m" (status) );
82:
83: if (status == 0) {
84:
85: /* good, now check for a proper control word */
86: control = 0xa5a5;
87: asm (" fnstcw %0 " : "=m" (control) : "m" (control));
88:
89: if ((control&0x103f) == 0x3f) {
90: /* then we have a numeric coprocessor */
91: /* XXX should force an exception here to generate an intr */
92: return (1);
93: }
94: }
95:
96: /* insure EM bit on */
97: return (0);
98: }
99:
100: /*
101: * Attach routine - announce which it is, and wire into system
102: */
103: npxattach(dvp)
104: struct isa_device *dvp;
105: {
106:
107: npxinit(0x262);
108: /* check for ET bit to decide 387/287 */
109: /*outb(0xb1,0); /* reset processor */
110: npxexists++;
111: npx0mask = dvp->id_irq;
112: }
113:
114: /*
115: * Initialize floating point unit, usually after an error
116: */
117: npxinit(control) {
118:
119: if (npxexists == 0) return;
120:
121:
122: load_cr0(rcr0() & ~CR0_EM); /* stop emulating */
123: #ifdef INTEL_COMPAT
124: asm (" finit");
125: asm(" fldcw %0" : : "g" (control));
126: asm(" fnsave %0 " : : "g" (curpcb->pcb_savefpu) );
127: #else
128: asm("fninit");
129: asm(" fnsave %0 " : : "g" (curpcb->pcb_savefpu) );
130: #endif
131: load_cr0(rcr0() | CR0_EM); /* start emulating */
132:
133: }
134:
135: /*
136: * Load floating point context and record ownership to suite
137: */
138: npxload() {
139:
140: if (npxproc) panic ("npxload");
141: npxproc = curproc;
142: npxpcb = curpcb;
143: asm(" frstor %0 " : : "g" (curpcb->pcb_savefpu) );
144: }
145:
146: /*
147: * Unload floating point context and relinquish ownership
148: */
149: npxunload() {
150:
151: if (npxproc == 0) panic ("npxunload");
152: asm(" fsave %0 " : : "g" (npxpcb->pcb_savefpu) );
153: npxproc = 0 ;
154: }
155:
156: /*
157: * Record information needed in processing an exception and clear status word
158: */
159: npxintr(frame) struct intrframe frame; {
160: struct trapframe tf;
161:
162: outb(0xf0,0); /* reset processor */
163:
164: /* sync state in process context structure, in advance of debugger/process looking for it */
165: if (npxproc == 0 || npxexists == 0) panic ("npxintr");
166: asm (" fnsave %0 " : : "g" (npxpcb->pcb_savefpu) );
167:
168: /*
169: * Prepair a trap frame for our generic exception processing routine, trap()
170: */
171: bcopy(&frame.if_es, &tf, sizeof(tf));
172: tf.tf_trapno = T_ARITHTRAP;
173: #ifdef notyet
174: /* encode the appropriate code for detailed information on this exception */
175: tf.tf_err = ???;
176: #endif
177: trap(tf);
178:
179: /*
180: * Restore with any changes to superior frame
181: */
182: bcopy(&tf, &frame.if_es, sizeof(tf));
183:
184: /* clear the exception so we can catch others like it */
185: asm (" fnclex");
186: }
187:
188: /*
189: * Implement device not available (DNA) exception
190: */
191: npxdna() {
192:
193: if (npxexists == 0) return(0);
194: if (!(curpcb->pcb_flags & FP_WASUSED)
195: ||(curpcb->pcb_flags & FP_NEEDSRESTORE)) {
196: load_cr0(rcr0() & ~CR0_EM); /* stop emulating */
197: asm(" frstor %0 " : : "g" (curpcb->pcb_savefpu));
198: curpcb->pcb_flags |= FP_WASUSED | FP_NEEDSSAVE;
199: curpcb->pcb_flags &= ~FP_NEEDSRESTORE;
200: npxproc = curproc;
201: npxpcb = curpcb;
202:
203: return(1);
204: }
205: return (0);
206: }
207: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.