Subversion Repositories HelenOS

Rev

Rev 4433 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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