|
|
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: */
1.1.1.2 root 36: static char rcsid[] = "$Header: /usr/bill/working/sys/i386/isa/RCS/npx.c,v 1.2 92/01/21 14:34:27 william Exp $";
1.1 root 37: #include "npx.h"
38: #if NNPX > 0
39:
40: #include "param.h"
41: #include "systm.h"
42: #include "conf.h"
43: #include "file.h"
44: #include "proc.h"
45: #include "machine/cpu.h"
46: #include "machine/pcb.h"
47: #include "machine/trap.h"
48: #include "ioctl.h"
49: #include "machine/specialreg.h"
50: #include "i386/isa/isa_device.h"
51: #include "icu.h"
52: /*
53: * 387 and 287 Numeric Coprocessor Extension (NPX) Driver.
54: */
55:
56: int npxprobe(), npxattach(), npxintr();
57: struct isa_driver npxdriver = {
58: npxprobe, npxattach, "npx",
59: };
60:
61: struct proc *npxproc; /* process who owns device, otherwise zero */
62: struct pcb *npxpcb; /* owners context structure */
1.1.1.3 ! root 63: int npxexists;
1.1 root 64: extern long npx0mask;
65:
66: /*
67: * Probe routine - look device, otherwise set emulator bit
68: */
69: npxprobe(dvp)
70: struct isa_device *dvp;
71: { static status, control;
72:
73: #ifdef lint
74: npxintr();
75: #endif
76:
77: /* insure EM bit off */
1.1.1.2 root 78: load_cr0(rcr0() & ~CR0_EM); /* stop emulating */
1.1 root 79: asm(" fninit "); /* put device in known state */
80:
81: /* check for a proper status of zero */
1.1.1.2 root 82: status = 0x5a5a;
1.1 root 83: asm (" fnstsw %0 " : "=m" (status) : "m" (status) );
84:
1.1.1.2 root 85: if ((status&0xff) == 0) {
1.1 root 86:
87: /* good, now check for a proper control word */
1.1.1.2 root 88: asm (" fnstcw %0 " : "=m" (status) : "m" (status));
1.1 root 89:
1.1.1.2 root 90: if ((status&0x103f) == 0x3f) {
1.1 root 91: /* then we have a numeric coprocessor */
92: /* XXX should force an exception here to generate an intr */
93: return (1);
94: }
95: }
96:
1.1.1.3 ! root 97: /* insure EM bit on */
1.1.1.2 root 98: load_cr0(rcr0() | CR0_EM); /* start emulating */
1.1 root 99: return (0);
100: }
101:
102: /*
103: * Attach routine - announce which it is, and wire into system
104: */
105: npxattach(dvp)
106: struct isa_device *dvp;
107: {
108:
1.1.1.3 ! root 109: npxinit(__INITIAL_NPXCW__);
1.1 root 110: npxexists++;
111: npx0mask = dvp->id_irq;
112: }
113:
114: /*
1.1.1.3 ! root 115: * Initialize floating point unit.
1.1 root 116: */
117: npxinit(control) {
1.1.1.3 ! root 118: static short wd;
1.1 root 119:
120: if (npxexists == 0) return;
121:
122:
1.1.1.3 ! root 123: wd = control;
! 124: wd = 0x272;
1.1 root 125: load_cr0(rcr0() & ~CR0_EM); /* stop emulating */
1.1.1.2 root 126: asm (" fninit");
127: asm(" fldcw %0" : : "g" (wd));
1.1.1.3 ! root 128: if (curpcb) {
! 129: asm(" fnsave %0 " : : "g" (curpcb->pcb_savefpu) );
! 130: curpcb->pcb_flags |= FP_NEEDSRESTORE;
! 131: }
1.1 root 132: load_cr0(rcr0() | CR0_EM); /* start emulating */
1.1.1.3 ! root 133: outb(0xb1,0); /* reset processor */
1.1 root 134: }
135:
136: /*
137: * Load floating point context and record ownership to suite
138: */
139: npxload() {
140:
141: if (npxproc) panic ("npxload");
142: npxproc = curproc;
143: npxpcb = curpcb;
144: asm(" frstor %0 " : : "g" (curpcb->pcb_savefpu) );
145: }
146:
147: /*
148: * Unload floating point context and relinquish ownership
149: */
150: npxunload() {
151:
152: if (npxproc == 0) panic ("npxunload");
153: asm(" fsave %0 " : : "g" (npxpcb->pcb_savefpu) );
154: npxproc = 0 ;
155: }
156:
157: /*
158: * Record information needed in processing an exception and clear status word
159: */
160: npxintr(frame) struct intrframe frame; {
1.1.1.3 ! root 161: int code;
! 162: static status;
1.1 root 163:
164: outb(0xf0,0); /* reset processor */
1.1.1.3 ! root 165: /*pg("npxintr");*/
1.1 root 166:
1.1.1.3 ! root 167: asm (" fnstsw %0 " : "=m" (status) : "m" (status) );
1.1 root 168: /* sync state in process context structure, in advance of debugger/process looking for it */
169: if (npxproc == 0 || npxexists == 0) panic ("npxintr");
170: asm (" fnsave %0 " : : "g" (npxpcb->pcb_savefpu) );
171:
172: #ifdef notyet
173: /* encode the appropriate code for detailed information on this exception */
1.1.1.3 ! root 174: code = ???;
! 175: #else
! 176: code = 0; /* XXX */
1.1 root 177: #endif
178:
1.1.1.3 ! root 179: /*if((pg("status %x", status) & 0x7f) == 't') {*/
! 180: /* pass exception to process, which may not be the current one */
! 181: if (npxproc == curproc) {
! 182: /* Q: what if in an interrupt, or in trap processing? */
! 183: if (ISPL(frame.if_cs) == SEL_UPL) {
! 184: curproc->p_regs = (int *)&frame.if_es;
! 185: curpcb->pcb_flags |= FM_TRAP; /* used by sendsig */
! 186: } /* else printf("*");*/
! 187: trapsignal(curproc, SIGFPE, code);
! 188: curpcb->pcb_flags &= ~FM_TRAP; /* used by sendsig */
! 189: } else {
! 190: /* printf("P");*/
! 191: psignal(npxproc, SIGFPE);
! 192: }
! 193: /*}*/
1.1 root 194:
195: /* clear the exception so we can catch others like it */
196: asm (" fnclex");
197: }
198:
199: /*
200: * Implement device not available (DNA) exception
201: */
202: npxdna() {
1.1.1.2 root 203: /*pg("npxdna");*/
204:
1.1 root 205:
206: if (npxexists == 0) return(0);
1.1.1.2 root 207: load_cr0(rcr0() & ~CR0_EM); /* stop emulating */
208: if (curpcb->pcb_flags & FP_NEEDSRESTORE)
1.1 root 209: asm(" frstor %0 " : : "g" (curpcb->pcb_savefpu));
1.1.1.2 root 210: curpcb->pcb_flags |= FP_WASUSED | FP_NEEDSSAVE;
211: curpcb->pcb_flags &= ~FP_NEEDSRESTORE;
212: npxproc = curproc;
213: npxpcb = curpcb;
214: return (1);
1.1 root 215: }
216: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.