MCPcopy Create free account
hub / github.com/F-Stack/f-stack / npx_probe

Function npx_probe

freebsd/i386/i386/npx.c:226–313  ·  view source on GitHub ↗

* Determine if an FPU is present and how to use it. */

Source from the content-addressed store, hash-verified

224 * Determine if an FPU is present and how to use it.
225 */
226static int
227npx_probe(void)
228{
229 struct gate_descriptor save_idt_npxtrap;
230 u_short control, status;
231
232 /*
233 * Modern CPUs all have an FPU that uses the INT16 interface
234 * and provide a simple way to verify that, so handle the
235 * common case right away.
236 */
237 if (cpu_feature & CPUID_FPU) {
238 hw_float = 1;
239 return (1);
240 }
241
242 save_idt_npxtrap = idt[IDT_MF];
243 setidt(IDT_MF, probetrap, SDT_SYS386TGT, SEL_KPL,
244 GSEL(GCODE_SEL, SEL_KPL));
245
246 /*
247 * Don't trap while we're probing.
248 */
249 stop_emulating();
250
251 /*
252 * Finish resetting the coprocessor, if any. If there is an error
253 * pending, then we may get a bogus IRQ13, but npx_intr() will handle
254 * it OK. Bogus halts have never been observed, but we enabled
255 * IRQ13 and cleared the BUSY# latch early to handle them anyway.
256 */
257 fninit();
258
259 /*
260 * Don't use fwait here because it might hang.
261 * Don't use fnop here because it usually hangs if there is no FPU.
262 */
263 DELAY(1000); /* wait for any IRQ13 */
264#ifdef DIAGNOSTIC
265 if (npx_traps_while_probing != 0)
266 printf("fninit caused %u bogus npx trap(s)\n",
267 npx_traps_while_probing);
268#endif
269 /*
270 * Check for a status of mostly zero.
271 */
272 status = 0x5a5a;
273 fnstsw(&status);
274 if ((status & 0xb8ff) == 0) {
275 /*
276 * Good, now check for a proper control word.
277 */
278 control = 0x5a5a;
279 fnstcw(&control);
280 if ((control & 0x1f3f) == 0x033f) {
281 /*
282 * We have an npx, now divide by 0 to see if exception
283 * 16 works.

Callers 1

npxinitFunction · 0.85

Calls 3

setidtFunction · 0.70
DELAYFunction · 0.50
printfFunction · 0.50

Tested by

no test coverage detected