xref: /original-bsd/sys/i386/isa/npx.c (revision 7c3db03c)
1 /*
2  * Copyright (c) 1990 W. Jolitz
3  * @(#)npx.c	1.3 (Berkeley) 01/08/91
4  */
5 #include "npx.h"
6 #if	NNPX > 0
7 
8 #include "param.h"
9 #include "systm.h"
10 #include "conf.h"
11 #include "file.h"
12 #include "dir.h"
13 #include "user.h"
14 #include "ioctl.h"
15 #include "vm.h"
16 #include "machine/pte.h"
17 #include "machine/isa/isa_device.h"
18 #include "icu.h"
19 /*
20  * 387 and 287 Numeric Coprocessor Extension (NPX) Driver.
21  */
22 
23 int	npxprobe(), npxattach(), npxintr();
24 struct	isa_driver npxdriver = {
25 	npxprobe, npxattach, "npx",
26 };
27 
28 struct proc	*npxproc;	/* process who owns device, otherwise zero */
29 extern struct user npxutl;	/* owners user structure */
30 extern struct pte Npxmap[];	/* kernel ptes mapping owner's user structure */
31 
32 /*
33  * Probe routine - look device, otherwise set emulator bit
34  */
35 npxprobe(dvp)
36 	struct isa_device *dvp;
37 {	static status, control;
38 
39 #ifdef lint
40 	npxintr();
41 #endif
42 
43 	/* insure EM bit off */
44 	asm("	fninit ");	/* put device in known state */
45 
46 	/* check for a proper status of zero */
47 	status = 0xa5a5;
48 	asm ("	fnstsw	%0 " : "=m" (status) : "m" (status) );
49 
50 	if (status == 0) {
51 
52 		/* good, now check for a proper control word */
53 		control = 0xa5a5;
54 		asm ("	fnstcw %0 " : "=m" (control) : "m" (control));
55 
56 		if ((control&0x103f) == 0x3f) {
57 			/* then we have a numeric coprocessor */
58 		/* XXX should force an exception here to generate an intr */
59 			return (1);
60 		}
61 	}
62 
63 /* insure EM bit on */
64 	return (0);
65 }
66 
67 /*
68  * Attach routine - announce which it is, and wire into system
69  */
70 npxattach(dvp)
71 	struct isa_device *dvp;
72 {
73 
74 	npxinit(0x262);
75 	/* check for ET bit to decide 387/287 */
76 	/*outb(0xb1,0);		/* reset processor */
77 }
78 
79 /*
80  * Initialize floating point unit, usually after an error
81  */
82 npxinit(control) {
83 
84 	asm ("	fninit");
85 	asm("	fldcw %0" : : "g" (control));
86 
87 }
88 
89 /*
90  * Load floating point context and record ownership to suite
91  */
92 npxload() {
93 
94 	if (npxproc) panic ("npxload");
95 	npxproc = u.u_procp;
96 	uaccess(npxproc, Npxmap, &npxutl);
97 	asm("	frstor %0 " : : "g" (u.u_pcb.pcb_savefpu) );
98 }
99 
100 /*
101  * Unload floating point context and relinquish ownership
102  */
103 npxunload() {
104 
105 	if (npxproc == 0) panic ("npxunload");
106 	asm("	fsave %0 " : : "g" (npxutl.u_pcb.pcb_savefpu) );
107 	npxproc = 0 ;
108 }
109 
110 /*
111  * Record information needed in processing an exception and clear status word
112  */
113 npxexcept() {
114 
115 	/* save state in appropriate user structure */
116 	if (npxproc == 0) panic ("npxexcept");
117 	asm ("	fsave %0 " : : "g" (npxutl.u_pcb.pcb_savefpu) );
118 
119 	/*
120 	 * encode the appropriate u_code for detailed information
121          * on this exception
122 	 */
123 
124 	/* signal appropriate process */
125 	psignal (npxproc, SIGFPE);
126 
127 	/* clear the exception so we can catch others like it */
128 	asm ("	fnclex");
129 }
130 
131 /*
132  * Catch AT/386 interrupt used to signal exception, and simulate trap()
133  */
134 npxintr() {
135 	outb(0xf0,0);
136 	pg("npxintr");
137 }
138 
139 /*
140  * Implement device not available (DNA) exception
141  */
142 npxdna() {
143 }
144 #endif
145