source: mainline/arch/sparc64/src/trap/trap_table.S@ 65fb232

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 65fb232 was feb5915, checked in by Jakub Jermar <jakub@…>, 20 years ago

sparc64 work.
Rename saving_handler() to preemptible_handler()
and fix it to make sparc64 kernel preemptive.
Add two handlers for two fatal exceptions (i.e.
instruction_access_exception and mem_address_not_aligned.
Fix panic_printf() to not allocate its own register window.

  • Property mode set to 100644
File size: 9.4 KB
Line 
1#
2# Copyright (C) 2005 Jakub 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/**
30 * This file contains two trap tables.
31 * First, trap_table, is the one wich contains handlers implemented by
32 * kernel. During initialization, these handlers are copied out to
33 * the second trap table, trap_table_save, and the first table is
34 * overwritten with copy of OFW's own trap table. The copy is then patched
35 * from the trap_table_save.
36 *
37 * This arrangement is beneficial because kernel handlers stay on their
38 * link-time addresses which is good for debugging.
39 */
40
41.register %g2, #scratch
42.register %g3, #scratch
43.register %g6, #scratch
44.register %g7, #scratch
45
46.text
47
48#include <arch/trap/trap_table.h>
49#include <arch/trap/regwin.h>
50#include <arch/trap/interrupt.h>
51#include <arch/trap/exception.h>
52#include <arch/stack.h>
53
54#define TABLE_SIZE TRAP_TABLE_SIZE
55#define ENTRY_SIZE TRAP_TABLE_ENTRY_SIZE
56
57/*
58 * Kernel trap table.
59 */
60.align TABLE_SIZE
61.global trap_table
62trap_table:
63
64/* TT = 0x08, TL = 0, instruction_access_exception */
65.org trap_table + TT_INSTRUCTION_ACCESS_EXCEPTION*ENTRY_SIZE
66.global instruction_access_exception
67instruction_access_exception:
68 SIMPLE_HANDLER do_instruction_access_exc
69
70/* TT = 0x24, TL = 0, clean_window handler */
71.org trap_table + TT_CLEAN_WINDOW*ENTRY_SIZE
72.global clean_window_handler
73clean_window_handler:
74 CLEAN_WINDOW_HANDLER
75
76/* TT = 0x34, TL = 0, mem_address_not_aligned */
77.org trap_table + TT_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
78.global mem_address_not_aligned
79mem_address_not_aligned:
80 SIMPLE_HANDLER do_mem_address_not_aligned
81
82/* TT = 0x41, TL = 0, interrupt_level_1 handler */
83.org trap_table + TT_INTERRUPT_LEVEL_1*ENTRY_SIZE
84.global interrupt_level_1_handler
85interrupt_level_1_handler:
86 INTERRUPT_LEVEL_N_HANDLER 1
87
88/* TT = 0x42, TL = 0, interrupt_level_2 handler */
89.org trap_table + TT_INTERRUPT_LEVEL_2*ENTRY_SIZE
90.global interrupt_level_2_handler
91interrupt_level_2_handler:
92 INTERRUPT_LEVEL_N_HANDLER 2
93
94/* TT = 0x43, TL = 0, interrupt_level_3 handler */
95.org trap_table + TT_INTERRUPT_LEVEL_3*ENTRY_SIZE
96.global interrupt_level_3_handler
97interrupt_level_3_handler:
98 INTERRUPT_LEVEL_N_HANDLER 3
99
100/* TT = 0x44, TL = 0, interrupt_level_4 handler */
101.org trap_table + TT_INTERRUPT_LEVEL_4*ENTRY_SIZE
102.global interrupt_level_4_handler
103interrupt_level_4_handler:
104 INTERRUPT_LEVEL_N_HANDLER 4
105
106/* TT = 0x45, TL = 0, interrupt_level_5 handler */
107.org trap_table + TT_INTERRUPT_LEVEL_5*ENTRY_SIZE
108.global interrupt_level_5_handler
109interrupt_level_5_handler:
110 INTERRUPT_LEVEL_N_HANDLER 5
111
112/* TT = 0x46, TL = 0, interrupt_level_6 handler */
113.org trap_table + TT_INTERRUPT_LEVEL_6*ENTRY_SIZE
114.global interrupt_level_6_handler
115interrupt_level_6_handler:
116 INTERRUPT_LEVEL_N_HANDLER 6
117
118/* TT = 0x47, TL = 0, interrupt_level_7 handler */
119.org trap_table + TT_INTERRUPT_LEVEL_7*ENTRY_SIZE
120.global interrupt_level_7_handler
121interrupt_level_7_handler:
122 INTERRUPT_LEVEL_N_HANDLER 7
123
124/* TT = 0x48, TL = 0, interrupt_level_8 handler */
125.org trap_table + TT_INTERRUPT_LEVEL_8*ENTRY_SIZE
126.global interrupt_level_8_handler
127interrupt_level_8_handler:
128 INTERRUPT_LEVEL_N_HANDLER 8
129
130/* TT = 0x49, TL = 0, interrupt_level_9 handler */
131.org trap_table + TT_INTERRUPT_LEVEL_9*ENTRY_SIZE
132.global interrupt_level_9_handler
133interrupt_level_9_handler:
134 INTERRUPT_LEVEL_N_HANDLER 9
135
136/* TT = 0x4a, TL = 0, interrupt_level_10 handler */
137.org trap_table + TT_INTERRUPT_LEVEL_10*ENTRY_SIZE
138.global interrupt_level_10_handler
139interrupt_level_10_handler:
140 INTERRUPT_LEVEL_N_HANDLER 10
141
142/* TT = 0x4b, TL = 0, interrupt_level_11 handler */
143.org trap_table + TT_INTERRUPT_LEVEL_11*ENTRY_SIZE
144.global interrupt_level_11_handler
145interrupt_level_11_handler:
146 INTERRUPT_LEVEL_N_HANDLER 11
147
148/* TT = 0x4c, TL = 0, interrupt_level_12 handler */
149.org trap_table + TT_INTERRUPT_LEVEL_12*ENTRY_SIZE
150.global interrupt_level_12_handler
151interrupt_level_12_handler:
152 INTERRUPT_LEVEL_N_HANDLER 12
153
154/* TT = 0x4d, TL = 0, interrupt_level_13 handler */
155.org trap_table + TT_INTERRUPT_LEVEL_13*ENTRY_SIZE
156.global interrupt_level_13_handler
157interrupt_level_13_handler:
158 INTERRUPT_LEVEL_N_HANDLER 13
159
160/* TT = 0x4e, TL = 0, interrupt_level_14 handler */
161.org trap_table + TT_INTERRUPT_LEVEL_14*ENTRY_SIZE
162.global interrupt_level_14_handler
163interrupt_level_14_handler:
164 INTERRUPT_LEVEL_N_HANDLER 14
165
166/* TT = 0x4f, TL = 0, interrupt_level_15 handler */
167.org trap_table + TT_INTERRUPT_LEVEL_15*ENTRY_SIZE
168.global interrupt_level_15_handler
169interrupt_level_15_handler:
170 INTERRUPT_LEVEL_N_HANDLER 15
171
172/* TT = 0x60, TL = 0, interrupt_vector_trap handler */
173.org trap_table + TT_INTERRUPT_VECTOR_TRAP*ENTRY_SIZE
174.global interrupt_vector_trap_handler
175interrupt_vector_trap_handler:
176 INTERRUPT_VECTOR_TRAP_HANDLER
177
178/* TT = 0x80, TL = 0, spill_0_normal handler */
179.org trap_table + TT_SPILL_0_NORMAL*ENTRY_SIZE
180.global spill_0_normal
181spill_0_normal:
182 SPILL_NORMAL_HANDLER
183
184/* TT = 0xc0, TL = 0, fill_0_normal handler */
185.org trap_table + TT_FILL_0_NORMAL*ENTRY_SIZE
186.global fill_0_normal
187fill_0_normal:
188 FILL_NORMAL_HANDLER
189
190/*
191 * Handlers for TL>0.
192 */
193
194/* TT = 0x08, TL > 0, instruction_access_exception */
195.org trap_table + (TT_INSTRUCTION_ACCESS_EXCEPTION+512)*ENTRY_SIZE
196.global instruction_access_exception_high
197instruction_access_exception_high:
198 SIMPLE_HANDLER do_instruction_access_exc
199
200/* TT = 0x24, TL > 0, clean_window handler */
201.org trap_table + (TT_CLEAN_WINDOW+512)*ENTRY_SIZE
202.global clean_window_handler_high
203clean_window_handler_high:
204 CLEAN_WINDOW_HANDLER
205
206/* TT = 0x34, TL > 0, mem_address_not_aligned */
207.org trap_table + (TT_MEM_ADDRESS_NOT_ALIGNED+512)*ENTRY_SIZE
208.global mem_address_not_aligned_high
209mem_address_not_aligned_high:
210 SIMPLE_HANDLER do_mem_address_not_aligned
211
212/* TT = 0x80, TL > 0, spill_0_normal handler */
213.org trap_table + (TT_SPILL_0_NORMAL+512)*ENTRY_SIZE
214.global spill_0_normal_high
215spill_0_normal_high:
216 SPILL_NORMAL_HANDLER
217
218/* TT = 0xc0, TL > 0, fill_0_normal handler */
219.org trap_table + (TT_FILL_0_NORMAL+512)*ENTRY_SIZE
220.global fill_0_normal_high
221fill_0_normal_high:
222 FILL_NORMAL_HANDLER
223
224
225
226/*
227 * Save trap table.
228 */
229.align TABLE_SIZE
230.global trap_table_save
231trap_table_save:
232 .space TABLE_SIZE, 0
233
234
235/* Preemptible trap handler.
236 *
237 * This trap handler makes arrangements to
238 * make calling scheduler() possible.
239 *
240 * The caller is responsible for doing save
241 * and allocating PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE
242 * bytes on stack.
243 *
244 * Input registers:
245 * %l0 Address of function to call.
246 * Output registers:
247 * %l1 - %l7 Copy of %g1 - %g7
248 */
249.global preemptible_handler
250preemptible_handler:
251 /*
252 * Save TSTATE, TPC, TNPC and PSTATE aside.
253 */
254 rdpr %tstate, %g1
255 rdpr %tpc, %g2
256 rdpr %tnpc, %g3
257 rdpr %pstate, %g4
258
259 stx %g1, [%fp + STACK_BIAS + SAVED_TSTATE]
260 stx %g2, [%fp + STACK_BIAS + SAVED_TPC]
261 stx %g3, [%fp + STACK_BIAS + SAVED_TNPC]
262 stx %g4, [%fp + STACK_BIAS + SAVED_PSTATE]
263
264 /*
265 * Write 0 to TL.
266 */
267 wrpr %g0, 0, %tl
268
269 /*
270 * Alter PSTATE.
271 * - switch to normal globals.
272 */
273 and %g4, ~1, %g4 ! mask alternate globals
274 wrpr %g4, 0, %pstate
275
276 /*
277 * Save the normal globals.
278 */
279 SAVE_GLOBALS
280
281 /*
282 * Call the higher-level handler.
283 */
284 call %l0
285 nop
286
287 /*
288 * Restore the normal global register set.
289 */
290 RESTORE_GLOBALS
291
292 /*
293 * Restore PSTATE from saved copy.
294 * Alternate globals become active.
295 */
296 ldx [%fp + STACK_BIAS + SAVED_PSTATE], %l4
297 wrpr %l4, 0, %pstate
298
299 /*
300 * Write 1 to TL.
301 */
302 wrpr %g0, 1, %tl
303
304 /*
305 * Read TSTATE, TPC and TNPC from saved copy.
306 */
307 ldx [%fp + STACK_BIAS + SAVED_TSTATE], %g1
308 ldx [%fp + STACK_BIAS + SAVED_TPC], %g2
309 ldx [%fp + STACK_BIAS + SAVED_TNPC], %g3
310
311 /*
312 * Do restore to match the save instruction from the top-level handler.
313 */
314 restore
315
316 /*
317 * On execution of retry instruction, CWP will be restored from TSTATE register.
318 * However, because of scheduling, it is possible that CWP in saved TSTATE
319 * is different from current CWP. The following chunk of code fixes CWP
320 * in the saved copy of TSTATE.
321 */
322 rdpr %cwp, %g4 ! read current CWP
323 and %g1, ~0x1f, %g1 ! clear CWP field in saved TSTATE
324 or %g1, %g4, %g1 ! write current CWP to TSTATE
325
326 /*
327 * Restore TSTATE, TPC and TNPC from saved copies.
328 */
329 wrpr %g1, 0, %tstate
330 wrpr %g2, 0, %tpc
331 wrpr %g3, 0, %tnpc
332
333 /*
334 * Return from interrupt.
335 */
336 retry
Note: See TracBrowser for help on using the repository browser.