Subversion Repositories HelenOS

Rev

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

Rev 3743 Rev 3798
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
 
50
 
51
#define TABLE_SIZE	TRAP_TABLE_SIZE
51
#define TABLE_SIZE	TRAP_TABLE_SIZE
52
#define ENTRY_SIZE	TRAP_TABLE_ENTRY_SIZE
52
#define ENTRY_SIZE	TRAP_TABLE_ENTRY_SIZE
53
 
53
 
54
/*
54
/*
55
 * Kernel trap table.
55
 * Kernel trap table.
56
 */
56
 */
57
.align TABLE_SIZE
57
.align TABLE_SIZE
58
.global trap_table
58
.global trap_table
59
trap_table:
59
trap_table:
60
 
60
 
61
/* TT = 0x08, TL = 0, instruction_access_exception */
61
/* TT = 0x08, TL = 0, instruction_access_exception */
62
.org trap_table + TT_INSTRUCTION_ACCESS_EXCEPTION*ENTRY_SIZE
62
.org trap_table + TT_INSTRUCTION_ACCESS_EXCEPTION*ENTRY_SIZE
63
.global instruction_access_exception_tl0
63
.global instruction_access_exception_tl0
64
instruction_access_exception_tl0:
64
instruction_access_exception_tl0:
65
	/*wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
65
	/*wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
66
	PREEMPTIBLE_HANDLER instruction_access_exception*/
66
	PREEMPTIBLE_HANDLER instruction_access_exception*/
67
 
67
 
68
/* TT = 0x0a, TL = 0, instruction_access_error */
68
/* TT = 0x0a, TL = 0, instruction_access_error */
69
.org trap_table + TT_INSTRUCTION_ACCESS_ERROR*ENTRY_SIZE
69
.org trap_table + TT_INSTRUCTION_ACCESS_ERROR*ENTRY_SIZE
70
.global instruction_access_error_tl0
70
.global instruction_access_error_tl0
71
instruction_access_error_tl0:
71
instruction_access_error_tl0:
72
	PREEMPTIBLE_HANDLER instruction_access_error
72
	PREEMPTIBLE_HANDLER instruction_access_error
73
 
73
 
74
/* TT = 0x10, TL = 0, illegal_instruction */
74
/* TT = 0x10, TL = 0, illegal_instruction */
75
.org trap_table + TT_ILLEGAL_INSTRUCTION*ENTRY_SIZE
75
.org trap_table + TT_ILLEGAL_INSTRUCTION*ENTRY_SIZE
76
.global illegal_instruction_tl0
76
.global illegal_instruction_tl0
77
illegal_instruction_tl0:
77
illegal_instruction_tl0:
78
	PREEMPTIBLE_HANDLER illegal_instruction
78
	PREEMPTIBLE_HANDLER illegal_instruction
79
 
79
 
80
/* TT = 0x11, TL = 0, privileged_opcode */
80
/* TT = 0x11, TL = 0, privileged_opcode */
81
.org trap_table + TT_PRIVILEGED_OPCODE*ENTRY_SIZE
81
.org trap_table + TT_PRIVILEGED_OPCODE*ENTRY_SIZE
82
.global privileged_opcode_tl0
82
.global privileged_opcode_tl0
83
privileged_opcode_tl0:
83
privileged_opcode_tl0:
84
	PREEMPTIBLE_HANDLER privileged_opcode
84
	PREEMPTIBLE_HANDLER privileged_opcode
85
 
85
 
86
/* TT = 0x12, TL = 0, unimplemented_LDD */
86
/* TT = 0x12, TL = 0, unimplemented_LDD */
87
.org trap_table + TT_UNIMPLEMENTED_LDD*ENTRY_SIZE
87
.org trap_table + TT_UNIMPLEMENTED_LDD*ENTRY_SIZE
88
.global unimplemented_LDD_tl0
88
.global unimplemented_LDD_tl0
89
unimplemented_LDD_tl0:
89
unimplemented_LDD_tl0:
90
	PREEMPTIBLE_HANDLER unimplemented_LDD
90
	PREEMPTIBLE_HANDLER unimplemented_LDD
91
 
91
 
92
/* TT = 0x13, TL = 0, unimplemented_STD */
92
/* TT = 0x13, TL = 0, unimplemented_STD */
93
.org trap_table + TT_UNIMPLEMENTED_STD*ENTRY_SIZE
93
.org trap_table + TT_UNIMPLEMENTED_STD*ENTRY_SIZE
94
.global unimplemented_STD_tl0
94
.global unimplemented_STD_tl0
95
unimplemented_STD_tl0:
95
unimplemented_STD_tl0:
96
	PREEMPTIBLE_HANDLER unimplemented_STD
96
	PREEMPTIBLE_HANDLER unimplemented_STD
97
 
97
 
98
/* TT = 0x20, TL = 0, fb_disabled handler */
98
/* TT = 0x20, TL = 0, fb_disabled handler */
99
.org trap_table + TT_FP_DISABLED*ENTRY_SIZE
99
.org trap_table + TT_FP_DISABLED*ENTRY_SIZE
100
.global fb_disabled_tl0
100
.global fb_disabled_tl0
101
fp_disabled_tl0:
101
fp_disabled_tl0:
102
	PREEMPTIBLE_HANDLER fp_disabled
102
	PREEMPTIBLE_HANDLER fp_disabled
103
 
103
 
104
/* TT = 0x21, TL = 0, fb_exception_ieee_754 handler */
104
/* TT = 0x21, TL = 0, fb_exception_ieee_754 handler */
105
.org trap_table + TT_FP_EXCEPTION_IEEE_754*ENTRY_SIZE
105
.org trap_table + TT_FP_EXCEPTION_IEEE_754*ENTRY_SIZE
106
.global fb_exception_ieee_754_tl0
106
.global fb_exception_ieee_754_tl0
107
fp_exception_ieee_754_tl0:
107
fp_exception_ieee_754_tl0:
108
	PREEMPTIBLE_HANDLER fp_exception_ieee_754
108
	PREEMPTIBLE_HANDLER fp_exception_ieee_754
109
 
109
 
110
/* TT = 0x22, TL = 0, fb_exception_other handler */
110
/* TT = 0x22, TL = 0, fb_exception_other handler */
111
.org trap_table + TT_FP_EXCEPTION_OTHER*ENTRY_SIZE
111
.org trap_table + TT_FP_EXCEPTION_OTHER*ENTRY_SIZE
112
.global fb_exception_other_tl0
112
.global fb_exception_other_tl0
113
fp_exception_other_tl0:
113
fp_exception_other_tl0:
114
	PREEMPTIBLE_HANDLER fp_exception_other
114
	PREEMPTIBLE_HANDLER fp_exception_other
115
 
115
 
116
/* TT = 0x23, TL = 0, tag_overflow */
116
/* TT = 0x23, TL = 0, tag_overflow */
117
.org trap_table + TT_TAG_OVERFLOW*ENTRY_SIZE
117
.org trap_table + TT_TAG_OVERFLOW*ENTRY_SIZE
118
.global tag_overflow_tl0
118
.global tag_overflow_tl0
119
tag_overflow_tl0:
119
tag_overflow_tl0:
120
	PREEMPTIBLE_HANDLER tag_overflow
120
	PREEMPTIBLE_HANDLER tag_overflow
121
 
121
 
122
/* TT = 0x24, TL = 0, clean_window handler */
122
/* TT = 0x24, TL = 0, clean_window handler */
123
.org trap_table + TT_CLEAN_WINDOW*ENTRY_SIZE
123
.org trap_table + TT_CLEAN_WINDOW*ENTRY_SIZE
124
.global clean_window_tl0
124
.global clean_window_tl0
125
clean_window_tl0:
125
clean_window_tl0:
126
	CLEAN_WINDOW_HANDLER
126
	CLEAN_WINDOW_HANDLER
127
 
127
 
128
/* TT = 0x28, TL = 0, division_by_zero */
128
/* TT = 0x28, TL = 0, division_by_zero */
129
.org trap_table + TT_DIVISION_BY_ZERO*ENTRY_SIZE
129
.org trap_table + TT_DIVISION_BY_ZERO*ENTRY_SIZE
130
.global division_by_zero_tl0
130
.global division_by_zero_tl0
131
division_by_zero_tl0:
131
division_by_zero_tl0:
132
	PREEMPTIBLE_HANDLER division_by_zero
132
	PREEMPTIBLE_HANDLER division_by_zero
133
 
133
 
134
/* TT = 0x30, TL = 0, data_access_exception */
134
/* TT = 0x30, TL = 0, data_access_exception */
135
.org trap_table + TT_DATA_ACCESS_EXCEPTION*ENTRY_SIZE
135
.org trap_table + TT_DATA_ACCESS_EXCEPTION*ENTRY_SIZE
136
.global data_access_exception_tl0
136
.global data_access_exception_tl0
137
data_access_exception_tl0:
137
data_access_exception_tl0:
138
	/*wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
138
	/*wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
139
	PREEMPTIBLE_HANDLER data_access_exception*/
139
	PREEMPTIBLE_HANDLER data_access_exception*/
140
 
140
 
141
/* TT = 0x32, TL = 0, data_access_error */
141
/* TT = 0x32, TL = 0, data_access_error */
142
.org trap_table + TT_DATA_ACCESS_ERROR*ENTRY_SIZE
142
.org trap_table + TT_DATA_ACCESS_ERROR*ENTRY_SIZE
143
.global data_access_error_tl0
143
.global data_access_error_tl0
144
data_access_error_tl0:
144
data_access_error_tl0:
145
	PREEMPTIBLE_HANDLER data_access_error
145
	PREEMPTIBLE_HANDLER data_access_error
146
 
146
 
147
/* TT = 0x34, TL = 0, mem_address_not_aligned */
147
/* TT = 0x34, TL = 0, mem_address_not_aligned */
148
.org trap_table + TT_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
148
.org trap_table + TT_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
149
.global mem_address_not_aligned_tl0
149
.global mem_address_not_aligned_tl0
150
mem_address_not_aligned_tl0:
150
mem_address_not_aligned_tl0:
151
	PREEMPTIBLE_HANDLER mem_address_not_aligned
151
	PREEMPTIBLE_HANDLER mem_address_not_aligned
152
 
152
 
153
/* TT = 0x35, TL = 0, LDDF_mem_address_not_aligned */
153
/* TT = 0x35, TL = 0, LDDF_mem_address_not_aligned */
154
.org trap_table + TT_LDDF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
154
.org trap_table + TT_LDDF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
155
.global LDDF_mem_address_not_aligned_tl0
155
.global LDDF_mem_address_not_aligned_tl0
156
LDDF_mem_address_not_aligned_tl0:
156
LDDF_mem_address_not_aligned_tl0:
157
	PREEMPTIBLE_HANDLER LDDF_mem_address_not_aligned
157
	PREEMPTIBLE_HANDLER LDDF_mem_address_not_aligned
158
 
158
 
159
/* TT = 0x36, TL = 0, STDF_mem_address_not_aligned */
159
/* TT = 0x36, TL = 0, STDF_mem_address_not_aligned */
160
.org trap_table + TT_STDF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
160
.org trap_table + TT_STDF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
161
.global STDF_mem_address_not_aligned_tl0
161
.global STDF_mem_address_not_aligned_tl0
162
STDF_mem_address_not_aligned_tl0:
162
STDF_mem_address_not_aligned_tl0:
163
	PREEMPTIBLE_HANDLER STDF_mem_address_not_aligned
163
	PREEMPTIBLE_HANDLER STDF_mem_address_not_aligned
164
 
164
 
165
/* TT = 0x37, TL = 0, privileged_action */
165
/* TT = 0x37, TL = 0, privileged_action */
166
.org trap_table + TT_PRIVILEGED_ACTION*ENTRY_SIZE
166
.org trap_table + TT_PRIVILEGED_ACTION*ENTRY_SIZE
167
.global privileged_action_tl0
167
.global privileged_action_tl0
168
privileged_action_tl0:
168
privileged_action_tl0:
169
	PREEMPTIBLE_HANDLER privileged_action
169
	PREEMPTIBLE_HANDLER privileged_action
170
 
170
 
171
/* TT = 0x38, TL = 0, LDQF_mem_address_not_aligned */
171
/* TT = 0x38, TL = 0, LDQF_mem_address_not_aligned */
172
.org trap_table + TT_LDQF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
172
.org trap_table + TT_LDQF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
173
.global LDQF_mem_address_not_aligned_tl0
173
.global LDQF_mem_address_not_aligned_tl0
174
LDQF_mem_address_not_aligned_tl0:
174
LDQF_mem_address_not_aligned_tl0:
175
	PREEMPTIBLE_HANDLER LDQF_mem_address_not_aligned
175
	PREEMPTIBLE_HANDLER LDQF_mem_address_not_aligned
176
 
176
 
177
/* TT = 0x39, TL = 0, STQF_mem_address_not_aligned */
177
/* TT = 0x39, TL = 0, STQF_mem_address_not_aligned */
178
.org trap_table + TT_STQF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
178
.org trap_table + TT_STQF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
179
.global STQF_mem_address_not_aligned_tl0
179
.global STQF_mem_address_not_aligned_tl0
180
STQF_mem_address_not_aligned_tl0:
180
STQF_mem_address_not_aligned_tl0:
181
	PREEMPTIBLE_HANDLER STQF_mem_address_not_aligned
181
	PREEMPTIBLE_HANDLER STQF_mem_address_not_aligned
182
 
182
 
183
/* TT = 0x41, TL = 0, interrupt_level_1 handler */
183
/* TT = 0x41, TL = 0, interrupt_level_1 handler */
184
.org trap_table + TT_INTERRUPT_LEVEL_1*ENTRY_SIZE
184
.org trap_table + TT_INTERRUPT_LEVEL_1*ENTRY_SIZE
185
.global interrupt_level_1_handler_tl0
185
.global interrupt_level_1_handler_tl0
186
interrupt_level_1_handler_tl0:
186
interrupt_level_1_handler_tl0:
187
	INTERRUPT_LEVEL_N_HANDLER 1
187
	INTERRUPT_LEVEL_N_HANDLER 1
188
 
188
 
189
/* TT = 0x42, TL = 0, interrupt_level_2 handler */
189
/* TT = 0x42, TL = 0, interrupt_level_2 handler */
190
.org trap_table + TT_INTERRUPT_LEVEL_2*ENTRY_SIZE
190
.org trap_table + TT_INTERRUPT_LEVEL_2*ENTRY_SIZE
191
.global interrupt_level_2_handler_tl0
191
.global interrupt_level_2_handler_tl0
192
interrupt_level_2_handler_tl0:
192
interrupt_level_2_handler_tl0:
193
	INTERRUPT_LEVEL_N_HANDLER 2
193
	INTERRUPT_LEVEL_N_HANDLER 2
194
 
194
 
195
/* TT = 0x43, TL = 0, interrupt_level_3 handler */
195
/* TT = 0x43, TL = 0, interrupt_level_3 handler */
196
.org trap_table + TT_INTERRUPT_LEVEL_3*ENTRY_SIZE
196
.org trap_table + TT_INTERRUPT_LEVEL_3*ENTRY_SIZE
197
.global interrupt_level_3_handler_tl0
197
.global interrupt_level_3_handler_tl0
198
interrupt_level_3_handler_tl0:
198
interrupt_level_3_handler_tl0:
199
	INTERRUPT_LEVEL_N_HANDLER 3
199
	INTERRUPT_LEVEL_N_HANDLER 3
200
 
200
 
201
/* TT = 0x44, TL = 0, interrupt_level_4 handler */
201
/* TT = 0x44, TL = 0, interrupt_level_4 handler */
202
.org trap_table + TT_INTERRUPT_LEVEL_4*ENTRY_SIZE
202
.org trap_table + TT_INTERRUPT_LEVEL_4*ENTRY_SIZE
203
.global interrupt_level_4_handler_tl0
203
.global interrupt_level_4_handler_tl0
204
interrupt_level_4_handler_tl0:
204
interrupt_level_4_handler_tl0:
205
	INTERRUPT_LEVEL_N_HANDLER 4
205
	INTERRUPT_LEVEL_N_HANDLER 4
206
 
206
 
207
/* TT = 0x45, TL = 0, interrupt_level_5 handler */
207
/* TT = 0x45, TL = 0, interrupt_level_5 handler */
208
.org trap_table + TT_INTERRUPT_LEVEL_5*ENTRY_SIZE
208
.org trap_table + TT_INTERRUPT_LEVEL_5*ENTRY_SIZE
209
.global interrupt_level_5_handler_tl0
209
.global interrupt_level_5_handler_tl0
210
interrupt_level_5_handler_tl0:
210
interrupt_level_5_handler_tl0:
211
	INTERRUPT_LEVEL_N_HANDLER 5
211
	INTERRUPT_LEVEL_N_HANDLER 5
212
 
212
 
213
/* TT = 0x46, TL = 0, interrupt_level_6 handler */
213
/* TT = 0x46, TL = 0, interrupt_level_6 handler */
214
.org trap_table + TT_INTERRUPT_LEVEL_6*ENTRY_SIZE
214
.org trap_table + TT_INTERRUPT_LEVEL_6*ENTRY_SIZE
215
.global interrupt_level_6_handler_tl0
215
.global interrupt_level_6_handler_tl0
216
interrupt_level_6_handler_tl0:
216
interrupt_level_6_handler_tl0:
217
	INTERRUPT_LEVEL_N_HANDLER 6
217
	INTERRUPT_LEVEL_N_HANDLER 6
218
 
218
 
219
/* TT = 0x47, TL = 0, interrupt_level_7 handler */
219
/* TT = 0x47, TL = 0, interrupt_level_7 handler */
220
.org trap_table + TT_INTERRUPT_LEVEL_7*ENTRY_SIZE
220
.org trap_table + TT_INTERRUPT_LEVEL_7*ENTRY_SIZE
221
.global interrupt_level_7_handler_tl0
221
.global interrupt_level_7_handler_tl0
222
interrupt_level_7_handler_tl0:
222
interrupt_level_7_handler_tl0:
223
	INTERRUPT_LEVEL_N_HANDLER 7
223
	INTERRUPT_LEVEL_N_HANDLER 7
224
 
224
 
225
/* TT = 0x48, TL = 0, interrupt_level_8 handler */
225
/* TT = 0x48, TL = 0, interrupt_level_8 handler */
226
.org trap_table + TT_INTERRUPT_LEVEL_8*ENTRY_SIZE
226
.org trap_table + TT_INTERRUPT_LEVEL_8*ENTRY_SIZE
227
.global interrupt_level_8_handler_tl0
227
.global interrupt_level_8_handler_tl0
228
interrupt_level_8_handler_tl0:
228
interrupt_level_8_handler_tl0:
229
	INTERRUPT_LEVEL_N_HANDLER 8
229
	INTERRUPT_LEVEL_N_HANDLER 8
230
 
230
 
231
/* TT = 0x49, TL = 0, interrupt_level_9 handler */
231
/* TT = 0x49, TL = 0, interrupt_level_9 handler */
232
.org trap_table + TT_INTERRUPT_LEVEL_9*ENTRY_SIZE
232
.org trap_table + TT_INTERRUPT_LEVEL_9*ENTRY_SIZE
233
.global interrupt_level_9_handler_tl0
233
.global interrupt_level_9_handler_tl0
234
interrupt_level_9_handler_tl0:
234
interrupt_level_9_handler_tl0:
235
	INTERRUPT_LEVEL_N_HANDLER 9
235
	INTERRUPT_LEVEL_N_HANDLER 9
236
 
236
 
237
/* TT = 0x4a, TL = 0, interrupt_level_10 handler */
237
/* TT = 0x4a, TL = 0, interrupt_level_10 handler */
238
.org trap_table + TT_INTERRUPT_LEVEL_10*ENTRY_SIZE
238
.org trap_table + TT_INTERRUPT_LEVEL_10*ENTRY_SIZE
239
.global interrupt_level_10_handler_tl0
239
.global interrupt_level_10_handler_tl0
240
interrupt_level_10_handler_tl0:
240
interrupt_level_10_handler_tl0:
241
	INTERRUPT_LEVEL_N_HANDLER 10
241
	INTERRUPT_LEVEL_N_HANDLER 10
242
 
242
 
243
/* TT = 0x4b, TL = 0, interrupt_level_11 handler */
243
/* TT = 0x4b, TL = 0, interrupt_level_11 handler */
244
.org trap_table + TT_INTERRUPT_LEVEL_11*ENTRY_SIZE
244
.org trap_table + TT_INTERRUPT_LEVEL_11*ENTRY_SIZE
245
.global interrupt_level_11_handler_tl0
245
.global interrupt_level_11_handler_tl0
246
interrupt_level_11_handler_tl0:
246
interrupt_level_11_handler_tl0:
247
	INTERRUPT_LEVEL_N_HANDLER 11
247
	INTERRUPT_LEVEL_N_HANDLER 11
248
 
248
 
249
/* TT = 0x4c, TL = 0, interrupt_level_12 handler */
249
/* TT = 0x4c, TL = 0, interrupt_level_12 handler */
250
.org trap_table + TT_INTERRUPT_LEVEL_12*ENTRY_SIZE
250
.org trap_table + TT_INTERRUPT_LEVEL_12*ENTRY_SIZE
251
.global interrupt_level_12_handler_tl0
251
.global interrupt_level_12_handler_tl0
252
interrupt_level_12_handler_tl0:
252
interrupt_level_12_handler_tl0:
253
	INTERRUPT_LEVEL_N_HANDLER 12
253
	INTERRUPT_LEVEL_N_HANDLER 12
254
 
254
 
255
/* TT = 0x4d, TL = 0, interrupt_level_13 handler */
255
/* TT = 0x4d, TL = 0, interrupt_level_13 handler */
256
.org trap_table + TT_INTERRUPT_LEVEL_13*ENTRY_SIZE
256
.org trap_table + TT_INTERRUPT_LEVEL_13*ENTRY_SIZE
257
.global interrupt_level_13_handler_tl0
257
.global interrupt_level_13_handler_tl0
258
interrupt_level_13_handler_tl0:
258
interrupt_level_13_handler_tl0:
259
	INTERRUPT_LEVEL_N_HANDLER 13
259
	INTERRUPT_LEVEL_N_HANDLER 13
260
 
260
 
261
/* TT = 0x4e, TL = 0, interrupt_level_14 handler */
261
/* TT = 0x4e, TL = 0, interrupt_level_14 handler */
262
.org trap_table + TT_INTERRUPT_LEVEL_14*ENTRY_SIZE
262
.org trap_table + TT_INTERRUPT_LEVEL_14*ENTRY_SIZE
263
.global interrupt_level_14_handler_tl0
263
.global interrupt_level_14_handler_tl0
264
interrupt_level_14_handler_tl0:
264
interrupt_level_14_handler_tl0:
265
	INTERRUPT_LEVEL_N_HANDLER 14
265
	INTERRUPT_LEVEL_N_HANDLER 14
266
 
266
 
267
/* TT = 0x4f, TL = 0, interrupt_level_15 handler */
267
/* TT = 0x4f, TL = 0, interrupt_level_15 handler */
268
.org trap_table + TT_INTERRUPT_LEVEL_15*ENTRY_SIZE
268
.org trap_table + TT_INTERRUPT_LEVEL_15*ENTRY_SIZE
269
.global interrupt_level_15_handler_tl0
269
.global interrupt_level_15_handler_tl0
270
interrupt_level_15_handler_tl0:
270
interrupt_level_15_handler_tl0:
271
	INTERRUPT_LEVEL_N_HANDLER 15
271
	INTERRUPT_LEVEL_N_HANDLER 15
272
 
272
 
273
/* TT = 0x60, TL = 0, interrupt_vector_trap handler */
273
/* TT = 0x60, TL = 0, interrupt_vector_trap handler */
274
.org trap_table + TT_INTERRUPT_VECTOR_TRAP*ENTRY_SIZE
274
.org trap_table + TT_INTERRUPT_VECTOR_TRAP*ENTRY_SIZE
275
.global interrupt_vector_trap_handler_tl0
275
.global interrupt_vector_trap_handler_tl0
276
interrupt_vector_trap_handler_tl0:
276
interrupt_vector_trap_handler_tl0:
277
	INTERRUPT_VECTOR_TRAP_HANDLER
277
	INTERRUPT_VECTOR_TRAP_HANDLER
278
 
278
 
279
/* TT = 0x64, TL = 0, fast_instruction_access_MMU_miss */
279
/* TT = 0x64, TL = 0, fast_instruction_access_MMU_miss */
280
.org trap_table + TT_FAST_INSTRUCTION_ACCESS_MMU_MISS*ENTRY_SIZE
280
.org trap_table + TT_FAST_INSTRUCTION_ACCESS_MMU_MISS*ENTRY_SIZE
281
.global fast_instruction_access_mmu_miss_handler_tl0
281
.global fast_instruction_access_mmu_miss_handler_tl0
282
fast_instruction_access_mmu_miss_handler_tl0:
282
fast_instruction_access_mmu_miss_handler_tl0:
283
	/*FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER*/
283
	/*FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER*/
284
 
284
 
285
/* TT = 0x68, TL = 0, fast_data_access_MMU_miss */
285
/* TT = 0x68, TL = 0, fast_data_access_MMU_miss */
286
.org trap_table + TT_FAST_DATA_ACCESS_MMU_MISS*ENTRY_SIZE
286
.org trap_table + TT_FAST_DATA_ACCESS_MMU_MISS*ENTRY_SIZE
287
.global fast_data_access_mmu_miss_handler_tl0
287
.global fast_data_access_mmu_miss_handler_tl0
288
fast_data_access_mmu_miss_handler_tl0:
288
fast_data_access_mmu_miss_handler_tl0:
289
	FAST_DATA_ACCESS_MMU_MISS_HANDLER 0
289
	FAST_DATA_ACCESS_MMU_MISS_HANDLER 0
290
 
290
 
291
/* TT = 0x6c, TL = 0, fast_data_access_protection */
291
/* TT = 0x6c, TL = 0, fast_data_access_protection */
292
.org trap_table + TT_FAST_DATA_ACCESS_PROTECTION*ENTRY_SIZE
292
.org trap_table + TT_FAST_DATA_ACCESS_PROTECTION*ENTRY_SIZE
293
.global fast_data_access_protection_handler_tl0
293
.global fast_data_access_protection_handler_tl0
294
fast_data_access_protection_handler_tl0:
294
fast_data_access_protection_handler_tl0:
295
	/*FAST_DATA_ACCESS_PROTECTION_HANDLER 0*/
295
	/*FAST_DATA_ACCESS_PROTECTION_HANDLER 0*/
296
 
296
 
297
/* TT = 0x80, TL = 0, spill_0_normal handler */
297
/* TT = 0x80, TL = 0, spill_0_normal handler */
298
.org trap_table + TT_SPILL_0_NORMAL*ENTRY_SIZE
298
.org trap_table + TT_SPILL_0_NORMAL*ENTRY_SIZE
299
.global spill_0_normal_tl0
299
.global spill_0_normal_tl0
300
spill_0_normal_tl0:
300
spill_0_normal_tl0:
301
	SPILL_NORMAL_HANDLER_KERNEL
301
	SPILL_NORMAL_HANDLER_KERNEL
302
 
302
 
303
/* TT = 0x84, TL = 0, spill_1_normal handler */
303
/* TT = 0x84, TL = 0, spill_1_normal handler */
304
.org trap_table + TT_SPILL_1_NORMAL*ENTRY_SIZE
304
.org trap_table + TT_SPILL_1_NORMAL*ENTRY_SIZE
305
.global spill_1_normal_tl0
305
.global spill_1_normal_tl0
306
spill_1_normal_tl0:
306
spill_1_normal_tl0:
307
	SPILL_NORMAL_HANDLER_USERSPACE
307
	SPILL_NORMAL_HANDLER_USERSPACE
308
 
308
 
309
/* TT = 0x88, TL = 0, spill_2_normal handler */
309
/* TT = 0x88, TL = 0, spill_2_normal handler */
310
.org trap_table + TT_SPILL_2_NORMAL*ENTRY_SIZE
310
.org trap_table + TT_SPILL_2_NORMAL*ENTRY_SIZE
311
.global spill_2_normal_tl0
311
.global spill_2_normal_tl0
312
spill_2_normal_tl0:
312
spill_2_normal_tl0:
313
	SPILL_TO_USPACE_WINDOW_BUFFER
313
	SPILL_TO_USPACE_WINDOW_BUFFER
314
 
314
 
315
/* TT = 0xa0, TL = 0, spill_0_other handler */
315
/* TT = 0xa0, TL = 0, spill_0_other handler */
316
.org trap_table + TT_SPILL_0_OTHER*ENTRY_SIZE
316
.org trap_table + TT_SPILL_0_OTHER*ENTRY_SIZE
317
.global spill_0_other_tl0
317
.global spill_0_other_tl0
318
spill_0_other_tl0:
318
spill_0_other_tl0:
319
	SPILL_TO_USPACE_WINDOW_BUFFER
319
	SPILL_TO_USPACE_WINDOW_BUFFER
320
 
320
 
321
/* TT = 0xc0, TL = 0, fill_0_normal handler */
321
/* TT = 0xc0, TL = 0, fill_0_normal handler */
322
.org trap_table + TT_FILL_0_NORMAL*ENTRY_SIZE
322
.org trap_table + TT_FILL_0_NORMAL*ENTRY_SIZE
323
.global fill_0_normal_tl0
323
.global fill_0_normal_tl0
324
fill_0_normal_tl0:
324
fill_0_normal_tl0:
325
	FILL_NORMAL_HANDLER_KERNEL
325
	FILL_NORMAL_HANDLER_KERNEL
326
 
326
 
327
/* TT = 0xc4, TL = 0, fill_1_normal handler */
327
/* TT = 0xc4, TL = 0, fill_1_normal handler */
328
.org trap_table + TT_FILL_1_NORMAL*ENTRY_SIZE
328
.org trap_table + TT_FILL_1_NORMAL*ENTRY_SIZE
329
.global fill_1_normal_tl0
329
.global fill_1_normal_tl0
330
fill_1_normal_tl0:
330
fill_1_normal_tl0:
331
	FILL_NORMAL_HANDLER_USERSPACE
331
	FILL_NORMAL_HANDLER_USERSPACE
332
 
332
 
333
/* TT = 0x100 - 0x17f, TL = 0, trap_instruction_0 - trap_instruction_7f */
333
/* TT = 0x100 - 0x17f, TL = 0, trap_instruction_0 - trap_instruction_7f */
334
.irp cur, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\
334
.irp cur, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\
335
    20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,\
335
    20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,\
336
    39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,\
336
    39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,\
337
    58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,\
337
    58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,\
338
    77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,\
338
    77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,\
339
    96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,\
339
    96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,\
340
    112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,\
340
    112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,\
341
    127
341
    127
342
.org trap_table + (TT_TRAP_INSTRUCTION_0+\cur)*ENTRY_SIZE
342
.org trap_table + (TT_TRAP_INSTRUCTION_0+\cur)*ENTRY_SIZE
343
.global trap_instruction_\cur\()_tl0
343
.global trap_instruction_\cur\()_tl0
344
trap_instruction_\cur\()_tl0:
344
trap_instruction_\cur\()_tl0:
345
	ba trap_instruction_handler
345
	ba trap_instruction_handler
346
	mov \cur, %g2
346
	mov \cur, %g2
347
.endr
347
.endr
348
 
348
 
349
/*
349
/*
350
 * Handlers for TL>0.
350
 * Handlers for TL>0.
351
 */
351
 */
352
 
352
 
353
/* TT = 0x08, TL > 0, instruction_access_exception */
353
/* TT = 0x08, TL > 0, instruction_access_exception */
354
.org trap_table + (TT_INSTRUCTION_ACCESS_EXCEPTION+512)*ENTRY_SIZE
354
.org trap_table + (TT_INSTRUCTION_ACCESS_EXCEPTION+512)*ENTRY_SIZE
355
.global instruction_access_exception_tl1
355
.global instruction_access_exception_tl1
356
instruction_access_exception_tl1:
356
instruction_access_exception_tl1:
357
	/*wrpr %g0, 1, %tl
357
	/*wrpr %g0, 1, %tl
358
	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
358
	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
359
	PREEMPTIBLE_HANDLER instruction_access_exception*/
359
	PREEMPTIBLE_HANDLER instruction_access_exception*/
360
 
360
 
361
/* TT = 0x0a, TL > 0, instruction_access_error */
361
/* TT = 0x0a, TL > 0, instruction_access_error */
362
.org trap_table + (TT_INSTRUCTION_ACCESS_ERROR+512)*ENTRY_SIZE
362
.org trap_table + (TT_INSTRUCTION_ACCESS_ERROR+512)*ENTRY_SIZE
363
.global instruction_access_error_tl1
363
.global instruction_access_error_tl1
364
instruction_access_error_tl1:
364
instruction_access_error_tl1:
365
	wrpr %g0, 1, %tl
365
	wrpr %g0, 1, %tl
366
	PREEMPTIBLE_HANDLER instruction_access_error
366
	PREEMPTIBLE_HANDLER instruction_access_error
367
 
367
 
368
/* TT = 0x10, TL > 0, illegal_instruction */
368
/* TT = 0x10, TL > 0, illegal_instruction */
369
.org trap_table + (TT_ILLEGAL_INSTRUCTION+512)*ENTRY_SIZE
369
.org trap_table + (TT_ILLEGAL_INSTRUCTION+512)*ENTRY_SIZE
370
.global illegal_instruction_tl1
370
.global illegal_instruction_tl1
371
illegal_instruction_tl1:
371
illegal_instruction_tl1:
372
	wrpr %g0, 1, %tl
372
	wrpr %g0, 1, %tl
373
	PREEMPTIBLE_HANDLER illegal_instruction
373
	PREEMPTIBLE_HANDLER illegal_instruction
374
 
374
 
375
/* TT = 0x24, TL > 0, clean_window handler */
375
/* TT = 0x24, TL > 0, clean_window handler */
376
.org trap_table + (TT_CLEAN_WINDOW+512)*ENTRY_SIZE
376
.org trap_table + (TT_CLEAN_WINDOW+512)*ENTRY_SIZE
377
.global clean_window_tl1
377
.global clean_window_tl1
378
clean_window_tl1:
378
clean_window_tl1:
379
	CLEAN_WINDOW_HANDLER
379
	CLEAN_WINDOW_HANDLER
380
 
380
 
381
/* TT = 0x28, TL > 0, division_by_zero */
381
/* TT = 0x28, TL > 0, division_by_zero */
382
.org trap_table + (TT_DIVISION_BY_ZERO+512)*ENTRY_SIZE
382
.org trap_table + (TT_DIVISION_BY_ZERO+512)*ENTRY_SIZE
383
.global division_by_zero_tl1
383
.global division_by_zero_tl1
384
division_by_zero_tl1:
384
division_by_zero_tl1:
385
	wrpr %g0, 1, %tl
385
	wrpr %g0, 1, %tl
386
	PREEMPTIBLE_HANDLER division_by_zero
386
	PREEMPTIBLE_HANDLER division_by_zero
387
 
387
 
388
/* TT = 0x30, TL > 0, data_access_exception */
388
/* TT = 0x30, TL > 0, data_access_exception */
389
.org trap_table + (TT_DATA_ACCESS_EXCEPTION+512)*ENTRY_SIZE
389
.org trap_table + (TT_DATA_ACCESS_EXCEPTION+512)*ENTRY_SIZE
390
.global data_access_exception_tl1
390
.global data_access_exception_tl1
391
data_access_exception_tl1:
391
data_access_exception_tl1:
392
	/*wrpr %g0, 1, %tl
392
	/*wrpr %g0, 1, %tl
393
	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
393
	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
394
	PREEMPTIBLE_HANDLER data_access_exception*/
394
	PREEMPTIBLE_HANDLER data_access_exception*/
395
 
395
 
396
/* TT = 0x32, TL > 0, data_access_error */
396
/* TT = 0x32, TL > 0, data_access_error */
397
.org trap_table + (TT_DATA_ACCESS_ERROR+512)*ENTRY_SIZE
397
.org trap_table + (TT_DATA_ACCESS_ERROR+512)*ENTRY_SIZE
398
.global data_access_error_tl1
398
.global data_access_error_tl1
399
data_access_error_tl1:
399
data_access_error_tl1:
400
	wrpr %g0, 1, %tl
400
	wrpr %g0, 1, %tl
401
	PREEMPTIBLE_HANDLER data_access_error
401
	PREEMPTIBLE_HANDLER data_access_error
402
 
402
 
403
/* TT = 0x34, TL > 0, mem_address_not_aligned */
403
/* TT = 0x34, TL > 0, mem_address_not_aligned */
404
.org trap_table + (TT_MEM_ADDRESS_NOT_ALIGNED+512)*ENTRY_SIZE
404
.org trap_table + (TT_MEM_ADDRESS_NOT_ALIGNED+512)*ENTRY_SIZE
405
.global mem_address_not_aligned_tl1
405
.global mem_address_not_aligned_tl1
406
mem_address_not_aligned_tl1:
406
mem_address_not_aligned_tl1:
407
	wrpr %g0, 1, %tl
407
	wrpr %g0, 1, %tl
408
	PREEMPTIBLE_HANDLER mem_address_not_aligned
408
	PREEMPTIBLE_HANDLER mem_address_not_aligned
409
 
409
 
410
/* TT = 0x68, TL > 0, fast_data_access_MMU_miss */
410
/* TT = 0x68, TL > 0, fast_data_access_MMU_miss */
411
.org trap_table + (TT_FAST_DATA_ACCESS_MMU_MISS+512)*ENTRY_SIZE
411
.org trap_table + (TT_FAST_DATA_ACCESS_MMU_MISS+512)*ENTRY_SIZE
412
.global fast_data_access_mmu_miss_handler_tl1
412
.global fast_data_access_mmu_miss_handler_tl1
413
fast_data_access_mmu_miss_handler_tl1:
413
fast_data_access_mmu_miss_handler_tl1:
414
	FAST_DATA_ACCESS_MMU_MISS_HANDLER 1
414
	FAST_DATA_ACCESS_MMU_MISS_HANDLER 1
415
 
415
 
416
/* TT = 0x6c, TL > 0, fast_data_access_protection */
416
/* TT = 0x6c, TL > 0, fast_data_access_protection */
417
.org trap_table + (TT_FAST_DATA_ACCESS_PROTECTION+512)*ENTRY_SIZE
417
.org trap_table + (TT_FAST_DATA_ACCESS_PROTECTION+512)*ENTRY_SIZE
418
.global fast_data_access_protection_handler_tl1
418
.global fast_data_access_protection_handler_tl1
419
fast_data_access_protection_handler_tl1:
419
fast_data_access_protection_handler_tl1:
420
	/*FAST_DATA_ACCESS_PROTECTION_HANDLER 1*/
420
	/*FAST_DATA_ACCESS_PROTECTION_HANDLER 1*/
421
 
421
 
422
/* TT = 0x80, TL > 0, spill_0_normal handler */
422
/* TT = 0x80, TL > 0, spill_0_normal handler */
423
.org trap_table + (TT_SPILL_0_NORMAL+512)*ENTRY_SIZE
423
.org trap_table + (TT_SPILL_0_NORMAL+512)*ENTRY_SIZE
424
.global spill_0_normal_tl1
424
.global spill_0_normal_tl1
425
spill_0_normal_tl1:
425
spill_0_normal_tl1:
426
	SPILL_NORMAL_HANDLER_KERNEL
426
	SPILL_NORMAL_HANDLER_KERNEL
427
 
427
 
428
/* TT = 0x88, TL > 0, spill_2_normal handler */
428
/* TT = 0x88, TL > 0, spill_2_normal handler */
429
.org trap_table + (TT_SPILL_2_NORMAL+512)*ENTRY_SIZE
429
.org trap_table + (TT_SPILL_2_NORMAL+512)*ENTRY_SIZE
430
.global spill_2_normal_tl1
430
.global spill_2_normal_tl1
431
spill_2_normal_tl1:
431
spill_2_normal_tl1:
432
	SPILL_TO_USPACE_WINDOW_BUFFER
432
	SPILL_TO_USPACE_WINDOW_BUFFER
433
 
433
 
434
/* TT = 0xa0, TL > 0, spill_0_other handler */
434
/* TT = 0xa0, TL > 0, spill_0_other handler */
435
.org trap_table + (TT_SPILL_0_OTHER+512)*ENTRY_SIZE
435
.org trap_table + (TT_SPILL_0_OTHER+512)*ENTRY_SIZE
436
.global spill_0_other_tl1
436
.global spill_0_other_tl1
437
spill_0_other_tl1:
437
spill_0_other_tl1:
438
	SPILL_TO_USPACE_WINDOW_BUFFER
438
	SPILL_TO_USPACE_WINDOW_BUFFER
439
 
439
 
440
/* TT = 0xc0, TL > 0, fill_0_normal handler */
440
/* TT = 0xc0, TL > 0, fill_0_normal handler */
441
.org trap_table + (TT_FILL_0_NORMAL+512)*ENTRY_SIZE
441
.org trap_table + (TT_FILL_0_NORMAL+512)*ENTRY_SIZE
442
.global fill_0_normal_tl1
442
.global fill_0_normal_tl1
443
fill_0_normal_tl1:
443
fill_0_normal_tl1:
444
	FILL_NORMAL_HANDLER_KERNEL
444
	FILL_NORMAL_HANDLER_KERNEL
445
 
445
 
446
.align TABLE_SIZE
446
.align TABLE_SIZE
447
 
447
 
448
 
448
 
-
 
449
/*
-
 
450
 * Spills the window at CWP + 2 to the kernel stack. This macro is to be
-
 
451
 * used before doing SAVE when the spill trap is undesirable.
-
 
452
 */
-
 
453
.macro INLINE_SPILL
-
 
454
	! CWP := CWP + 2
-
 
455
	rdpr %cwp, %g3
-
 
456
	add %g3, 2, %g3
-
 
457
	and %g3, NWINDOWS - 1, %g3		! modulo NWINDOWS
-
 
458
	wrpr %g3, %cwp
-
 
459
	
-
 
460
	! spill to kernel stack
-
 
461
	stx %l0, [%sp + STACK_BIAS + L0_OFFSET]	
-
 
462
	stx %l1, [%sp + STACK_BIAS + L1_OFFSET]
-
 
463
	stx %l2, [%sp + STACK_BIAS + L2_OFFSET]
-
 
464
	stx %l3, [%sp + STACK_BIAS + L3_OFFSET]
-
 
465
	stx %l4, [%sp + STACK_BIAS + L4_OFFSET]
-
 
466
	stx %l5, [%sp + STACK_BIAS + L5_OFFSET]
-
 
467
	stx %l6, [%sp + STACK_BIAS + L6_OFFSET]
-
 
468
	stx %l7, [%sp + STACK_BIAS + L7_OFFSET]
-
 
469
	stx %i0, [%sp + STACK_BIAS + I0_OFFSET]
-
 
470
	stx %i1, [%sp + STACK_BIAS + I1_OFFSET]
-
 
471
	stx %i2, [%sp + STACK_BIAS + I2_OFFSET]
-
 
472
	stx %i3, [%sp + STACK_BIAS + I3_OFFSET]
-
 
473
	stx %i4, [%sp + STACK_BIAS + I4_OFFSET]
-
 
474
	stx %i5, [%sp + STACK_BIAS + I5_OFFSET]
-
 
475
	stx %i6, [%sp + STACK_BIAS + I6_OFFSET]
-
 
476
	stx %i7, [%sp + STACK_BIAS + I7_OFFSET]
-
 
477
 
-
 
478
	! CWP := CWP - 2
449
#define NOT(x)	((x) == 0)
479
	add %g3, NWINDOWS - 2, %g3
-
 
480
	and %g3, NWINDOWS - 1, %g3		! modulo NWINDOWS
-
 
481
	wrpr %g3, %cwp
450
 
482
 
451
/* Preemptible trap handler for TL=1.
-
 
452
 *
-
 
453
 * This trap handler makes arrangements to make calling of scheduler() from
-
 
454
 * within a trap context possible. It is called from several other trap
-
 
455
 * handlers.
483
	saved
456
 *
484
.endm
457
 * This function can be entered either with interrupt globals or alternate
-
 
458
 * globals. Memory management trap handlers are obliged to switch to one of
-
 
459
 * those global sets prior to calling this function. Register window management
-
 
460
 * functions are not allowed to modify the alternate global registers.
-
 
461
 *
485
 
462
 * The kernel is designed to work on trap levels 0 - 4. For instance, the
-
 
463
 * following can happen:
-
 
464
 * TL0: kernel thread runs (CANSAVE=0, kernel stack not in DTLB)
-
 
465
 * TL1: preemptible trap handler started after a tick interrupt
-
 
466
 * TL2: preemptible trap handler did SAVE
-
 
467
 * TL3: spill handler touched the kernel stack  
-
 
468
 * TL4: hardware or software failure
-
 
469
 *
486
/*
470
 * Input registers:
-
 
471
 *	%g1		Address of function to call if this is not a syscall.
487
 * Fill the window at CWP - 1 from the kernel stack. This macro is to be
472
 * 	%g2	 	First argument for the function.
-
 
473
 *	%g6		Pre-set as kernel stack base if trap from userspace.
488
 * used before doing RESTORE when the fill trap is undesirable.
474
 *	%g7		Pre-set as address of the userspace window buffer.
-
 
475
 */
489
 */
-
 
490
.macro INLINE_FILL
-
 
491
	! CWP := CWP - 1
-
 
492
	rdpr %cwp, %g3
-
 
493
	add %g3, NWINDOWS - 1, %g3
-
 
494
	and %g3, NWINDOWS - 1, %g3
-
 
495
	wrpr %g3, %cwp
-
 
496
 
-
 
497
	! fill
-
 
498
	ldx [%sp + STACK_BIAS + L0_OFFSET], %l0
-
 
499
	ldx [%sp + STACK_BIAS + L1_OFFSET], %l1
-
 
500
	ldx [%sp + STACK_BIAS + L2_OFFSET], %l2
-
 
501
	ldx [%sp + STACK_BIAS + L3_OFFSET], %l3
-
 
502
	ldx [%sp + STACK_BIAS + L4_OFFSET], %l4
-
 
503
	ldx [%sp + STACK_BIAS + L5_OFFSET], %l5
-
 
504
	ldx [%sp + STACK_BIAS + L6_OFFSET], %l6
-
 
505
	ldx [%sp + STACK_BIAS + L7_OFFSET], %l7
-
 
506
	ldx [%sp + STACK_BIAS + I0_OFFSET], %i0
-
 
507
	ldx [%sp + STACK_BIAS + I1_OFFSET], %i1
-
 
508
	ldx [%sp + STACK_BIAS + I2_OFFSET], %i2
-
 
509
	ldx [%sp + STACK_BIAS + I3_OFFSET], %i3
-
 
510
	ldx [%sp + STACK_BIAS + I4_OFFSET], %i4
-
 
511
	ldx [%sp + STACK_BIAS + I5_OFFSET], %i5
-
 
512
	ldx [%sp + STACK_BIAS + I6_OFFSET], %i6
-
 
513
	ldx [%sp + STACK_BIAS + I7_OFFSET], %i7
-
 
514
 
-
 
515
	! CWP := CWP + 1
-
 
516
	add %g3, 1, %g3
-
 
517
	and %g3, NWINDOWS - 1, %g3
-
 
518
	wrpr %g3, %cwp
-
 
519
 
-
 
520
	restored
-
 
521
.endm
-
 
522
 
-
 
523
/*
-
 
524
 * Preemptible trap handler for handling traps from kernel.
-
 
525
 */
476
.macro PREEMPTIBLE_HANDLER_TEMPLATE is_syscall
526
.macro PREEMPTIBLE_HANDLER_KERNEL
477
#if 0
527
 
478
	/*
528
	/*
479
	 * ASSERT(%tl == 1)
529
	 * ASSERT(%tl == 1)
480
	 */
530
	 */
481
	rdpr %tl, %g3
531
	rdpr %tl, %g3
482
	cmp %g3, 1
532
	cmp %g3, 1
483
	be 1f
533
	be 1f
484
	nop
534
	nop
485
0:	ba 0b					! this is for debugging, if we ever get here
535
0:	ba 0b					! this is for debugging, if we ever get here
486
	nop					! it will be easy to find
536
	nop					! it will be easy to find
487
 
537
 
-
 
538
	/* prevent unnecessary CLEANWIN exceptions */
-
 
539
	wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(0), %wstate
488
1:
540
1:
489
.if NOT(\is_syscall)
-
 
490
	rdpr %tstate, %g3
-
 
491
	
-
 
492
	/*
-
 
493
	 * One of the ways this handler can be invoked is after a nested MMU trap from
-
 
494
	 * either spill_1_normal or fill_1_normal traps. Both of these traps manipulate
-
 
495
	 * the CWP register. We deal with the situation by simulating the MMU trap
-
 
496
	 * on TL=1 and restart the respective SAVE or RESTORE instruction once the MMU
-
 
497
	 * trap is resolved. However, because we are in the wrong window from the
-
 
498
	 * perspective of the MMU trap, we need to synchronize CWP with CWP from TL=0.
-
 
499
	 */ 
-
 
500
	and %g3, TSTATE_CWP_MASK, %g4
-
 
501
	wrpr %g4, 0, %cwp			! resynchronize CWP
-
 
502
 
-
 
503
	andcc %g3, TSTATE_PRIV_BIT, %g0		! if this trap came from the privileged mode...
-
 
504
	bnz 0f					! ...skip setting of kernel stack and primary context
-
 
505
	nop
-
 
506
	
-
 
507
.endif
-
 
508
	/*
-
 
509
	 * Normal window spills will go to the userspace window buffer.
-
 
510
	 */
-
 
511
	wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(2), %wstate
-
 
512
 
-
 
513
	wrpr %g0, NWINDOWS - 1, %cleanwin	! prevent unnecessary clean_window exceptions
-
 
514
 
-
 
515
	/*
541
	/*
516
	 * Switch to kernel stack. The old stack is
542
	 * Prevent SAVE instruction from causing a spill exception. If the
517
	 * automatically saved in the old window's %sp
543
	 * CANSAVE register is zero, explicitly spill the current register
518
	 * and the new window's %fp.
544
	 * window.
519
	 */
545
	 */
520
	save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
-
 
521
 
546
 
522
.if \is_syscall
-
 
523
	/*
-
 
524
	 * Copy arguments for the syscall to the new window.
-
 
525
	 */
-
 
526
	mov %i0, %o0
-
 
527
	mov %i1, %o1
-
 
528
	mov %i2, %o2
-
 
529
	mov %i3, %o3
-
 
530
	mov %i4, %o4
-
 
531
	mov %i5, %o5
-
 
532
.endif
-
 
533
 
-
 
534
	/*
-
 
535
	 * Mark the CANRESTORE windows as OTHER windows.
-
 
536
	 */
-
 
537
	rdpr %canrestore, %l0
547
	rdpr %cansave, %g3
538
	wrpr %l0, %otherwin
-
 
539
	wrpr %g0, %canrestore
-
 
540
 
-
 
541
	/*
-
 
542
	 * Switch to primary context 0.
-
 
543
	 */
-
 
544
	mov VA_PRIMARY_CONTEXT_REG, %l0
-
 
545
	stxa %g0, [%l0] ASI_DMMU
-
 
546
	rd %pc, %l0
548
	brnz %g3, 2f
547
	flush %l0
-
 
548
 
-
 
549
.if NOT(\is_syscall)
-
 
550
	ba 1f
-
 
551
	nop
549
	nop
-
 
550
	INLINE_SPILL
-
 
551
 
552
0:
552
2:
-
 
553
	/* ask for new register window */
553
	save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
554
	save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
554
 
555
 
555
	/*
-
 
556
	 * At this moment, we are using the kernel stack 
-
 
557
	 * and have successfully allocated a register window.
556
	/* copy higher level routine's address and its argument */
558
	 */
-
 
559
1:
-
 
560
.endif
-
 
561
	/*
-
 
562
	 * Other window spills will go to the userspace window buffer
-
 
563
	 * and normal spills will go to the kernel stack.
-
 
564
	 */
-
 
565
	wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(0), %wstate
-
 
566
	
-
 
567
	/*
-
 
568
	 * Copy arguments.
-
 
569
	 */
-
 
570
	mov %g1, %l0
557
	mov %g1, %l0
571
.if NOT(\is_syscall)
-
 
572
	mov %g2, %o0
558
	mov %g2, %o0
573
.else
-
 
574
	! store the syscall number on the stack as 7th argument
-
 
575
	stx %g2, [%sp + STACK_WINDOW_SAVE_AREA_SIZE + STACK_BIAS + STACK_ARG6] 
-
 
576
.endif
-
 
577
 
559
 
578
	/*
560
	/*
579
	 * Save TSTATE, TPC and TNPC aside.
561
	 * Save TSTATE, TPC and TNPC aside.
580
	 */
562
	 */
581
	rdpr %tstate, %g1
563
	rdpr %tstate, %g1
582
	rdpr %tpc, %g2
564
	rdpr %tpc, %g2
583
	rdpr %tnpc, %g3
565
	rdpr %tnpc, %g3
584
	rd %y, %g4
-
 
585
 
566
 
586
	stx %g1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE]
567
	stx %g1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE]
587
	stx %g2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC]
568
	stx %g2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC]
588
	stx %g3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC]
569
	stx %g3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC]
589
 
570
 
590
	/*
571
	/*
591
	 * Save the Y register.
572
	 * Save the Y register.
592
	 * This register is deprecated according to SPARC V9 specification
573
	 * This register is deprecated according to SPARC V9 specification
593
	 * and is only present for backward compatibility with previous
574
	 * and is only present for backward compatibility with previous
594
	 * versions of the SPARC architecture.
575
	 * versions of the SPARC architecture.
595
	 * Surprisingly, gcc makes use of this register without a notice.
576
	 * Surprisingly, gcc makes use of this register without a notice.
596
	 */
577
	 */
-
 
578
	rd %y, %g4
597
	stx %g4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y]
579
	stx %g4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y]
598
	
580
 
-
 
581
	/* switch to TL = 0, explicitly enable FPU */
599
	wrpr %g0, 0, %tl
582
	wrpr %g0, 0, %tl
600
	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT, %pstate
583
	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT, %pstate
-
 
584
 
-
 
585
	/* g1 -> l1, ..., g7 -> l7 */
601
	SAVE_GLOBALS
586
	SAVE_GLOBALS
602
	
587
 
603
.if NOT(\is_syscall)
-
 
604
	/*
-
 
605
	 * Call the higher-level handler and pass istate as second parameter.
588
	/* call higher-level service routine, pass istate as its 2nd parameter */
606
	 */
-
 
607
	call %l0
589
	call %l0
608
	add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1
590
	add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1
609
.else
-
 
610
	/*
-
 
611
	 * Call the higher-level syscall handler.
-
 
612
	 */
-
 
613
	call syscall_handler
-
 
614
	nop
-
 
615
	mov %o0, %i0				! copy the value returned by the syscall
-
 
616
.endif
-
 
617
 
591
 
-
 
592
	/* l1 -> g1, ..., l7 -> g7 */
618
	RESTORE_GLOBALS
593
	RESTORE_GLOBALS
-
 
594
 
619
	rdpr %pstate, %l1			! we must preserve the PEF bit
595
	/* we must prserve the PEF bit */
-
 
596
	rdpr %pstate, %l1
-
 
597
 
-
 
598
	/* TL := 1, GL := 1 */
620
	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
599
	wrpr %g0, PSTATE_PRIV_BIT, %pstate
621
	wrpr %g0, 1, %tl
600
	wrpr %g0, 1, %tl
-
 
601
	wrpr %g0, 1, %gl
622
	
602
 
623
	/*
-
 
624
	 * Read TSTATE, TPC and TNPC from saved copy.
603
	/* Read TSTATE, TPC and TNPC from saved copy. */
625
	 */
-
 
626
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE], %g1
604
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE], %g1
627
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC], %g2
605
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC], %g2
628
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC], %g3
606
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC], %g3
629
 
607
 
630
	/*
-
 
631
	 * Copy PSTATE.PEF to the in-register copy of TSTATE.
608
	/* Copy PSTATE.PEF to the in-register copy of TSTATE. */
632
	 */
-
 
633
	and %l1, PSTATE_PEF_BIT, %l1
609
	and %l1, PSTATE_PEF_BIT, %l1
634
	sllx %l1, TSTATE_PSTATE_SHIFT, %l1
610
	sllx %l1, TSTATE_PSTATE_SHIFT, %l1
635
	sethi %hi(TSTATE_PEF_BIT), %g4
611
	sethi %hi(TSTATE_PEF_BIT), %g4		! reset the PEF bit to 0 ...
636
	andn %g1, %g4, %g1
612
	andn %g1, %g4, %g1
637
	or %g1, %l1, %g1
613
	or %g1, %l1, %g1			! ... "or" it with saved PEF
638
 
614
 
639
	/*
-
 
640
	 * Restore TSTATE, TPC and TNPC from saved copies.
615
	/* Restore TSTATE, TPC and TNPC from saved copies. */
641
	 */
-
 
642
	wrpr %g1, 0, %tstate
616
	wrpr %g1, 0, %tstate
643
	wrpr %g2, 0, %tpc
617
	wrpr %g2, 0, %tpc
644
	wrpr %g3, 0, %tnpc
618
	wrpr %g3, 0, %tnpc
645
 
619
 
646
	/*
-
 
647
	 * Restore Y.
620
	/* Restore Y. */
648
	 */
-
 
649
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y], %g4
621
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y], %g4
650
	wr %g4, %y
622
	wr %g4, %y
651
 
623
	
652
	/*
-
 
653
	 * If OTHERWIN is zero, then all the userspace windows have been
-
 
654
	 * spilled to kernel memory (i.e. register window buffer). Moreover,
-
 
655
	 * if the scheduler was called in the meantime, all valid windows
-
 
656
	 * belonging to other threads were spilled by context_restore().
-
 
657
	 * If OTHERWIN is non-zero, then some userspace windows are still
-
 
658
	 * valid. Others might have been spilled. However, the CWP pointer
-
 
659
	 * needs no fixing because the scheduler had not been called.
-
 
660
	 */
-
 
661
	rdpr %otherwin, %l0
-
 
662
	brnz %l0, 0f
-
 
663
	nop
-
 
664
 
-
 
665
	/*
-
 
666
	 * OTHERWIN == 0
-
 
667
	 */
-
 
668
 
-
 
669
	/*
-
 
670
	 * If TSTATE.CWP + 1 == CWP, then we still do not have to fix CWP.
624
	/* If TSTATE.CWP + 1 == CWP, then we do not have to fix CWP. */
671
	 */
-
 
672
	and %g1, TSTATE_CWP_MASK, %l0
625
	and %g1, TSTATE_CWP_MASK, %l0
673
	inc %l0
626
	inc %l0
674
	and %l0, NWINDOWS - 1, %l0	! %l0 mod NWINDOWS
627
	and %l0, NWINDOWS - 1, %l0	! %l0 mod NWINDOWS
675
	rdpr %cwp, %l1
628
	rdpr %cwp, %l1
676
	cmp %l0, %l1
629
	cmp %l0, %l1
677
	bz 0f				! CWP is ok
630
	bz 4f				! CWP is ok
678
	nop
631
	nop
679
 
632
 
-
 
633
3:
680
	/*
634
	/*
681
	 * Fix CWP.
635
	 * Fix CWP.
682
	 * In order to recapitulate, the input registers in the current
636
	 * In order to recapitulate, the input registers in the current
683
	 * window are the output registers of the window to which we want
637
	 * window are the output registers of the window to which we want
684
	 * to restore. Because the fill trap fills only input and local
638
	 * to restore. Because the fill trap fills only input and local
685
	 * registers of a window, we need to preserve those output
639
	 * registers of a window, we need to preserve those output
686
	 * registers manually.
640
	 * registers manually.
687
	 */
641
	 */
688
	mov %sp, %g2
642
	mov %sp, %g2
689
	stx %i0, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0]
643
	stx %i0, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0]
690
	stx %i1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1]
644
	stx %i1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1]
691
	stx %i2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2]
645
	stx %i2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2]
692
	stx %i3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3]
646
	stx %i3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3]
693
	stx %i4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4]
647
	stx %i4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4]
694
	stx %i5, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5]
648
	stx %i5, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5]
695
	stx %i6, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6]
649
	stx %i6, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6]
696
	stx %i7, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7]
650
	stx %i7, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7]
697
	wrpr %l0, 0, %cwp
651
	wrpr %l0, 0, %cwp
698
	mov %g2, %sp
652
	mov %g2, %sp
699
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0], %i0
653
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0], %i0
700
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1], %i1
654
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1], %i1
701
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2], %i2
655
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2], %i2
702
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3], %i3
656
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3], %i3
703
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4], %i4
657
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4], %i4
704
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5], %i5
658
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5], %i5
705
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6], %i6
659
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6], %i6
706
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7], %i7
660
	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7], %i7
707
 
661
 
-
 
662
4:
708
	/*
663
	/*
709
	 * OTHERWIN != 0 or fall-through from the OTHERWIN == 0 case.
664
	 * Prevent RESTORE instruction from causing a spill exception. If the
710
	 * The CWP has already been restored to the value it had after the SAVE
665
	 * CANRESTORE register is zero, explicitly spill the current register
711
	 * at the beginning of this function.
666
	 * window.
712
	 */
667
	 */
713
0:
-
 
714
.if NOT(\is_syscall)
668
	rdpr %canrestore, %g1
715
	rdpr %tstate, %g1
669
	brnz %g1, 5f
716
	andcc %g1, TSTATE_PRIV_BIT, %g0		! if we are not returning to userspace...,
-
 
717
	bnz 1f					! ...skip restoring userspace windows
-
 
718
	nop
670
	nop
719
.endif
671
	INLINE_FILL
720
 
672
 
721
	/*
-
 
722
	 * Spills and fills will be processed by the {spill,fill}_1_normal
-
 
723
	 * handlers.
-
 
724
	 */
-
 
725
	wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(1), %wstate
-
 
726
 
-
 
727
	/*
-
 
728
	 * Set primary context according to secondary context.
-
 
729
	 */
-
 
730
	wr %g0, ASI_DMMU, %asi
-
 
731
	ldxa [VA_SECONDARY_CONTEXT_REG] %asi, %g1
-
 
732
	stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi
-
 
733
	rd %pc, %g1
-
 
734
	flush %g1
-
 
735
	
-
 
736
	rdpr %cwp, %g1
-
 
737
	rdpr %otherwin, %g2
-
 
738
 
-
 
739
	/*
-
 
740
	 * Skip all OTHERWIN windows and descend to the first window
-
 
741
	 * in the userspace window buffer.
-
 
742
	 */
-
 
743
	sub %g1, %g2, %g3
-
 
744
	dec %g3
-
 
745
	and %g3, NWINDOWS - 1, %g3
-
 
746
	wrpr %g3, 0, %cwp
-
 
747
 
-
 
748
	/*
-
 
749
	 * CWP is now in the window last saved in the userspace window buffer.
-
 
750
	 * Fill all windows stored in the buffer.
-
 
751
	 */
-
 
752
	clr %g4
-
 
753
0:	andcc %g7, UWB_ALIGNMENT - 1, %g0	! alignment check
-
 
754
	bz 0f					! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill
-
 
755
	nop
-
 
756
 
-
 
757
	add %g7, -STACK_WINDOW_SAVE_AREA_SIZE, %g7
-
 
758
	ldx [%g7 + L0_OFFSET], %l0
-
 
759
	ldx [%g7 + L1_OFFSET], %l1
-
 
760
	ldx [%g7 + L2_OFFSET], %l2
-
 
761
	ldx [%g7 + L3_OFFSET], %l3
-
 
762
	ldx [%g7 + L4_OFFSET], %l4
-
 
763
	ldx [%g7 + L5_OFFSET], %l5
-
 
764
	ldx [%g7 + L6_OFFSET], %l6
-
 
765
	ldx [%g7 + L7_OFFSET], %l7
-
 
766
	ldx [%g7 + I0_OFFSET], %i0
-
 
767
	ldx [%g7 + I1_OFFSET], %i1
-
 
768
	ldx [%g7 + I2_OFFSET], %i2
-
 
769
	ldx [%g7 + I3_OFFSET], %i3
-
 
770
	ldx [%g7 + I4_OFFSET], %i4
-
 
771
	ldx [%g7 + I5_OFFSET], %i5
-
 
772
	ldx [%g7 + I6_OFFSET], %i6
-
 
773
	ldx [%g7 + I7_OFFSET], %i7
-
 
774
 
-
 
775
	dec %g3
-
 
776
	and %g3, NWINDOWS - 1, %g3
-
 
777
	wrpr %g3, 0, %cwp			! switch to the preceeding window
-
 
778
 
-
 
779
	ba 0b
-
 
780
	inc %g4
-
 
781
 
-
 
782
0:
-
 
783
	/*
-
 
784
	 * Switch back to the proper current window and adjust
-
 
785
	 * OTHERWIN, CANRESTORE, CANSAVE and CLEANWIN.
-
 
786
	 */
-
 
787
	wrpr %g1, 0, %cwp
-
 
788
	add %g4, %g2, %g2
-
 
789
	cmp %g2, NWINDOWS - 2
-
 
790
	bg 2f					! fix the CANRESTORE=NWINDOWS-1 anomaly
-
 
791
	mov NWINDOWS - 2, %g1			! use dealy slot for both cases
-
 
792
	sub %g1, %g2, %g1
-
 
793
	
-
 
794
	wrpr %g0, 0, %otherwin
-
 
795
	wrpr %g1, 0, %cansave			! NWINDOWS - 2 - CANRESTORE
-
 
796
	wrpr %g2, 0, %canrestore		! OTHERWIN + windows in the buffer
-
 
797
	wrpr %g2, 0, %cleanwin			! avoid information leak
-
 
798
 
-
 
799
1:
673
5:
800
	restore
674
	restore
801
 
675
 
802
.if \is_syscall
-
 
803
	done
-
 
804
.else
-
 
805
	retry
676
	retry
806
.endif
677
.endm
807
 
678
 
808
	/*
-
 
809
	 * We got here in order to avoid inconsistency of the window state registers.
-
 
810
	 * If the:
-
 
811
	 *
-
 
812
	 * 	save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
-
 
813
	 *
-
 
814
	 * instruction trapped and spilled a register window into the userspace
-
 
815
	 * window buffer, we have just restored NWINDOWS - 1 register windows.
-
 
816
	 * However, CANRESTORE can be only NWINDOW - 2 at most.
-
 
817
	 *
-
 
818
	 * The solution is to manually switch to (CWP - 1) mod NWINDOWS
-
 
819
	 * and set the window state registers so that:
-
 
820
	 *
-
 
821
	 * 	CANRESTORE 	= NWINDOWS - 2
-
 
822
	 *	CLEANWIN	= NWINDOWS - 2
-
 
823
	 *	CANSAVE 	= 0
-
 
824
	 *	OTHERWIN	= 0
-
 
825
	 *
-
 
826
	 * The RESTORE instruction is therfore to be skipped.
-
 
827
	 */
-
 
828
2:
-
 
829
	wrpr %g0, 0, %otherwin
-
 
830
	wrpr %g0, 0, %cansave
-
 
831
	wrpr %g1, 0, %canrestore
-
 
832
	wrpr %g1, 0, %cleanwin
-
 
833
 
-
 
834
	rdpr %cwp, %g1
-
 
835
	dec %g1
-
 
836
	and %g1, NWINDOWS - 1, %g1
-
 
837
	wrpr %g1, 0, %cwp			! CWP--
-
 
838
	
-
 
839
.if \is_syscall
-
 
840
	done
-
 
841
.else
-
 
842
	retry
-
 
843
.endif
-
 
844
 
679
 
-
 
680
#define NOT(x)	((x) == 0)
-
 
681
 
-
 
682
/* Preemptible trap handler for TL=1.
-
 
683
 *
-
 
684
 * This trap handler makes arrangements to make calling of scheduler() from
-
 
685
 * within a trap context possible. It is called from several other trap
845
#endif
686
 * handlers.
-
 
687
 */
-
 
688
.macro PREEMPTIBLE_HANDLER_TEMPLATE is_syscall
-
 
689
	PREEMPTIBLE_HANDLER_KERNEL
846
.endm
690
.endm
847
 
691
 
848
.global preemptible_handler
692
.global preemptible_handler
849
preemptible_handler:
693
preemptible_handler:
850
	PREEMPTIBLE_HANDLER_TEMPLATE 0
694
	PREEMPTIBLE_HANDLER_TEMPLATE 0
851
 
695
 
852
.global trap_instruction_handler
696
.global trap_instruction_handler
853
trap_instruction_handler:
697
trap_instruction_handler:
854
	PREEMPTIBLE_HANDLER_TEMPLATE 1
698
	PREEMPTIBLE_HANDLER_TEMPLATE 1
855
 
699