Changeset eb79d60 in mainline
- Timestamp:
- 2009-11-29T18:17:43Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ba50a34
- Parents:
- 3f35634c
- Location:
- kernel/arch/sparc64
- Files:
-
- 3 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/sparc64/include/cpu.h
r3f35634c reb79d60 64 64 #endif 65 65 66 typedef struct {67 uint32_t mid; /**< Processor ID as read from68 UPA_CONFIG/FIREPLANE_CONFIG. */69 ver_reg_t ver;70 uint32_t clock_frequency; /**< Processor frequency in Hz. */71 uint64_t next_tick_cmpr; /**< Next clock interrupt should be72 generated when the TICK register73 matches this value. */74 } cpu_arch_t;75 66 67 #if defined (SUN4U) 68 #include <arch/sun4u/cpu.h> 69 #elif defined (SUN4V) 70 #include <arch/sun4v/cpu.h> 71 #endif 76 72 77 /**78 * Reads the module ID (agent ID/CPUID) of the current CPU.79 */80 static inline uint32_t read_mid(void)81 {82 uint64_t icbus_config = asi_u64_read(ASI_ICBUS_CONFIG, 0);83 icbus_config = icbus_config >> ICBUS_CONFIG_MID_SHIFT;84 #if defined (US)85 return icbus_config & 0x1f;86 #elif defined (US3)87 if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIII_I)88 return icbus_config & 0x1f;89 else90 return icbus_config & 0x3ff;91 #endif92 }93 73 94 74 #endif -
kernel/arch/sparc64/include/sun4u/cpu.h
r3f35634c reb79d60 33 33 */ 34 34 35 #ifndef KERN_sparc64_ CPU_H_36 #define KERN_sparc64_ CPU_H_35 #ifndef KERN_sparc64_sun4u_CPU_H_ 36 #define KERN_sparc64_sun4u_CPU_H_ 37 37 38 38 #define MANUF_FUJITSU 0x04 -
kernel/arch/sparc64/include/sun4v/cpu.h
r3f35634c reb79d60 46 46 struct cpu; 47 47 48 /* 48 49 typedef struct { 49 50 uint64_t exec_unit_id; … … 54 55 SPINLOCK_DECLARE(proposed_nrdy_lock); 55 56 } exec_unit_t; 57 */ 56 58 57 // MH58 #if 059 59 typedef struct cpu_arch { 60 60 uint64_t id; /**< virtual processor ID */ … … 63 63 generated when the TICK register 64 64 matches this value. */ 65 exec_unit_t *exec_unit; /**< Physical core. */66 unsigned long proposed_nrdy; /**< Proposed No. of ready threads67 so that cores are equally balanced. */65 //exec_unit_t *exec_unit; /**< Physical core. */ 66 //unsigned long proposed_nrdy; /**< Proposed No. of ready threads 67 // so that cores are equally balanced. */ 68 68 } cpu_arch_t; 69 #endif70 69 71 70 #endif -
kernel/arch/sparc64/include/trap/regwin.h
r3f35634c reb79d60 131 131 132 132 /* 133 * Macro used to spill userspace window to userspace window buffer.134 * It can be either triggered from preemptible_handler doing SAVE135 * at (TL=1) or from normal kernel code doing SAVE when OTHERWIN>0136 * at (TL=0).137 */138 .macro SPILL_TO_USPACE_WINDOW_BUFFER139 stx %l0, [%g7 + L0_OFFSET]140 stx %l1, [%g7 + L1_OFFSET]141 stx %l2, [%g7 + L2_OFFSET]142 stx %l3, [%g7 + L3_OFFSET]143 stx %l4, [%g7 + L4_OFFSET]144 stx %l5, [%g7 + L5_OFFSET]145 stx %l6, [%g7 + L6_OFFSET]146 stx %l7, [%g7 + L7_OFFSET]147 stx %i0, [%g7 + I0_OFFSET]148 stx %i1, [%g7 + I1_OFFSET]149 stx %i2, [%g7 + I2_OFFSET]150 stx %i3, [%g7 + I3_OFFSET]151 stx %i4, [%g7 + I4_OFFSET]152 stx %i5, [%g7 + I5_OFFSET]153 stx %i6, [%g7 + I6_OFFSET]154 stx %i7, [%g7 + I7_OFFSET]155 add %g7, STACK_WINDOW_SAVE_AREA_SIZE, %g7156 saved157 retry158 .endm159 160 161 /*162 133 * Macro used by the nucleus and the primary context 0 during normal fills. 163 134 */ … … 232 203 #endif /* __ASM__ */ 233 204 205 #if defined (SUN4U) 206 #include <arch/trap/sun4u/regwin.h> 207 #elif defined (SUN4V) 208 #include <arch/trap/sun4v/regwin.h> 234 209 #endif 235 210 211 #endif 212 236 213 /** @} 237 214 */ -
kernel/arch/sparc64/src/mm/sun4v/tlb.c
r3f35634c reb79d60 212 212 void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate) 213 213 { 214 asm volatile ("sethi 0x41906, %g0"); 214 215 uintptr_t page_16k = ALIGN_DOWN(istate->tpc, PAGE_SIZE); 215 216 size_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE; -
kernel/arch/sparc64/src/trap/sun4v/trap_table.S
r3f35634c reb79d60 136 136 .global data_access_exception_tl0 137 137 data_access_exception_tl0: 138 /*wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate139 PREEMPTIBLE_HANDLER data_access_exception */138 wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate 139 PREEMPTIBLE_HANDLER data_access_exception 140 140 141 141 /* TT = 0x32, TL = 0, data_access_error */ … … 293 293 .global fast_data_access_protection_handler_tl0 294 294 fast_data_access_protection_handler_tl0: 295 /*FAST_DATA_ACCESS_PROTECTION_HANDLER 0*/295 FAST_DATA_ACCESS_PROTECTION_HANDLER 0 296 296 297 297 /* TT = 0x80, TL = 0, spill_0_normal handler */ … … 355 355 .global instruction_access_exception_tl1 356 356 instruction_access_exception_tl1: 357 /*wrpr %g0, 1, %tl357 wrpr %g0, 1, %tl 358 358 wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate 359 PREEMPTIBLE_HANDLER instruction_access_exception */359 PREEMPTIBLE_HANDLER instruction_access_exception 360 360 361 361 /* TT = 0x0a, TL > 0, instruction_access_error */ … … 418 418 .global fast_data_access_protection_handler_tl1 419 419 fast_data_access_protection_handler_tl1: 420 /*FAST_DATA_ACCESS_PROTECTION_HANDLER 1*/420 FAST_DATA_ACCESS_PROTECTION_HANDLER 1 421 421 422 422 /* TT = 0x80, TL > 0, spill_0_normal handler */ … … 525 525 .endm 526 526 527 #define NOT(x) ((x) == 0) 528 527 529 /* 528 * Preemptible trap handler for handling traps from kernel. 530 * Perform all the actions of the preemptible trap handler which are common 531 * for trapping from kernel and trapping from userspace, including call of the 532 * higher level service routine. 533 * 534 * Important note: 535 * This macro must be inserted between the "2:" and "4:" labels. The 536 * inserting code must be aware of the usage of all the registers 537 * contained in this macro. 529 538 */ 530 .macro PREEMPTIBLE_HANDLER_KERNEL 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, WSTATE_OTHER(0) | WSTATE_NORMAL(0), %wstate 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 539 .macro MIDDLE_PART is_syscall 560 540 /* copy higher level routine's address and its argument */ 561 541 mov %g1, %l0 542 .if NOT(\is_syscall) 562 543 mov %g2, %o0 544 .else 545 ! store the syscall number on the stack as 7th argument 546 stx %g2, [%sp + STACK_WINDOW_SAVE_AREA_SIZE + STACK_BIAS + STACK_ARG6] 547 .endif 563 548 564 549 /* … … 591 576 SAVE_GLOBALS 592 577 578 .if NOT(\is_syscall) 593 579 /* call higher-level service routine, pass istate as its 2nd parameter */ 594 580 call %l0 595 581 add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1 582 .else 583 /* Call the higher-level syscall handler. */ 584 !wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT | PSTATE_IE_BIT, %pstate 585 call syscall_handler 586 nop 587 /* copy the value returned by the syscall */ 588 mov %o0, %i0 589 .endif 596 590 597 591 /* l1 -> g1, ..., l7 -> g7 */ … … 664 658 ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6], %i6 665 659 ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7], %i7 660 .endm 661 662 663 #if 0 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 /* prevent unnecessary CLEANWIN exceptions */ 680 wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(0), %wstate 681 1: 682 /* 683 * Prevent SAVE instruction from causing a spill exception. If the 684 * CANSAVE register is zero, explicitly spill register window 685 * at CWP + 2. 686 */ 687 688 rdpr %cansave, %g3 689 brnz %g3, 2f 690 nop 691 INLINE_SPILL %g3, %g4 692 693 2: 694 /* ask for new register window */ 695 save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp 696 697 /* copy higher level routine's address and its argument */ 698 mov %g1, %l0 699 mov %g2, %o0 700 701 /* 702 * Save TSTATE, TPC and TNPC aside. 703 */ 704 rdpr %tstate, %g1 705 rdpr %tpc, %g2 706 rdpr %tnpc, %g3 707 708 stx %g1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE] 709 stx %g2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC] 710 stx %g3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC] 711 712 /* 713 * Save the Y register. 714 * This register is deprecated according to SPARC V9 specification 715 * and is only present for backward compatibility with previous 716 * versions of the SPARC architecture. 717 * Surprisingly, gcc makes use of this register without a notice. 718 */ 719 rd %y, %g4 720 stx %g4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y] 721 722 /* switch to TL = 0, explicitly enable FPU */ 723 wrpr %g0, 0, %tl 724 wrpr %g0, 0, %gl 725 wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT, %pstate 726 727 /* g1 -> l1, ..., g7 -> l7 */ 728 SAVE_GLOBALS 729 730 /* call higher-level service routine, pass istate as its 2nd parameter */ 731 call %l0 732 add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1 733 734 /* l1 -> g1, ..., l7 -> g7 */ 735 RESTORE_GLOBALS 736 737 /* we must prserve the PEF bit */ 738 rdpr %pstate, %l1 739 740 /* TL := 1, GL := 1 */ 741 wrpr %g0, PSTATE_PRIV_BIT, %pstate 742 wrpr %g0, 1, %tl 743 wrpr %g0, 1, %gl 744 745 /* Read TSTATE, TPC and TNPC from saved copy. */ 746 ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE], %g1 747 ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC], %g2 748 ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC], %g3 749 750 /* Copy PSTATE.PEF to the in-register copy of TSTATE. */ 751 and %l1, PSTATE_PEF_BIT, %l1 752 sllx %l1, TSTATE_PSTATE_SHIFT, %l1 753 sethi %hi(TSTATE_PEF_BIT), %g4 ! reset the PEF bit to 0 ... 754 andn %g1, %g4, %g1 755 or %g1, %l1, %g1 ! ... "or" it with saved PEF 756 757 /* Restore TSTATE, TPC and TNPC from saved copies. */ 758 wrpr %g1, 0, %tstate 759 wrpr %g2, 0, %tpc 760 wrpr %g3, 0, %tnpc 761 762 /* Restore Y. */ 763 ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y], %g4 764 wr %g4, %y 765 766 /* If TSTATE.CWP + 1 == CWP, then we do not have to fix CWP. */ 767 and %g1, TSTATE_CWP_MASK, %l0 768 inc %l0 769 and %l0, NWINDOWS - 1, %l0 ! %l0 mod NWINDOWS 770 rdpr %cwp, %l1 771 cmp %l0, %l1 772 bz 4f ! CWP is ok 773 nop 774 775 3: 776 /* 777 * Fix CWP. 778 * In order to recapitulate, the input registers in the current 779 * window are the output registers of the window to which we want 780 * to restore. Because the fill trap fills only input and local 781 * registers of a window, we need to preserve those output 782 * registers manually. 783 */ 784 mov %sp, %g2 785 stx %i0, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0] 786 stx %i1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1] 787 stx %i2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2] 788 stx %i3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3] 789 stx %i4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4] 790 stx %i5, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5] 791 stx %i6, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6] 792 stx %i7, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7] 793 wrpr %l0, 0, %cwp 794 mov %g2, %sp 795 ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0], %i0 796 ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1], %i1 797 ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2], %i2 798 ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3], %i3 799 ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4], %i4 800 ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5], %i5 801 ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6], %i6 802 ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7], %i7 666 803 667 804 4: … … 682 819 .endm 683 820 684 685 #define NOT(x) ((x) == 0) 821 #endif 822 823 /* 824 * Preemptible trap handler for handling traps from kernel. 825 */ 826 .macro PREEMPTIBLE_HANDLER_KERNEL 827 828 /* 829 * ASSERT(%tl == 1) 830 */ 831 rdpr %tl, %g3 832 cmp %g3, 1 833 be 1f 834 nop 835 0: ba 0b ! this is for debugging, if we ever get here 836 nop ! it will be easy to find 837 838 1: 839 /* prevent unnecessary CLEANWIN exceptions */ 840 wrpr %g0, NWINDOWS - 1, %cleanwin 841 842 /* 843 * Prevent SAVE instruction from causing a spill exception. If the 844 * CANSAVE register is zero, explicitly spill register window 845 * at CWP + 2. 846 */ 847 848 rdpr %cansave, %g3 849 brnz %g3, 2f 850 nop 851 INLINE_SPILL %g3, %g4 852 853 2: 854 /* ask for new register window */ 855 save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp 856 857 MIDDLE_PART 0 858 859 4: 860 /* 861 * Prevent RESTORE instruction from causing a fill exception. If the 862 * CANRESTORE register is zero, explicitly fill register window 863 * at CWP - 1. 864 */ 865 rdpr %canrestore, %g1 866 brnz %g1, 5f 867 nop 868 INLINE_FILL %g3, %g4 869 870 5: 871 restore 872 retry 873 .endm 874 875 876 877 /* 878 * Spills the window at CWP + 2 to the userspace window buffer. This macro 879 * is to be used before doing SAVE when the spill trap is undesirable. 880 * 881 * Parameters: 882 * tmpreg1 global register to be used for scratching purposes 883 * tmpreg2 global register to be used for scratching purposes 884 * tmpreg3 global register to be used for scratching purposes 885 */ 886 .macro INLINE_SPILL_TO_WBUF tmpreg1, tmpreg2, tmpreg3 887 ! CWP := CWP + 2 888 rdpr %cwp, \tmpreg2 889 add \tmpreg2, 2, \tmpreg1 890 and \tmpreg1, NWINDOWS - 1, \tmpreg1 ! modulo NWINDOWS 891 wrpr \tmpreg1, %cwp 892 893 ! spill to userspace window buffer 894 SAVE_TO_USPACE_WBUF \tmpreg3, \tmpreg1 895 896 ! CWP := CWP - 2 897 wrpr \tmpreg2, %cwp 898 899 saved 900 .endm 901 902 /* 903 * Preemptible handler for handling traps from userspace. 904 */ 905 .macro PREEMPTIBLE_HANDLER_USPACE is_syscall 906 /* 907 * One of the ways this handler can be invoked is after a nested MMU trap from 908 * either spill_1_normal or fill_1_normal traps. Both of these traps manipulate 909 * the CWP register. We deal with the situation by simulating the MMU trap 910 * on TL=1 and restart the respective SAVE or RESTORE instruction once the MMU 911 * trap is resolved. However, because we are in the wrong window from the 912 * perspective of the MMU trap, we need to synchronize CWP with CWP from TL=0. 913 */ 914 .if NOT(\is_syscall) 915 rdpr %tstate, %g3 916 and %g3, TSTATE_CWP_MASK, %g4 917 wrpr %g4, 0, %cwp ! resynchronize CWP 918 .endif 919 920 /* prevent unnecessary CLEANWIN exceptions */ 921 wrpr %g0, NWINDOWS - 1, %cleanwin 922 923 /* 924 * Prevent SAVE instruction from causing a spill exception. If the 925 * CANSAVE register is zero, explicitly spill register window 926 * at CWP + 2. 927 */ 928 rdpr %cansave, %g3 929 brnz %g3, 2f 930 nop 931 INLINE_SPILL_TO_WBUF %g3, %g4, %g7 932 933 2: 934 set SCRATCHPAD_KSTACK, %g4 935 ldxa [%g4] ASI_SCRATCHPAD, %g6 936 save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp 937 938 .if \is_syscall 939 /* Copy arguments for the syscall to the new window. */ 940 mov %i0, %o0 941 mov %i1, %o1 942 mov %i2, %o2 943 mov %i3, %o3 944 mov %i4, %o4 945 mov %i5, %o5 946 .endif 947 948 mov VA_PRIMARY_CONTEXT_REG, %l0 949 stxa %g0, [%l0] ASI_PRIMARY_CONTEXT_REG 950 rd %pc, %l0 951 flush %l0 952 953 /* Mark the CANRESTORE windows as OTHER windows. */ 954 rdpr %canrestore, %l0 955 wrpr %l0, %otherwin 956 wrpr %g0, %canrestore 957 958 /* 959 * Other window spills will go to the userspace window buffer 960 * and normal spills will go to the kernel stack. 961 */ 962 wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(0), %wstate 963 964 MIDDLE_PART \is_syscall 965 966 4: 967 /* 968 * Spills and fills will be processed by the {spill,fill}_1_normal 969 * handlers. 970 */ 971 wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(1), %wstate 972 973 /* 974 * Set primary context according to secondary context. 975 */ 976 wr %g0, ASI_SECONDARY_CONTEXT_REG, %asi 977 ldxa [VA_SECONDARY_CONTEXT_REG] %asi, %g1 978 wr %g0, ASI_PRIMARY_CONTEXT_REG, %asi 979 stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi 980 rd %pc, %g1 981 flush %g1 982 983 /* Restoring userspace windows: */ 984 985 /* Save address of the userspace window buffer to the %g7 register. */ 986 set SCRATCHPAD_WBUF, %g5 987 ldxa [%g5] ASI_SCRATCHPAD, %g7 988 989 rdpr %cwp, %g1 990 rdpr %otherwin, %g2 991 992 /* 993 * Skip all OTHERWIN windows and descend to the first window 994 * in the userspace window buffer. 995 */ 996 sub %g1, %g2, %g3 997 dec %g3 998 and %g3, NWINDOWS - 1, %g3 999 wrpr %g3, 0, %cwp 1000 1001 /* 1002 * CWP is now in the window last saved in the userspace window buffer. 1003 * Fill all windows stored in the buffer. 1004 */ 1005 clr %g4 1006 5: andcc %g7, UWB_ALIGNMENT - 1, %g0 ! alignment check 1007 bz 6f ! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill 1008 nop 1009 1010 add %g7, -STACK_WINDOW_SAVE_AREA_SIZE, %g7 1011 ldx [%g7 + L0_OFFSET], %l0 1012 ldx [%g7 + L1_OFFSET], %l1 1013 ldx [%g7 + L2_OFFSET], %l2 1014 ldx [%g7 + L3_OFFSET], %l3 1015 ldx [%g7 + L4_OFFSET], %l4 1016 ldx [%g7 + L5_OFFSET], %l5 1017 ldx [%g7 + L6_OFFSET], %l6 1018 ldx [%g7 + L7_OFFSET], %l7 1019 ldx [%g7 + I0_OFFSET], %i0 1020 ldx [%g7 + I1_OFFSET], %i1 1021 ldx [%g7 + I2_OFFSET], %i2 1022 ldx [%g7 + I3_OFFSET], %i3 1023 ldx [%g7 + I4_OFFSET], %i4 1024 ldx [%g7 + I5_OFFSET], %i5 1025 ldx [%g7 + I6_OFFSET], %i6 1026 ldx [%g7 + I7_OFFSET], %i7 1027 1028 dec %g3 1029 and %g3, NWINDOWS - 1, %g3 1030 wrpr %g3, 0, %cwp ! switch to the preceeding window 1031 1032 ba 5b 1033 inc %g4 1034 1035 6: 1036 /* Save changes of the address of the userspace window buffer. */ 1037 stxa %g7, [%g5] ASI_SCRATCHPAD 1038 1039 /* 1040 * Switch back to the proper current window and adjust 1041 * OTHERWIN, CANRESTORE, CANSAVE and CLEANWIN. 1042 */ 1043 wrpr %g1, 0, %cwp 1044 add %g4, %g2, %g2 1045 cmp %g2, NWINDOWS - 2 1046 bg 8f ! fix the CANRESTORE=NWINDOWS-1 anomaly 1047 mov NWINDOWS - 2, %g1 ! use dealy slot for both cases 1048 sub %g1, %g2, %g1 1049 1050 wrpr %g0, 0, %otherwin 1051 wrpr %g1, 0, %cansave ! NWINDOWS - 2 - CANRESTORE 1052 wrpr %g2, 0, %canrestore ! OTHERWIN + windows in the buffer 1053 wrpr %g2, 0, %cleanwin ! avoid information leak 1054 1055 7: 1056 restore 1057 1058 .if \is_syscall 1059 done 1060 .else 1061 retry 1062 .endif 1063 1064 8: 1065 /* 1066 * We got here in order to avoid inconsistency of the window state registers. 1067 * If the: 1068 * 1069 * save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp 1070 * 1071 * instruction trapped and spilled a register window into the userspace 1072 * window buffer, we have just restored NWINDOWS - 1 register windows. 1073 * However, CANRESTORE can be only NWINDOW - 2 at most. 1074 * 1075 * The solution is to manually switch to (CWP - 1) mod NWINDOWS 1076 * and set the window state registers so that: 1077 * 1078 * CANRESTORE = NWINDOWS - 2 1079 * CLEANWIN = NWINDOWS - 2 1080 * CANSAVE = 0 1081 * OTHERWIN = 0 1082 * 1083 * The RESTORE instruction is therfore to be skipped. 1084 */ 1085 wrpr %g0, 0, %otherwin 1086 wrpr %g0, 0, %cansave 1087 wrpr %g1, 0, %canrestore 1088 wrpr %g1, 0, %cleanwin 1089 1090 rdpr %cwp, %g1 1091 dec %g1 1092 and %g1, NWINDOWS - 1, %g1 1093 wrpr %g1, 0, %cwp ! CWP-- 1094 1095 .if \is_syscall 1096 done 1097 .else 1098 retry 1099 .endif 1100 1101 .endm 1102 1103 686 1104 687 1105 /* Preemptible trap handler for TL=1. … … 692 1110 */ 693 1111 .macro PREEMPTIBLE_HANDLER_TEMPLATE is_syscall 1112 rdpr %tstate, %g3 1113 and %g3, TSTATE_PRIV_BIT, %g3 1114 brz %g3, 100f ! trapping from userspace 1115 nop 1116 694 1117 PREEMPTIBLE_HANDLER_KERNEL 1118 ba 101f 1119 nop 1120 1121 100: 1122 PREEMPTIBLE_HANDLER_USPACE \is_syscall 1123 1124 101: 695 1125 .endm 696 1126
Note:
See TracChangeset
for help on using the changeset viewer.