Subversion Repositories HelenOS

Rev

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

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