Rev 3863 | Rev 4064 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3863 | Rev 3993 | ||
|---|---|---|---|
| Line 45... | Line 45... | ||
| 45 | #include <arch/trap/sun4v/mmu.h> |
45 | #include <arch/trap/sun4v/mmu.h> |
| 46 | #include <arch/mm/sun4v/mmu.h> |
46 | #include <arch/mm/sun4v/mmu.h> |
| 47 | #include <arch/mm/page.h> |
47 | #include <arch/mm/page.h> |
| 48 | #include <arch/stack.h> |
48 | #include <arch/stack.h> |
| 49 | #include <arch/sun4v/regdef.h> |
49 | #include <arch/sun4v/regdef.h> |
| - | 50 | #include <arch/sun4v/arch.h> |
|
| - | 51 | #include <arch/sun4v/cpu.h> |
|
| 50 | 52 | ||
| 51 | #define TABLE_SIZE TRAP_TABLE_SIZE |
53 | #define TABLE_SIZE TRAP_TABLE_SIZE |
| 52 | #define ENTRY_SIZE TRAP_TABLE_ENTRY_SIZE |
54 | #define ENTRY_SIZE TRAP_TABLE_ENTRY_SIZE |
| 53 | 55 | ||
| 54 | /* |
56 | /* |
| Line 290... | Line 292... | ||
| 290 | 292 | ||
| 291 | /* TT = 0x6c, TL = 0, fast_data_access_protection */ |
293 | /* TT = 0x6c, TL = 0, fast_data_access_protection */ |
| 292 | .org trap_table + TT_FAST_DATA_ACCESS_PROTECTION*ENTRY_SIZE |
294 | .org trap_table + TT_FAST_DATA_ACCESS_PROTECTION*ENTRY_SIZE |
| 293 | .global fast_data_access_protection_handler_tl0 |
295 | .global fast_data_access_protection_handler_tl0 |
| 294 | fast_data_access_protection_handler_tl0: |
296 | fast_data_access_protection_handler_tl0: |
| 295 | /*FAST_DATA_ACCESS_PROTECTION_HANDLER 0*/ |
297 | FAST_DATA_ACCESS_PROTECTION_HANDLER 0 |
| 296 | 298 | ||
| 297 | /* TT = 0x80, TL = 0, spill_0_normal handler */ |
299 | /* TT = 0x80, TL = 0, spill_0_normal handler */ |
| 298 | .org trap_table + TT_SPILL_0_NORMAL*ENTRY_SIZE |
300 | .org trap_table + TT_SPILL_0_NORMAL*ENTRY_SIZE |
| 299 | .global spill_0_normal_tl0 |
301 | .global spill_0_normal_tl0 |
| 300 | spill_0_normal_tl0: |
302 | spill_0_normal_tl0: |
| Line 522... | Line 524... | ||
| 522 | wrpr \tmpreg2, %cwp |
524 | wrpr \tmpreg2, %cwp |
| 523 | 525 | ||
| 524 | restored |
526 | restored |
| 525 | .endm |
527 | .endm |
| 526 | 528 | ||
| - | 529 | #define NOT(x) ((x) == 0) |
|
| - | 530 | ||
| 527 | /* |
531 | /* |
| - | 532 | * Perform all the actions of the preemptible trap handler which are common |
|
| - | 533 | * for trapping from kernel and trapping from userspace, including call of the |
|
| - | 534 | * higher level service routine. |
|
| - | 535 | * |
|
| - | 536 | * Important note: |
|
| - | 537 | * This macro must be inserted between the "2:" and "4:" labels. The |
|
| 528 | * Preemptible trap handler for handling traps from kernel. |
538 | * inserting code must be aware of the usage of all the registers |
| - | 539 | * contained in this macro. |
|
| 529 | */ |
540 | */ |
| 530 | .macro PREEMPTIBLE_HANDLER_KERNEL |
541 | .macro MIDDLE_PART is_syscall |
| 531 | - | ||
| 532 | /* |
- | |
| 533 | * ASSERT(%tl == 1) |
- | |
| 534 | */ |
- | |
| 535 | rdpr %tl, %g3 |
- | |
| 536 | cmp %g3, 1 |
- | |
| 537 | be 1f |
- | |
| 538 | nop |
- | |
| 539 | 0: ba 0b ! this is for debugging, if we ever get here |
- | |
| 540 | nop ! it will be easy to find |
- | |
| 541 | - | ||
| 542 | /* prevent unnecessary CLEANWIN exceptions */ |
- | |
| 543 | wrpr %g0, NWINDOWS - 1, %cleanwin |
- | |
| 544 | 1: |
- | |
| 545 | /* |
- | |
| 546 | * Prevent SAVE instruction from causing a spill exception. If the |
- | |
| 547 | * CANSAVE register is zero, explicitly spill register window |
- | |
| 548 | * at CWP + 2. |
- | |
| 549 | */ |
- | |
| 550 | - | ||
| 551 | rdpr %cansave, %g3 |
- | |
| 552 | brnz %g3, 2f |
- | |
| 553 | nop |
- | |
| 554 | INLINE_SPILL %g3, %g4 |
- | |
| 555 | - | ||
| 556 | 2: |
- | |
| 557 | /* ask for new register window */ |
- | |
| 558 | save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp |
- | |
| 559 | - | ||
| 560 | /* copy higher level routine's address and its argument */ |
542 | /* copy higher level routine's address and its argument */ |
| 561 | mov %g1, %l0 |
543 | mov %g1, %l0 |
| - | 544 | .if NOT(\is_syscall) |
|
| 562 | mov %g2, %o0 |
545 | mov %g2, %o0 |
| - | 546 | .else |
|
| - | 547 | ! store the syscall number on the stack as 7th argument |
|
| - | 548 | stx %g2, [%sp + STACK_WINDOW_SAVE_AREA_SIZE + STACK_BIAS + STACK_ARG6] |
|
| - | 549 | .endif |
|
| 563 | 550 | ||
| 564 | /* |
551 | /* |
| 565 | * Save TSTATE, TPC and TNPC aside. |
552 | * Save TSTATE, TPC and TNPC aside. |
| 566 | */ |
553 | */ |
| 567 | rdpr %tstate, %g1 |
554 | rdpr %tstate, %g1 |
| Line 588... | Line 575... | ||
| 588 | wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT, %pstate |
575 | wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT, %pstate |
| 589 | 576 | ||
| 590 | /* g1 -> l1, ..., g7 -> l7 */ |
577 | /* g1 -> l1, ..., g7 -> l7 */ |
| 591 | SAVE_GLOBALS |
578 | SAVE_GLOBALS |
| 592 | 579 | ||
| - | 580 | .if NOT(\is_syscall) |
|
| 593 | /* call higher-level service routine, pass istate as its 2nd parameter */ |
581 | /* call higher-level service routine, pass istate as its 2nd parameter */ |
| 594 | call %l0 |
582 | call %l0 |
| 595 | add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1 |
583 | add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1 |
| - | 584 | .else |
|
| - | 585 | /* Call the higher-level syscall handler. */ |
|
| - | 586 | wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT | PSTATE_IE_BIT, %pstate |
|
| - | 587 | call syscall_handler |
|
| - | 588 | nop |
|
| - | 589 | /* copy the value returned by the syscall */ |
|
| - | 590 | mov %o0, %i0 |
|
| - | 591 | .endif |
|
| 596 | 592 | ||
| 597 | /* l1 -> g1, ..., l7 -> g7 */ |
593 | /* l1 -> g1, ..., l7 -> g7 */ |
| 598 | RESTORE_GLOBALS |
594 | RESTORE_GLOBALS |
| 599 | 595 | ||
| 600 | /* we must prserve the PEF bit */ |
596 | /* we must prserve the PEF bit */ |
| Line 661... | Line 657... | ||
| 661 | ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3], %i3 |
657 | ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3], %i3 |
| 662 | ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4], %i4 |
658 | ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4], %i4 |
| 663 | ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5], %i5 |
659 | ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5], %i5 |
| 664 | ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6], %i6 |
660 | ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6], %i6 |
| 665 | ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7], %i7 |
661 | ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7], %i7 |
| - | 662 | .endm |
|
| - | 663 | ||
| - | 664 | /* |
|
| - | 665 | * Preemptible trap handler for handling traps from kernel. |
|
| - | 666 | */ |
|
| - | 667 | .macro PREEMPTIBLE_HANDLER_KERNEL |
|
| - | 668 | ||
| - | 669 | /* |
|
| - | 670 | * ASSERT(%tl == 1) |
|
| - | 671 | */ |
|
| - | 672 | rdpr %tl, %g3 |
|
| - | 673 | cmp %g3, 1 |
|
| - | 674 | be 1f |
|
| - | 675 | nop |
|
| - | 676 | 0: ba 0b ! this is for debugging, if we ever get here |
|
| - | 677 | nop ! it will be easy to find |
|
| - | 678 | ||
| - | 679 | 1: |
|
| - | 680 | /* prevent unnecessary CLEANWIN exceptions */ |
|
| - | 681 | wrpr %g0, NWINDOWS - 1, %cleanwin |
|
| - | 682 | ||
| - | 683 | /* |
|
| - | 684 | * Prevent SAVE instruction from causing a spill exception. If the |
|
| - | 685 | * CANSAVE register is zero, explicitly spill register window |
|
| - | 686 | * at CWP + 2. |
|
| - | 687 | */ |
|
| - | 688 | ||
| - | 689 | rdpr %cansave, %g3 |
|
| - | 690 | brnz %g3, 2f |
|
| - | 691 | nop |
|
| - | 692 | INLINE_SPILL %g3, %g4 |
|
| - | 693 | ||
| - | 694 | 2: |
|
| - | 695 | /* ask for new register window */ |
|
| - | 696 | save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp |
|
| - | 697 | ||
| - | 698 | MIDDLE_PART 0 |
|
| 666 | 699 | ||
| 667 | 4: |
700 | 4: |
| 668 | /* |
701 | /* |
| 669 | * Prevent RESTORE instruction from causing a fill exception. If the |
702 | * Prevent RESTORE instruction from causing a fill exception. If the |
| 670 | * CANRESTORE register is zero, explicitly fill register window |
703 | * CANRESTORE register is zero, explicitly fill register window |
| Line 679... | Line 712... | ||
| 679 | restore |
712 | restore |
| 680 | 713 | ||
| 681 | retry |
714 | retry |
| 682 | .endm |
715 | .endm |
| 683 | 716 | ||
| - | 717 | /* |
|
| - | 718 | * Spills the window at CWP + 2 to the userspace window buffer. This macro |
|
| - | 719 | * is to be used before doing SAVE when the spill trap is undesirable. |
|
| - | 720 | * |
|
| - | 721 | * Parameters: |
|
| - | 722 | * tmpreg1 global register to be used for scratching purposes |
|
| - | 723 | * tmpreg2 global register to be used for scratching purposes |
|
| - | 724 | * tmpreg3 global register to be used for scratching purposes |
|
| - | 725 | */ |
|
| - | 726 | .macro INLINE_SPILL_TO_WBUF tmpreg1, tmpreg2, tmpreg3 |
|
| - | 727 | ! CWP := CWP + 2 |
|
| - | 728 | rdpr %cwp, \tmpreg2 |
|
| - | 729 | add \tmpreg2, 2, \tmpreg1 |
|
| - | 730 | and \tmpreg1, NWINDOWS - 1, \tmpreg1 ! modulo NWINDOWS |
|
| - | 731 | wrpr \tmpreg1, %cwp |
|
| - | 732 | ||
| - | 733 | ! spill to userspace window buffer |
|
| - | 734 | SAVE_TO_USPACE_WBUF \tmpreg3, \tmpreg1 |
|
| 684 | 735 | ||
| - | 736 | ! CWP := CWP - 2 |
|
| - | 737 | wrpr \tmpreg2, %cwp |
|
| - | 738 | ||
| - | 739 | saved |
|
| - | 740 | .endm |
|
| - | 741 | ||
| - | 742 | /* |
|
| - | 743 | * Preemptible handler for handling traps from userspace. |
|
| - | 744 | */ |
|
| - | 745 | .macro PREEMPTIBLE_HANDLER_USPACE is_syscall |
|
| - | 746 | /* |
|
| - | 747 | * One of the ways this handler can be invoked is after a nested MMU trap from |
|
| - | 748 | * either spill_1_normal or fill_1_normal traps. Both of these traps manipulate |
|
| - | 749 | * the CWP register. We deal with the situation by simulating the MMU trap |
|
| - | 750 | * on TL=1 and restart the respective SAVE or RESTORE instruction once the MMU |
|
| - | 751 | * trap is resolved. However, because we are in the wrong window from the |
|
| - | 752 | * perspective of the MMU trap, we need to synchronize CWP with CWP from TL=0. |
|
| - | 753 | */ |
|
| 685 | #define NOT(x) ((x) == 0) |
754 | .if NOT(\is_syscall) |
| - | 755 | rdpr %tstate, %g3 |
|
| - | 756 | and %g3, TSTATE_CWP_MASK, %g4 |
|
| - | 757 | wrpr %g4, 0, %cwp ! resynchronize CWP |
|
| - | 758 | .endif |
|
| - | 759 | ||
| - | 760 | /* prevent unnecessary CLEANWIN exceptions */ |
|
| - | 761 | wrpr %g0, NWINDOWS - 1, %cleanwin |
|
| - | 762 | ||
| - | 763 | /* |
|
| - | 764 | * Prevent SAVE instruction from causing a spill exception. If the |
|
| - | 765 | * CANSAVE register is zero, explicitly spill register window |
|
| - | 766 | * at CWP + 2. |
|
| - | 767 | */ |
|
| - | 768 | rdpr %cansave, %g3 |
|
| - | 769 | brnz %g3, 2f |
|
| - | 770 | nop |
|
| - | 771 | INLINE_SPILL_TO_WBUF %g3, %g4, %g7 |
|
| - | 772 | ||
| - | 773 | 2: |
|
| - | 774 | get_kstack_wbuf_ptr %g3, %g4 |
|
| - | 775 | ldx [%g4], %g6 |
|
| - | 776 | save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp |
|
| - | 777 | ||
| - | 778 | .if \is_syscall |
|
| - | 779 | /* Copy arguments for the syscall to the new window. */ |
|
| - | 780 | mov %i0, %o0 |
|
| - | 781 | mov %i1, %o1 |
|
| - | 782 | mov %i2, %o2 |
|
| - | 783 | mov %i3, %o3 |
|
| - | 784 | mov %i4, %o4 |
|
| - | 785 | mov %i5, %o5 |
|
| - | 786 | .endif |
|
| - | 787 | ||
| - | 788 | mov VA_PRIMARY_CONTEXT_REG, %l0 |
|
| - | 789 | stxa %g0, [%l0] ASI_PRIMARY_CONTEXT_REG |
|
| - | 790 | rd %pc, %l0 |
|
| - | 791 | flush %l0 |
|
| - | 792 | ||
| - | 793 | /* Mark the CANRESTORE windows as OTHER windows. */ |
|
| - | 794 | rdpr %canrestore, %l0 |
|
| - | 795 | wrpr %l0, %otherwin |
|
| - | 796 | wrpr %g0, %canrestore |
|
| - | 797 | ||
| - | 798 | /* |
|
| - | 799 | * Other window spills will go to the userspace window buffer |
|
| - | 800 | * and normal spills will go to the kernel stack. |
|
| - | 801 | */ |
|
| - | 802 | wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(0), %wstate |
|
| - | 803 | ||
| - | 804 | MIDDLE_PART \is_syscall |
|
| - | 805 | ||
| - | 806 | 4: |
|
| - | 807 | /* |
|
| - | 808 | * Spills and fills will be processed by the {spill,fill}_1_normal |
|
| - | 809 | * handlers. |
|
| - | 810 | */ |
|
| - | 811 | wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(1), %wstate |
|
| - | 812 | ||
| - | 813 | /* |
|
| - | 814 | * Set primary context according to secondary context. |
|
| - | 815 | */ |
|
| - | 816 | wr %g0, ASI_SECONDARY_CONTEXT_REG, %asi |
|
| - | 817 | ldxa [VA_SECONDARY_CONTEXT_REG] %asi, %g1 |
|
| - | 818 | wr %g0, ASI_PRIMARY_CONTEXT_REG, %asi |
|
| - | 819 | stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi |
|
| - | 820 | rd %pc, %g1 |
|
| - | 821 | flush %g1 |
|
| - | 822 | ||
| - | 823 | /* Restoring userspace windows: */ |
|
| - | 824 | ||
| - | 825 | /* Save address of the userspace window buffer to the %g7 register. */ |
|
| - | 826 | get_kstack_wbuf_ptr %g1, %g5 |
|
| - | 827 | ldx [%g5 + 8], %g7 |
|
| - | 828 | ||
| - | 829 | rdpr %cwp, %g1 |
|
| - | 830 | rdpr %otherwin, %g2 |
|
| - | 831 | ||
| - | 832 | /* |
|
| - | 833 | * Skip all OTHERWIN windows and descend to the first window |
|
| - | 834 | * in the userspace window buffer. |
|
| - | 835 | */ |
|
| - | 836 | sub %g1, %g2, %g3 |
|
| - | 837 | dec %g3 |
|
| - | 838 | and %g3, NWINDOWS - 1, %g3 |
|
| - | 839 | wrpr %g3, 0, %cwp |
|
| - | 840 | ||
| - | 841 | /* |
|
| - | 842 | * CWP is now in the window last saved in the userspace window buffer. |
|
| - | 843 | * Fill all windows stored in the buffer. |
|
| - | 844 | */ |
|
| - | 845 | clr %g4 |
|
| - | 846 | 5: andcc %g7, UWB_ALIGNMENT - 1, %g0 ! alignment check |
|
| - | 847 | bz 6f ! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill |
|
| - | 848 | nop |
|
| - | 849 | ||
| - | 850 | add %g7, -STACK_WINDOW_SAVE_AREA_SIZE, %g7 |
|
| - | 851 | ldx [%g7 + L0_OFFSET], %l0 |
|
| - | 852 | ldx [%g7 + L1_OFFSET], %l1 |
|
| - | 853 | ldx [%g7 + L2_OFFSET], %l2 |
|
| - | 854 | ldx [%g7 + L3_OFFSET], %l3 |
|
| - | 855 | ldx [%g7 + L4_OFFSET], %l4 |
|
| - | 856 | ldx [%g7 + L5_OFFSET], %l5 |
|
| - | 857 | ldx [%g7 + L6_OFFSET], %l6 |
|
| - | 858 | ldx [%g7 + L7_OFFSET], %l7 |
|
| - | 859 | ldx [%g7 + I0_OFFSET], %i0 |
|
| - | 860 | ldx [%g7 + I1_OFFSET], %i1 |
|
| - | 861 | ldx [%g7 + I2_OFFSET], %i2 |
|
| - | 862 | ldx [%g7 + I3_OFFSET], %i3 |
|
| - | 863 | ldx [%g7 + I4_OFFSET], %i4 |
|
| - | 864 | ldx [%g7 + I5_OFFSET], %i5 |
|
| - | 865 | ldx [%g7 + I6_OFFSET], %i6 |
|
| - | 866 | ldx [%g7 + I7_OFFSET], %i7 |
|
| - | 867 | ||
| - | 868 | dec %g3 |
|
| - | 869 | and %g3, NWINDOWS - 1, %g3 |
|
| - | 870 | wrpr %g3, 0, %cwp ! switch to the preceeding window |
|
| - | 871 | ||
| - | 872 | ba 5b |
|
| - | 873 | inc %g4 |
|
| - | 874 | ||
| - | 875 | 6: |
|
| - | 876 | /* Save changes of the address of the userspace window buffer. */ |
|
| - | 877 | stx %g7, [%g5 + 8] |
|
| - | 878 | ||
| - | 879 | /* |
|
| - | 880 | * Switch back to the proper current window and adjust |
|
| - | 881 | * OTHERWIN, CANRESTORE, CANSAVE and CLEANWIN. |
|
| - | 882 | */ |
|
| - | 883 | wrpr %g1, 0, %cwp |
|
| - | 884 | add %g4, %g2, %g2 |
|
| - | 885 | cmp %g2, NWINDOWS - 2 |
|
| - | 886 | bg 8f ! fix the CANRESTORE=NWINDOWS-1 anomaly |
|
| - | 887 | mov NWINDOWS - 2, %g1 ! use dealy slot for both cases |
|
| - | 888 | sub %g1, %g2, %g1 |
|
| - | 889 | ||
| - | 890 | wrpr %g0, 0, %otherwin |
|
| - | 891 | wrpr %g1, 0, %cansave ! NWINDOWS - 2 - CANRESTORE |
|
| - | 892 | wrpr %g2, 0, %canrestore ! OTHERWIN + windows in the buffer |
|
| - | 893 | wrpr %g2, 0, %cleanwin ! avoid information leak |
|
| - | 894 | ||
| - | 895 | 7: |
|
| - | 896 | restore |
|
| - | 897 | ||
| - | 898 | .if \is_syscall |
|
| - | 899 | done |
|
| - | 900 | .else |
|
| - | 901 | retry |
|
| - | 902 | .endif |
|
| - | 903 | ||
| - | 904 | 8: |
|
| - | 905 | /* |
|
| - | 906 | * We got here in order to avoid inconsistency of the window state registers. |
|
| - | 907 | * If the: |
|
| - | 908 | * |
|
| - | 909 | * save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp |
|
| - | 910 | * |
|
| - | 911 | * instruction trapped and spilled a register window into the userspace |
|
| - | 912 | * window buffer, we have just restored NWINDOWS - 1 register windows. |
|
| - | 913 | * However, CANRESTORE can be only NWINDOW - 2 at most. |
|
| - | 914 | * |
|
| - | 915 | * The solution is to manually switch to (CWP - 1) mod NWINDOWS |
|
| - | 916 | * and set the window state registers so that: |
|
| - | 917 | * |
|
| - | 918 | * CANRESTORE = NWINDOWS - 2 |
|
| - | 919 | * CLEANWIN = NWINDOWS - 2 |
|
| - | 920 | * CANSAVE = 0 |
|
| - | 921 | * OTHERWIN = 0 |
|
| - | 922 | * |
|
| - | 923 | * The RESTORE instruction is therfore to be skipped. |
|
| - | 924 | */ |
|
| - | 925 | wrpr %g0, 0, %otherwin |
|
| - | 926 | wrpr %g0, 0, %cansave |
|
| - | 927 | wrpr %g1, 0, %canrestore |
|
| - | 928 | wrpr %g1, 0, %cleanwin |
|
| - | 929 | ||
| - | 930 | rdpr %cwp, %g1 |
|
| - | 931 | dec %g1 |
|
| - | 932 | and %g1, NWINDOWS - 1, %g1 |
|
| - | 933 | wrpr %g1, 0, %cwp ! CWP-- |
|
| - | 934 | ||
| - | 935 | .if \is_syscall |
|
| - | 936 | done |
|
| - | 937 | .else |
|
| - | 938 | retry |
|
| - | 939 | .endif |
|
| - | 940 | ||
| - | 941 | .endm |
|
| 686 | 942 | ||
| 687 | /* Preemptible trap handler for TL=1. |
943 | /* Preemptible trap handler for TL=1. |
| 688 | * |
944 | * |
| 689 | * This trap handler makes arrangements to make calling of scheduler() from |
945 | * This trap handler makes arrangements to make calling of scheduler() from |
| 690 | * within a trap context possible. It is called from several other trap |
946 | * within a trap context possible. It is called from several other trap |
| 691 | * handlers. |
947 | * handlers. |
| 692 | */ |
948 | */ |
| 693 | .macro PREEMPTIBLE_HANDLER_TEMPLATE is_syscall |
949 | .macro PREEMPTIBLE_HANDLER_TEMPLATE is_syscall |
| - | 950 | rdpr %tstate, %g3 |
|
| - | 951 | and %g3, TSTATE_PRIV_BIT, %g3 |
|
| - | 952 | brz %g3, 100f ! trapping from userspace |
|
| - | 953 | nop |
|
| - | 954 | ||
| 694 | PREEMPTIBLE_HANDLER_KERNEL |
955 | PREEMPTIBLE_HANDLER_KERNEL |
| - | 956 | ba 101f |
|
| - | 957 | nop |
|
| - | 958 | ||
| - | 959 | 100: |
|
| - | 960 | PREEMPTIBLE_HANDLER_USPACE \is_syscall |
|
| - | 961 | ||
| - | 962 | 101: |
|
| 695 | .endm |
963 | .endm |
| 696 | 964 | ||
| 697 | .global preemptible_handler |
965 | .global preemptible_handler |
| 698 | preemptible_handler: |
966 | preemptible_handler: |
| 699 | PREEMPTIBLE_HANDLER_TEMPLATE 0 |
967 | PREEMPTIBLE_HANDLER_TEMPLATE 0 |