Subversion Repositories HelenOS

Rev

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

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