Rev 1916 | Rev 1977 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1916 | Rev 1917 | ||
|---|---|---|---|
| Line 671... | Line 671... | ||
| 671 | /* |
671 | /* |
| 672 | * Normal window spills will go to the userspace window buffer. |
672 | * Normal window spills will go to the userspace window buffer. |
| 673 | */ |
673 | */ |
| 674 | wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(2), %wstate |
674 | wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(2), %wstate |
| 675 | 675 | ||
| 676 | wrpr %g0, NWINDOW - 1, %cleanwin ! prevent unnecessary clean_window exceptions |
676 | wrpr %g0, NWINDOWS - 1, %cleanwin ! prevent unnecessary clean_window exceptions |
| 677 | 677 | ||
| 678 | /* |
678 | /* |
| 679 | * Switch to kernel stack. The old stack is |
679 | * Switch to kernel stack. The old stack is |
| 680 | * automatically saved in the old window's %sp |
680 | * automatically saved in the old window's %sp |
| 681 | * and the new window's %fp. |
681 | * and the new window's %fp. |
| Line 828... | Line 828... | ||
| 828 | /* |
828 | /* |
| 829 | * If TSTATE.CWP + 1 == CWP, then we still do not have to fix CWP. |
829 | * If TSTATE.CWP + 1 == CWP, then we still do not have to fix CWP. |
| 830 | */ |
830 | */ |
| 831 | and %g1, TSTATE_CWP_MASK, %l0 |
831 | and %g1, TSTATE_CWP_MASK, %l0 |
| 832 | inc %l0 |
832 | inc %l0 |
| 833 | and %l0, NWINDOW - 1, %l0 ! %l0 mod NWINDOW |
833 | and %l0, NWINDOWS - 1, %l0 ! %l0 mod NWINDOWS |
| 834 | rdpr %cwp, %l1 |
834 | rdpr %cwp, %l1 |
| 835 | cmp %l0, %l1 |
835 | cmp %l0, %l1 |
| 836 | bz 0f ! CWP is ok |
836 | bz 0f ! CWP is ok |
| 837 | nop |
837 | nop |
| 838 | 838 | ||
| Line 899... | Line 899... | ||
| 899 | * Skip all OTHERWIN windows and descend to the first window |
899 | * Skip all OTHERWIN windows and descend to the first window |
| 900 | * in the userspace window buffer. |
900 | * in the userspace window buffer. |
| 901 | */ |
901 | */ |
| 902 | sub %g1, %g2, %g3 |
902 | sub %g1, %g2, %g3 |
| 903 | dec %g3 |
903 | dec %g3 |
| 904 | and %g3, NWINDOW - 1, %g3 |
904 | and %g3, NWINDOWS - 1, %g3 |
| 905 | wrpr %g3, 0, %cwp |
905 | wrpr %g3, 0, %cwp |
| 906 | 906 | ||
| 907 | /* |
907 | /* |
| 908 | * CWP is now in the window last saved in the userspace window buffer. |
908 | * CWP is now in the window last saved in the userspace window buffer. |
| 909 | * Fill all windows stored in the buffer. |
909 | * Fill all windows stored in the buffer. |
| Line 931... | Line 931... | ||
| 931 | ldx [%g7 + I5_OFFSET], %i5 |
931 | ldx [%g7 + I5_OFFSET], %i5 |
| 932 | ldx [%g7 + I6_OFFSET], %i6 |
932 | ldx [%g7 + I6_OFFSET], %i6 |
| 933 | ldx [%g7 + I7_OFFSET], %i7 |
933 | ldx [%g7 + I7_OFFSET], %i7 |
| 934 | 934 | ||
| 935 | dec %g3 |
935 | dec %g3 |
| 936 | and %g3, NWINDOW - 1, %g3 |
936 | and %g3, NWINDOWS - 1, %g3 |
| 937 | wrpr %g3, 0, %cwp ! switch to the preceeding window |
937 | wrpr %g3, 0, %cwp ! switch to the preceeding window |
| 938 | 938 | ||
| 939 | ba 0b |
939 | ba 0b |
| 940 | inc %g4 |
940 | inc %g4 |
| 941 | 941 | ||
| Line 944... | Line 944... | ||
| 944 | * Switch back to the proper current window and adjust |
944 | * Switch back to the proper current window and adjust |
| 945 | * OTHERWIN, CANRESTORE, CANSAVE and CLEANWIN. |
945 | * OTHERWIN, CANRESTORE, CANSAVE and CLEANWIN. |
| 946 | */ |
946 | */ |
| 947 | wrpr %g1, 0, %cwp |
947 | wrpr %g1, 0, %cwp |
| 948 | add %g4, %g2, %g2 |
948 | add %g4, %g2, %g2 |
| 949 | cmp %g2, NWINDOW - 2 |
949 | cmp %g2, NWINDOWS - 2 |
| 950 | bg 2f ! fix the CANRESTORE=NWINDOW-1 anomaly |
950 | bg 2f ! fix the CANRESTORE=NWINDOWS-1 anomaly |
| 951 | mov NWINDOW - 2, %g1 ! use dealy slot for both cases |
951 | mov NWINDOWS - 2, %g1 ! use dealy slot for both cases |
| 952 | sub %g1, %g2, %g1 |
952 | sub %g1, %g2, %g1 |
| 953 | 953 | ||
| 954 | wrpr %g0, 0, %otherwin |
954 | wrpr %g0, 0, %otherwin |
| 955 | wrpr %g1, 0, %cansave ! NWINDOW - 2 - CANRESTORE |
955 | wrpr %g1, 0, %cansave ! NWINDOWS - 2 - CANRESTORE |
| 956 | wrpr %g2, 0, %canrestore ! OTHERWIN + windows in the buffer |
956 | wrpr %g2, 0, %canrestore ! OTHERWIN + windows in the buffer |
| 957 | wrpr %g2, 0, %cleanwin ! avoid information leak |
957 | wrpr %g2, 0, %cleanwin ! avoid information leak |
| 958 | 958 | ||
| 959 | 1: |
959 | 1: |
| 960 | restore |
960 | restore |
| Line 970... | Line 970... | ||
| 970 | * If the: |
970 | * If the: |
| 971 | * |
971 | * |
| 972 | * save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp |
972 | * save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp |
| 973 | * |
973 | * |
| 974 | * instruction trapped and spilled a register window into the userspace |
974 | * instruction trapped and spilled a register window into the userspace |
| 975 | * window buffer, we have just restored NWINDOW - 1 register windows. |
975 | * window buffer, we have just restored NWINDOWS - 1 register windows. |
| 976 | * However, CANRESTORE can be only NWINDOW - 2 at most. |
976 | * However, CANRESTORE can be only NWINDOW - 2 at most. |
| 977 | * |
977 | * |
| 978 | * The solution is to manually switch to (CWP - 1) mod NWINDOW |
978 | * The solution is to manually switch to (CWP - 1) mod NWINDOWS |
| 979 | * and set the window state registers so that: |
979 | * and set the window state registers so that: |
| 980 | * |
980 | * |
| 981 | * CANRESTORE = NWINDOW - 2 |
981 | * CANRESTORE = NWINDOWS - 2 |
| 982 | * CLEANWIN = NWINDOW - 2 |
982 | * CLEANWIN = NWINDOWS - 2 |
| 983 | * CANSAVE = 0 |
983 | * CANSAVE = 0 |
| 984 | * OTHERWIN = 0 |
984 | * OTHERWIN = 0 |
| 985 | * |
985 | * |
| 986 | * The RESTORE instruction is therfore to be skipped. |
986 | * The RESTORE instruction is therfore to be skipped. |
| 987 | */ |
987 | */ |
| Line 991... | Line 991... | ||
| 991 | wrpr %g1, 0, %canrestore |
991 | wrpr %g1, 0, %canrestore |
| 992 | wrpr %g1, 0, %cleanwin |
992 | wrpr %g1, 0, %cleanwin |
| 993 | 993 | ||
| 994 | rdpr %cwp, %g1 |
994 | rdpr %cwp, %g1 |
| 995 | dec %g1 |
995 | dec %g1 |
| 996 | and %g1, NWINDOW - 1, %g1 |
996 | and %g1, NWINDOWS - 1, %g1 |
| 997 | wrpr %g1, 0, %cwp ! CWP-- |
997 | wrpr %g1, 0, %cwp ! CWP-- |
| 998 | 998 | ||
| 999 | .if \is_syscall |
999 | .if \is_syscall |
| 1000 | done |
1000 | done |
| 1001 | .else |
1001 | .else |