7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #if !defined(lint)
28 #include "assym.h"
29 #endif /* !lint */
30 #include <sys/asm_linkage.h>
31 #include <sys/privregs.h>
32 #include <sys/sun4asi.h>
33 #include <sys/machasi.h>
34 #include <sys/hypervisor_api.h>
35 #include <sys/machtrap.h>
36 #include <sys/machthread.h>
37 #include <sys/machbrand.h>
38 #include <sys/pcb.h>
39 #include <sys/pte.h>
40 #include <sys/mmu.h>
41 #include <sys/machpcb.h>
42 #include <sys/async.h>
43 #include <sys/intreg.h>
44 #include <sys/scb.h>
45 #include <sys/psr_compat.h>
46 #include <sys/syscall.h>
47 #include <sys/machparam.h>
48 #include <sys/traptrace.h>
49 #include <vm/hat_sfmmu.h>
101 #define TT_TRACE_L_INS 3
102
103 #else
104
105 #define TT_TRACE(label)
106 #define TT_TRACE_INS 0
107
108 #define TT_TRACE_L(label)
109 #define TT_TRACE_L_INS 0
110
111 #endif
112
113 /*
114 * This first set are funneled to trap() with %tt as the type.
115 * Trap will then either panic or send the user a signal.
116 */
117 /*
118 * NOT is used for traps that just shouldn't happen.
119 * It comes in both single and quadruple flavors.
120 */
121 #if !defined(lint)
122 .global trap
123 #endif /* !lint */
124 #define NOT \
125 TT_TRACE(trace_gen) ;\
126 set trap, %g1 ;\
127 rdpr %tt, %g3 ;\
128 ba,pt %xcc, sys_trap ;\
129 sub %g0, 1, %g4 ;\
130 .align 32
131 #define NOT4 NOT; NOT; NOT; NOT
132
133 #define NOTP \
134 TT_TRACE(trace_gen) ;\
135 ba,pt %xcc, ptl1_panic ;\
136 mov PTL1_BAD_TRAP, %g1 ;\
137 .align 32
138 #define NOTP4 NOTP; NOTP; NOTP; NOTP
139
140
141 /*
142 * BAD is used for trap vectors we don't have a kernel
143 * handler for.
144 * It also comes in single and quadruple versions.
145 */
146 #define BAD NOT
147 #define BAD4 NOT4
148
149 #define DONE \
150 done; \
151 .align 32
152
153 /*
154 * TRAP vectors to the trap() function.
155 * It's main use is for user errors.
156 */
157 #if !defined(lint)
158 .global trap
159 #endif /* !lint */
160 #define TRAP(arg) \
161 TT_TRACE(trace_gen) ;\
162 set trap, %g1 ;\
163 mov arg, %g3 ;\
164 ba,pt %xcc, sys_trap ;\
165 sub %g0, 1, %g4 ;\
166 .align 32
167
168 /*
169 * SYSCALL is used for unsupported syscall interfaces (with 'which'
170 * set to 'nosys') and legacy support of old SunOS 4.x syscalls (with
171 * 'which' set to 'syscall_trap32').
172 *
173 * The SYSCALL_TRAP* macros are used for syscall entry points.
174 * SYSCALL_TRAP is used to support LP64 syscalls and SYSCALL_TRAP32
175 * is used to support ILP32. Each macro can only be used once
176 * since they each define a symbol. The symbols are used as hot patch
177 * points by the brand infrastructure to dynamically enable and disable
178 * brand syscall interposition. See the comments around BRAND_CALLBACK
179 * and brand_plat_interposition_enable() for more information.
256 * REGISTER WINDOW MANAGEMENT MACROS
257 */
258
259 /*
260 * various convenient units of padding
261 */
262 #define SKIP(n) .skip 4*(n)
263
264 /*
265 * CLEAN_WINDOW is the simple handler for cleaning a register window.
266 */
267 #define CLEAN_WINDOW \
268 TT_TRACE_L(trace_win) ;\
269 rdpr %cleanwin, %l0; inc %l0; wrpr %l0, %cleanwin ;\
270 clr %l0; clr %l1; clr %l2; clr %l3 ;\
271 clr %l4; clr %l5; clr %l6; clr %l7 ;\
272 clr %o0; clr %o1; clr %o2; clr %o3 ;\
273 clr %o4; clr %o5; clr %o6; clr %o7 ;\
274 retry; .align 128
275
276 #if !defined(lint)
277
278 /*
279 * If we get an unresolved tlb miss while in a window handler, the fault
280 * handler will resume execution at the last instruction of the window
281 * hander, instead of delivering the fault to the kernel. Spill handlers
282 * use this to spill windows into the wbuf.
283 *
284 * The mixed handler works by checking %sp, and branching to the correct
285 * handler. This is done by branching back to label 1: for 32b frames,
286 * or label 2: for 64b frames; which implies the handler order is: 32b,
287 * 64b, mixed. The 1: and 2: labels are offset into the routines to
288 * allow the branchs' delay slots to contain useful instructions.
289 */
290
291 /*
292 * SPILL_32bit spills a 32-bit-wide kernel register window. It
293 * assumes that the kernel context and the nucleus context are the
294 * same. The stack pointer is required to be eight-byte aligned even
295 * though this code only needs it to be four-byte aligned.
296 */
297 #define SPILL_32bit(tail) \
567 ldxa [%g5 + %g2]asi_num, %l5 ;\
568 ldxa [%g5 + %g3]asi_num, %l6 ;\
569 ldxa [%g5 + %g4]asi_num, %l7 ;\
570 add %g5, 32, %g5 ;\
571 ldxa [%g5 + %g1]asi_num, %i0 ;\
572 ldxa [%g5 + %g2]asi_num, %i1 ;\
573 ldxa [%g5 + %g3]asi_num, %i2 ;\
574 ldxa [%g5 + %g4]asi_num, %i3 ;\
575 add %g5, 32, %g5 ;\
576 ldxa [%g5 + %g1]asi_num, %i4 ;\
577 ldxa [%g5 + %g2]asi_num, %i5 ;\
578 ldxa [%g5 + %g3]asi_num, %i6 ;\
579 ldxa [%g5 + %g4]asi_num, %i7 ;\
580 restored ;\
581 retry ;\
582 SKIP(31-25-TT_TRACE_L_INS) ;\
583 ba,a,pt %xcc, fault_64bit_/**/tail ;\
584 .empty
585
586
587 #endif /* !lint */
588
589 /*
590 * SPILL_mixed spills either size window, depending on
591 * whether %sp is even or odd, to a 32-bit address space.
592 * This may only be used in conjunction with SPILL_32bit/
593 * FILL_64bit.
594 * Clear upper 32 bits of %sp if it is odd.
595 * We won't need to clear them in 64 bit kernel.
596 */
597 #define SPILL_mixed \
598 btst 1, %sp ;\
599 bz,a,pt %xcc, 1b ;\
600 srl %sp, 0, %sp ;\
601 ba,pt %xcc, 2b ;\
602 nop ;\
603 .align 128
604
605 /*
606 * FILL_mixed(ASI) fills either size window, depending on
607 * whether %sp is even or odd, from a 32-bit address space.
608 * This may only be used in conjunction with FILL_32bit/
708 TT_TRACE(trace_gen) ;\
709 ba,pt %xcc,.fp_disabled ;\
710 nop ;\
711 .align 32
712
713 /*
714 * Floating point exceptions.
715 */
716 #define FP_IEEE_TRAP \
717 TT_TRACE(trace_gen) ;\
718 ba,pt %xcc,.fp_ieee_exception ;\
719 nop ;\
720 .align 32
721
722 #define FP_TRAP \
723 TT_TRACE(trace_gen) ;\
724 ba,pt %xcc,.fp_exception ;\
725 nop ;\
726 .align 32
727
728 #if !defined(lint)
729
730 /*
731 * ECACHE_ECC error traps at level 0 and level 1
732 */
733 #define ECACHE_ECC(table_name) \
734 .global table_name ;\
735 table_name: ;\
736 membar #Sync ;\
737 set trap, %g1 ;\
738 rdpr %tt, %g3 ;\
739 ba,pt %xcc, sys_trap ;\
740 sub %g0, 1, %g4 ;\
741 .align 32
742
743 #endif /* !lint */
744
745 /*
746 * illegal instruction trap
747 */
748 #define ILLTRAP_INSTR \
749 membar #Sync ;\
750 TT_TRACE(trace_gen) ;\
751 or %g0, P_UTRAP4, %g2 ;\
752 or %g0, T_UNIMP_INSTR, %g3 ;\
753 sethi %hi(.check_v9utrap), %g4 ;\
754 jmp %g4 + %lo(.check_v9utrap) ;\
755 nop ;\
756 .align 32
757
758 /*
759 * tag overflow trap
760 */
761 #define TAG_OVERFLOW \
762 TT_TRACE(trace_gen) ;\
763 or %g0, P_UTRAP10, %g2 ;\
764 or %g0, T_TAG_OVERFLOW, %g3 ;\
1070 mov MMFSA_D_ADDR, %g1 ;\
1071 cmp %g6, FAST_IMMU_MISS_TT ;\
1072 move %xcc, MMFSA_I_ADDR, %g1 ;\
1073 cmp %g6, T_INSTR_MMU_MISS ;\
1074 move %xcc, MMFSA_I_ADDR, %g1 ;\
1075 ldx [%g4 + %g1], %g1 ;\
1076 stxa %g1, [%g3 + TRAP_ENT_TSTATE]%asi /* fault addr */ ;\
1077 mov MMFSA_D_CTX, %g1 ;\
1078 cmp %g6, FAST_IMMU_MISS_TT ;\
1079 move %xcc, MMFSA_I_CTX, %g1 ;\
1080 cmp %g6, T_INSTR_MMU_MISS ;\
1081 move %xcc, MMFSA_I_CTX, %g1 ;\
1082 ldx [%g4 + %g1], %g1 ;\
1083 stna %g1, [%g3 + TRAP_ENT_TR]%asi ;\
1084 TRACE_NEXT(%g3, %g4, %g6)
1085 #else
1086 #define TRACE_TSBHIT(ttextra)
1087 #endif
1088
1089
1090 #if defined(lint)
1091
1092 struct scb trap_table;
1093 struct scb scb; /* trap_table/scb are the same object */
1094
1095 #else /* lint */
1096
1097 /*
1098 * =======================================================================
1099 * SPARC V9 TRAP TABLE
1100 *
1101 * The trap table is divided into two halves: the first half is used when
1102 * taking traps when TL=0; the second half is used when taking traps from
1103 * TL>0. Note that handlers in the second half of the table might not be able
1104 * to make the same assumptions as handlers in the first half of the table.
1105 *
1106 * Worst case trap nesting so far:
1107 *
1108 * at TL=0 client issues software trap requesting service
1109 * at TL=1 nucleus wants a register window
1110 * at TL=2 register window clean/spill/fill takes a TLB miss
1111 * at TL=3 processing TLB miss
1112 * at TL=4 handle asynchronous error
1113 *
1114 * Note that a trap from TL=4 to TL=5 places Spitfire in "RED mode".
1115 *
1116 * =======================================================================
2880 * %g1: return address (where the brand handler jumps back to) \
2881 * %g2: address of CPU structure \
2882 * %g3: address of brand handler (where we will jump to) \
2883 */ \
2884 mov %pc, %g1 ;\
2885 add %g1, 16, %g1 ;\
2886 jmp %g3 ;\
2887 nop ;\
2888 1:
2889
2890 ENTRY_NP(syscall_wrapper32)
2891 BRAND_CALLBACK(BRAND_CB_SYSCALL32)
2892 SYSCALL_NOTT(syscall_trap32)
2893 SET_SIZE(syscall_wrapper32)
2894
2895 ENTRY_NP(syscall_wrapper)
2896 BRAND_CALLBACK(BRAND_CB_SYSCALL)
2897 SYSCALL_NOTT(syscall_trap)
2898 SET_SIZE(syscall_wrapper)
2899
2900 #endif /* lint */
|
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include "assym.h"
28 #include <sys/asm_linkage.h>
29 #include <sys/privregs.h>
30 #include <sys/sun4asi.h>
31 #include <sys/machasi.h>
32 #include <sys/hypervisor_api.h>
33 #include <sys/machtrap.h>
34 #include <sys/machthread.h>
35 #include <sys/machbrand.h>
36 #include <sys/pcb.h>
37 #include <sys/pte.h>
38 #include <sys/mmu.h>
39 #include <sys/machpcb.h>
40 #include <sys/async.h>
41 #include <sys/intreg.h>
42 #include <sys/scb.h>
43 #include <sys/psr_compat.h>
44 #include <sys/syscall.h>
45 #include <sys/machparam.h>
46 #include <sys/traptrace.h>
47 #include <vm/hat_sfmmu.h>
99 #define TT_TRACE_L_INS 3
100
101 #else
102
103 #define TT_TRACE(label)
104 #define TT_TRACE_INS 0
105
106 #define TT_TRACE_L(label)
107 #define TT_TRACE_L_INS 0
108
109 #endif
110
111 /*
112 * This first set are funneled to trap() with %tt as the type.
113 * Trap will then either panic or send the user a signal.
114 */
115 /*
116 * NOT is used for traps that just shouldn't happen.
117 * It comes in both single and quadruple flavors.
118 */
119 .global trap
120 #define NOT \
121 TT_TRACE(trace_gen) ;\
122 set trap, %g1 ;\
123 rdpr %tt, %g3 ;\
124 ba,pt %xcc, sys_trap ;\
125 sub %g0, 1, %g4 ;\
126 .align 32
127 #define NOT4 NOT; NOT; NOT; NOT
128
129 #define NOTP \
130 TT_TRACE(trace_gen) ;\
131 ba,pt %xcc, ptl1_panic ;\
132 mov PTL1_BAD_TRAP, %g1 ;\
133 .align 32
134 #define NOTP4 NOTP; NOTP; NOTP; NOTP
135
136
137 /*
138 * BAD is used for trap vectors we don't have a kernel
139 * handler for.
140 * It also comes in single and quadruple versions.
141 */
142 #define BAD NOT
143 #define BAD4 NOT4
144
145 #define DONE \
146 done; \
147 .align 32
148
149 /*
150 * TRAP vectors to the trap() function.
151 * It's main use is for user errors.
152 */
153 .global trap
154 #define TRAP(arg) \
155 TT_TRACE(trace_gen) ;\
156 set trap, %g1 ;\
157 mov arg, %g3 ;\
158 ba,pt %xcc, sys_trap ;\
159 sub %g0, 1, %g4 ;\
160 .align 32
161
162 /*
163 * SYSCALL is used for unsupported syscall interfaces (with 'which'
164 * set to 'nosys') and legacy support of old SunOS 4.x syscalls (with
165 * 'which' set to 'syscall_trap32').
166 *
167 * The SYSCALL_TRAP* macros are used for syscall entry points.
168 * SYSCALL_TRAP is used to support LP64 syscalls and SYSCALL_TRAP32
169 * is used to support ILP32. Each macro can only be used once
170 * since they each define a symbol. The symbols are used as hot patch
171 * points by the brand infrastructure to dynamically enable and disable
172 * brand syscall interposition. See the comments around BRAND_CALLBACK
173 * and brand_plat_interposition_enable() for more information.
250 * REGISTER WINDOW MANAGEMENT MACROS
251 */
252
253 /*
254 * various convenient units of padding
255 */
256 #define SKIP(n) .skip 4*(n)
257
258 /*
259 * CLEAN_WINDOW is the simple handler for cleaning a register window.
260 */
261 #define CLEAN_WINDOW \
262 TT_TRACE_L(trace_win) ;\
263 rdpr %cleanwin, %l0; inc %l0; wrpr %l0, %cleanwin ;\
264 clr %l0; clr %l1; clr %l2; clr %l3 ;\
265 clr %l4; clr %l5; clr %l6; clr %l7 ;\
266 clr %o0; clr %o1; clr %o2; clr %o3 ;\
267 clr %o4; clr %o5; clr %o6; clr %o7 ;\
268 retry; .align 128
269
270 /*
271 * If we get an unresolved tlb miss while in a window handler, the fault
272 * handler will resume execution at the last instruction of the window
273 * hander, instead of delivering the fault to the kernel. Spill handlers
274 * use this to spill windows into the wbuf.
275 *
276 * The mixed handler works by checking %sp, and branching to the correct
277 * handler. This is done by branching back to label 1: for 32b frames,
278 * or label 2: for 64b frames; which implies the handler order is: 32b,
279 * 64b, mixed. The 1: and 2: labels are offset into the routines to
280 * allow the branchs' delay slots to contain useful instructions.
281 */
282
283 /*
284 * SPILL_32bit spills a 32-bit-wide kernel register window. It
285 * assumes that the kernel context and the nucleus context are the
286 * same. The stack pointer is required to be eight-byte aligned even
287 * though this code only needs it to be four-byte aligned.
288 */
289 #define SPILL_32bit(tail) \
559 ldxa [%g5 + %g2]asi_num, %l5 ;\
560 ldxa [%g5 + %g3]asi_num, %l6 ;\
561 ldxa [%g5 + %g4]asi_num, %l7 ;\
562 add %g5, 32, %g5 ;\
563 ldxa [%g5 + %g1]asi_num, %i0 ;\
564 ldxa [%g5 + %g2]asi_num, %i1 ;\
565 ldxa [%g5 + %g3]asi_num, %i2 ;\
566 ldxa [%g5 + %g4]asi_num, %i3 ;\
567 add %g5, 32, %g5 ;\
568 ldxa [%g5 + %g1]asi_num, %i4 ;\
569 ldxa [%g5 + %g2]asi_num, %i5 ;\
570 ldxa [%g5 + %g3]asi_num, %i6 ;\
571 ldxa [%g5 + %g4]asi_num, %i7 ;\
572 restored ;\
573 retry ;\
574 SKIP(31-25-TT_TRACE_L_INS) ;\
575 ba,a,pt %xcc, fault_64bit_/**/tail ;\
576 .empty
577
578
579 /*
580 * SPILL_mixed spills either size window, depending on
581 * whether %sp is even or odd, to a 32-bit address space.
582 * This may only be used in conjunction with SPILL_32bit/
583 * FILL_64bit.
584 * Clear upper 32 bits of %sp if it is odd.
585 * We won't need to clear them in 64 bit kernel.
586 */
587 #define SPILL_mixed \
588 btst 1, %sp ;\
589 bz,a,pt %xcc, 1b ;\
590 srl %sp, 0, %sp ;\
591 ba,pt %xcc, 2b ;\
592 nop ;\
593 .align 128
594
595 /*
596 * FILL_mixed(ASI) fills either size window, depending on
597 * whether %sp is even or odd, from a 32-bit address space.
598 * This may only be used in conjunction with FILL_32bit/
698 TT_TRACE(trace_gen) ;\
699 ba,pt %xcc,.fp_disabled ;\
700 nop ;\
701 .align 32
702
703 /*
704 * Floating point exceptions.
705 */
706 #define FP_IEEE_TRAP \
707 TT_TRACE(trace_gen) ;\
708 ba,pt %xcc,.fp_ieee_exception ;\
709 nop ;\
710 .align 32
711
712 #define FP_TRAP \
713 TT_TRACE(trace_gen) ;\
714 ba,pt %xcc,.fp_exception ;\
715 nop ;\
716 .align 32
717
718 /*
719 * ECACHE_ECC error traps at level 0 and level 1
720 */
721 #define ECACHE_ECC(table_name) \
722 .global table_name ;\
723 table_name: ;\
724 membar #Sync ;\
725 set trap, %g1 ;\
726 rdpr %tt, %g3 ;\
727 ba,pt %xcc, sys_trap ;\
728 sub %g0, 1, %g4 ;\
729 .align 32
730
731 /*
732 * illegal instruction trap
733 */
734 #define ILLTRAP_INSTR \
735 membar #Sync ;\
736 TT_TRACE(trace_gen) ;\
737 or %g0, P_UTRAP4, %g2 ;\
738 or %g0, T_UNIMP_INSTR, %g3 ;\
739 sethi %hi(.check_v9utrap), %g4 ;\
740 jmp %g4 + %lo(.check_v9utrap) ;\
741 nop ;\
742 .align 32
743
744 /*
745 * tag overflow trap
746 */
747 #define TAG_OVERFLOW \
748 TT_TRACE(trace_gen) ;\
749 or %g0, P_UTRAP10, %g2 ;\
750 or %g0, T_TAG_OVERFLOW, %g3 ;\
1056 mov MMFSA_D_ADDR, %g1 ;\
1057 cmp %g6, FAST_IMMU_MISS_TT ;\
1058 move %xcc, MMFSA_I_ADDR, %g1 ;\
1059 cmp %g6, T_INSTR_MMU_MISS ;\
1060 move %xcc, MMFSA_I_ADDR, %g1 ;\
1061 ldx [%g4 + %g1], %g1 ;\
1062 stxa %g1, [%g3 + TRAP_ENT_TSTATE]%asi /* fault addr */ ;\
1063 mov MMFSA_D_CTX, %g1 ;\
1064 cmp %g6, FAST_IMMU_MISS_TT ;\
1065 move %xcc, MMFSA_I_CTX, %g1 ;\
1066 cmp %g6, T_INSTR_MMU_MISS ;\
1067 move %xcc, MMFSA_I_CTX, %g1 ;\
1068 ldx [%g4 + %g1], %g1 ;\
1069 stna %g1, [%g3 + TRAP_ENT_TR]%asi ;\
1070 TRACE_NEXT(%g3, %g4, %g6)
1071 #else
1072 #define TRACE_TSBHIT(ttextra)
1073 #endif
1074
1075
1076 /*
1077 * =======================================================================
1078 * SPARC V9 TRAP TABLE
1079 *
1080 * The trap table is divided into two halves: the first half is used when
1081 * taking traps when TL=0; the second half is used when taking traps from
1082 * TL>0. Note that handlers in the second half of the table might not be able
1083 * to make the same assumptions as handlers in the first half of the table.
1084 *
1085 * Worst case trap nesting so far:
1086 *
1087 * at TL=0 client issues software trap requesting service
1088 * at TL=1 nucleus wants a register window
1089 * at TL=2 register window clean/spill/fill takes a TLB miss
1090 * at TL=3 processing TLB miss
1091 * at TL=4 handle asynchronous error
1092 *
1093 * Note that a trap from TL=4 to TL=5 places Spitfire in "RED mode".
1094 *
1095 * =======================================================================
2859 * %g1: return address (where the brand handler jumps back to) \
2860 * %g2: address of CPU structure \
2861 * %g3: address of brand handler (where we will jump to) \
2862 */ \
2863 mov %pc, %g1 ;\
2864 add %g1, 16, %g1 ;\
2865 jmp %g3 ;\
2866 nop ;\
2867 1:
2868
2869 ENTRY_NP(syscall_wrapper32)
2870 BRAND_CALLBACK(BRAND_CB_SYSCALL32)
2871 SYSCALL_NOTT(syscall_trap32)
2872 SET_SIZE(syscall_wrapper32)
2873
2874 ENTRY_NP(syscall_wrapper)
2875 BRAND_CALLBACK(BRAND_CB_SYSCALL)
2876 SYSCALL_NOTT(syscall_trap)
2877 SET_SIZE(syscall_wrapper)
2878
|