Deleted Added
full compact
npx.c (45100) npx.c (45720)
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:

--- 18 unchanged lines hidden (view full) ---

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 * from: @(#)npx.c 7.2 (Berkeley) 5/12/91
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:

--- 18 unchanged lines hidden (view full) ---

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 * from: @(#)npx.c 7.2 (Berkeley) 5/12/91
35 * $Id: npx.c,v 1.65 1999/01/08 16:29:59 bde Exp $
35 * $Id: npx.c,v 1.66 1999/03/28 23:28:18 dt Exp $
36 */
37
38#include "npx.h"
39#if NNPX > 0
40
41#include "opt_debug_npx.h"
42#include "opt_math_emulate.h"
43
44#include <sys/param.h>
45#include <sys/systm.h>
36 */
37
38#include "npx.h"
39#if NNPX > 0
40
41#include "opt_debug_npx.h"
42#include "opt_math_emulate.h"
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/bus.h>
46#include <sys/kernel.h>
47#include <sys/malloc.h>
47#include <sys/kernel.h>
48#include <sys/malloc.h>
49#include <sys/module.h>
48#include <sys/sysctl.h>
49#include <sys/proc.h>
50#include <sys/sysctl.h>
51#include <sys/proc.h>
52#include <machine/bus.h>
53#include <sys/rman.h>
50#ifdef NPX_DEBUG
51#include <sys/syslog.h>
52#endif
53#include <sys/signalvar.h>
54
55#ifndef SMP
56#include <machine/asmacros.h>
57#endif
58#include <machine/cputypes.h>
59#include <machine/frame.h>
60#include <machine/ipl.h>
61#include <machine/md_var.h>
62#include <machine/pcb.h>
63#include <machine/psl.h>
64#ifndef SMP
65#include <machine/clock.h>
66#endif
54#ifdef NPX_DEBUG
55#include <sys/syslog.h>
56#endif
57#include <sys/signalvar.h>
58
59#ifndef SMP
60#include <machine/asmacros.h>
61#endif
62#include <machine/cputypes.h>
63#include <machine/frame.h>
64#include <machine/ipl.h>
65#include <machine/md_var.h>
66#include <machine/pcb.h>
67#include <machine/psl.h>
68#ifndef SMP
69#include <machine/clock.h>
70#endif
71#include <machine/resource.h>
67#include <machine/specialreg.h>
68#include <machine/segments.h>
69
70#ifndef SMP
71#include <i386/isa/icu.h>
72#include <i386/isa/intr_machdep.h>
73#include <i386/isa/isa.h>
74#endif
72#include <machine/specialreg.h>
73#include <machine/segments.h>
74
75#ifndef SMP
76#include <i386/isa/icu.h>
77#include <i386/isa/intr_machdep.h>
78#include <i386/isa/isa.h>
79#endif
75#include <i386/isa/isa_device.h>
76
77/*
78 * 387 and 287 Numeric Coprocessor Extension (NPX) Driver.
79 */
80
81/* Configuration flags. */
82#define NPX_DISABLE_I586_OPTIMIZED_BCOPY (1 << 0)
83#define NPX_DISABLE_I586_OPTIMIZED_BZERO (1 << 1)
84#define NPX_DISABLE_I586_OPTIMIZED_COPYIO (1 << 2)
85
80
81/*
82 * 387 and 287 Numeric Coprocessor Extension (NPX) Driver.
83 */
84
85/* Configuration flags. */
86#define NPX_DISABLE_I586_OPTIMIZED_BCOPY (1 << 0)
87#define NPX_DISABLE_I586_OPTIMIZED_BZERO (1 << 1)
88#define NPX_DISABLE_I586_OPTIMIZED_COPYIO (1 << 2)
89
86/* XXX - should be in header file. */
87ointhand2_t npxintr;
88
89#ifdef __GNUC__
90
91#define fldcw(addr) __asm("fldcw %0" : : "m" (*(addr)))
92#define fnclex() __asm("fnclex")
93#define fninit() __asm("fninit")
94#define fnop() __asm("fnop")
95#define fnsave(addr) __asm __volatile("fnsave %0" : "=m" (*(addr)))
96#define fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr)))

--- 17 unchanged lines hidden (view full) ---

114void frstor __P((caddr_t addr));
115void start_emulating __P((void));
116void stop_emulating __P((void));
117
118#endif /* __GNUC__ */
119
120typedef u_char bool_t;
121
90#ifdef __GNUC__
91
92#define fldcw(addr) __asm("fldcw %0" : : "m" (*(addr)))
93#define fnclex() __asm("fnclex")
94#define fninit() __asm("fninit")
95#define fnop() __asm("fnop")
96#define fnsave(addr) __asm __volatile("fnsave %0" : "=m" (*(addr)))
97#define fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr)))

--- 17 unchanged lines hidden (view full) ---

115void frstor __P((caddr_t addr));
116void start_emulating __P((void));
117void stop_emulating __P((void));
118
119#endif /* __GNUC__ */
120
121typedef u_char bool_t;
122
122static int npxattach __P((struct isa_device *dvp));
123static int npxprobe __P((struct isa_device *dvp));
124static int npxprobe1 __P((struct isa_device *dvp));
123static int npx_attach __P((device_t dev));
124 void npx_intr __P((void *));
125static int npx_probe __P((device_t dev));
126static int npx_probe1 __P((device_t dev));
125#ifdef I586_CPU
126static long timezero __P((const char *funcname,
127 void (*func)(void *buf, size_t len)));
128#endif /* I586_CPU */
129
127#ifdef I586_CPU
128static long timezero __P((const char *funcname,
129 void (*func)(void *buf, size_t len)));
130#endif /* I586_CPU */
131
130struct isa_driver npxdriver = {
131 npxprobe, npxattach, "npx",
132};
133
134int hw_float; /* XXX currently just alias for npx_exists */
135
136SYSCTL_INT(_hw,HW_FLOATINGPT, floatingpoint,
137 CTLFLAG_RD, &hw_float, 0,
138 "Floatingpoint instructions executed in hardware");
139
140#ifndef SMP
141static u_int npx0_imask = SWI_CLOCK_MASK;

--- 44 unchanged lines hidden (view full) ---

186
187/*
188 * Probe routine. Initialize cr0 to give correct behaviour for [f]wait
189 * whether the device exists or not (XXX should be elsewhere). Set flags
190 * to tell npxattach() what to do. Modify device struct if npx doesn't
191 * need to use interrupts. Return 1 if device exists.
192 */
193static int
132int hw_float; /* XXX currently just alias for npx_exists */
133
134SYSCTL_INT(_hw,HW_FLOATINGPT, floatingpoint,
135 CTLFLAG_RD, &hw_float, 0,
136 "Floatingpoint instructions executed in hardware");
137
138#ifndef SMP
139static u_int npx0_imask = SWI_CLOCK_MASK;

--- 44 unchanged lines hidden (view full) ---

184
185/*
186 * Probe routine. Initialize cr0 to give correct behaviour for [f]wait
187 * whether the device exists or not (XXX should be elsewhere). Set flags
188 * to tell npxattach() what to do. Modify device struct if npx doesn't
189 * need to use interrupts. Return 1 if device exists.
190 */
191static int
194npxprobe(dvp)
195 struct isa_device *dvp;
192npx_probe(dev)
193 device_t dev;
196{
194{
197#ifdef SMP
195/*#ifdef SMP*/
196#if 1
198
197
199 return npxprobe1(dvp);
198 return npx_probe1(dev);
200
201#else /* SMP */
202
203 int result;
204 u_long save_eflags;
205 u_char save_icu1_mask;
206 u_char save_icu2_mask;
207 struct gate_descriptor save_idt_npxintr;
208 struct gate_descriptor save_idt_npxtrap;
209 /*
210 * This routine is now just a wrapper for npxprobe1(), to install
211 * special npx interrupt and trap handlers, to enable npx interrupts
212 * and to disable other interrupts. Someday isa_configure() will
213 * install suitable handlers and run with interrupts enabled so we
214 * won't need to do so much here.
215 */
199
200#else /* SMP */
201
202 int result;
203 u_long save_eflags;
204 u_char save_icu1_mask;
205 u_char save_icu2_mask;
206 struct gate_descriptor save_idt_npxintr;
207 struct gate_descriptor save_idt_npxtrap;
208 /*
209 * This routine is now just a wrapper for npxprobe1(), to install
210 * special npx interrupt and trap handlers, to enable npx interrupts
211 * and to disable other interrupts. Someday isa_configure() will
212 * install suitable handlers and run with interrupts enabled so we
213 * won't need to do so much here.
214 */
216 npx_intrno = NRSVIDT + ffs(dvp->id_irq) - 1;
215 npx_intrno = NRSVIDT + 13;
217 save_eflags = read_eflags();
218 disable_intr();
219 save_icu1_mask = inb(IO_ICU1 + 1);
220 save_icu2_mask = inb(IO_ICU2 + 1);
221 save_idt_npxintr = idt[npx_intrno];
222 save_idt_npxtrap = idt[16];
216 save_eflags = read_eflags();
217 disable_intr();
218 save_icu1_mask = inb(IO_ICU1 + 1);
219 save_icu2_mask = inb(IO_ICU2 + 1);
220 save_idt_npxintr = idt[npx_intrno];
221 save_idt_npxtrap = idt[16];
223 outb(IO_ICU1 + 1, ~(IRQ_SLAVE | dvp->id_irq));
224 outb(IO_ICU2 + 1, ~(dvp->id_irq >> 8));
222 outb(IO_ICU1 + 1, ~IRQ_SLAVE);
223 outb(IO_ICU2 + 1, ~(1 << (13 - 8)));
225 setidt(16, probetrap, SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
226 setidt(npx_intrno, probeintr, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
227 npx_idt_probeintr = idt[npx_intrno];
228 enable_intr();
224 setidt(16, probetrap, SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
225 setidt(npx_intrno, probeintr, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
226 npx_idt_probeintr = idt[npx_intrno];
227 enable_intr();
229 result = npxprobe1(dvp);
228 result = npx_probe1(dev);
230 disable_intr();
231 outb(IO_ICU1 + 1, save_icu1_mask);
232 outb(IO_ICU2 + 1, save_icu2_mask);
233 idt[npx_intrno] = save_idt_npxintr;
234 idt[16] = save_idt_npxtrap;
235 write_eflags(save_eflags);
236 return (result);
237
238#endif /* SMP */
239}
240
241static int
229 disable_intr();
230 outb(IO_ICU1 + 1, save_icu1_mask);
231 outb(IO_ICU2 + 1, save_icu2_mask);
232 idt[npx_intrno] = save_idt_npxintr;
233 idt[16] = save_idt_npxtrap;
234 write_eflags(save_eflags);
235 return (result);
236
237#endif /* SMP */
238}
239
240static int
242npxprobe1(dvp)
243 struct isa_device *dvp;
241npx_probe1(dev)
242 device_t dev;
244{
245#ifndef SMP
246 u_short control;
247 u_short status;
248#endif
249
250 /*
251 * Partially reset the coprocessor, if any. Some BIOS's don't reset

--- 23 unchanged lines hidden (view full) ---

275 /*
276 * Finish resetting the coprocessor, if any. If there is an error
277 * pending, then we may get a bogus IRQ13, but probeintr() will handle
278 * it OK. Bogus halts have never been observed, but we enabled
279 * IRQ13 and cleared the BUSY# latch early to handle them anyway.
280 */
281 fninit();
282
243{
244#ifndef SMP
245 u_short control;
246 u_short status;
247#endif
248
249 /*
250 * Partially reset the coprocessor, if any. Some BIOS's don't reset

--- 23 unchanged lines hidden (view full) ---

274 /*
275 * Finish resetting the coprocessor, if any. If there is an error
276 * pending, then we may get a bogus IRQ13, but probeintr() will handle
277 * it OK. Bogus halts have never been observed, but we enabled
278 * IRQ13 and cleared the BUSY# latch early to handle them anyway.
279 */
280 fninit();
281
283#ifdef SMP
284
282/*#ifdef SMP*/
283#if 1
285 /*
286 * Exception 16 MUST work for SMP.
287 */
288 npx_irq13 = 0;
289 npx_ex16 = hw_float = npx_exists = 1;
284 /*
285 * Exception 16 MUST work for SMP.
286 */
287 npx_irq13 = 0;
288 npx_ex16 = hw_float = npx_exists = 1;
290 dvp->id_irq = 0; /* zap the interrupt */
291 /*
292 * special return value to flag that we do not
293 * actually use any I/O registers
294 */
295 return (-1);
289 device_set_desc(dev, "math processor");
290 return (0);
296
291
297#else /* SMP */
292#else /* !SMP */
293 device_set_desc(dev, "math processor");
298
299 /*
300 * Don't use fwait here because it might hang.
301 * Don't use fnop here because it usually hangs if there is no FPU.
302 */
303 DELAY(1000); /* wait for any IRQ13 */
304#ifdef DIAGNOSTIC
305 if (npx_intrs_while_probing != 0)

--- 24 unchanged lines hidden (view full) ---

330 fldcw(&control);
331 npx_traps_while_probing = npx_intrs_while_probing = 0;
332 fp_divide_by_0();
333 if (npx_traps_while_probing != 0) {
334 /*
335 * Good, exception 16 works.
336 */
337 npx_ex16 = 1;
294
295 /*
296 * Don't use fwait here because it might hang.
297 * Don't use fnop here because it usually hangs if there is no FPU.
298 */
299 DELAY(1000); /* wait for any IRQ13 */
300#ifdef DIAGNOSTIC
301 if (npx_intrs_while_probing != 0)

--- 24 unchanged lines hidden (view full) ---

326 fldcw(&control);
327 npx_traps_while_probing = npx_intrs_while_probing = 0;
328 fp_divide_by_0();
329 if (npx_traps_while_probing != 0) {
330 /*
331 * Good, exception 16 works.
332 */
333 npx_ex16 = 1;
338 dvp->id_irq = 0; /* zap the interrupt */
339 /*
340 * special return value to flag that we do not
341 * actually use any I/O registers
342 */
343 return (-1);
334 return (0);
344 }
345 if (npx_intrs_while_probing != 0) {
335 }
336 if (npx_intrs_while_probing != 0) {
337 int rid;
338 struct resource *r;
339 void *intr;
346 /*
347 * Bad, we are stuck with IRQ13.
348 */
349 npx_irq13 = 1;
350 /*
351 * npxattach would be too late to set npx0_imask.
352 */
340 /*
341 * Bad, we are stuck with IRQ13.
342 */
343 npx_irq13 = 1;
344 /*
345 * npxattach would be too late to set npx0_imask.
346 */
353 npx0_imask |= dvp->id_irq;
354 return (IO_NPXSIZE);
347 npx0_imask |= (1 << 13);
348
349 /*
350 * We allocate these resources permanently,
351 * so there is no need to keep track of them.
352 */
353 rid = 0;
354 r = bus_alloc_resource(dev, SYS_RES_IOPORT,
355 &rid, IO_NPX, IO_NPX,
356 IO_NPXSIZE, RF_ACTIVE);
357 if (r == 0)
358 panic("npx: can't get ports");
359 rid = 0;
360 r = bus_alloc_resource(dev, SYS_RES_IRQ,
361 &rid, 13, 13,
362 1, RF_ACTIVE);
363 if (r == 0)
364 panic("npx: can't get IRQ");
365 BUS_SETUP_INTR(device_get_parent(dev),
366 dev, r, npx_intr, 0, &intr);
367 if (intr == 0)
368 panic("npx: can't create intr");
369
370 return (0);
355 }
356 /*
357 * Worse, even IRQ13 is broken. Use emulator.
358 */
359 }
360 }
361 /*
362 * Probe failed, but we want to get to npxattach to initialize the
363 * emulator and say that it has been installed. XXX handle devices
364 * that aren't really devices better.
365 */
371 }
372 /*
373 * Worse, even IRQ13 is broken. Use emulator.
374 */
375 }
376 }
377 /*
378 * Probe failed, but we want to get to npxattach to initialize the
379 * emulator and say that it has been installed. XXX handle devices
380 * that aren't really devices better.
381 */
366 dvp->id_irq = 0;
367 /*
368 * special return value to flag that we do not
369 * actually use any I/O registers
370 */
371 return (-1);
372
382 return (0);
373#endif /* SMP */
374}
375
376/*
377 * Attach routine - announce which it is, and wire into system
378 */
379int
383#endif /* SMP */
384}
385
386/*
387 * Attach routine - announce which it is, and wire into system
388 */
389int
380npxattach(dvp)
381 struct isa_device *dvp;
390npx_attach(dev)
391 device_t dev;
382{
392{
383 dvp->id_ointr = npxintr;
393 int flags;
384
394
385 /* The caller has printed "irq 13" for the npx_irq13 case. */
386 if (!npx_irq13) {
387 printf("npx%d: ", dvp->id_unit);
395 device_print_prettyname(dev);
396 if (npx_irq13) {
397 printf("using IRQ 13 interface\n");
398 } else {
388 if (npx_ex16)
389 printf("INT 16 interface\n");
390#if defined(MATH_EMULATE) || defined(GPL_MATH_EMULATE)
391 else if (npx_exists) {
392 printf("error reporting broken; using 387 emulator\n");
393 hw_float = npx_exists = 0;
394 } else
395 printf("387 emulator\n");
396#else
397 else
398 printf("no 387 emulator in kernel!\n");
399#endif
400 }
401 npxinit(__INITIAL_NPXCW__);
402
403#ifdef I586_CPU
399 if (npx_ex16)
400 printf("INT 16 interface\n");
401#if defined(MATH_EMULATE) || defined(GPL_MATH_EMULATE)
402 else if (npx_exists) {
403 printf("error reporting broken; using 387 emulator\n");
404 hw_float = npx_exists = 0;
405 } else
406 printf("387 emulator\n");
407#else
408 else
409 printf("no 387 emulator in kernel!\n");
410#endif
411 }
412 npxinit(__INITIAL_NPXCW__);
413
414#ifdef I586_CPU
415 if (resource_int_value("npx", 0, "flags", &flags) != 0)
416 flags = 0;
417
404 if (cpu_class == CPUCLASS_586 && npx_ex16 &&
405 timezero("i586_bzero()", i586_bzero) <
406 timezero("bzero()", bzero) * 4 / 5) {
418 if (cpu_class == CPUCLASS_586 && npx_ex16 &&
419 timezero("i586_bzero()", i586_bzero) <
420 timezero("bzero()", bzero) * 4 / 5) {
407 if (!(dvp->id_flags & NPX_DISABLE_I586_OPTIMIZED_BCOPY)) {
421 if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BCOPY)) {
408 bcopy_vector = i586_bcopy;
409 ovbcopy_vector = i586_bcopy;
410 }
422 bcopy_vector = i586_bcopy;
423 ovbcopy_vector = i586_bcopy;
424 }
411 if (!(dvp->id_flags & NPX_DISABLE_I586_OPTIMIZED_BZERO))
425 if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BZERO))
412 bzero = i586_bzero;
426 bzero = i586_bzero;
413 if (!(dvp->id_flags & NPX_DISABLE_I586_OPTIMIZED_COPYIO)) {
427 if (!(flags & NPX_DISABLE_I586_OPTIMIZED_COPYIO)) {
414 copyin_vector = i586_copyin;
415 copyout_vector = i586_copyout;
416 }
417 }
418#endif
419
428 copyin_vector = i586_copyin;
429 copyout_vector = i586_copyout;
430 }
431 }
432#endif
433
420 return (1); /* XXX unused */
434 return (0); /* XXX unused */
421}
422
423/*
424 * Initialize floating point unit.
425 */
426void
427npxinit(control)
428 u_short control;

--- 60 unchanged lines hidden (view full) ---

489 *
490 * XXX the FP state is not preserved across signal handlers. So signal
491 * handlers cannot afford to do FP unless they preserve the state or
492 * longjmp() out. Both preserving the state and longjmp()ing may be
493 * destroyed by IRQ13 bugs. Clearing FP exceptions is not an acceptable
494 * solution for signals other than SIGFPE.
495 */
496void
435}
436
437/*
438 * Initialize floating point unit.
439 */
440void
441npxinit(control)
442 u_short control;

--- 60 unchanged lines hidden (view full) ---

503 *
504 * XXX the FP state is not preserved across signal handlers. So signal
505 * handlers cannot afford to do FP unless they preserve the state or
506 * longjmp() out. Both preserving the state and longjmp()ing may be
507 * destroyed by IRQ13 bugs. Clearing FP exceptions is not an acceptable
508 * solution for signals other than SIGFPE.
509 */
510void
497npxintr(unit)
498 int unit;
511npx_intr(dummy)
512 void *dummy;
499{
500 int code;
501 struct intrframe *frame;
502
503 if (npxproc == NULL || !npx_exists) {
504 printf("npxintr: npxproc = %p, curproc = %p, npx_exists = %d\n",
505 npxproc, curproc, npx_exists);
506 panic("npxintr from nowhere");

--- 6 unchanged lines hidden (view full) ---

513
514 outb(0xf0, 0);
515 fnstsw(&curpcb->pcb_savefpu.sv_ex_sw);
516 fnclex();
517
518 /*
519 * Pass exception to process.
520 */
513{
514 int code;
515 struct intrframe *frame;
516
517 if (npxproc == NULL || !npx_exists) {
518 printf("npxintr: npxproc = %p, curproc = %p, npx_exists = %d\n",
519 npxproc, curproc, npx_exists);
520 panic("npxintr from nowhere");

--- 6 unchanged lines hidden (view full) ---

527
528 outb(0xf0, 0);
529 fnstsw(&curpcb->pcb_savefpu.sv_ex_sw);
530 fnclex();
531
532 /*
533 * Pass exception to process.
534 */
521 frame = (struct intrframe *)&unit; /* XXX */
535 frame = (struct intrframe *)&dummy; /* XXX */
522 if ((ISPL(frame->if_cs) == SEL_UPL) || (frame->if_eflags & PSL_VM)) {
523 /*
524 * Interrupt is essentially a trap, so we can afford to call
525 * the SIGFPE handler (if any) as soon as the interrupt
526 * returns.
527 *
528 * XXX little or nothing is gained from this, and plenty is
529 * lost - the interrupt frame has to contain the trap frame

--- 151 unchanged lines hidden (view full) ---

681 if (bootverbose)
682 printf("%s bandwidth = %ld bytes/sec\n",
683 funcname, (long)(BUFSIZE * (int64_t)1000000 / usec));
684 free(buf, M_TEMP);
685 return (usec);
686}
687#endif /* I586_CPU */
688
536 if ((ISPL(frame->if_cs) == SEL_UPL) || (frame->if_eflags & PSL_VM)) {
537 /*
538 * Interrupt is essentially a trap, so we can afford to call
539 * the SIGFPE handler (if any) as soon as the interrupt
540 * returns.
541 *
542 * XXX little or nothing is gained from this, and plenty is
543 * lost - the interrupt frame has to contain the trap frame

--- 151 unchanged lines hidden (view full) ---

695 if (bootverbose)
696 printf("%s bandwidth = %ld bytes/sec\n",
697 funcname, (long)(BUFSIZE * (int64_t)1000000 / usec));
698 free(buf, M_TEMP);
699 return (usec);
700}
701#endif /* I586_CPU */
702
703static device_method_t npx_methods[] = {
704 /* Device interface */
705 DEVMETHOD(device_probe, npx_probe),
706 DEVMETHOD(device_attach, npx_attach),
707 DEVMETHOD(device_detach, bus_generic_detach),
708 DEVMETHOD(device_shutdown, bus_generic_shutdown),
709 DEVMETHOD(device_suspend, bus_generic_suspend),
710 DEVMETHOD(device_resume, bus_generic_resume),
711
712 { 0, 0 }
713};
714
715static driver_t npx_driver = {
716 "npx",
717 npx_methods,
718 DRIVER_TYPE_MISC,
719 1, /* no softc */
720};
721
722static devclass_t npx_devclass;
723
724/*
725 * We prefer to attach to the root nexus so that the usual case (exception 16)
726 * doesn't describe the processor as being `on isa'.
727 */
728DRIVER_MODULE(npx, nexus, npx_driver, npx_devclass, 0, 0);
729
689#endif /* NNPX > 0 */
730#endif /* NNPX > 0 */