Subversion Repositories HelenOS

Rev

Rev 4369 | Rev 4433 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4369 Rev 4383
1
#
1
#
2
# Copyright (c) 2005 Jakub Jermar
2
# Copyright (c) 2005 Jakub Jermar
3
# Copyright (c) 2008 Pavel Rimsky
3
# Copyright (c) 2008 Pavel Rimsky
4
# All rights reserved.
4
# All rights reserved.
5
#
5
#
6
# Redistribution and use in source and binary forms, with or without
6
# Redistribution and use in source and binary forms, with or without
7
# modification, are permitted provided that the following conditions
7
# modification, are permitted provided that the following conditions
8
# are met:
8
# are met:
9
#
9
#
10
# - Redistributions of source code must retain the above copyright
10
# - Redistributions of source code must retain the above copyright
11
#   notice, this list of conditions and the following disclaimer.
11
#   notice, this list of conditions and the following disclaimer.
12
# - Redistributions in binary form must reproduce the above copyright
12
# - Redistributions in binary form must reproduce the above copyright
13
#   notice, this list of conditions and the following disclaimer in the
13
#   notice, this list of conditions and the following disclaimer in the
14
#   documentation and/or other materials provided with the distribution.
14
#   documentation and/or other materials provided with the distribution.
15
# - The name of the author may not be used to endorse or promote products
15
# - The name of the author may not be used to endorse or promote products
16
#   derived from this software without specific prior written permission.
16
#   derived from this software without specific prior written permission.
17
#
17
#
18
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
#
28
#
29
 
29
 
30
/**
30
/**
31
 * @file
31
 * @file
32
 * @brief This file contains kernel trap table.
32
 * @brief This file contains kernel trap table.
33
 */
33
 */
34
 
34
 
35
.register %g2, #scratch
35
.register %g2, #scratch
36
.register %g3, #scratch
36
.register %g3, #scratch
37
 
37
 
38
.text
38
.text
39
 
39
 
40
#include <arch/trap/trap_table.h>
40
#include <arch/trap/trap_table.h>
41
#include <arch/trap/regwin.h>
41
#include <arch/trap/regwin.h>
42
#include <arch/trap/interrupt.h>
42
#include <arch/trap/interrupt.h>
43
#include <arch/trap/exception.h>
43
#include <arch/trap/exception.h>
44
#include <arch/trap/syscall.h>
44
#include <arch/trap/syscall.h>
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>
50
#include <arch/sun4v/arch.h>
51
#include <arch/sun4v/cpu.h>
51
#include <arch/sun4v/cpu.h>
52
 
52
 
53
#define TABLE_SIZE	TRAP_TABLE_SIZE
53
#define TABLE_SIZE	TRAP_TABLE_SIZE
54
#define ENTRY_SIZE	TRAP_TABLE_ENTRY_SIZE
54
#define ENTRY_SIZE	TRAP_TABLE_ENTRY_SIZE
55
 
55
 
56
/*
56
/*
57
 * Kernel trap table.
57
 * Kernel trap table.
58
 */
58
 */
59
.align TABLE_SIZE
59
.align TABLE_SIZE
60
.global trap_table
60
.global trap_table
61
trap_table:
61
trap_table:
62
 
62
 
63
/* TT = 0x08, TL = 0, instruction_access_exception */
63
/* TT = 0x08, TL = 0, instruction_access_exception */
-
 
64
/* TT = 0x08, TL = 0, IAE_privilege_violation on UltraSPARC T2 */
64
.org trap_table + TT_INSTRUCTION_ACCESS_EXCEPTION*ENTRY_SIZE
65
.org trap_table + TT_INSTRUCTION_ACCESS_EXCEPTION*ENTRY_SIZE
65
.global instruction_access_exception_tl0
66
.global instruction_access_exception_tl0
66
instruction_access_exception_tl0:
67
instruction_access_exception_tl0:
67
	/*wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
-
 
68
	PREEMPTIBLE_HANDLER instruction_access_exception*/
68
	PREEMPTIBLE_HANDLER instruction_access_exception
69
 
69
 
70
/* TT = 0x0a, TL = 0, instruction_access_error */
70
/* TT = 0x0a, TL = 0, instruction_access_error */
71
.org trap_table + TT_INSTRUCTION_ACCESS_ERROR*ENTRY_SIZE
71
.org trap_table + TT_INSTRUCTION_ACCESS_ERROR*ENTRY_SIZE
72
.global instruction_access_error_tl0
72
.global instruction_access_error_tl0
73
instruction_access_error_tl0:
73
instruction_access_error_tl0:
74
	PREEMPTIBLE_HANDLER instruction_access_error
74
	PREEMPTIBLE_HANDLER instruction_access_error
75
 
75
 
-
 
76
/* TT = 0x0b, TL = 0, IAE_unauth_access */
-
 
77
.org trap_table + TT_IAE_UNAUTH_ACCESS*ENTRY_SIZE
-
 
78
.global iae_unauth_access_tl0
-
 
79
iae_unauth_access_tl0:
-
 
80
	PREEMPTIBLE_HANDLER instruction_access_exception
-
 
81
 
-
 
82
/* TT = 0x0c, TL = 0, IAE_nfo_page */
-
 
83
.org trap_table + TT_IAE_NFO_PAGE*ENTRY_SIZE
-
 
84
.global iae_nfo_page_tl0
-
 
85
iae_nfo_page_tl0:
-
 
86
	PREEMPTIBLE_HANDLER instruction_access_exception
-
 
87
 
76
/* TT = 0x10, TL = 0, illegal_instruction */
88
/* TT = 0x10, TL = 0, illegal_instruction */
77
.org trap_table + TT_ILLEGAL_INSTRUCTION*ENTRY_SIZE
89
.org trap_table + TT_ILLEGAL_INSTRUCTION*ENTRY_SIZE
78
.global illegal_instruction_tl0
90
.global illegal_instruction_tl0
79
illegal_instruction_tl0:
91
illegal_instruction_tl0:
80
	PREEMPTIBLE_HANDLER illegal_instruction
92
	PREEMPTIBLE_HANDLER illegal_instruction
81
 
93
 
82
/* TT = 0x11, TL = 0, privileged_opcode */
94
/* TT = 0x11, TL = 0, privileged_opcode */
83
.org trap_table + TT_PRIVILEGED_OPCODE*ENTRY_SIZE
95
.org trap_table + TT_PRIVILEGED_OPCODE*ENTRY_SIZE
84
.global privileged_opcode_tl0
96
.global privileged_opcode_tl0
85
privileged_opcode_tl0:
97
privileged_opcode_tl0:
86
	PREEMPTIBLE_HANDLER privileged_opcode
98
	PREEMPTIBLE_HANDLER privileged_opcode
87
 
99
 
88
/* TT = 0x12, TL = 0, unimplemented_LDD */
100
/* TT = 0x12, TL = 0, unimplemented_LDD */
89
.org trap_table + TT_UNIMPLEMENTED_LDD*ENTRY_SIZE
101
.org trap_table + TT_UNIMPLEMENTED_LDD*ENTRY_SIZE
90
.global unimplemented_LDD_tl0
102
.global unimplemented_LDD_tl0
91
unimplemented_LDD_tl0:
103
unimplemented_LDD_tl0:
92
	PREEMPTIBLE_HANDLER unimplemented_LDD
104
	PREEMPTIBLE_HANDLER unimplemented_LDD
93
 
105
 
94
/* TT = 0x13, TL = 0, unimplemented_STD */
106
/* TT = 0x13, TL = 0, unimplemented_STD */
95
.org trap_table + TT_UNIMPLEMENTED_STD*ENTRY_SIZE
107
.org trap_table + TT_UNIMPLEMENTED_STD*ENTRY_SIZE
96
.global unimplemented_STD_tl0
108
.global unimplemented_STD_tl0
97
unimplemented_STD_tl0:
109
unimplemented_STD_tl0:
98
	PREEMPTIBLE_HANDLER unimplemented_STD
110
	PREEMPTIBLE_HANDLER unimplemented_STD
99
 
111
 
-
 
112
/* TT = 0x14, TL = 0, DAE_invalid_asi */
-
 
113
.org trap_table + TT_DAE_INVALID_ASI*ENTRY_SIZE
-
 
114
.global dae_invalid_asi_tl0
-
 
115
dae_invalid_asi_tl0:
-
 
116
	PREEMPTIBLE_HANDLER data_access_exception
-
 
117
 
-
 
118
/* TT = 0x15, TL = 0, DAE_privilege_violation */
-
 
119
.org trap_table + TT_DAE_PRIVILEGE_VIOLATION*ENTRY_SIZE
-
 
120
.global dae_privilege_violation_tl0
-
 
121
dae_privilege_violation_tl0:
-
 
122
	PREEMPTIBLE_HANDLER data_access_exception
-
 
123
 
-
 
124
/* TT = 0x16, TL = 0, DAE_nc_page */
-
 
125
.org trap_table + TT_DAE_NC_PAGE*ENTRY_SIZE
-
 
126
.global dae_nc_page_tl0
-
 
127
dae_nc_page_tl0:
-
 
128
	PREEMPTIBLE_HANDLER data_access_exception
-
 
129
 
-
 
130
/* TT = 0x17, TL = 0, DAE_nfo_page */
-
 
131
.org trap_table + TT_DAE_NFO_PAGE*ENTRY_SIZE
-
 
132
.global dae_nfo_page_tl0
-
 
133
dae_nfo_page_tl0:
-
 
134
	PREEMPTIBLE_HANDLER data_access_exception
-
 
135
 
100
/* TT = 0x20, TL = 0, fb_disabled handler */
136
/* TT = 0x20, TL = 0, fb_disabled handler */
101
.org trap_table + TT_FP_DISABLED*ENTRY_SIZE
137
.org trap_table + TT_FP_DISABLED*ENTRY_SIZE
102
.global fb_disabled_tl0
138
.global fb_disabled_tl0
103
fp_disabled_tl0:
139
fp_disabled_tl0:
104
	PREEMPTIBLE_HANDLER fp_disabled
140
	PREEMPTIBLE_HANDLER fp_disabled
105
 
141
 
106
/* TT = 0x21, TL = 0, fb_exception_ieee_754 handler */
142
/* TT = 0x21, TL = 0, fb_exception_ieee_754 handler */
107
.org trap_table + TT_FP_EXCEPTION_IEEE_754*ENTRY_SIZE
143
.org trap_table + TT_FP_EXCEPTION_IEEE_754*ENTRY_SIZE
108
.global fb_exception_ieee_754_tl0
144
.global fb_exception_ieee_754_tl0
109
fp_exception_ieee_754_tl0:
145
fp_exception_ieee_754_tl0:
110
	PREEMPTIBLE_HANDLER fp_exception_ieee_754
146
	PREEMPTIBLE_HANDLER fp_exception_ieee_754
111
 
147
 
112
/* TT = 0x22, TL = 0, fb_exception_other handler */
148
/* TT = 0x22, TL = 0, fb_exception_other handler */
113
.org trap_table + TT_FP_EXCEPTION_OTHER*ENTRY_SIZE
149
.org trap_table + TT_FP_EXCEPTION_OTHER*ENTRY_SIZE
114
.global fb_exception_other_tl0
150
.global fb_exception_other_tl0
115
fp_exception_other_tl0:
151
fp_exception_other_tl0:
116
	PREEMPTIBLE_HANDLER fp_exception_other
152
	PREEMPTIBLE_HANDLER fp_exception_other
117
 
153
 
118
/* TT = 0x23, TL = 0, tag_overflow */
154
/* TT = 0x23, TL = 0, tag_overflow */
119
.org trap_table + TT_TAG_OVERFLOW*ENTRY_SIZE
155
.org trap_table + TT_TAG_OVERFLOW*ENTRY_SIZE
120
.global tag_overflow_tl0
156
.global tag_overflow_tl0
121
tag_overflow_tl0:
157
tag_overflow_tl0:
122
	PREEMPTIBLE_HANDLER tag_overflow
158
	PREEMPTIBLE_HANDLER tag_overflow
123
 
159
 
124
/* TT = 0x24, TL = 0, clean_window handler */
160
/* TT = 0x24, TL = 0, clean_window handler */
125
.org trap_table + TT_CLEAN_WINDOW*ENTRY_SIZE
161
.org trap_table + TT_CLEAN_WINDOW*ENTRY_SIZE
126
.global clean_window_tl0
162
.global clean_window_tl0
127
clean_window_tl0:
163
clean_window_tl0:
128
	CLEAN_WINDOW_HANDLER
164
	CLEAN_WINDOW_HANDLER
129
 
165
 
130
/* TT = 0x28, TL = 0, division_by_zero */
166
/* TT = 0x28, TL = 0, division_by_zero */
131
.org trap_table + TT_DIVISION_BY_ZERO*ENTRY_SIZE
167
.org trap_table + TT_DIVISION_BY_ZERO*ENTRY_SIZE
132
.global division_by_zero_tl0
168
.global division_by_zero_tl0
133
division_by_zero_tl0:
169
division_by_zero_tl0:
134
	PREEMPTIBLE_HANDLER division_by_zero
170
	PREEMPTIBLE_HANDLER division_by_zero
135
 
171
 
136
/* TT = 0x30, TL = 0, data_access_exception */
172
/* TT = 0x30, TL = 0, data_access_exception */
-
 
173
/* TT = 0x30, TL = 0, DAE_side_effect_page for UltraPSARC T2 */
137
.org trap_table + TT_DATA_ACCESS_EXCEPTION*ENTRY_SIZE
174
.org trap_table + TT_DATA_ACCESS_EXCEPTION*ENTRY_SIZE
138
.global data_access_exception_tl0
175
.global data_access_exception_tl0
139
data_access_exception_tl0:
176
data_access_exception_tl0:
140
	/*wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
-
 
141
	PREEMPTIBLE_HANDLER data_access_exception*/
177
	PREEMPTIBLE_HANDLER data_access_exception
142
 
178
 
143
/* TT = 0x32, TL = 0, data_access_error */
179
/* TT = 0x32, TL = 0, data_access_error */
144
.org trap_table + TT_DATA_ACCESS_ERROR*ENTRY_SIZE
180
.org trap_table + TT_DATA_ACCESS_ERROR*ENTRY_SIZE
145
.global data_access_error_tl0
181
.global data_access_error_tl0
146
data_access_error_tl0:
182
data_access_error_tl0:
147
	PREEMPTIBLE_HANDLER data_access_error
183
	PREEMPTIBLE_HANDLER data_access_error
148
 
184
 
149
/* TT = 0x34, TL = 0, mem_address_not_aligned */
185
/* TT = 0x34, TL = 0, mem_address_not_aligned */
150
.org trap_table + TT_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
186
.org trap_table + TT_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
151
.global mem_address_not_aligned_tl0
187
.global mem_address_not_aligned_tl0
152
mem_address_not_aligned_tl0:
188
mem_address_not_aligned_tl0:
153
	PREEMPTIBLE_HANDLER mem_address_not_aligned
189
	PREEMPTIBLE_HANDLER mem_address_not_aligned
154
 
190
 
155
/* TT = 0x35, TL = 0, LDDF_mem_address_not_aligned */
191
/* TT = 0x35, TL = 0, LDDF_mem_address_not_aligned */
156
.org trap_table + TT_LDDF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
192
.org trap_table + TT_LDDF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
157
.global LDDF_mem_address_not_aligned_tl0
193
.global LDDF_mem_address_not_aligned_tl0
158
LDDF_mem_address_not_aligned_tl0:
194
LDDF_mem_address_not_aligned_tl0:
159
	PREEMPTIBLE_HANDLER LDDF_mem_address_not_aligned
195
	PREEMPTIBLE_HANDLER LDDF_mem_address_not_aligned
160
 
196
 
161
/* TT = 0x36, TL = 0, STDF_mem_address_not_aligned */
197
/* TT = 0x36, TL = 0, STDF_mem_address_not_aligned */
162
.org trap_table + TT_STDF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
198
.org trap_table + TT_STDF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
163
.global STDF_mem_address_not_aligned_tl0
199
.global STDF_mem_address_not_aligned_tl0
164
STDF_mem_address_not_aligned_tl0:
200
STDF_mem_address_not_aligned_tl0:
165
	PREEMPTIBLE_HANDLER STDF_mem_address_not_aligned
201
	PREEMPTIBLE_HANDLER STDF_mem_address_not_aligned
166
 
202
 
167
/* TT = 0x37, TL = 0, privileged_action */
203
/* TT = 0x37, TL = 0, privileged_action */
168
.org trap_table + TT_PRIVILEGED_ACTION*ENTRY_SIZE
204
.org trap_table + TT_PRIVILEGED_ACTION*ENTRY_SIZE
169
.global privileged_action_tl0
205
.global privileged_action_tl0
170
privileged_action_tl0:
206
privileged_action_tl0:
171
	PREEMPTIBLE_HANDLER privileged_action
207
	PREEMPTIBLE_HANDLER privileged_action
172
 
208
 
173
/* TT = 0x38, TL = 0, LDQF_mem_address_not_aligned */
209
/* TT = 0x38, TL = 0, LDQF_mem_address_not_aligned */
174
.org trap_table + TT_LDQF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
210
.org trap_table + TT_LDQF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
175
.global LDQF_mem_address_not_aligned_tl0
211
.global LDQF_mem_address_not_aligned_tl0
176
LDQF_mem_address_not_aligned_tl0:
212
LDQF_mem_address_not_aligned_tl0:
177
	PREEMPTIBLE_HANDLER LDQF_mem_address_not_aligned
213
	PREEMPTIBLE_HANDLER LDQF_mem_address_not_aligned
178
 
214
 
179
/* TT = 0x39, TL = 0, STQF_mem_address_not_aligned */
215
/* TT = 0x39, TL = 0, STQF_mem_address_not_aligned */
180
.org trap_table + TT_STQF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
216
.org trap_table + TT_STQF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
181
.global STQF_mem_address_not_aligned_tl0
217
.global STQF_mem_address_not_aligned_tl0
182
STQF_mem_address_not_aligned_tl0:
218
STQF_mem_address_not_aligned_tl0:
183
	PREEMPTIBLE_HANDLER STQF_mem_address_not_aligned
219
	PREEMPTIBLE_HANDLER STQF_mem_address_not_aligned
184
 
220
 
185
/* TT = 0x41, TL = 0, interrupt_level_1 handler */
221
/* TT = 0x41, TL = 0, interrupt_level_1 handler */
186
.org trap_table + TT_INTERRUPT_LEVEL_1*ENTRY_SIZE
222
.org trap_table + TT_INTERRUPT_LEVEL_1*ENTRY_SIZE
187
.global interrupt_level_1_handler_tl0
223
.global interrupt_level_1_handler_tl0
188
interrupt_level_1_handler_tl0:
224
interrupt_level_1_handler_tl0:
189
	INTERRUPT_LEVEL_N_HANDLER 1
225
	INTERRUPT_LEVEL_N_HANDLER 1
190
 
226
 
191
/* TT = 0x42, TL = 0, interrupt_level_2 handler */
227
/* TT = 0x42, TL = 0, interrupt_level_2 handler */
192
.org trap_table + TT_INTERRUPT_LEVEL_2*ENTRY_SIZE
228
.org trap_table + TT_INTERRUPT_LEVEL_2*ENTRY_SIZE
193
.global interrupt_level_2_handler_tl0
229
.global interrupt_level_2_handler_tl0
194
interrupt_level_2_handler_tl0:
230
interrupt_level_2_handler_tl0:
195
	INTERRUPT_LEVEL_N_HANDLER 2
231
	INTERRUPT_LEVEL_N_HANDLER 2
196
 
232
 
197
/* TT = 0x43, TL = 0, interrupt_level_3 handler */
233
/* TT = 0x43, TL = 0, interrupt_level_3 handler */
198
.org trap_table + TT_INTERRUPT_LEVEL_3*ENTRY_SIZE
234
.org trap_table + TT_INTERRUPT_LEVEL_3*ENTRY_SIZE
199
.global interrupt_level_3_handler_tl0
235
.global interrupt_level_3_handler_tl0
200
interrupt_level_3_handler_tl0:
236
interrupt_level_3_handler_tl0:
201
	INTERRUPT_LEVEL_N_HANDLER 3
237
	INTERRUPT_LEVEL_N_HANDLER 3
202
 
238
 
203
/* TT = 0x44, TL = 0, interrupt_level_4 handler */
239
/* TT = 0x44, TL = 0, interrupt_level_4 handler */
204
.org trap_table + TT_INTERRUPT_LEVEL_4*ENTRY_SIZE
240
.org trap_table + TT_INTERRUPT_LEVEL_4*ENTRY_SIZE
205
.global interrupt_level_4_handler_tl0
241
.global interrupt_level_4_handler_tl0
206
interrupt_level_4_handler_tl0:
242
interrupt_level_4_handler_tl0:
207
	INTERRUPT_LEVEL_N_HANDLER 4
243
	INTERRUPT_LEVEL_N_HANDLER 4
208
 
244
 
209
/* TT = 0x45, TL = 0, interrupt_level_5 handler */
245
/* TT = 0x45, TL = 0, interrupt_level_5 handler */
210
.org trap_table + TT_INTERRUPT_LEVEL_5*ENTRY_SIZE
246
.org trap_table + TT_INTERRUPT_LEVEL_5*ENTRY_SIZE
211
.global interrupt_level_5_handler_tl0
247
.global interrupt_level_5_handler_tl0
212
interrupt_level_5_handler_tl0:
248
interrupt_level_5_handler_tl0:
213
	INTERRUPT_LEVEL_N_HANDLER 5
249
	INTERRUPT_LEVEL_N_HANDLER 5
214
 
250
 
215
/* TT = 0x46, TL = 0, interrupt_level_6 handler */
251
/* TT = 0x46, TL = 0, interrupt_level_6 handler */
216
.org trap_table + TT_INTERRUPT_LEVEL_6*ENTRY_SIZE
252
.org trap_table + TT_INTERRUPT_LEVEL_6*ENTRY_SIZE
217
.global interrupt_level_6_handler_tl0
253
.global interrupt_level_6_handler_tl0
218
interrupt_level_6_handler_tl0:
254
interrupt_level_6_handler_tl0:
219
	INTERRUPT_LEVEL_N_HANDLER 6
255
	INTERRUPT_LEVEL_N_HANDLER 6
220
 
256
 
221
/* TT = 0x47, TL = 0, interrupt_level_7 handler */
257
/* TT = 0x47, TL = 0, interrupt_level_7 handler */
222
.org trap_table + TT_INTERRUPT_LEVEL_7*ENTRY_SIZE
258
.org trap_table + TT_INTERRUPT_LEVEL_7*ENTRY_SIZE
223
.global interrupt_level_7_handler_tl0
259
.global interrupt_level_7_handler_tl0
224
interrupt_level_7_handler_tl0:
260
interrupt_level_7_handler_tl0:
225
	INTERRUPT_LEVEL_N_HANDLER 7
261
	INTERRUPT_LEVEL_N_HANDLER 7
226
 
262
 
227
/* TT = 0x48, TL = 0, interrupt_level_8 handler */
263
/* TT = 0x48, TL = 0, interrupt_level_8 handler */
228
.org trap_table + TT_INTERRUPT_LEVEL_8*ENTRY_SIZE
264
.org trap_table + TT_INTERRUPT_LEVEL_8*ENTRY_SIZE
229
.global interrupt_level_8_handler_tl0
265
.global interrupt_level_8_handler_tl0
230
interrupt_level_8_handler_tl0:
266
interrupt_level_8_handler_tl0:
231
	INTERRUPT_LEVEL_N_HANDLER 8
267
	INTERRUPT_LEVEL_N_HANDLER 8
232
 
268
 
233
/* TT = 0x49, TL = 0, interrupt_level_9 handler */
269
/* TT = 0x49, TL = 0, interrupt_level_9 handler */
234
.org trap_table + TT_INTERRUPT_LEVEL_9*ENTRY_SIZE
270
.org trap_table + TT_INTERRUPT_LEVEL_9*ENTRY_SIZE
235
.global interrupt_level_9_handler_tl0
271
.global interrupt_level_9_handler_tl0
236
interrupt_level_9_handler_tl0:
272
interrupt_level_9_handler_tl0:
237
	INTERRUPT_LEVEL_N_HANDLER 9
273
	INTERRUPT_LEVEL_N_HANDLER 9
238
 
274
 
239
/* TT = 0x4a, TL = 0, interrupt_level_10 handler */
275
/* TT = 0x4a, TL = 0, interrupt_level_10 handler */
240
.org trap_table + TT_INTERRUPT_LEVEL_10*ENTRY_SIZE
276
.org trap_table + TT_INTERRUPT_LEVEL_10*ENTRY_SIZE
241
.global interrupt_level_10_handler_tl0
277
.global interrupt_level_10_handler_tl0
242
interrupt_level_10_handler_tl0:
278
interrupt_level_10_handler_tl0:
243
	INTERRUPT_LEVEL_N_HANDLER 10
279
	INTERRUPT_LEVEL_N_HANDLER 10
244
 
280
 
245
/* TT = 0x4b, TL = 0, interrupt_level_11 handler */
281
/* TT = 0x4b, TL = 0, interrupt_level_11 handler */
246
.org trap_table + TT_INTERRUPT_LEVEL_11*ENTRY_SIZE
282
.org trap_table + TT_INTERRUPT_LEVEL_11*ENTRY_SIZE
247
.global interrupt_level_11_handler_tl0
283
.global interrupt_level_11_handler_tl0
248
interrupt_level_11_handler_tl0:
284
interrupt_level_11_handler_tl0:
249
	INTERRUPT_LEVEL_N_HANDLER 11
285
	INTERRUPT_LEVEL_N_HANDLER 11
250
 
286
 
251
/* TT = 0x4c, TL = 0, interrupt_level_12 handler */
287
/* TT = 0x4c, TL = 0, interrupt_level_12 handler */
252
.org trap_table + TT_INTERRUPT_LEVEL_12*ENTRY_SIZE
288
.org trap_table + TT_INTERRUPT_LEVEL_12*ENTRY_SIZE
253
.global interrupt_level_12_handler_tl0
289
.global interrupt_level_12_handler_tl0
254
interrupt_level_12_handler_tl0:
290
interrupt_level_12_handler_tl0:
255
	INTERRUPT_LEVEL_N_HANDLER 12
291
	INTERRUPT_LEVEL_N_HANDLER 12
256
 
292
 
257
/* TT = 0x4d, TL = 0, interrupt_level_13 handler */
293
/* TT = 0x4d, TL = 0, interrupt_level_13 handler */
258
.org trap_table + TT_INTERRUPT_LEVEL_13*ENTRY_SIZE
294
.org trap_table + TT_INTERRUPT_LEVEL_13*ENTRY_SIZE
259
.global interrupt_level_13_handler_tl0
295
.global interrupt_level_13_handler_tl0
260
interrupt_level_13_handler_tl0:
296
interrupt_level_13_handler_tl0:
261
	INTERRUPT_LEVEL_N_HANDLER 13
297
	INTERRUPT_LEVEL_N_HANDLER 13
262
 
298
 
263
/* TT = 0x4e, TL = 0, interrupt_level_14 handler */
299
/* TT = 0x4e, TL = 0, interrupt_level_14 handler */
264
.org trap_table + TT_INTERRUPT_LEVEL_14*ENTRY_SIZE
300
.org trap_table + TT_INTERRUPT_LEVEL_14*ENTRY_SIZE
265
.global interrupt_level_14_handler_tl0
301
.global interrupt_level_14_handler_tl0
266
interrupt_level_14_handler_tl0:
302
interrupt_level_14_handler_tl0:
267
	INTERRUPT_LEVEL_N_HANDLER 14
303
	INTERRUPT_LEVEL_N_HANDLER 14
268
 
304
 
269
/* TT = 0x4f, TL = 0, interrupt_level_15 handler */
305
/* TT = 0x4f, TL = 0, interrupt_level_15 handler */
270
.org trap_table + TT_INTERRUPT_LEVEL_15*ENTRY_SIZE
306
.org trap_table + TT_INTERRUPT_LEVEL_15*ENTRY_SIZE
271
.global interrupt_level_15_handler_tl0
307
.global interrupt_level_15_handler_tl0
272
interrupt_level_15_handler_tl0:
308
interrupt_level_15_handler_tl0:
273
	INTERRUPT_LEVEL_N_HANDLER 15
309
	INTERRUPT_LEVEL_N_HANDLER 15
274
 
310
 
275
/* TT = 0x60, TL = 0, interrupt_vector_trap handler */
311
/* TT = 0x60, TL = 0, interrupt_vector_trap handler */
276
.org trap_table + TT_INTERRUPT_VECTOR_TRAP*ENTRY_SIZE
312
.org trap_table + TT_INTERRUPT_VECTOR_TRAP*ENTRY_SIZE
277
.global interrupt_vector_trap_handler_tl0
313
.global interrupt_vector_trap_handler_tl0
278
interrupt_vector_trap_handler_tl0:
314
interrupt_vector_trap_handler_tl0:
279
	INTERRUPT_VECTOR_TRAP_HANDLER
315
	INTERRUPT_VECTOR_TRAP_HANDLER
280
 
316
 
281
/* TT = 0x64, TL = 0, fast_instruction_access_MMU_miss */
317
/* TT = 0x64, TL = 0, fast_instruction_access_MMU_miss */
282
.org trap_table + TT_FAST_INSTRUCTION_ACCESS_MMU_MISS*ENTRY_SIZE
318
.org trap_table + TT_FAST_INSTRUCTION_ACCESS_MMU_MISS*ENTRY_SIZE
283
.global fast_instruction_access_mmu_miss_handler_tl0
319
.global fast_instruction_access_mmu_miss_handler_tl0
284
fast_instruction_access_mmu_miss_handler_tl0:
320
fast_instruction_access_mmu_miss_handler_tl0:
285
	FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
321
	FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
286
 
322
 
287
/* TT = 0x68, TL = 0, fast_data_access_MMU_miss */
323
/* TT = 0x68, TL = 0, fast_data_access_MMU_miss */
288
.org trap_table + TT_FAST_DATA_ACCESS_MMU_MISS*ENTRY_SIZE
324
.org trap_table + TT_FAST_DATA_ACCESS_MMU_MISS*ENTRY_SIZE
289
.global fast_data_access_mmu_miss_handler_tl0
325
.global fast_data_access_mmu_miss_handler_tl0
290
fast_data_access_mmu_miss_handler_tl0:
326
fast_data_access_mmu_miss_handler_tl0:
291
	FAST_DATA_ACCESS_MMU_MISS_HANDLER 0
327
	FAST_DATA_ACCESS_MMU_MISS_HANDLER 0
292
 
328
 
293
/* TT = 0x6c, TL = 0, fast_data_access_protection */
329
/* TT = 0x6c, TL = 0, fast_data_access_protection */
294
.org trap_table + TT_FAST_DATA_ACCESS_PROTECTION*ENTRY_SIZE
330
.org trap_table + TT_FAST_DATA_ACCESS_PROTECTION*ENTRY_SIZE
295
.global fast_data_access_protection_handler_tl0
331
.global fast_data_access_protection_handler_tl0
296
fast_data_access_protection_handler_tl0:
332
fast_data_access_protection_handler_tl0:
297
	FAST_DATA_ACCESS_PROTECTION_HANDLER 0
333
	FAST_DATA_ACCESS_PROTECTION_HANDLER 0
298
 
334
 
299
/* TT = 0x80, TL = 0, spill_0_normal handler */
335
/* TT = 0x80, TL = 0, spill_0_normal handler */
300
.org trap_table + TT_SPILL_0_NORMAL*ENTRY_SIZE
336
.org trap_table + TT_SPILL_0_NORMAL*ENTRY_SIZE
301
.global spill_0_normal_tl0
337
.global spill_0_normal_tl0
302
spill_0_normal_tl0:
338
spill_0_normal_tl0:
303
	SPILL_NORMAL_HANDLER_KERNEL
339
	SPILL_NORMAL_HANDLER_KERNEL
304
 
340
 
305
/* TT = 0x84, TL = 0, spill_1_normal handler */
341
/* TT = 0x84, TL = 0, spill_1_normal handler */
306
.org trap_table + TT_SPILL_1_NORMAL*ENTRY_SIZE
342
.org trap_table + TT_SPILL_1_NORMAL*ENTRY_SIZE
307
.global spill_1_normal_tl0
343
.global spill_1_normal_tl0
308
spill_1_normal_tl0:
344
spill_1_normal_tl0:
309
	SPILL_NORMAL_HANDLER_USERSPACE
345
	SPILL_NORMAL_HANDLER_USERSPACE
310
 
346
 
311
/* TT = 0x88, TL = 0, spill_2_normal handler */
347
/* TT = 0x88, TL = 0, spill_2_normal handler */
312
.org trap_table + TT_SPILL_2_NORMAL*ENTRY_SIZE
348
.org trap_table + TT_SPILL_2_NORMAL*ENTRY_SIZE
313
.global spill_2_normal_tl0
349
.global spill_2_normal_tl0
314
spill_2_normal_tl0:
350
spill_2_normal_tl0:
315
	SPILL_TO_USPACE_WINDOW_BUFFER
351
	SPILL_TO_USPACE_WINDOW_BUFFER
316
 
352
 
317
/* TT = 0xa0, TL = 0, spill_0_other handler */
353
/* TT = 0xa0, TL = 0, spill_0_other handler */
318
.org trap_table + TT_SPILL_0_OTHER*ENTRY_SIZE
354
.org trap_table + TT_SPILL_0_OTHER*ENTRY_SIZE
319
.global spill_0_other_tl0
355
.global spill_0_other_tl0
320
spill_0_other_tl0:
356
spill_0_other_tl0:
321
	SPILL_TO_USPACE_WINDOW_BUFFER
357
	SPILL_TO_USPACE_WINDOW_BUFFER
322
 
358
 
323
/* TT = 0xc0, TL = 0, fill_0_normal handler */
359
/* TT = 0xc0, TL = 0, fill_0_normal handler */
324
.org trap_table + TT_FILL_0_NORMAL*ENTRY_SIZE
360
.org trap_table + TT_FILL_0_NORMAL*ENTRY_SIZE
325
.global fill_0_normal_tl0
361
.global fill_0_normal_tl0
326
fill_0_normal_tl0:
362
fill_0_normal_tl0:
327
	FILL_NORMAL_HANDLER_KERNEL
363
	FILL_NORMAL_HANDLER_KERNEL
328
 
364
 
329
/* TT = 0xc4, TL = 0, fill_1_normal handler */
365
/* TT = 0xc4, TL = 0, fill_1_normal handler */
330
.org trap_table + TT_FILL_1_NORMAL*ENTRY_SIZE
366
.org trap_table + TT_FILL_1_NORMAL*ENTRY_SIZE
331
.global fill_1_normal_tl0
367
.global fill_1_normal_tl0
332
fill_1_normal_tl0:
368
fill_1_normal_tl0:
333
	FILL_NORMAL_HANDLER_USERSPACE
369
	FILL_NORMAL_HANDLER_USERSPACE
334
 
370
 
335
/* TT = 0x100 - 0x17f, TL = 0, trap_instruction_0 - trap_instruction_7f */
371
/* TT = 0x100 - 0x17f, TL = 0, trap_instruction_0 - trap_instruction_7f */
336
.irp cur, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\
372
.irp cur, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\
337
    20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,\
373
    20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,\
338
    39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,\
374
    39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,\
339
    58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,\
375
    58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,\
340
    77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,\
376
    77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,\
341
    96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,\
377
    96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,\
342
    112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,\
378
    112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,\
343
    127
379
    127
344
.org trap_table + (TT_TRAP_INSTRUCTION_0+\cur)*ENTRY_SIZE
380
.org trap_table + (TT_TRAP_INSTRUCTION_0+\cur)*ENTRY_SIZE
345
.global trap_instruction_\cur\()_tl0
381
.global trap_instruction_\cur\()_tl0
346
trap_instruction_\cur\()_tl0:
382
trap_instruction_\cur\()_tl0:
347
	ba trap_instruction_handler
383
	ba trap_instruction_handler
348
	mov \cur, %g2
384
	mov \cur, %g2
349
.endr
385
.endr
350
 
386
 
351
/*
387
/*
352
 * Handlers for TL>0.
388
 * Handlers for TL>0.
353
 */
389
 */
354
 
390
 
355
/* TT = 0x08, TL > 0, instruction_access_exception */
391
/* TT = 0x08, TL > 0, instruction_access_exception */
-
 
392
/* TT = 0x08, TL > 0, IAE_privilege_violation on UltraSPARC T2 */
356
.org trap_table + (TT_INSTRUCTION_ACCESS_EXCEPTION+512)*ENTRY_SIZE
393
.org trap_table + (TT_INSTRUCTION_ACCESS_EXCEPTION+512)*ENTRY_SIZE
357
.global instruction_access_exception_tl1
394
.global instruction_access_exception_tl1
358
instruction_access_exception_tl1:
395
instruction_access_exception_tl1:
359
	/*wrpr %g0, 1, %tl
396
	wrpr %g0, 1, %tl
360
	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
-
 
361
	PREEMPTIBLE_HANDLER instruction_access_exception*/
397
	PREEMPTIBLE_HANDLER instruction_access_exception
362
 
398
 
363
/* TT = 0x0a, TL > 0, instruction_access_error */
399
/* TT = 0x0a, TL > 0, instruction_access_error */
364
.org trap_table + (TT_INSTRUCTION_ACCESS_ERROR+512)*ENTRY_SIZE
400
.org trap_table + (TT_INSTRUCTION_ACCESS_ERROR+512)*ENTRY_SIZE
365
.global instruction_access_error_tl1
401
.global instruction_access_error_tl1
366
instruction_access_error_tl1:
402
instruction_access_error_tl1:
367
	wrpr %g0, 1, %tl
403
	wrpr %g0, 1, %tl
368
	PREEMPTIBLE_HANDLER instruction_access_error
404
	PREEMPTIBLE_HANDLER instruction_access_error
369
 
405
 
-
 
406
/* TT = 0x0b, TL > 0, IAE_unauth_access */
-
 
407
.org trap_table + (TT_IAE_UNAUTH_ACCESS+512)*ENTRY_SIZE
-
 
408
.global iae_unauth_access_tl1
-
 
409
iae_unauth_access_tl1:
-
 
410
	wrpr %g0, 1, %tl
-
 
411
	PREEMPTIBLE_HANDLER instruction_access_exception
-
 
412
 
-
 
413
/* TT = 0x0c, TL > 0, IAE_nfo_page */
-
 
414
.org trap_table + (TT_IAE_NFO_PAGE+512)*ENTRY_SIZE
-
 
415
.global iae_nfo_page_tl1
-
 
416
iae_nfo_page_tl1:
-
 
417
	wrpr %g0, 1, %tl
-
 
418
	PREEMPTIBLE_HANDLER instruction_access_exception
-
 
419
 
370
/* TT = 0x10, TL > 0, illegal_instruction */
420
/* TT = 0x10, TL > 0, illegal_instruction */
371
.org trap_table + (TT_ILLEGAL_INSTRUCTION+512)*ENTRY_SIZE
421
.org trap_table + (TT_ILLEGAL_INSTRUCTION+512)*ENTRY_SIZE
372
.global illegal_instruction_tl1
422
.global illegal_instruction_tl1
373
illegal_instruction_tl1:
423
illegal_instruction_tl1:
374
	wrpr %g0, 1, %tl
424
	wrpr %g0, 1, %tl
375
	PREEMPTIBLE_HANDLER illegal_instruction
425
	PREEMPTIBLE_HANDLER illegal_instruction
376
 
426
 
-
 
427
/* TT = 0x14, TL > 0, DAE_invalid_asi */
-
 
428
.org trap_table + (TT_DAE_INVALID_ASI+512)*ENTRY_SIZE
-
 
429
.global dae_invalid_asi_tl1
-
 
430
dae_invalid_asi_tl1:
-
 
431
	wrpr %g0, 1, %tl
-
 
432
	PREEMPTIBLE_HANDLER data_access_exception
-
 
433
 
-
 
434
/* TT = 0x15, TL > 0, DAE_privilege_violation */
-
 
435
.org trap_table + (TT_DAE_PRIVILEGE_VIOLATION+512)*ENTRY_SIZE
-
 
436
.global dae_privilege_violation_tl1
-
 
437
dae_privilege_violation_tl1:
-
 
438
	wrpr %g0, 1, %tl
-
 
439
	PREEMPTIBLE_HANDLER data_access_exception
-
 
440
 
-
 
441
/* TT = 0x16, TL > 0, DAE_nc_page */
-
 
442
.org trap_table + (TT_DAE_NC_PAGE+512)*ENTRY_SIZE
-
 
443
.global dae_nc_page_tl1
-
 
444
dae_nc_page_tl1:
-
 
445
	wrpr %g0, 1, %tl
-
 
446
	PREEMPTIBLE_HANDLER data_access_exception
-
 
447
 
-
 
448
/* TT = 0x17, TL > 0, DAE_nfo_page */
-
 
449
.org trap_table + (TT_DAE_NFO_PAGE+512)*ENTRY_SIZE
-
 
450
.global dae_nfo_page_tl1
-
 
451
dae_nfo_page_tl1:
-
 
452
	wrpr %g0, 1, %tl
-
 
453
	PREEMPTIBLE_HANDLER data_access_exception
-
 
454
 
377
/* TT = 0x24, TL > 0, clean_window handler */
455
/* TT = 0x24, TL > 0, clean_window handler */
378
.org trap_table + (TT_CLEAN_WINDOW+512)*ENTRY_SIZE
456
.org trap_table + (TT_CLEAN_WINDOW+512)*ENTRY_SIZE
379
.global clean_window_tl1
457
.global clean_window_tl1
380
clean_window_tl1:
458
clean_window_tl1:
381
	CLEAN_WINDOW_HANDLER
459
	CLEAN_WINDOW_HANDLER
382
 
460
 
383
/* TT = 0x28, TL > 0, division_by_zero */
461
/* TT = 0x28, TL > 0, division_by_zero */
384
.org trap_table + (TT_DIVISION_BY_ZERO+512)*ENTRY_SIZE
462
.org trap_table + (TT_DIVISION_BY_ZERO+512)*ENTRY_SIZE
385
.global division_by_zero_tl1
463
.global division_by_zero_tl1
386
division_by_zero_tl1:
464
division_by_zero_tl1:
387
	wrpr %g0, 1, %tl
465
	wrpr %g0, 1, %tl
388
	PREEMPTIBLE_HANDLER division_by_zero
466
	PREEMPTIBLE_HANDLER division_by_zero
389
 
467
 
390
/* TT = 0x30, TL > 0, data_access_exception */
468
/* TT = 0x30, TL > 0, data_access_exception */
391
.org trap_table + (TT_DATA_ACCESS_EXCEPTION+512)*ENTRY_SIZE
469
.org trap_table + (TT_DATA_ACCESS_EXCEPTION+512)*ENTRY_SIZE
392
.global data_access_exception_tl1
470
.global data_access_exception_tl1
393
data_access_exception_tl1:
471
data_access_exception_tl1:
394
	/*wrpr %g0, 1, %tl
472
	/*wrpr %g0, 1, %tl
395
	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
473
	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
396
	PREEMPTIBLE_HANDLER data_access_exception*/
474
	PREEMPTIBLE_HANDLER data_access_exception*/
397
 
475
 
398
/* TT = 0x32, TL > 0, data_access_error */
476
/* TT = 0x32, TL > 0, data_access_error */
399
.org trap_table + (TT_DATA_ACCESS_ERROR+512)*ENTRY_SIZE
477
.org trap_table + (TT_DATA_ACCESS_ERROR+512)*ENTRY_SIZE
400
.global data_access_error_tl1
478
.global data_access_error_tl1
401
data_access_error_tl1:
479
data_access_error_tl1:
402
	wrpr %g0, 1, %tl
480
	wrpr %g0, 1, %tl
403
	PREEMPTIBLE_HANDLER data_access_error
481
	PREEMPTIBLE_HANDLER data_access_error
404
 
482
 
405
/* TT = 0x34, TL > 0, mem_address_not_aligned */
483
/* TT = 0x34, TL > 0, mem_address_not_aligned */
406
.org trap_table + (TT_MEM_ADDRESS_NOT_ALIGNED+512)*ENTRY_SIZE
484
.org trap_table + (TT_MEM_ADDRESS_NOT_ALIGNED+512)*ENTRY_SIZE
407
.global mem_address_not_aligned_tl1
485
.global mem_address_not_aligned_tl1
408
mem_address_not_aligned_tl1:
486
mem_address_not_aligned_tl1:
409
	wrpr %g0, 1, %tl
487
	wrpr %g0, 1, %tl
410
	PREEMPTIBLE_HANDLER mem_address_not_aligned
488
	PREEMPTIBLE_HANDLER mem_address_not_aligned
411
 
489
 
412
/* TT = 0x68, TL > 0, fast_data_access_MMU_miss */
490
/* TT = 0x68, TL > 0, fast_data_access_MMU_miss */
413
.org trap_table + (TT_FAST_DATA_ACCESS_MMU_MISS+512)*ENTRY_SIZE
491
.org trap_table + (TT_FAST_DATA_ACCESS_MMU_MISS+512)*ENTRY_SIZE
414
.global fast_data_access_mmu_miss_handler_tl1
492
.global fast_data_access_mmu_miss_handler_tl1
415
fast_data_access_mmu_miss_handler_tl1:
493
fast_data_access_mmu_miss_handler_tl1:
416
	FAST_DATA_ACCESS_MMU_MISS_HANDLER 1
494
	FAST_DATA_ACCESS_MMU_MISS_HANDLER 1
417
 
495
 
418
/* TT = 0x6c, TL > 0, fast_data_access_protection */
496
/* TT = 0x6c, TL > 0, fast_data_access_protection */
419
.org trap_table + (TT_FAST_DATA_ACCESS_PROTECTION+512)*ENTRY_SIZE
497
.org trap_table + (TT_FAST_DATA_ACCESS_PROTECTION+512)*ENTRY_SIZE
420
.global fast_data_access_protection_handler_tl1
498
.global fast_data_access_protection_handler_tl1
421
fast_data_access_protection_handler_tl1:
499
fast_data_access_protection_handler_tl1:
422
	FAST_DATA_ACCESS_PROTECTION_HANDLER 1
500
	FAST_DATA_ACCESS_PROTECTION_HANDLER 1
423
 
501
 
424
/* TT = 0x80, TL > 0, spill_0_normal handler */
502
/* TT = 0x80, TL > 0, spill_0_normal handler */
425
.org trap_table + (TT_SPILL_0_NORMAL+512)*ENTRY_SIZE
503
.org trap_table + (TT_SPILL_0_NORMAL+512)*ENTRY_SIZE
426
.global spill_0_normal_tl1
504
.global spill_0_normal_tl1
427
spill_0_normal_tl1:
505
spill_0_normal_tl1:
428
	SPILL_NORMAL_HANDLER_KERNEL
506
	SPILL_NORMAL_HANDLER_KERNEL
429
 
507
 
430
/* TT = 0x88, TL > 0, spill_2_normal handler */
508
/* TT = 0x88, TL > 0, spill_2_normal handler */
431
.org trap_table + (TT_SPILL_2_NORMAL+512)*ENTRY_SIZE
509
.org trap_table + (TT_SPILL_2_NORMAL+512)*ENTRY_SIZE
432
.global spill_2_normal_tl1
510
.global spill_2_normal_tl1
433
spill_2_normal_tl1:
511
spill_2_normal_tl1:
434
	SPILL_TO_USPACE_WINDOW_BUFFER
512
	SPILL_TO_USPACE_WINDOW_BUFFER
435
 
513
 
436
/* TT = 0xa0, TL > 0, spill_0_other handler */
514
/* TT = 0xa0, TL > 0, spill_0_other handler */
437
.org trap_table + (TT_SPILL_0_OTHER+512)*ENTRY_SIZE
515
.org trap_table + (TT_SPILL_0_OTHER+512)*ENTRY_SIZE
438
.global spill_0_other_tl1
516
.global spill_0_other_tl1
439
spill_0_other_tl1:
517
spill_0_other_tl1:
440
	SPILL_TO_USPACE_WINDOW_BUFFER
518
	SPILL_TO_USPACE_WINDOW_BUFFER
441
 
519
 
442
/* TT = 0xc0, TL > 0, fill_0_normal handler */
520
/* TT = 0xc0, TL > 0, fill_0_normal handler */
443
.org trap_table + (TT_FILL_0_NORMAL+512)*ENTRY_SIZE
521
.org trap_table + (TT_FILL_0_NORMAL+512)*ENTRY_SIZE
444
.global fill_0_normal_tl1
522
.global fill_0_normal_tl1
445
fill_0_normal_tl1:
523
fill_0_normal_tl1:
446
	FILL_NORMAL_HANDLER_KERNEL
524
	FILL_NORMAL_HANDLER_KERNEL
447
 
525
 
448
.align TABLE_SIZE
526
.align TABLE_SIZE
449
 
527
 
450
 
528
 
451
/*
529
/*
452
 * Spills the window at CWP + 2 to the kernel stack. This macro is to be
530
 * Spills the window at CWP + 2 to the kernel stack. This macro is to be
453
 * used before doing SAVE when the spill trap is undesirable.
531
 * used before doing SAVE when the spill trap is undesirable.
454
 * 
532
 * 
455
 * Parameters:
533
 * Parameters:
456
 * 	tmpreg1		global register to be used for scratching purposes
534
 * 	tmpreg1		global register to be used for scratching purposes
457
 * 	tmpreg2		global register to be used for scratching purposes
535
 * 	tmpreg2		global register to be used for scratching purposes
458
 */
536
 */
459
.macro INLINE_SPILL tmpreg1, tmpreg2
537
.macro INLINE_SPILL tmpreg1, tmpreg2
460
	! CWP := CWP + 2
538
	! CWP := CWP + 2
461
	rdpr %cwp, \tmpreg2
539
	rdpr %cwp, \tmpreg2
462
	add \tmpreg2, 2, \tmpreg1
540
	add \tmpreg2, 2, \tmpreg1
463
	and \tmpreg1, NWINDOWS - 1, \tmpreg1		! modulo NWINDOWS
541
	and \tmpreg1, NWINDOWS - 1, \tmpreg1		! modulo NWINDOWS
464
	wrpr \tmpreg1, %cwp
542
	wrpr \tmpreg1, %cwp
465
	
543
	
466
	! spill to kernel stack
544
	! spill to kernel stack
467
	stx %l0, [%sp + STACK_BIAS + L0_OFFSET]	
545
	stx %l0, [%sp + STACK_BIAS + L0_OFFSET]	
468
	stx %l1, [%sp + STACK_BIAS + L1_OFFSET]
546
	stx %l1, [%sp + STACK_BIAS + L1_OFFSET]
469
	stx %l2, [%sp + STACK_BIAS + L2_OFFSET]
547
	stx %l2, [%sp + STACK_BIAS + L2_OFFSET]
470
	stx %l3, [%sp + STACK_BIAS + L3_OFFSET]
548
	stx %l3, [%sp + STACK_BIAS + L3_OFFSET]
471
	stx %l4, [%sp + STACK_BIAS + L4_OFFSET]
549
	stx %l4, [%sp + STACK_BIAS + L4_OFFSET]
472
	stx %l5, [%sp + STACK_BIAS + L5_OFFSET]
550
	stx %l5, [%sp + STACK_BIAS + L5_OFFSET]
473
	stx %l6, [%sp + STACK_BIAS + L6_OFFSET]
551
	stx %l6, [%sp + STACK_BIAS + L6_OFFSET]
474
	stx %l7, [%sp + STACK_BIAS + L7_OFFSET]
552
	stx %l7, [%sp + STACK_BIAS + L7_OFFSET]
475
	stx %i0, [%sp + STACK_BIAS + I0_OFFSET]
553
	stx %i0, [%sp + STACK_BIAS + I0_OFFSET]
476
	stx %i1, [%sp + STACK_BIAS + I1_OFFSET]
554
	stx %i1, [%sp + STACK_BIAS + I1_OFFSET]
477
	stx %i2, [%sp + STACK_BIAS + I2_OFFSET]
555
	stx %i2, [%sp + STACK_BIAS + I2_OFFSET]
478
	stx %i3, [%sp + STACK_BIAS + I3_OFFSET]
556
	stx %i3, [%sp + STACK_BIAS + I3_OFFSET]
479
	stx %i4, [%sp + STACK_BIAS + I4_OFFSET]
557
	stx %i4, [%sp + STACK_BIAS + I4_OFFSET]
480
	stx %i5, [%sp + STACK_BIAS + I5_OFFSET]
558
	stx %i5, [%sp + STACK_BIAS + I5_OFFSET]
481
	stx %i6, [%sp + STACK_BIAS + I6_OFFSET]
559
	stx %i6, [%sp + STACK_BIAS + I6_OFFSET]
482
	stx %i7, [%sp + STACK_BIAS + I7_OFFSET]
560
	stx %i7, [%sp + STACK_BIAS + I7_OFFSET]
483
 
561
 
484
	! CWP := CWP - 2
562
	! CWP := CWP - 2
485
	wrpr \tmpreg2, %cwp
563
	wrpr \tmpreg2, %cwp
486
 
564
 
487
	saved
565
	saved
488
.endm
566
.endm
489
 
567
 
490
/*
568
/*
491
 * Fill the window at CWP - 1 from the kernel stack. This macro is to be
569
 * Fill the window at CWP - 1 from the kernel stack. This macro is to be
492
 * used before doing RESTORE when the fill trap is undesirable.
570
 * used before doing RESTORE when the fill trap is undesirable.
493
 * 
571
 * 
494
 * Parameters:
572
 * Parameters:
495
 * 	tmpreg1		global register to be used for scratching purposes
573
 * 	tmpreg1		global register to be used for scratching purposes
496
 * 	tmpreg2		global register to be used for scratching purposes
574
 * 	tmpreg2		global register to be used for scratching purposes
497
 */
575
 */
498
.macro INLINE_FILL tmpreg1, tmpreg2
576
.macro INLINE_FILL tmpreg1, tmpreg2
499
	! CWP := CWP - 1
577
	! CWP := CWP - 1
500
	rdpr %cwp, \tmpreg2
578
	rdpr %cwp, \tmpreg2
501
	add \tmpreg2, NWINDOWS - 1, \tmpreg1
579
	add \tmpreg2, NWINDOWS - 1, \tmpreg1
502
	and \tmpreg1, NWINDOWS - 1, \tmpreg1
580
	and \tmpreg1, NWINDOWS - 1, \tmpreg1
503
	wrpr \tmpreg1, %cwp
581
	wrpr \tmpreg1, %cwp
504
 
582
 
505
	! fill from kernel stack
583
	! fill from kernel stack
506
	ldx [%sp + STACK_BIAS + L0_OFFSET], %l0
584
	ldx [%sp + STACK_BIAS + L0_OFFSET], %l0
507
	ldx [%sp + STACK_BIAS + L1_OFFSET], %l1
585
	ldx [%sp + STACK_BIAS + L1_OFFSET], %l1
508
	ldx [%sp + STACK_BIAS + L2_OFFSET], %l2
586
	ldx [%sp + STACK_BIAS + L2_OFFSET], %l2
509
	ldx [%sp + STACK_BIAS + L3_OFFSET], %l3
587
	ldx [%sp + STACK_BIAS + L3_OFFSET], %l3
510
	ldx [%sp + STACK_BIAS + L4_OFFSET], %l4
588
	ldx [%sp + STACK_BIAS + L4_OFFSET], %l4
511
	ldx [%sp + STACK_BIAS + L5_OFFSET], %l5
589
	ldx [%sp + STACK_BIAS + L5_OFFSET], %l5
512
	ldx [%sp + STACK_BIAS + L6_OFFSET], %l6
590
	ldx [%sp + STACK_BIAS + L6_OFFSET], %l6
513
	ldx [%sp + STACK_BIAS + L7_OFFSET], %l7
591
	ldx [%sp + STACK_BIAS + L7_OFFSET], %l7
514
	ldx [%sp + STACK_BIAS + I0_OFFSET], %i0
592
	ldx [%sp + STACK_BIAS + I0_OFFSET], %i0
515
	ldx [%sp + STACK_BIAS + I1_OFFSET], %i1
593
	ldx [%sp + STACK_BIAS + I1_OFFSET], %i1
516
	ldx [%sp + STACK_BIAS + I2_OFFSET], %i2
594
	ldx [%sp + STACK_BIAS + I2_OFFSET], %i2
517
	ldx [%sp + STACK_BIAS + I3_OFFSET], %i3
595
	ldx [%sp + STACK_BIAS + I3_OFFSET], %i3
518
	ldx [%sp + STACK_BIAS + I4_OFFSET], %i4
596
	ldx [%sp + STACK_BIAS + I4_OFFSET], %i4
519
	ldx [%sp + STACK_BIAS + I5_OFFSET], %i5
597
	ldx [%sp + STACK_BIAS + I5_OFFSET], %i5
520
	ldx [%sp + STACK_BIAS + I6_OFFSET], %i6
598
	ldx [%sp + STACK_BIAS + I6_OFFSET], %i6
521
	ldx [%sp + STACK_BIAS + I7_OFFSET], %i7
599
	ldx [%sp + STACK_BIAS + I7_OFFSET], %i7
522
 
600
 
523
	! CWP := CWP + 1
601
	! CWP := CWP + 1
524
	wrpr \tmpreg2, %cwp
602
	wrpr \tmpreg2, %cwp
525
 
603
 
526
	restored
604
	restored
527
.endm
605
.endm
528
 
606
 
529
#define NOT(x)	((x) == 0)
607
#define NOT(x)	((x) == 0)
530
 
608
 
531
/*
609
/*
532
 * Perform all the actions of the preemptible trap handler which are common
610
 * 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
611
 * for trapping from kernel and trapping from userspace, including call of the
534
 * higher level service routine.
612
 * higher level service routine.
535
 *
613
 *
536
 * Important note:
614
 * Important note:
537
 * 	This macro must be inserted between the "2:" and "4:" labels. The
615
 * 	This macro must be inserted between the "2:" and "4:" labels. The
538
 *	inserting code must be aware of the usage of all the registers
616
 *	inserting code must be aware of the usage of all the registers
539
 *	contained in this macro.
617
 *	contained in this macro.
540
 */
618
 */
541
.macro MIDDLE_PART is_syscall
619
.macro MIDDLE_PART is_syscall
542
	/* copy higher level routine's address and its argument */
620
	/* copy higher level routine's address and its argument */
543
	mov %g1, %l0
621
	mov %g1, %l0
544
.if NOT(\is_syscall)
622
.if NOT(\is_syscall)
545
	mov %g2, %o0
623
	mov %g2, %o0
546
.else
624
.else
547
	! store the syscall number on the stack as 7th argument
625
	! store the syscall number on the stack as 7th argument
548
	stx %g2, [%sp + STACK_WINDOW_SAVE_AREA_SIZE + STACK_BIAS + STACK_ARG6] 
626
	stx %g2, [%sp + STACK_WINDOW_SAVE_AREA_SIZE + STACK_BIAS + STACK_ARG6] 
549
.endif
627
.endif
550
 
628
 
551
	/*
629
	/*
552
	 * Save TSTATE, TPC and TNPC aside.
630
	 * Save TSTATE, TPC and TNPC aside.
553
	 */
631
	 */
554
	rdpr %tstate, %g1
632
	rdpr %tstate, %g1
555
	rdpr %tpc, %g2
633
	rdpr %tpc, %g2
556
	rdpr %tnpc, %g3
634
	rdpr %tnpc, %g3
557
 
635
 
558
	stx %g1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE]
636
	stx %g1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE]
559
	stx %g2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC]
637
	stx %g2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC]
560
	stx %g3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC]
638
	stx %g3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC]
561
 
639
 
562
	/*
640
	/*
563
	 * Save the Y register.
641
	 * Save the Y register.
564
	 * This register is deprecated according to SPARC V9 specification
642
	 * This register is deprecated according to SPARC V9 specification
565
	 * and is only present for backward compatibility with previous
643
	 * and is only present for backward compatibility with previous
566
	 * versions of the SPARC architecture.
644
	 * versions of the SPARC architecture.
567
	 * Surprisingly, gcc makes use of this register without a notice.
645
	 * Surprisingly, gcc makes use of this register without a notice.
568
	 */
646
	 */
569
	rd %y, %g4
647
	rd %y, %g4
570
	stx %g4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y]
648
	stx %g4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y]
571
 
649
 
572
	/* switch to TL = 0, explicitly enable FPU */
650
	/* switch to TL = 0, explicitly enable FPU */
573
	wrpr %g0, 0, %tl
651
	wrpr %g0, 0, %tl
574
	wrpr %g0, 0, %gl
652
	wrpr %g0, 0, %gl
575
	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT, %pstate
653
	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT, %pstate
576
 
654
 
577
	/* g1 -> l1, ..., g7 -> l7 */
655
	/* g1 -> l1, ..., g7 -> l7 */
578
	SAVE_GLOBALS
656
	SAVE_GLOBALS
579
 
657
 
580
.if NOT(\is_syscall)
658
.if NOT(\is_syscall)
581
	/* call higher-level service routine, pass istate as its 2nd parameter */
659
	/* call higher-level service routine, pass istate as its 2nd parameter */
582
	call %l0
660
	call %l0
583
	add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1
661
	add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1
584
.else
662
.else
585
	/* Call the higher-level syscall handler. */
663
	/* Call the higher-level syscall handler. */
586
	!wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT | PSTATE_IE_BIT, %pstate
664
	!wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT | PSTATE_IE_BIT, %pstate
587
	call syscall_handler
665
	call syscall_handler
588
	nop
666
	nop
589
	/* copy the value returned by the syscall */
667
	/* copy the value returned by the syscall */
590
	mov %o0, %i0
668
	mov %o0, %i0
591
.endif
669
.endif
592
 
670
 
593
	/* l1 -> g1, ..., l7 -> g7 */
671
	/* l1 -> g1, ..., l7 -> g7 */
594
	RESTORE_GLOBALS
672
	RESTORE_GLOBALS
595
 
673
 
596
	/* we must prserve the PEF bit */
674
	/* we must prserve the PEF bit */
597
	rdpr %pstate, %l1
675
	rdpr %pstate, %l1
598
 
676
 
599
	/* TL := 1, GL := 1 */
677
	/* TL := 1, GL := 1 */
600
	wrpr %g0, PSTATE_PRIV_BIT, %pstate
678
	wrpr %g0, PSTATE_PRIV_BIT, %pstate
601
	wrpr %g0, 1, %tl
679
	wrpr %g0, 1, %tl
602
	wrpr %g0, 1, %gl
680
	wrpr %g0, 1, %gl
603
 
681
 
604
	/* Read TSTATE, TPC and TNPC from saved copy. */
682
	/* Read TSTATE, TPC and TNPC from saved copy. */
605
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE], %g1
683
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE], %g1
606
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC], %g2
684
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC], %g2
607
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC], %g3
685
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC], %g3
608
 
686
 
609
	/* Copy PSTATE.PEF to the in-register copy of TSTATE. */
687
	/* Copy PSTATE.PEF to the in-register copy of TSTATE. */
610
	and %l1, PSTATE_PEF_BIT, %l1
688
	and %l1, PSTATE_PEF_BIT, %l1
611
	sllx %l1, TSTATE_PSTATE_SHIFT, %l1
689
	sllx %l1, TSTATE_PSTATE_SHIFT, %l1
612
	sethi %hi(TSTATE_PEF_BIT), %g4		! reset the PEF bit to 0 ...
690
	sethi %hi(TSTATE_PEF_BIT), %g4		! reset the PEF bit to 0 ...
613
	andn %g1, %g4, %g1
691
	andn %g1, %g4, %g1
614
	or %g1, %l1, %g1			! ... "or" it with saved PEF
692
	or %g1, %l1, %g1			! ... "or" it with saved PEF
615
 
693
 
616
	/* Restore TSTATE, TPC and TNPC from saved copies. */
694
	/* Restore TSTATE, TPC and TNPC from saved copies. */
617
	wrpr %g1, 0, %tstate
695
	wrpr %g1, 0, %tstate
618
	wrpr %g2, 0, %tpc
696
	wrpr %g2, 0, %tpc
619
	wrpr %g3, 0, %tnpc
697
	wrpr %g3, 0, %tnpc
620
 
698
 
621
	/* Restore Y. */
699
	/* Restore Y. */
622
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y], %g4
700
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y], %g4
623
	wr %g4, %y
701
	wr %g4, %y
624
	
702
	
625
	/* If TSTATE.CWP + 1 == CWP, then we do not have to fix CWP. */
703
	/* If TSTATE.CWP + 1 == CWP, then we do not have to fix CWP. */
626
	and %g1, TSTATE_CWP_MASK, %l0
704
	and %g1, TSTATE_CWP_MASK, %l0
627
	inc %l0
705
	inc %l0
628
	and %l0, NWINDOWS - 1, %l0	! %l0 mod NWINDOWS
706
	and %l0, NWINDOWS - 1, %l0	! %l0 mod NWINDOWS
629
	rdpr %cwp, %l1
707
	rdpr %cwp, %l1
630
	cmp %l0, %l1
708
	cmp %l0, %l1
631
	bz 4f				! CWP is ok
709
	bz 4f				! CWP is ok
632
	nop
710
	nop
633
 
711
 
634
3:
712
3:
635
	/*
713
	/*
636
	 * Fix CWP.
714
	 * Fix CWP.
637
	 * In order to recapitulate, the input registers in the current
715
	 * In order to recapitulate, the input registers in the current
638
	 * window are the output registers of the window to which we want
716
	 * window are the output registers of the window to which we want
639
	 * to restore. Because the fill trap fills only input and local
717
	 * to restore. Because the fill trap fills only input and local
640
	 * registers of a window, we need to preserve those output
718
	 * registers of a window, we need to preserve those output
641
	 * registers manually.
719
	 * registers manually.
642
	 */
720
	 */
643
	mov %sp, %g2
721
	mov %sp, %g2
644
	stx %i0, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0]
722
	stx %i0, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0]
645
	stx %i1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1]
723
	stx %i1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1]
646
	stx %i2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2]
724
	stx %i2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2]
647
	stx %i3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3]
725
	stx %i3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3]
648
	stx %i4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4]
726
	stx %i4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4]
649
	stx %i5, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5]
727
	stx %i5, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5]
650
	stx %i6, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6]
728
	stx %i6, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6]
651
	stx %i7, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7]
729
	stx %i7, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7]
652
	wrpr %l0, 0, %cwp
730
	wrpr %l0, 0, %cwp
653
	mov %g2, %sp
731
	mov %g2, %sp
654
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0], %i0
732
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0], %i0
655
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1], %i1
733
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1], %i1
656
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2], %i2
734
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2], %i2
657
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3], %i3
735
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3], %i3
658
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4], %i4
736
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4], %i4
659
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5], %i5
737
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5], %i5
660
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6], %i6
738
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6], %i6
661
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7], %i7
739
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7], %i7
662
.endm
740
.endm
663
 
741
 
664
/*
742
/*
665
 * Preemptible trap handler for handling traps from kernel.
743
 * Preemptible trap handler for handling traps from kernel.
666
 */
744
 */
667
.macro PREEMPTIBLE_HANDLER_KERNEL
745
.macro PREEMPTIBLE_HANDLER_KERNEL
668
 
746
 
669
	/*
747
	/*
670
	 * ASSERT(%tl == 1)
748
	 * ASSERT(%tl == 1)
671
	 */
749
	 */
672
	rdpr %tl, %g3
750
	rdpr %tl, %g3
673
	cmp %g3, 1
751
	cmp %g3, 1
674
	be 1f
752
	be 1f
675
	nop
753
	nop
676
0:	ba 0b					! this is for debugging, if we ever get here
754
0:	ba 0b					! this is for debugging, if we ever get here
677
	nop					! it will be easy to find
755
	nop					! it will be easy to find
678
 
756
 
679
1:
757
1:
680
	/* prevent unnecessary CLEANWIN exceptions */
758
	/* prevent unnecessary CLEANWIN exceptions */
681
	wrpr %g0, NWINDOWS - 1, %cleanwin
759
	wrpr %g0, NWINDOWS - 1, %cleanwin
682
 
760
 
683
	/*
761
	/*
684
	 * Prevent SAVE instruction from causing a spill exception. If the
762
	 * Prevent SAVE instruction from causing a spill exception. If the
685
	 * CANSAVE register is zero, explicitly spill register window
763
	 * CANSAVE register is zero, explicitly spill register window
686
	 * at CWP + 2.
764
	 * at CWP + 2.
687
	 */
765
	 */
688
 
766
 
689
	rdpr %cansave, %g3
767
	rdpr %cansave, %g3
690
	brnz %g3, 2f
768
	brnz %g3, 2f
691
	nop
769
	nop
692
	INLINE_SPILL %g3, %g4
770
	INLINE_SPILL %g3, %g4
693
 
771
 
694
2:
772
2:
695
	/* ask for new register window */
773
	/* ask for new register window */
696
	save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
774
	save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
697
 
775
 
698
	MIDDLE_PART 0
776
	MIDDLE_PART 0
699
 
777
 
700
4:
778
4:
701
	/*
779
	/*
702
	 * Prevent RESTORE instruction from causing a fill exception. If the
780
	 * Prevent RESTORE instruction from causing a fill exception. If the
703
	 * CANRESTORE register is zero, explicitly fill register window
781
	 * CANRESTORE register is zero, explicitly fill register window
704
	 * at CWP - 1.
782
	 * at CWP - 1.
705
	 */
783
	 */
706
	rdpr %canrestore, %g1
784
	rdpr %canrestore, %g1
707
	brnz %g1, 5f
785
	brnz %g1, 5f
708
	nop
786
	nop
709
	INLINE_FILL %g3, %g4
787
	INLINE_FILL %g3, %g4
710
 
788
 
711
5:
789
5:
712
	restore
790
	restore
713
 
791
 
714
	retry
792
	retry
715
.endm
793
.endm
716
 
794
 
717
/*
795
/*
718
 * Spills the window at CWP + 2 to the userspace window buffer. This macro
796
 * 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.
797
 * is to be used before doing SAVE when the spill trap is undesirable.
720
 * 
798
 * 
721
 * Parameters:
799
 * Parameters:
722
 * 	tmpreg1		global register to be used for scratching purposes
800
 * 	tmpreg1		global register to be used for scratching purposes
723
 * 	tmpreg2		global register to be used for scratching purposes
801
 * 	tmpreg2		global register to be used for scratching purposes
724
 * 	tmpreg3		global register to be used for scratching purposes
802
 * 	tmpreg3		global register to be used for scratching purposes
725
 */
803
 */
726
.macro INLINE_SPILL_TO_WBUF tmpreg1, tmpreg2, tmpreg3
804
.macro INLINE_SPILL_TO_WBUF tmpreg1, tmpreg2, tmpreg3
727
	! CWP := CWP + 2
805
	! CWP := CWP + 2
728
	rdpr %cwp, \tmpreg2
806
	rdpr %cwp, \tmpreg2
729
	add \tmpreg2, 2, \tmpreg1
807
	add \tmpreg2, 2, \tmpreg1
730
	and \tmpreg1, NWINDOWS - 1, \tmpreg1		! modulo NWINDOWS
808
	and \tmpreg1, NWINDOWS - 1, \tmpreg1		! modulo NWINDOWS
731
	wrpr \tmpreg1, %cwp
809
	wrpr \tmpreg1, %cwp
732
	
810
	
733
	! spill to userspace window buffer
811
	! spill to userspace window buffer
734
	SAVE_TO_USPACE_WBUF \tmpreg3, \tmpreg1
812
	SAVE_TO_USPACE_WBUF \tmpreg3, \tmpreg1
735
 
813
 
736
	! CWP := CWP - 2
814
	! CWP := CWP - 2
737
	wrpr \tmpreg2, %cwp
815
	wrpr \tmpreg2, %cwp
738
 
816
 
739
	saved
817
	saved
740
.endm
818
.endm
741
 
819
 
742
/*
820
/*
743
 * Preemptible handler for handling traps from userspace.
821
 * Preemptible handler for handling traps from userspace.
744
 */
822
 */
745
.macro PREEMPTIBLE_HANDLER_USPACE is_syscall
823
.macro PREEMPTIBLE_HANDLER_USPACE is_syscall
746
	/*
824
	/*
747
	 * One of the ways this handler can be invoked is after a nested MMU trap from
825
	 * 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
826
	 * 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
827
	 * 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
828
	 * 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
829
	 * 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.
830
	 * perspective of the MMU trap, we need to synchronize CWP with CWP from TL=0.
753
	 */ 
831
	 */ 
754
.if NOT(\is_syscall)
832
.if NOT(\is_syscall)
755
	rdpr %tstate, %g3
833
	rdpr %tstate, %g3
756
	and %g3, TSTATE_CWP_MASK, %g4
834
	and %g3, TSTATE_CWP_MASK, %g4
757
	wrpr %g4, 0, %cwp			! resynchronize CWP
835
	wrpr %g4, 0, %cwp			! resynchronize CWP
758
.endif
836
.endif
759
 
837
 
760
	/* prevent unnecessary CLEANWIN exceptions */
838
	/* prevent unnecessary CLEANWIN exceptions */
761
	wrpr %g0, NWINDOWS - 1, %cleanwin
839
	wrpr %g0, NWINDOWS - 1, %cleanwin
762
 
840
 
763
	/*
841
	/*
764
	 * Prevent SAVE instruction from causing a spill exception. If the
842
	 * Prevent SAVE instruction from causing a spill exception. If the
765
	 * CANSAVE register is zero, explicitly spill register window
843
	 * CANSAVE register is zero, explicitly spill register window
766
	 * at CWP + 2.
844
	 * at CWP + 2.
767
	 */
845
	 */
768
	rdpr %cansave, %g3
846
	rdpr %cansave, %g3
769
	brnz %g3, 2f
847
	brnz %g3, 2f
770
	nop
848
	nop
771
	INLINE_SPILL_TO_WBUF %g3, %g4, %g7
849
	INLINE_SPILL_TO_WBUF %g3, %g4, %g7
772
 
850
 
773
2:
851
2:
774
	set SCRATCHPAD_KSTACK, %g4
852
	set SCRATCHPAD_KSTACK, %g4
775
	ldxa [%g4] ASI_SCRATCHPAD, %g6
853
	ldxa [%g4] ASI_SCRATCHPAD, %g6
776
	save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
854
	save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
777
 
855
 
778
.if \is_syscall
856
.if \is_syscall
779
	/* Copy arguments for the syscall to the new window. */
857
	/* Copy arguments for the syscall to the new window. */
780
	mov %i0, %o0
858
	mov %i0, %o0
781
	mov %i1, %o1
859
	mov %i1, %o1
782
	mov %i2, %o2
860
	mov %i2, %o2
783
	mov %i3, %o3
861
	mov %i3, %o3
784
	mov %i4, %o4
862
	mov %i4, %o4
785
	mov %i5, %o5
863
	mov %i5, %o5
786
.endif
864
.endif
787
 
865
 
788
	mov VA_PRIMARY_CONTEXT_REG, %l0 
866
	mov VA_PRIMARY_CONTEXT_REG, %l0 
789
	stxa %g0, [%l0] ASI_PRIMARY_CONTEXT_REG
867
	stxa %g0, [%l0] ASI_PRIMARY_CONTEXT_REG
790
	rd %pc, %l0
868
	rd %pc, %l0
791
	flush %l0
869
	flush %l0
792
 
870
 
793
	/* Mark the CANRESTORE windows as OTHER windows. */
871
	/* Mark the CANRESTORE windows as OTHER windows. */
794
	rdpr %canrestore, %l0
872
	rdpr %canrestore, %l0
795
	wrpr %l0, %otherwin
873
	wrpr %l0, %otherwin
796
	wrpr %g0, %canrestore
874
	wrpr %g0, %canrestore
797
 
875
 
798
	/*
876
	/*
799
	 * Other window spills will go to the userspace window buffer
877
	 * Other window spills will go to the userspace window buffer
800
	 * and normal spills will go to the kernel stack.
878
	 * and normal spills will go to the kernel stack.
801
	 */
879
	 */
802
	wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(0), %wstate
880
	wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(0), %wstate
803
 
881
 
804
	MIDDLE_PART \is_syscall
882
	MIDDLE_PART \is_syscall
805
 
883
 
806
4:
884
4:
807
	/*
885
	/*
808
	 * Spills and fills will be processed by the {spill,fill}_1_normal
886
	 * Spills and fills will be processed by the {spill,fill}_1_normal
809
	 * handlers.
887
	 * handlers.
810
	 */
888
	 */
811
	wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(1), %wstate
889
	wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(1), %wstate
812
 
890
 
813
	/*
891
	/*
814
	 * Set primary context according to secondary context.
892
	 * Set primary context according to secondary context.
815
	 */
893
	 */
816
	wr %g0, ASI_SECONDARY_CONTEXT_REG, %asi
894
	wr %g0, ASI_SECONDARY_CONTEXT_REG, %asi
817
	ldxa [VA_SECONDARY_CONTEXT_REG] %asi, %g1
895
	ldxa [VA_SECONDARY_CONTEXT_REG] %asi, %g1
818
	wr %g0, ASI_PRIMARY_CONTEXT_REG, %asi
896
	wr %g0, ASI_PRIMARY_CONTEXT_REG, %asi
819
	stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi
897
	stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi
820
	rd %pc, %g1
898
	rd %pc, %g1
821
	flush %g1
899
	flush %g1
822
 
900
 
823
	/* Restoring userspace windows: */
901
	/* Restoring userspace windows: */
824
 
902
 
825
	/* Save address of the userspace window buffer to the %g7 register. */
903
	/* Save address of the userspace window buffer to the %g7 register. */
826
	set SCRATCHPAD_WBUF, %g5
904
	set SCRATCHPAD_WBUF, %g5
827
	ldxa [%g5] ASI_SCRATCHPAD, %g7
905
	ldxa [%g5] ASI_SCRATCHPAD, %g7
828
 
906
 
829
	rdpr %cwp, %g1
907
	rdpr %cwp, %g1
830
	rdpr %otherwin, %g2
908
	rdpr %otherwin, %g2
831
 
909
 
832
	/*
910
	/*
833
	 * Skip all OTHERWIN windows and descend to the first window
911
	 * Skip all OTHERWIN windows and descend to the first window
834
	 * in the userspace window buffer.
912
	 * in the userspace window buffer.
835
	 */
913
	 */
836
	sub %g1, %g2, %g3
914
	sub %g1, %g2, %g3
837
	dec %g3
915
	dec %g3
838
	and %g3, NWINDOWS - 1, %g3
916
	and %g3, NWINDOWS - 1, %g3
839
	wrpr %g3, 0, %cwp
917
	wrpr %g3, 0, %cwp
840
 
918
 
841
	/*
919
	/*
842
	 * CWP is now in the window last saved in the userspace window buffer.
920
	 * CWP is now in the window last saved in the userspace window buffer.
843
	 * Fill all windows stored in the buffer.
921
	 * Fill all windows stored in the buffer.
844
	 */
922
	 */
845
	clr %g4
923
	clr %g4
846
5:	andcc %g7, UWB_ALIGNMENT - 1, %g0	! alignment check
924
5:	andcc %g7, UWB_ALIGNMENT - 1, %g0	! alignment check
847
	bz 6f					! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill
925
	bz 6f					! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill
848
	nop
926
	nop
849
 
927
 
850
	add %g7, -STACK_WINDOW_SAVE_AREA_SIZE, %g7
928
	add %g7, -STACK_WINDOW_SAVE_AREA_SIZE, %g7
851
	ldx [%g7 + L0_OFFSET], %l0
929
	ldx [%g7 + L0_OFFSET], %l0
852
	ldx [%g7 + L1_OFFSET], %l1
930
	ldx [%g7 + L1_OFFSET], %l1
853
	ldx [%g7 + L2_OFFSET], %l2
931
	ldx [%g7 + L2_OFFSET], %l2
854
	ldx [%g7 + L3_OFFSET], %l3
932
	ldx [%g7 + L3_OFFSET], %l3
855
	ldx [%g7 + L4_OFFSET], %l4
933
	ldx [%g7 + L4_OFFSET], %l4
856
	ldx [%g7 + L5_OFFSET], %l5
934
	ldx [%g7 + L5_OFFSET], %l5
857
	ldx [%g7 + L6_OFFSET], %l6
935
	ldx [%g7 + L6_OFFSET], %l6
858
	ldx [%g7 + L7_OFFSET], %l7
936
	ldx [%g7 + L7_OFFSET], %l7
859
	ldx [%g7 + I0_OFFSET], %i0
937
	ldx [%g7 + I0_OFFSET], %i0
860
	ldx [%g7 + I1_OFFSET], %i1
938
	ldx [%g7 + I1_OFFSET], %i1
861
	ldx [%g7 + I2_OFFSET], %i2
939
	ldx [%g7 + I2_OFFSET], %i2
862
	ldx [%g7 + I3_OFFSET], %i3
940
	ldx [%g7 + I3_OFFSET], %i3
863
	ldx [%g7 + I4_OFFSET], %i4
941
	ldx [%g7 + I4_OFFSET], %i4
864
	ldx [%g7 + I5_OFFSET], %i5
942
	ldx [%g7 + I5_OFFSET], %i5
865
	ldx [%g7 + I6_OFFSET], %i6
943
	ldx [%g7 + I6_OFFSET], %i6
866
	ldx [%g7 + I7_OFFSET], %i7
944
	ldx [%g7 + I7_OFFSET], %i7
867
 
945
 
868
	dec %g3
946
	dec %g3
869
	and %g3, NWINDOWS - 1, %g3
947
	and %g3, NWINDOWS - 1, %g3
870
	wrpr %g3, 0, %cwp			! switch to the preceeding window
948
	wrpr %g3, 0, %cwp			! switch to the preceeding window
871
 
949
 
872
	ba 5b
950
	ba 5b
873
	inc %g4
951
	inc %g4
874
 
952
 
875
6:
953
6:
876
	/* Save changes of the address of the userspace window buffer. */
954
	/* Save changes of the address of the userspace window buffer. */
877
	stxa %g7, [%g5] ASI_SCRATCHPAD
955
	stxa %g7, [%g5] ASI_SCRATCHPAD
878
 
956
 
879
	/*
957
	/*
880
	 * Switch back to the proper current window and adjust
958
	 * Switch back to the proper current window and adjust
881
	 * OTHERWIN, CANRESTORE, CANSAVE and CLEANWIN.
959
	 * OTHERWIN, CANRESTORE, CANSAVE and CLEANWIN.
882
	 */
960
	 */
883
	wrpr %g1, 0, %cwp
961
	wrpr %g1, 0, %cwp
884
	add %g4, %g2, %g2
962
	add %g4, %g2, %g2
885
	cmp %g2, NWINDOWS - 2
963
	cmp %g2, NWINDOWS - 2
886
	bg 8f					! fix the CANRESTORE=NWINDOWS-1 anomaly
964
	bg 8f					! fix the CANRESTORE=NWINDOWS-1 anomaly
887
	mov NWINDOWS - 2, %g1			! use dealy slot for both cases
965
	mov NWINDOWS - 2, %g1			! use dealy slot for both cases
888
	sub %g1, %g2, %g1
966
	sub %g1, %g2, %g1
889
	
967
	
890
	wrpr %g0, 0, %otherwin
968
	wrpr %g0, 0, %otherwin
891
	wrpr %g1, 0, %cansave			! NWINDOWS - 2 - CANRESTORE
969
	wrpr %g1, 0, %cansave			! NWINDOWS - 2 - CANRESTORE
892
	wrpr %g2, 0, %canrestore		! OTHERWIN + windows in the buffer
970
	wrpr %g2, 0, %canrestore		! OTHERWIN + windows in the buffer
893
	wrpr %g2, 0, %cleanwin			! avoid information leak
971
	wrpr %g2, 0, %cleanwin			! avoid information leak
894
 
972
 
895
7:
973
7:
896
	restore
974
	restore
897
 
975
 
898
.if \is_syscall
976
.if \is_syscall
899
	done
977
	done
900
.else
978
.else
901
	retry
979
	retry
902
.endif
980
.endif
903
 
981
 
904
8:
982
8:
905
	/*
983
	/*
906
	 * We got here in order to avoid inconsistency of the window state registers.
984
	 * We got here in order to avoid inconsistency of the window state registers.
907
	 * If the:
985
	 * If the:
908
	 *
986
	 *
909
	 * 	save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
987
	 * 	save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
910
	 *
988
	 *
911
	 * instruction trapped and spilled a register window into the userspace
989
	 * instruction trapped and spilled a register window into the userspace
912
	 * window buffer, we have just restored NWINDOWS - 1 register windows.
990
	 * window buffer, we have just restored NWINDOWS - 1 register windows.
913
	 * However, CANRESTORE can be only NWINDOW - 2 at most.
991
	 * However, CANRESTORE can be only NWINDOW - 2 at most.
914
	 *
992
	 *
915
	 * The solution is to manually switch to (CWP - 1) mod NWINDOWS
993
	 * The solution is to manually switch to (CWP - 1) mod NWINDOWS
916
	 * and set the window state registers so that:
994
	 * and set the window state registers so that:
917
	 *
995
	 *
918
	 * 	CANRESTORE 	= NWINDOWS - 2
996
	 * 	CANRESTORE 	= NWINDOWS - 2
919
	 *	CLEANWIN	= NWINDOWS - 2
997
	 *	CLEANWIN	= NWINDOWS - 2
920
	 *	CANSAVE 	= 0
998
	 *	CANSAVE 	= 0
921
	 *	OTHERWIN	= 0
999
	 *	OTHERWIN	= 0
922
	 *
1000
	 *
923
	 * The RESTORE instruction is therfore to be skipped.
1001
	 * The RESTORE instruction is therfore to be skipped.
924
	 */
1002
	 */
925
	wrpr %g0, 0, %otherwin
1003
	wrpr %g0, 0, %otherwin
926
	wrpr %g0, 0, %cansave
1004
	wrpr %g0, 0, %cansave
927
	wrpr %g1, 0, %canrestore
1005
	wrpr %g1, 0, %canrestore
928
	wrpr %g1, 0, %cleanwin
1006
	wrpr %g1, 0, %cleanwin
929
 
1007
 
930
	rdpr %cwp, %g1
1008
	rdpr %cwp, %g1
931
	dec %g1
1009
	dec %g1
932
	and %g1, NWINDOWS - 1, %g1
1010
	and %g1, NWINDOWS - 1, %g1
933
	wrpr %g1, 0, %cwp			! CWP--
1011
	wrpr %g1, 0, %cwp			! CWP--
934
	
1012
	
935
.if \is_syscall
1013
.if \is_syscall
936
	done
1014
	done
937
.else
1015
.else
938
	retry
1016
	retry
939
.endif
1017
.endif
940
 
1018
 
941
.endm
1019
.endm
942
 
1020
 
943
/* Preemptible trap handler for TL=1.
1021
/* Preemptible trap handler for TL=1.
944
 *
1022
 *
945
 * This trap handler makes arrangements to make calling of scheduler() from
1023
 * This trap handler makes arrangements to make calling of scheduler() from
946
 * within a trap context possible. It is called from several other trap
1024
 * within a trap context possible. It is called from several other trap
947
 * handlers.
1025
 * handlers.
948
 */
1026
 */
949
.macro PREEMPTIBLE_HANDLER_TEMPLATE is_syscall
1027
.macro PREEMPTIBLE_HANDLER_TEMPLATE is_syscall
950
	rdpr %tstate, %g3
1028
	rdpr %tstate, %g3
951
	and %g3, TSTATE_PRIV_BIT, %g3
1029
	and %g3, TSTATE_PRIV_BIT, %g3
952
	brz %g3, 100f			! trapping from userspace
1030
	brz %g3, 100f			! trapping from userspace
953
	nop
1031
	nop
954
 
1032
 
955
	PREEMPTIBLE_HANDLER_KERNEL
1033
	PREEMPTIBLE_HANDLER_KERNEL
956
	ba 101f
1034
	ba 101f
957
	nop
1035
	nop
958
 
1036
 
959
	100:
1037
	100:
960
	PREEMPTIBLE_HANDLER_USPACE \is_syscall
1038
	PREEMPTIBLE_HANDLER_USPACE \is_syscall
961
 
1039
 
962
	101:
1040
	101:
963
.endm
1041
.endm
964
 
1042
 
965
.global preemptible_handler
1043
.global preemptible_handler
966
preemptible_handler:
1044
preemptible_handler:
967
	PREEMPTIBLE_HANDLER_TEMPLATE 0
1045
	PREEMPTIBLE_HANDLER_TEMPLATE 0
968
 
1046
 
969
.global trap_instruction_handler
1047
.global trap_instruction_handler
970
trap_instruction_handler:
1048
trap_instruction_handler:
971
	PREEMPTIBLE_HANDLER_TEMPLATE 1
1049
	PREEMPTIBLE_HANDLER_TEMPLATE 1
972
 
1050