Commit | Line | Data |
---|---|---|
4686adac BJ |
1 | /* |
2 | * Copyright (c) 1990 W. Jolitz | |
d50f5e7d | 3 | * @(#)npx.c 1.3 (Berkeley) %G% |
4686adac BJ |
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" | |
33822afd BJ |
19 | /* |
20 | * 387 and 287 Numeric Coprocessor Extension (NPX) Driver. | |
33822afd BJ |
21 | */ |
22 | ||
23 | int npxprobe(), npxattach(), npxintr(); | |
4686adac | 24 | struct isa_driver npxdriver = { |
33822afd BJ |
25 | npxprobe, npxattach, "npx", |
26 | }; | |
27 | ||
28 | struct proc *npxproc; /* process who owns device, otherwise zero */ | |
4686adac BJ |
29 | extern struct user npxutl; /* owners user structure */ |
30 | extern struct pte Npxmap[]; /* kernel ptes mapping owner's user structure */ | |
33822afd BJ |
31 | |
32 | /* | |
33 | * Probe routine - look device, otherwise set emulator bit | |
34 | */ | |
35 | npxprobe(dvp) | |
4686adac BJ |
36 | struct isa_device *dvp; |
37 | { static status, control; | |
33822afd BJ |
38 | |
39 | #ifdef lint | |
40 | npxintr(); | |
41 | #endif | |
4686adac BJ |
42 | |
43 | /* insure EM bit off */ | |
44 | asm(" fninit "); /* put device in known state */ | |
33822afd BJ |
45 | |
46 | /* check for a proper status of zero */ | |
47 | status = 0xa5a5; | |
4686adac | 48 | asm (" fnstsw %0 " : "=m" (status) : "m" (status) ); |
33822afd BJ |
49 | |
50 | if (status == 0) { | |
33822afd BJ |
51 | |
52 | /* good, now check for a proper control word */ | |
53 | control = 0xa5a5; | |
4686adac | 54 | asm (" fnstcw %0 " : "=m" (control) : "m" (control)); |
33822afd | 55 | |
4686adac | 56 | if ((control&0x103f) == 0x3f) { |
33822afd BJ |
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) | |
4686adac | 71 | struct isa_device *dvp; |
33822afd | 72 | { |
33822afd | 73 | |
4686adac | 74 | npxinit(0x262); |
33822afd | 75 | /* check for ET bit to decide 387/287 */ |
33822afd BJ |
76 | /*outb(0xb1,0); /* reset processor */ |
77 | } | |
78 | ||
79 | /* | |
80 | * Initialize floating point unit, usually after an error | |
81 | */ | |
4686adac | 82 | npxinit(control) { |
33822afd BJ |
83 | |
84 | asm (" fninit"); | |
4686adac | 85 | asm(" fldcw %0" : : "g" (control)); |
33822afd BJ |
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); | |
4686adac | 97 | asm(" frstor %0 " : : "g" (u.u_pcb.pcb_savefpu) ); |
33822afd BJ |
98 | } |
99 | ||
100 | /* | |
101 | * Unload floating point context and relinquish ownership | |
102 | */ | |
103 | npxunload() { | |
104 | ||
105 | if (npxproc == 0) panic ("npxunload"); | |
4686adac | 106 | asm(" fsave %0 " : : "g" (npxutl.u_pcb.pcb_savefpu) ); |
33822afd BJ |
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"); | |
4686adac | 117 | asm (" fsave %0 " : : "g" (npxutl.u_pcb.pcb_savefpu) ); |
33822afd BJ |
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 | } | |
4686adac | 144 | #endif |