source: mainline/kernel/arch/sparc64/src/trap/sun4v/trap_table.S@ 3f35634c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3f35634c was 3da11f37, checked in by Pavel Rimsky <pavel@…>, 16 years ago

Merged changes essential for the code to reach 'uinit'.

  • Property mode set to 100644
File size: 22.4 KB
Line 
1#
2# Copyright (c) 2005 Jakub Jermar
3# Copyright (c) 2008 Pavel Rimsky
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9#
10# - Redistributions of source code must retain the above copyright
11# notice, this list of conditions and the following disclaimer.
12# - Redistributions in binary form must reproduce the above copyright
13# notice, this list of conditions and the following disclaimer in the
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
16# derived from this software without specific prior written permission.
17#
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
20# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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
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
27# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28#
29
30/**
31 * @file
32 * @brief This file contains kernel trap table.
33 */
34
35.register %g2, #scratch
36.register %g3, #scratch
37
38.text
39
40#include <arch/trap/trap_table.h>
41#include <arch/trap/regwin.h>
42#include <arch/trap/interrupt.h>
43#include <arch/trap/exception.h>
44#include <arch/trap/syscall.h>
45#include <arch/trap/sun4v/mmu.h>
46#include <arch/mm/sun4v/mmu.h>
47#include <arch/mm/page.h>
48#include <arch/stack.h>
49#include <arch/sun4v/regdef.h>
50
51#define TABLE_SIZE TRAP_TABLE_SIZE
52#define ENTRY_SIZE TRAP_TABLE_ENTRY_SIZE
53
54/*
55 * Kernel trap table.
56 */
57.align TABLE_SIZE
58.global trap_table
59trap_table:
60
61/* TT = 0x08, TL = 0, instruction_access_exception */
62.org trap_table + TT_INSTRUCTION_ACCESS_EXCEPTION*ENTRY_SIZE
63.global instruction_access_exception_tl0
64instruction_access_exception_tl0:
65 /*wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
66 PREEMPTIBLE_HANDLER instruction_access_exception*/
67
68/* TT = 0x0a, TL = 0, instruction_access_error */
69.org trap_table + TT_INSTRUCTION_ACCESS_ERROR*ENTRY_SIZE
70.global instruction_access_error_tl0
71instruction_access_error_tl0:
72 PREEMPTIBLE_HANDLER instruction_access_error
73
74/* TT = 0x10, TL = 0, illegal_instruction */
75.org trap_table + TT_ILLEGAL_INSTRUCTION*ENTRY_SIZE
76.global illegal_instruction_tl0
77illegal_instruction_tl0:
78 PREEMPTIBLE_HANDLER illegal_instruction
79
80/* TT = 0x11, TL = 0, privileged_opcode */
81.org trap_table + TT_PRIVILEGED_OPCODE*ENTRY_SIZE
82.global privileged_opcode_tl0
83privileged_opcode_tl0:
84 PREEMPTIBLE_HANDLER privileged_opcode
85
86/* TT = 0x12, TL = 0, unimplemented_LDD */
87.org trap_table + TT_UNIMPLEMENTED_LDD*ENTRY_SIZE
88.global unimplemented_LDD_tl0
89unimplemented_LDD_tl0:
90 PREEMPTIBLE_HANDLER unimplemented_LDD
91
92/* TT = 0x13, TL = 0, unimplemented_STD */
93.org trap_table + TT_UNIMPLEMENTED_STD*ENTRY_SIZE
94.global unimplemented_STD_tl0
95unimplemented_STD_tl0:
96 PREEMPTIBLE_HANDLER unimplemented_STD
97
98/* TT = 0x20, TL = 0, fb_disabled handler */
99.org trap_table + TT_FP_DISABLED*ENTRY_SIZE
100.global fb_disabled_tl0
101fp_disabled_tl0:
102 PREEMPTIBLE_HANDLER fp_disabled
103
104/* TT = 0x21, TL = 0, fb_exception_ieee_754 handler */
105.org trap_table + TT_FP_EXCEPTION_IEEE_754*ENTRY_SIZE
106.global fb_exception_ieee_754_tl0
107fp_exception_ieee_754_tl0:
108 PREEMPTIBLE_HANDLER fp_exception_ieee_754
109
110/* TT = 0x22, TL = 0, fb_exception_other handler */
111.org trap_table + TT_FP_EXCEPTION_OTHER*ENTRY_SIZE
112.global fb_exception_other_tl0
113fp_exception_other_tl0:
114 PREEMPTIBLE_HANDLER fp_exception_other
115
116/* TT = 0x23, TL = 0, tag_overflow */
117.org trap_table + TT_TAG_OVERFLOW*ENTRY_SIZE
118.global tag_overflow_tl0
119tag_overflow_tl0:
120 PREEMPTIBLE_HANDLER tag_overflow
121
122/* TT = 0x24, TL = 0, clean_window handler */
123.org trap_table + TT_CLEAN_WINDOW*ENTRY_SIZE
124.global clean_window_tl0
125clean_window_tl0:
126 CLEAN_WINDOW_HANDLER
127
128/* TT = 0x28, TL = 0, division_by_zero */
129.org trap_table + TT_DIVISION_BY_ZERO*ENTRY_SIZE
130.global division_by_zero_tl0
131division_by_zero_tl0:
132 PREEMPTIBLE_HANDLER division_by_zero
133
134/* TT = 0x30, TL = 0, data_access_exception */
135.org trap_table + TT_DATA_ACCESS_EXCEPTION*ENTRY_SIZE
136.global data_access_exception_tl0
137data_access_exception_tl0:
138 /*wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
139 PREEMPTIBLE_HANDLER data_access_exception*/
140
141/* TT = 0x32, TL = 0, data_access_error */
142.org trap_table + TT_DATA_ACCESS_ERROR*ENTRY_SIZE
143.global data_access_error_tl0
144data_access_error_tl0:
145 PREEMPTIBLE_HANDLER data_access_error
146
147/* TT = 0x34, TL = 0, mem_address_not_aligned */
148.org trap_table + TT_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
149.global mem_address_not_aligned_tl0
150mem_address_not_aligned_tl0:
151 PREEMPTIBLE_HANDLER mem_address_not_aligned
152
153/* TT = 0x35, TL = 0, LDDF_mem_address_not_aligned */
154.org trap_table + TT_LDDF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
155.global LDDF_mem_address_not_aligned_tl0
156LDDF_mem_address_not_aligned_tl0:
157 PREEMPTIBLE_HANDLER LDDF_mem_address_not_aligned
158
159/* TT = 0x36, TL = 0, STDF_mem_address_not_aligned */
160.org trap_table + TT_STDF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
161.global STDF_mem_address_not_aligned_tl0
162STDF_mem_address_not_aligned_tl0:
163 PREEMPTIBLE_HANDLER STDF_mem_address_not_aligned
164
165/* TT = 0x37, TL = 0, privileged_action */
166.org trap_table + TT_PRIVILEGED_ACTION*ENTRY_SIZE
167.global privileged_action_tl0
168privileged_action_tl0:
169 PREEMPTIBLE_HANDLER privileged_action
170
171/* TT = 0x38, TL = 0, LDQF_mem_address_not_aligned */
172.org trap_table + TT_LDQF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
173.global LDQF_mem_address_not_aligned_tl0
174LDQF_mem_address_not_aligned_tl0:
175 PREEMPTIBLE_HANDLER LDQF_mem_address_not_aligned
176
177/* TT = 0x39, TL = 0, STQF_mem_address_not_aligned */
178.org trap_table + TT_STQF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
179.global STQF_mem_address_not_aligned_tl0
180STQF_mem_address_not_aligned_tl0:
181 PREEMPTIBLE_HANDLER STQF_mem_address_not_aligned
182
183/* TT = 0x41, TL = 0, interrupt_level_1 handler */
184.org trap_table + TT_INTERRUPT_LEVEL_1*ENTRY_SIZE
185.global interrupt_level_1_handler_tl0
186interrupt_level_1_handler_tl0:
187 INTERRUPT_LEVEL_N_HANDLER 1
188
189/* TT = 0x42, TL = 0, interrupt_level_2 handler */
190.org trap_table + TT_INTERRUPT_LEVEL_2*ENTRY_SIZE
191.global interrupt_level_2_handler_tl0
192interrupt_level_2_handler_tl0:
193 INTERRUPT_LEVEL_N_HANDLER 2
194
195/* TT = 0x43, TL = 0, interrupt_level_3 handler */
196.org trap_table + TT_INTERRUPT_LEVEL_3*ENTRY_SIZE
197.global interrupt_level_3_handler_tl0
198interrupt_level_3_handler_tl0:
199 INTERRUPT_LEVEL_N_HANDLER 3
200
201/* TT = 0x44, TL = 0, interrupt_level_4 handler */
202.org trap_table + TT_INTERRUPT_LEVEL_4*ENTRY_SIZE
203.global interrupt_level_4_handler_tl0
204interrupt_level_4_handler_tl0:
205 INTERRUPT_LEVEL_N_HANDLER 4
206
207/* TT = 0x45, TL = 0, interrupt_level_5 handler */
208.org trap_table + TT_INTERRUPT_LEVEL_5*ENTRY_SIZE
209.global interrupt_level_5_handler_tl0
210interrupt_level_5_handler_tl0:
211 INTERRUPT_LEVEL_N_HANDLER 5
212
213/* TT = 0x46, TL = 0, interrupt_level_6 handler */
214.org trap_table + TT_INTERRUPT_LEVEL_6*ENTRY_SIZE
215.global interrupt_level_6_handler_tl0
216interrupt_level_6_handler_tl0:
217 INTERRUPT_LEVEL_N_HANDLER 6
218
219/* TT = 0x47, TL = 0, interrupt_level_7 handler */
220.org trap_table + TT_INTERRUPT_LEVEL_7*ENTRY_SIZE
221.global interrupt_level_7_handler_tl0
222interrupt_level_7_handler_tl0:
223 INTERRUPT_LEVEL_N_HANDLER 7
224
225/* TT = 0x48, TL = 0, interrupt_level_8 handler */
226.org trap_table + TT_INTERRUPT_LEVEL_8*ENTRY_SIZE
227.global interrupt_level_8_handler_tl0
228interrupt_level_8_handler_tl0:
229 INTERRUPT_LEVEL_N_HANDLER 8
230
231/* TT = 0x49, TL = 0, interrupt_level_9 handler */
232.org trap_table + TT_INTERRUPT_LEVEL_9*ENTRY_SIZE
233.global interrupt_level_9_handler_tl0
234interrupt_level_9_handler_tl0:
235 INTERRUPT_LEVEL_N_HANDLER 9
236
237/* TT = 0x4a, TL = 0, interrupt_level_10 handler */
238.org trap_table + TT_INTERRUPT_LEVEL_10*ENTRY_SIZE
239.global interrupt_level_10_handler_tl0
240interrupt_level_10_handler_tl0:
241 INTERRUPT_LEVEL_N_HANDLER 10
242
243/* TT = 0x4b, TL = 0, interrupt_level_11 handler */
244.org trap_table + TT_INTERRUPT_LEVEL_11*ENTRY_SIZE
245.global interrupt_level_11_handler_tl0
246interrupt_level_11_handler_tl0:
247 INTERRUPT_LEVEL_N_HANDLER 11
248
249/* TT = 0x4c, TL = 0, interrupt_level_12 handler */
250.org trap_table + TT_INTERRUPT_LEVEL_12*ENTRY_SIZE
251.global interrupt_level_12_handler_tl0
252interrupt_level_12_handler_tl0:
253 INTERRUPT_LEVEL_N_HANDLER 12
254
255/* TT = 0x4d, TL = 0, interrupt_level_13 handler */
256.org trap_table + TT_INTERRUPT_LEVEL_13*ENTRY_SIZE
257.global interrupt_level_13_handler_tl0
258interrupt_level_13_handler_tl0:
259 INTERRUPT_LEVEL_N_HANDLER 13
260
261/* TT = 0x4e, TL = 0, interrupt_level_14 handler */
262.org trap_table + TT_INTERRUPT_LEVEL_14*ENTRY_SIZE
263.global interrupt_level_14_handler_tl0
264interrupt_level_14_handler_tl0:
265 INTERRUPT_LEVEL_N_HANDLER 14
266
267/* TT = 0x4f, TL = 0, interrupt_level_15 handler */
268.org trap_table + TT_INTERRUPT_LEVEL_15*ENTRY_SIZE
269.global interrupt_level_15_handler_tl0
270interrupt_level_15_handler_tl0:
271 INTERRUPT_LEVEL_N_HANDLER 15
272
273/* TT = 0x60, TL = 0, interrupt_vector_trap handler */
274.org trap_table + TT_INTERRUPT_VECTOR_TRAP*ENTRY_SIZE
275.global interrupt_vector_trap_handler_tl0
276interrupt_vector_trap_handler_tl0:
277 INTERRUPT_VECTOR_TRAP_HANDLER
278
279/* TT = 0x64, TL = 0, fast_instruction_access_MMU_miss */
280.org trap_table + TT_FAST_INSTRUCTION_ACCESS_MMU_MISS*ENTRY_SIZE
281.global fast_instruction_access_mmu_miss_handler_tl0
282fast_instruction_access_mmu_miss_handler_tl0:
283 FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
284
285/* TT = 0x68, TL = 0, fast_data_access_MMU_miss */
286.org trap_table + TT_FAST_DATA_ACCESS_MMU_MISS*ENTRY_SIZE
287.global fast_data_access_mmu_miss_handler_tl0
288fast_data_access_mmu_miss_handler_tl0:
289 FAST_DATA_ACCESS_MMU_MISS_HANDLER 0
290
291/* TT = 0x6c, TL = 0, fast_data_access_protection */
292.org trap_table + TT_FAST_DATA_ACCESS_PROTECTION*ENTRY_SIZE
293.global fast_data_access_protection_handler_tl0
294fast_data_access_protection_handler_tl0:
295 /*FAST_DATA_ACCESS_PROTECTION_HANDLER 0*/
296
297/* TT = 0x80, TL = 0, spill_0_normal handler */
298.org trap_table + TT_SPILL_0_NORMAL*ENTRY_SIZE
299.global spill_0_normal_tl0
300spill_0_normal_tl0:
301 SPILL_NORMAL_HANDLER_KERNEL
302
303/* TT = 0x84, TL = 0, spill_1_normal handler */
304.org trap_table + TT_SPILL_1_NORMAL*ENTRY_SIZE
305.global spill_1_normal_tl0
306spill_1_normal_tl0:
307 SPILL_NORMAL_HANDLER_USERSPACE
308
309/* TT = 0x88, TL = 0, spill_2_normal handler */
310.org trap_table + TT_SPILL_2_NORMAL*ENTRY_SIZE
311.global spill_2_normal_tl0
312spill_2_normal_tl0:
313 SPILL_TO_USPACE_WINDOW_BUFFER
314
315/* TT = 0xa0, TL = 0, spill_0_other handler */
316.org trap_table + TT_SPILL_0_OTHER*ENTRY_SIZE
317.global spill_0_other_tl0
318spill_0_other_tl0:
319 SPILL_TO_USPACE_WINDOW_BUFFER
320
321/* TT = 0xc0, TL = 0, fill_0_normal handler */
322.org trap_table + TT_FILL_0_NORMAL*ENTRY_SIZE
323.global fill_0_normal_tl0
324fill_0_normal_tl0:
325 FILL_NORMAL_HANDLER_KERNEL
326
327/* TT = 0xc4, TL = 0, fill_1_normal handler */
328.org trap_table + TT_FILL_1_NORMAL*ENTRY_SIZE
329.global fill_1_normal_tl0
330fill_1_normal_tl0:
331 FILL_NORMAL_HANDLER_USERSPACE
332
333/* TT = 0x100 - 0x17f, TL = 0, trap_instruction_0 - trap_instruction_7f */
334.irp cur, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\
335 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,\
336 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,\
337 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,\
338 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,\
339 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,\
340 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,\
341 127
342.org trap_table + (TT_TRAP_INSTRUCTION_0+\cur)*ENTRY_SIZE
343.global trap_instruction_\cur\()_tl0
344trap_instruction_\cur\()_tl0:
345 ba trap_instruction_handler
346 mov \cur, %g2
347.endr
348
349/*
350 * Handlers for TL>0.
351 */
352
353/* TT = 0x08, TL > 0, instruction_access_exception */
354.org trap_table + (TT_INSTRUCTION_ACCESS_EXCEPTION+512)*ENTRY_SIZE
355.global instruction_access_exception_tl1
356instruction_access_exception_tl1:
357 /*wrpr %g0, 1, %tl
358 wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
359 PREEMPTIBLE_HANDLER instruction_access_exception*/
360
361/* TT = 0x0a, TL > 0, instruction_access_error */
362.org trap_table + (TT_INSTRUCTION_ACCESS_ERROR+512)*ENTRY_SIZE
363.global instruction_access_error_tl1
364instruction_access_error_tl1:
365 wrpr %g0, 1, %tl
366 PREEMPTIBLE_HANDLER instruction_access_error
367
368/* TT = 0x10, TL > 0, illegal_instruction */
369.org trap_table + (TT_ILLEGAL_INSTRUCTION+512)*ENTRY_SIZE
370.global illegal_instruction_tl1
371illegal_instruction_tl1:
372 wrpr %g0, 1, %tl
373 PREEMPTIBLE_HANDLER illegal_instruction
374
375/* TT = 0x24, TL > 0, clean_window handler */
376.org trap_table + (TT_CLEAN_WINDOW+512)*ENTRY_SIZE
377.global clean_window_tl1
378clean_window_tl1:
379 CLEAN_WINDOW_HANDLER
380
381/* TT = 0x28, TL > 0, division_by_zero */
382.org trap_table + (TT_DIVISION_BY_ZERO+512)*ENTRY_SIZE
383.global division_by_zero_tl1
384division_by_zero_tl1:
385 wrpr %g0, 1, %tl
386 PREEMPTIBLE_HANDLER division_by_zero
387
388/* TT = 0x30, TL > 0, data_access_exception */
389.org trap_table + (TT_DATA_ACCESS_EXCEPTION+512)*ENTRY_SIZE
390.global data_access_exception_tl1
391data_access_exception_tl1:
392 wrpr %g0, 1, %tl
393 wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
394 PREEMPTIBLE_HANDLER data_access_exception
395
396/* TT = 0x32, TL > 0, data_access_error */
397.org trap_table + (TT_DATA_ACCESS_ERROR+512)*ENTRY_SIZE
398.global data_access_error_tl1
399data_access_error_tl1:
400 wrpr %g0, 1, %tl
401 PREEMPTIBLE_HANDLER data_access_error
402
403/* TT = 0x34, TL > 0, mem_address_not_aligned */
404.org trap_table + (TT_MEM_ADDRESS_NOT_ALIGNED+512)*ENTRY_SIZE
405.global mem_address_not_aligned_tl1
406mem_address_not_aligned_tl1:
407 wrpr %g0, 1, %tl
408 PREEMPTIBLE_HANDLER mem_address_not_aligned
409
410/* TT = 0x68, TL > 0, fast_data_access_MMU_miss */
411.org trap_table + (TT_FAST_DATA_ACCESS_MMU_MISS+512)*ENTRY_SIZE
412.global fast_data_access_mmu_miss_handler_tl1
413fast_data_access_mmu_miss_handler_tl1:
414 FAST_DATA_ACCESS_MMU_MISS_HANDLER 1
415
416/* TT = 0x6c, TL > 0, fast_data_access_protection */
417.org trap_table + (TT_FAST_DATA_ACCESS_PROTECTION+512)*ENTRY_SIZE
418.global fast_data_access_protection_handler_tl1
419fast_data_access_protection_handler_tl1:
420 /*FAST_DATA_ACCESS_PROTECTION_HANDLER 1*/
421
422/* TT = 0x80, TL > 0, spill_0_normal handler */
423.org trap_table + (TT_SPILL_0_NORMAL+512)*ENTRY_SIZE
424.global spill_0_normal_tl1
425spill_0_normal_tl1:
426 SPILL_NORMAL_HANDLER_KERNEL
427
428/* TT = 0x88, TL > 0, spill_2_normal handler */
429.org trap_table + (TT_SPILL_2_NORMAL+512)*ENTRY_SIZE
430.global spill_2_normal_tl1
431spill_2_normal_tl1:
432 SPILL_TO_USPACE_WINDOW_BUFFER
433
434/* TT = 0xa0, TL > 0, spill_0_other handler */
435.org trap_table + (TT_SPILL_0_OTHER+512)*ENTRY_SIZE
436.global spill_0_other_tl1
437spill_0_other_tl1:
438 SPILL_TO_USPACE_WINDOW_BUFFER
439
440/* TT = 0xc0, TL > 0, fill_0_normal handler */
441.org trap_table + (TT_FILL_0_NORMAL+512)*ENTRY_SIZE
442.global fill_0_normal_tl1
443fill_0_normal_tl1:
444 FILL_NORMAL_HANDLER_KERNEL
445
446.align TABLE_SIZE
447
448
449/*
450 * Spills the window at CWP + 2 to the kernel stack. This macro is to be
451 * used before doing SAVE when the spill trap is undesirable.
452 *
453 * Parameters:
454 * tmpreg1 global register to be used for scratching purposes
455 * tmpreg2 global register to be used for scratching purposes
456 */
457.macro INLINE_SPILL tmpreg1, tmpreg2
458 ! CWP := CWP + 2
459 rdpr %cwp, \tmpreg2
460 add \tmpreg2, 2, \tmpreg1
461 and \tmpreg1, NWINDOWS - 1, \tmpreg1 ! modulo NWINDOWS
462 wrpr \tmpreg1, %cwp
463
464 ! spill to kernel stack
465 stx %l0, [%sp + STACK_BIAS + L0_OFFSET]
466 stx %l1, [%sp + STACK_BIAS + L1_OFFSET]
467 stx %l2, [%sp + STACK_BIAS + L2_OFFSET]
468 stx %l3, [%sp + STACK_BIAS + L3_OFFSET]
469 stx %l4, [%sp + STACK_BIAS + L4_OFFSET]
470 stx %l5, [%sp + STACK_BIAS + L5_OFFSET]
471 stx %l6, [%sp + STACK_BIAS + L6_OFFSET]
472 stx %l7, [%sp + STACK_BIAS + L7_OFFSET]
473 stx %i0, [%sp + STACK_BIAS + I0_OFFSET]
474 stx %i1, [%sp + STACK_BIAS + I1_OFFSET]
475 stx %i2, [%sp + STACK_BIAS + I2_OFFSET]
476 stx %i3, [%sp + STACK_BIAS + I3_OFFSET]
477 stx %i4, [%sp + STACK_BIAS + I4_OFFSET]
478 stx %i5, [%sp + STACK_BIAS + I5_OFFSET]
479 stx %i6, [%sp + STACK_BIAS + I6_OFFSET]
480 stx %i7, [%sp + STACK_BIAS + I7_OFFSET]
481
482 ! CWP := CWP - 2
483 wrpr \tmpreg2, %cwp
484
485 saved
486.endm
487
488/*
489 * 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.
491 *
492 * Parameters:
493 * tmpreg1 global register to be used for scratching purposes
494 * tmpreg2 global register to be used for scratching purposes
495 */
496.macro INLINE_FILL tmpreg1, tmpreg2
497 ! CWP := CWP - 1
498 rdpr %cwp, \tmpreg2
499 add \tmpreg2, NWINDOWS - 1, \tmpreg1
500 and \tmpreg1, NWINDOWS - 1, \tmpreg1
501 wrpr \tmpreg1, %cwp
502
503 ! fill from kernel stack
504 ldx [%sp + STACK_BIAS + L0_OFFSET], %l0
505 ldx [%sp + STACK_BIAS + L1_OFFSET], %l1
506 ldx [%sp + STACK_BIAS + L2_OFFSET], %l2
507 ldx [%sp + STACK_BIAS + L3_OFFSET], %l3
508 ldx [%sp + STACK_BIAS + L4_OFFSET], %l4
509 ldx [%sp + STACK_BIAS + L5_OFFSET], %l5
510 ldx [%sp + STACK_BIAS + L6_OFFSET], %l6
511 ldx [%sp + STACK_BIAS + L7_OFFSET], %l7
512 ldx [%sp + STACK_BIAS + I0_OFFSET], %i0
513 ldx [%sp + STACK_BIAS + I1_OFFSET], %i1
514 ldx [%sp + STACK_BIAS + I2_OFFSET], %i2
515 ldx [%sp + STACK_BIAS + I3_OFFSET], %i3
516 ldx [%sp + STACK_BIAS + I4_OFFSET], %i4
517 ldx [%sp + STACK_BIAS + I5_OFFSET], %i5
518 ldx [%sp + STACK_BIAS + I6_OFFSET], %i6
519 ldx [%sp + STACK_BIAS + I7_OFFSET], %i7
520
521 ! CWP := CWP + 1
522 wrpr \tmpreg2, %cwp
523
524 restored
525.endm
526
527/*
528 * Preemptible trap handler for handling traps from kernel.
529 */
530.macro PREEMPTIBLE_HANDLER_KERNEL
531
532 /*
533 * ASSERT(%tl == 1)
534 */
535 rdpr %tl, %g3
536 cmp %g3, 1
537 be 1f
538 nop
5390: 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, WSTATE_OTHER(0) | WSTATE_NORMAL(0), %wstate
5441:
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
5562:
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 */
561 mov %g1, %l0
562 mov %g2, %o0
563
564 /*
565 * Save TSTATE, TPC and TNPC aside.
566 */
567 rdpr %tstate, %g1
568 rdpr %tpc, %g2
569 rdpr %tnpc, %g3
570
571 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]
573 stx %g3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC]
574
575 /*
576 * Save the Y register.
577 * This register is deprecated according to SPARC V9 specification
578 * and is only present for backward compatibility with previous
579 * versions of the SPARC architecture.
580 * Surprisingly, gcc makes use of this register without a notice.
581 */
582 rd %y, %g4
583 stx %g4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y]
584
585 /* switch to TL = 0, explicitly enable FPU */
586 wrpr %g0, 0, %tl
587 wrpr %g0, 0, %gl
588 wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT, %pstate
589
590 /* g1 -> l1, ..., g7 -> l7 */
591 SAVE_GLOBALS
592
593 /* call higher-level service routine, pass istate as its 2nd parameter */
594 call %l0
595 add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1
596
597 /* l1 -> g1, ..., l7 -> g7 */
598 RESTORE_GLOBALS
599
600 /* we must prserve the PEF bit */
601 rdpr %pstate, %l1
602
603 /* TL := 1, GL := 1 */
604 wrpr %g0, PSTATE_PRIV_BIT, %pstate
605 wrpr %g0, 1, %tl
606 wrpr %g0, 1, %gl
607
608 /* Read TSTATE, TPC and TNPC from saved copy. */
609 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
611 ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC], %g3
612
613 /* Copy PSTATE.PEF to the in-register copy of TSTATE. */
614 and %l1, PSTATE_PEF_BIT, %l1
615 sllx %l1, TSTATE_PSTATE_SHIFT, %l1
616 sethi %hi(TSTATE_PEF_BIT), %g4 ! reset the PEF bit to 0 ...
617 andn %g1, %g4, %g1
618 or %g1, %l1, %g1 ! ... "or" it with saved PEF
619
620 /* Restore TSTATE, TPC and TNPC from saved copies. */
621 wrpr %g1, 0, %tstate
622 wrpr %g2, 0, %tpc
623 wrpr %g3, 0, %tnpc
624
625 /* Restore Y. */
626 ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y], %g4
627 wr %g4, %y
628
629 /* If TSTATE.CWP + 1 == CWP, then we do not have to fix CWP. */
630 and %g1, TSTATE_CWP_MASK, %l0
631 inc %l0
632 and %l0, NWINDOWS - 1, %l0 ! %l0 mod NWINDOWS
633 rdpr %cwp, %l1
634 cmp %l0, %l1
635 bz 4f ! CWP is ok
636 nop
637
6383:
639 /*
640 * Fix CWP.
641 * In order to recapitulate, the input registers in the current
642 * window are the output registers of the window to which we want
643 * to restore. Because the fill trap fills only input and local
644 * registers of a window, we need to preserve those output
645 * registers manually.
646 */
647 mov %sp, %g2
648 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]
650 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]
652 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]
654 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]
656 wrpr %l0, 0, %cwp
657 mov %g2, %sp
658 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
660 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
662 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
664 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
666
6674:
668 /*
669 * Prevent RESTORE instruction from causing a fill exception. If the
670 * CANRESTORE register is zero, explicitly fill register window
671 * at CWP - 1.
672 */
673 rdpr %canrestore, %g1
674 brnz %g1, 5f
675 nop
676 INLINE_FILL %g3, %g4
677
6785:
679 restore
680
681 retry
682.endm
683
684
685#define NOT(x) ((x) == 0)
686
687/* Preemptible trap handler for TL=1.
688 *
689 * This trap handler makes arrangements to make calling of scheduler() from
690 * within a trap context possible. It is called from several other trap
691 * handlers.
692 */
693.macro PREEMPTIBLE_HANDLER_TEMPLATE is_syscall
694 PREEMPTIBLE_HANDLER_KERNEL
695.endm
696
697.global preemptible_handler
698preemptible_handler:
699 PREEMPTIBLE_HANDLER_TEMPLATE 0
700
701.global trap_instruction_handler
702trap_instruction_handler:
703 PREEMPTIBLE_HANDLER_TEMPLATE 1
704
Note: See TracBrowser for help on using the repository browser.