npx.c (47226) | npx.c (49081) |
---|---|
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.72 1999/05/11 16:29:18 luoqi Exp $ | 35 * $Id: npx.c,v 1.73 1999/05/15 17:58:58 peter 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 --- 37 unchanged lines hidden (view full) --- 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) | 36 */ 37 38#include "npx.h" 39#if NNPX > 0 40 41#include "opt_debug_npx.h" 42#include "opt_math_emulate.h" 43 --- 37 unchanged lines hidden (view full) --- 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#define NPX_PREFER_EMULATOR (1 << 3) |
|
89 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))) --- 294 unchanged lines hidden (view full) --- 391 392/* 393 * Attach routine - announce which it is, and wire into system 394 */ 395int 396npx_attach(dev) 397 device_t dev; 398{ | 90 91#ifdef __GNUC__ 92 93#define fldcw(addr) __asm("fldcw %0" : : "m" (*(addr))) 94#define fnclex() __asm("fnclex") 95#define fninit() __asm("fninit") 96#define fnop() __asm("fnop") 97#define fnsave(addr) __asm __volatile("fnsave %0" : "=m" (*(addr))) --- 294 unchanged lines hidden (view full) --- 392 393/* 394 * Attach routine - announce which it is, and wire into system 395 */ 396int 397npx_attach(dev) 398 device_t dev; 399{ |
399#ifdef I586_CPU | |
400 int flags; | 400 int flags; |
401#endif | |
402 | 401 |
402 if (resource_int_value("npx", 0, "flags", &flags) != 0) 403 flags = 0; 404 |
|
403 device_print_prettyname(dev); 404 if (npx_irq13) { 405 printf("using IRQ 13 interface\n"); 406 } else { | 405 device_print_prettyname(dev); 406 if (npx_irq13) { 407 printf("using IRQ 13 interface\n"); 408 } else { |
407 if (npx_ex16) 408 printf("INT 16 interface\n"); | |
409#if defined(MATH_EMULATE) || defined(GPL_MATH_EMULATE) | 409#if defined(MATH_EMULATE) || defined(GPL_MATH_EMULATE) |
410 else if (npx_exists) { | 410 if (npx_ex16) { 411 if (!(flags & NPX_PREFER_EMULATOR)) 412 printf("INT 16 interface\n"); 413 else { 414 printf("FPU exists, but flags request " 415 "emulator\n"); 416 hw_float = npx_exists = 0; 417 } 418 } else if (npx_exists) { |
411 printf("error reporting broken; using 387 emulator\n"); 412 hw_float = npx_exists = 0; 413 } else 414 printf("387 emulator\n"); 415#else | 419 printf("error reporting broken; using 387 emulator\n"); 420 hw_float = npx_exists = 0; 421 } else 422 printf("387 emulator\n"); 423#else |
416 else 417 printf("no 387 emulator in kernel!\n"); | 424 if (npx_ex16) { 425 printf("INT 16 interface\n"); 426 if (flags & NPX_PREFER_EMULATOR) { 427 printf("emulator requested, but none compiled " 428 "into kernel, using FPU\n"); 429 } 430 } else 431 printf("no 387 emulator in kernel and no FPU!\n"); |
418#endif 419 } 420 npxinit(__INITIAL_NPXCW__); 421 422#ifdef I586_CPU | 432#endif 433 } 434 npxinit(__INITIAL_NPXCW__); 435 436#ifdef I586_CPU |
423 if (resource_int_value("npx", 0, "flags", &flags) != 0) 424 flags = 0; 425 426 if (cpu_class == CPUCLASS_586 && npx_ex16 && | 437 if (cpu_class == CPUCLASS_586 && npx_ex16 && npx_exists && |
427 timezero("i586_bzero()", i586_bzero) < 428 timezero("bzero()", bzero) * 4 / 5) { 429 if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BCOPY)) { 430 bcopy_vector = i586_bcopy; 431 ovbcopy_vector = i586_bcopy; 432 } 433 if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BZERO)) 434 bzero = i586_bzero; --- 54 unchanged lines hidden (view full) --- 489 if (masked_exceptions & 0x0d) 490 log(LOG_ERR, 491 "pid %d (%s) exited with masked floating point exceptions 0x%02x\n", 492 p->p_pid, p->p_comm, masked_exceptions); 493 } 494#endif 495} 496 | 438 timezero("i586_bzero()", i586_bzero) < 439 timezero("bzero()", bzero) * 4 / 5) { 440 if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BCOPY)) { 441 bcopy_vector = i586_bcopy; 442 ovbcopy_vector = i586_bcopy; 443 } 444 if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BZERO)) 445 bzero = i586_bzero; --- 54 unchanged lines hidden (view full) --- 500 if (masked_exceptions & 0x0d) 501 log(LOG_ERR, 502 "pid %d (%s) exited with masked floating point exceptions 0x%02x\n", 503 p->p_pid, p->p_comm, masked_exceptions); 504 } 505#endif 506} 507 |
508/* 509 * The following mechanism is used to ensure that the FPE_... value 510 * that is passed as a trapcode to the signal handler of the user 511 * process does not have more than one bit set. 512 * 513 * Multiple bits may be set if the user process modifies the control 514 * word while a status word bit is already set. While this is a sign 515 * of bad coding, we have no choise than to narrow them down to one 516 * bit, since we must not send a trapcode that is not exactly one of 517 * the FPE_ macros. 518 * 519 * The mechanism has a static table with 127 entries. Each combination 520 * of the 7 FPU status word exception bits directly translates to a 521 * position in this table, where a single FPE_... value is stored. 522 * This FPE_... value stored there is considered the "most important" 523 * of the exception bits and will be sent as the signal code. The 524 * precedence of the bits is based upon Intel Document "Numerical 525 * Applications", Chapter "Special Computational Situations". 526 * 527 * The macro to choose one of these values does these steps: 1) Throw 528 * away status word bits that cannot be masked. 2) Throw away the bits 529 * currently masked in the control word, assuming the user isn't 530 * interested in them anymore. 3) Reinsert status word bit 7 (stack 531 * fault) if it is set, which cannot be masked but must be presered. 532 * 4) Use the remaining bits to point into the trapcode table. 533 * 534 * The 6 maskable bits in order of their preference, as stated in the 535 * above referenced Intel manual: 536 * 1 Invalid operation (FP_X_INV) 537 * 1a Stack underflow 538 * 1b Stack overflow 539 * 1c Operand of unsupported format 540 * 1d SNaN operand. 541 * 2 QNaN operand (not an exception, irrelavant here) 542 * 3 Any other invalid-operation not mentioned above or zero divide 543 * (FP_X_INV, FP_X_DZ) 544 * 4 Denormal operand (FP_X_DNML) 545 * 5 Numeric over/underflow (FP_X_OFL, FP_X_UFL) 546 * 6 Inexact result (FP_X_IMP) */ 547 548static char fpetable[128] = { 549 0, 550 FPE_FLTINV, /* 1 - INV */ 551 FPE_FLTUND, /* 2 - DNML */ 552 FPE_FLTINV, /* 3 - INV | DNML */ 553 FPE_FLTDIV, /* 4 - DZ */ 554 FPE_FLTINV, /* 5 - INV | DZ */ 555 FPE_FLTDIV, /* 6 - DNML | DZ */ 556 FPE_FLTINV, /* 7 - INV | DNML | DZ */ 557 FPE_FLTOVF, /* 8 - OFL */ 558 FPE_FLTINV, /* 9 - INV | OFL */ 559 FPE_FLTUND, /* A - DNML | OFL */ 560 FPE_FLTINV, /* B - INV | DNML | OFL */ 561 FPE_FLTDIV, /* C - DZ | OFL */ 562 FPE_FLTINV, /* D - INV | DZ | OFL */ 563 FPE_FLTDIV, /* E - DNML | DZ | OFL */ 564 FPE_FLTINV, /* F - INV | DNML | DZ | OFL */ 565 FPE_FLTUND, /* 10 - UFL */ 566 FPE_FLTINV, /* 11 - INV | UFL */ 567 FPE_FLTUND, /* 12 - DNML | UFL */ 568 FPE_FLTINV, /* 13 - INV | DNML | UFL */ 569 FPE_FLTDIV, /* 14 - DZ | UFL */ 570 FPE_FLTINV, /* 15 - INV | DZ | UFL */ 571 FPE_FLTDIV, /* 16 - DNML | DZ | UFL */ 572 FPE_FLTINV, /* 17 - INV | DNML | DZ | UFL */ 573 FPE_FLTOVF, /* 18 - OFL | UFL */ 574 FPE_FLTINV, /* 19 - INV | OFL | UFL */ 575 FPE_FLTUND, /* 1A - DNML | OFL | UFL */ 576 FPE_FLTINV, /* 1B - INV | DNML | OFL | UFL */ 577 FPE_FLTDIV, /* 1C - DZ | OFL | UFL */ 578 FPE_FLTINV, /* 1D - INV | DZ | OFL | UFL */ 579 FPE_FLTDIV, /* 1E - DNML | DZ | OFL | UFL */ 580 FPE_FLTINV, /* 1F - INV | DNML | DZ | OFL | UFL */ 581 FPE_FLTRES, /* 20 - IMP */ 582 FPE_FLTINV, /* 21 - INV | IMP */ 583 FPE_FLTUND, /* 22 - DNML | IMP */ 584 FPE_FLTINV, /* 23 - INV | DNML | IMP */ 585 FPE_FLTDIV, /* 24 - DZ | IMP */ 586 FPE_FLTINV, /* 25 - INV | DZ | IMP */ 587 FPE_FLTDIV, /* 26 - DNML | DZ | IMP */ 588 FPE_FLTINV, /* 27 - INV | DNML | DZ | IMP */ 589 FPE_FLTOVF, /* 28 - OFL | IMP */ 590 FPE_FLTINV, /* 29 - INV | OFL | IMP */ 591 FPE_FLTUND, /* 2A - DNML | OFL | IMP */ 592 FPE_FLTINV, /* 2B - INV | DNML | OFL | IMP */ 593 FPE_FLTDIV, /* 2C - DZ | OFL | IMP */ 594 FPE_FLTINV, /* 2D - INV | DZ | OFL | IMP */ 595 FPE_FLTDIV, /* 2E - DNML | DZ | OFL | IMP */ 596 FPE_FLTINV, /* 2F - INV | DNML | DZ | OFL | IMP */ 597 FPE_FLTUND, /* 30 - UFL | IMP */ 598 FPE_FLTINV, /* 31 - INV | UFL | IMP */ 599 FPE_FLTUND, /* 32 - DNML | UFL | IMP */ 600 FPE_FLTINV, /* 33 - INV | DNML | UFL | IMP */ 601 FPE_FLTDIV, /* 34 - DZ | UFL | IMP */ 602 FPE_FLTINV, /* 35 - INV | DZ | UFL | IMP */ 603 FPE_FLTDIV, /* 36 - DNML | DZ | UFL | IMP */ 604 FPE_FLTINV, /* 37 - INV | DNML | DZ | UFL | IMP */ 605 FPE_FLTOVF, /* 38 - OFL | UFL | IMP */ 606 FPE_FLTINV, /* 39 - INV | OFL | UFL | IMP */ 607 FPE_FLTUND, /* 3A - DNML | OFL | UFL | IMP */ 608 FPE_FLTINV, /* 3B - INV | DNML | OFL | UFL | IMP */ 609 FPE_FLTDIV, /* 3C - DZ | OFL | UFL | IMP */ 610 FPE_FLTINV, /* 3D - INV | DZ | OFL | UFL | IMP */ 611 FPE_FLTDIV, /* 3E - DNML | DZ | OFL | UFL | IMP */ 612 FPE_FLTINV, /* 3F - INV | DNML | DZ | OFL | UFL | IMP */ 613 FPE_FLTSUB, /* 40 - STK */ 614 FPE_FLTSUB, /* 41 - INV | STK */ 615 FPE_FLTUND, /* 42 - DNML | STK */ 616 FPE_FLTSUB, /* 43 - INV | DNML | STK */ 617 FPE_FLTDIV, /* 44 - DZ | STK */ 618 FPE_FLTSUB, /* 45 - INV | DZ | STK */ 619 FPE_FLTDIV, /* 46 - DNML | DZ | STK */ 620 FPE_FLTSUB, /* 47 - INV | DNML | DZ | STK */ 621 FPE_FLTOVF, /* 48 - OFL | STK */ 622 FPE_FLTSUB, /* 49 - INV | OFL | STK */ 623 FPE_FLTUND, /* 4A - DNML | OFL | STK */ 624 FPE_FLTSUB, /* 4B - INV | DNML | OFL | STK */ 625 FPE_FLTDIV, /* 4C - DZ | OFL | STK */ 626 FPE_FLTSUB, /* 4D - INV | DZ | OFL | STK */ 627 FPE_FLTDIV, /* 4E - DNML | DZ | OFL | STK */ 628 FPE_FLTSUB, /* 4F - INV | DNML | DZ | OFL | STK */ 629 FPE_FLTUND, /* 50 - UFL | STK */ 630 FPE_FLTSUB, /* 51 - INV | UFL | STK */ 631 FPE_FLTUND, /* 52 - DNML | UFL | STK */ 632 FPE_FLTSUB, /* 53 - INV | DNML | UFL | STK */ 633 FPE_FLTDIV, /* 54 - DZ | UFL | STK */ 634 FPE_FLTSUB, /* 55 - INV | DZ | UFL | STK */ 635 FPE_FLTDIV, /* 56 - DNML | DZ | UFL | STK */ 636 FPE_FLTSUB, /* 57 - INV | DNML | DZ | UFL | STK */ 637 FPE_FLTOVF, /* 58 - OFL | UFL | STK */ 638 FPE_FLTSUB, /* 59 - INV | OFL | UFL | STK */ 639 FPE_FLTUND, /* 5A - DNML | OFL | UFL | STK */ 640 FPE_FLTSUB, /* 5B - INV | DNML | OFL | UFL | STK */ 641 FPE_FLTDIV, /* 5C - DZ | OFL | UFL | STK */ 642 FPE_FLTSUB, /* 5D - INV | DZ | OFL | UFL | STK */ 643 FPE_FLTDIV, /* 5E - DNML | DZ | OFL | UFL | STK */ 644 FPE_FLTSUB, /* 5F - INV | DNML | DZ | OFL | UFL | STK */ 645 FPE_FLTRES, /* 60 - IMP | STK */ 646 FPE_FLTSUB, /* 61 - INV | IMP | STK */ 647 FPE_FLTUND, /* 62 - DNML | IMP | STK */ 648 FPE_FLTSUB, /* 63 - INV | DNML | IMP | STK */ 649 FPE_FLTDIV, /* 64 - DZ | IMP | STK */ 650 FPE_FLTSUB, /* 65 - INV | DZ | IMP | STK */ 651 FPE_FLTDIV, /* 66 - DNML | DZ | IMP | STK */ 652 FPE_FLTSUB, /* 67 - INV | DNML | DZ | IMP | STK */ 653 FPE_FLTOVF, /* 68 - OFL | IMP | STK */ 654 FPE_FLTSUB, /* 69 - INV | OFL | IMP | STK */ 655 FPE_FLTUND, /* 6A - DNML | OFL | IMP | STK */ 656 FPE_FLTSUB, /* 6B - INV | DNML | OFL | IMP | STK */ 657 FPE_FLTDIV, /* 6C - DZ | OFL | IMP | STK */ 658 FPE_FLTSUB, /* 6D - INV | DZ | OFL | IMP | STK */ 659 FPE_FLTDIV, /* 6E - DNML | DZ | OFL | IMP | STK */ 660 FPE_FLTSUB, /* 6F - INV | DNML | DZ | OFL | IMP | STK */ 661 FPE_FLTUND, /* 70 - UFL | IMP | STK */ 662 FPE_FLTSUB, /* 71 - INV | UFL | IMP | STK */ 663 FPE_FLTUND, /* 72 - DNML | UFL | IMP | STK */ 664 FPE_FLTSUB, /* 73 - INV | DNML | UFL | IMP | STK */ 665 FPE_FLTDIV, /* 74 - DZ | UFL | IMP | STK */ 666 FPE_FLTSUB, /* 75 - INV | DZ | UFL | IMP | STK */ 667 FPE_FLTDIV, /* 76 - DNML | DZ | UFL | IMP | STK */ 668 FPE_FLTSUB, /* 77 - INV | DNML | DZ | UFL | IMP | STK */ 669 FPE_FLTOVF, /* 78 - OFL | UFL | IMP | STK */ 670 FPE_FLTSUB, /* 79 - INV | OFL | UFL | IMP | STK */ 671 FPE_FLTUND, /* 7A - DNML | OFL | UFL | IMP | STK */ 672 FPE_FLTSUB, /* 7B - INV | DNML | OFL | UFL | IMP | STK */ 673 FPE_FLTDIV, /* 7C - DZ | OFL | UFL | IMP | STK */ 674 FPE_FLTSUB, /* 7D - INV | DZ | OFL | UFL | IMP | STK */ 675 FPE_FLTDIV, /* 7E - DNML | DZ | OFL | UFL | IMP | STK */ 676 FPE_FLTSUB, /* 7F - INV | DNML | DZ | OFL | UFL | IMP | STK */ 677}; 678 679#define ENCODE(_sw, _cw) (fpetable[(_sw & ~_cw & 0x3f) | (_sw & 0x40)]) 680 |
|
497/* 498 * Preserve the FP status word, clear FP exceptions, then generate a SIGFPE. 499 * 500 * Clearing exceptions is necessary mainly to avoid IRQ13 bugs. We now 501 * depend on longjmp() restoring a usable state. Restoring the state 502 * or examining it might fail if we didn't clear exceptions. 503 * | 681/* 682 * Preserve the FP status word, clear FP exceptions, then generate a SIGFPE. 683 * 684 * Clearing exceptions is necessary mainly to avoid IRQ13 bugs. We now 685 * depend on longjmp() restoring a usable state. Restoring the state 686 * or examining it might fail if we didn't clear exceptions. 687 * |
504 * XXX there is no standard way to tell SIGFPE handlers about the error 505 * state. The old interface: | 688 * The error code chosen will be one of the FPE_... macros. It will be 689 * sent as the second argument to old BSD-style signal handlers and as 690 * "siginfo_t->si_code" (second argument) to SA_SIGINFO signal handlers. |
506 * | 691 * |
507 * void handler(int sig, int code, struct sigcontext *scp); 508 * 509 * is broken because it is non-ANSI and because the FP state is not in 510 * struct sigcontext. 511 * | |
512 * XXX the FP state is not preserved across signal handlers. So signal 513 * handlers cannot afford to do FP unless they preserve the state or 514 * longjmp() out. Both preserving the state and longjmp()ing may be 515 * destroyed by IRQ13 bugs. Clearing FP exceptions is not an acceptable 516 * solution for signals other than SIGFPE. 517 */ 518void 519npx_intr(dummy) 520 void *dummy; 521{ 522 int code; | 692 * XXX the FP state is not preserved across signal handlers. So signal 693 * handlers cannot afford to do FP unless they preserve the state or 694 * longjmp() out. Both preserving the state and longjmp()ing may be 695 * destroyed by IRQ13 bugs. Clearing FP exceptions is not an acceptable 696 * solution for signals other than SIGFPE. 697 */ 698void 699npx_intr(dummy) 700 void *dummy; 701{ 702 int code; |
703 u_long cw; |
|
523 struct intrframe *frame; 524 525 if (npxproc == NULL || !npx_exists) { 526 printf("npxintr: npxproc = %p, curproc = %p, npx_exists = %d\n", 527 npxproc, curproc, npx_exists); 528 panic("npxintr from nowhere"); 529 } 530 if (npxproc != curproc) { 531 printf("npxintr: npxproc = %p, curproc = %p, npx_exists = %d\n", 532 npxproc, curproc, npx_exists); 533 panic("npxintr from non-current process"); 534 } 535 536 outb(0xf0, 0); 537 fnstsw(&curpcb->pcb_savefpu.sv_ex_sw); | 704 struct intrframe *frame; 705 706 if (npxproc == NULL || !npx_exists) { 707 printf("npxintr: npxproc = %p, curproc = %p, npx_exists = %d\n", 708 npxproc, curproc, npx_exists); 709 panic("npxintr from nowhere"); 710 } 711 if (npxproc != curproc) { 712 printf("npxintr: npxproc = %p, curproc = %p, npx_exists = %d\n", 713 npxproc, curproc, npx_exists); 714 panic("npxintr from non-current process"); 715 } 716 717 outb(0xf0, 0); 718 fnstsw(&curpcb->pcb_savefpu.sv_ex_sw); |
719 fnstcw(&cw); |
|
538 fnclex(); 539 540 /* 541 * Pass exception to process. 542 */ 543 frame = (struct intrframe *)&dummy; /* XXX */ 544 if ((ISPL(frame->if_cs) == SEL_UPL) || (frame->if_eflags & PSL_VM)) { 545 /* 546 * Interrupt is essentially a trap, so we can afford to call 547 * the SIGFPE handler (if any) as soon as the interrupt 548 * returns. 549 * 550 * XXX little or nothing is gained from this, and plenty is 551 * lost - the interrupt frame has to contain the trap frame 552 * (this is otherwise only necessary for the rescheduling trap 553 * in doreti, and the frame for that could easily be set up 554 * just before it is used). 555 */ 556 curproc->p_md.md_regs = INTR_TO_TRAPFRAME(frame); | 720 fnclex(); 721 722 /* 723 * Pass exception to process. 724 */ 725 frame = (struct intrframe *)&dummy; /* XXX */ 726 if ((ISPL(frame->if_cs) == SEL_UPL) || (frame->if_eflags & PSL_VM)) { 727 /* 728 * Interrupt is essentially a trap, so we can afford to call 729 * the SIGFPE handler (if any) as soon as the interrupt 730 * returns. 731 * 732 * XXX little or nothing is gained from this, and plenty is 733 * lost - the interrupt frame has to contain the trap frame 734 * (this is otherwise only necessary for the rescheduling trap 735 * in doreti, and the frame for that could easily be set up 736 * just before it is used). 737 */ 738 curproc->p_md.md_regs = INTR_TO_TRAPFRAME(frame); |
557#ifdef notyet | |
558 /* 559 * Encode the appropriate code for detailed information on 560 * this exception. 561 */ | 739 /* 740 * Encode the appropriate code for detailed information on 741 * this exception. 742 */ |
562 code = XXX_ENCODE(curpcb->pcb_savefpu.sv_ex_sw); 563#else 564 code = 0; /* XXX */ 565#endif | 743 code = ENCODE(curpcb->pcb_savefpu.sv_ex_sw, cw); |
566 trapsignal(curproc, SIGFPE, code); 567 } else { 568 /* 569 * Nested interrupt. These losers occur when: 570 * o an IRQ13 is bogusly generated at a bogus time, e.g.: 571 * o immediately after an fnsave or frstor of an 572 * error state. 573 * o a couple of 386 instructions after --- 164 unchanged lines hidden --- | 744 trapsignal(curproc, SIGFPE, code); 745 } else { 746 /* 747 * Nested interrupt. These losers occur when: 748 * o an IRQ13 is bogusly generated at a bogus time, e.g.: 749 * o immediately after an fnsave or frstor of an 750 * error state. 751 * o a couple of 386 instructions after --- 164 unchanged lines hidden --- |