Subversion Repositories HelenOS

Rev

Rev 3749 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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