Rev 3863 | Rev 4068 | 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 |