Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* entry-table.S: main trap vector tables and exception jump table |
2 | * | |
3 | * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | |
4 | * Written by David Howells (dhowells@redhat.com) | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU General Public License | |
8 | * as published by the Free Software Foundation; either version | |
9 | * 2 of the License, or (at your option) any later version. | |
10 | * | |
11 | */ | |
12 | ||
13 | #include <linux/sys.h> | |
1da177e4 LT |
14 | #include <linux/linkage.h> |
15 | #include <asm/spr-regs.h> | |
16 | ||
17 | ############################################################################### | |
18 | # | |
19 | # Declare the main trap and vector tables | |
20 | # | |
21 | # There are six tables: | |
22 | # | |
23 | # (1) The trap table for debug mode | |
24 | # (2) The trap table for kernel mode | |
25 | # (3) The trap table for user mode | |
26 | # | |
27 | # The CPU jumps to an appropriate slot in the appropriate table to perform | |
28 | # exception processing. We have three different tables for the three | |
29 | # different CPU modes because there is no hardware differentiation between | |
30 | # stack pointers for these three modes, and so we have to invent one when | |
31 | # crossing mode boundaries. | |
32 | # | |
33 | # (4) The exception handler vector table | |
34 | # | |
35 | # The user and kernel trap tables use the same prologue for normal | |
36 | # exception processing. The prologue then jumps to the handler in this | |
37 | # table, as indexed by the exception ID from the TBR. | |
38 | # | |
39 | # (5) The fixup table for kernel-trap single-step | |
40 | # (6) The fixup table for user-trap single-step | |
41 | # | |
42 | # Due to the way single-stepping works on this CPU (single-step is not | |
43 | # disabled when crossing exception boundaries, only when in debug mode), | |
44 | # we have to catch the single-step event in break.S and jump to the fixup | |
45 | # routine pointed to by this table. | |
46 | # | |
47 | # The linker script places the user mode and kernel mode trap tables on to | |
48 | # the same 8Kb page, so that break.S can be more efficient when performing | |
49 | # single-step bypass management | |
50 | # | |
51 | ############################################################################### | |
52 | ||
53 | # trap table for entry from debug mode | |
54 | .section .trap.break,"ax" | |
55 | .balign 256*16 | |
56 | .globl __entry_breaktrap_table | |
57 | __entry_breaktrap_table: | |
58 | ||
59 | # trap table for entry from user mode | |
60 | .section .trap.user,"ax" | |
61 | .balign 256*16 | |
62 | .globl __entry_usertrap_table | |
63 | __entry_usertrap_table: | |
64 | ||
65 | # trap table for entry from kernel mode | |
66 | .section .trap.kernel,"ax" | |
67 | .balign 256*16 | |
68 | .globl __entry_kerneltrap_table | |
69 | __entry_kerneltrap_table: | |
70 | ||
71 | # exception handler jump table | |
72 | .section .trap.vector,"ax" | |
73 | .balign 256*4 | |
74 | .globl __entry_vector_table | |
75 | __entry_vector_table: | |
76 | ||
77 | # trap fixup table for single-stepping in user mode | |
78 | .section .trap.fixup.user,"a" | |
79 | .balign 256*4 | |
80 | .globl __break_usertrap_fixup_table | |
81 | __break_usertrap_fixup_table: | |
82 | ||
83 | # trap fixup table for single-stepping in user mode | |
84 | .section .trap.fixup.kernel,"a" | |
85 | .balign 256*4 | |
86 | .globl __break_kerneltrap_fixup_table | |
87 | __break_kerneltrap_fixup_table: | |
88 | ||
25985edc | 89 | # handler declaration for a software or program interrupt |
1da177e4 LT |
90 | .macro VECTOR_SOFTPROG tbr_tt, vec |
91 | .section .trap.user | |
92 | .org \tbr_tt | |
93 | bra __entry_uspace_softprog_interrupt | |
94 | .section .trap.fixup.user | |
95 | .org \tbr_tt >> 2 | |
96 | .long __break_step_uspace_softprog_interrupt | |
97 | .section .trap.kernel | |
98 | .org \tbr_tt | |
99 | bra __entry_kernel_softprog_interrupt | |
100 | .section .trap.fixup.kernel | |
101 | .org \tbr_tt >> 2 | |
102 | .long __break_step_kernel_softprog_interrupt | |
103 | .section .trap.vector | |
104 | .org \tbr_tt >> 2 | |
105 | .long \vec | |
106 | .endm | |
107 | ||
108 | # handler declaration for a maskable external interrupt | |
109 | .macro VECTOR_IRQ tbr_tt, vec | |
110 | .section .trap.user | |
111 | .org \tbr_tt | |
112 | bra __entry_uspace_external_interrupt | |
113 | .section .trap.fixup.user | |
114 | .org \tbr_tt >> 2 | |
115 | .long __break_step_uspace_external_interrupt | |
116 | .section .trap.kernel | |
117 | .org \tbr_tt | |
28baebae DH |
118 | # deal with virtual interrupt disablement |
119 | beq icc2,#0,__entry_kernel_external_interrupt_virtually_disabled | |
1da177e4 LT |
120 | bra __entry_kernel_external_interrupt |
121 | .section .trap.fixup.kernel | |
122 | .org \tbr_tt >> 2 | |
123 | .long __break_step_kernel_external_interrupt | |
124 | .section .trap.vector | |
125 | .org \tbr_tt >> 2 | |
126 | .long \vec | |
127 | .endm | |
128 | ||
129 | # handler declaration for an NMI external interrupt | |
130 | .macro VECTOR_NMI tbr_tt, vec | |
131 | .section .trap.user | |
132 | .org \tbr_tt | |
133 | break | |
134 | break | |
135 | break | |
136 | break | |
137 | .section .trap.kernel | |
138 | .org \tbr_tt | |
139 | break | |
140 | break | |
141 | break | |
142 | break | |
143 | .section .trap.vector | |
144 | .org \tbr_tt >> 2 | |
145 | .long \vec | |
146 | .endm | |
147 | ||
25985edc | 148 | # handler declaration for an MMU only software or program interrupt |
1da177e4 LT |
149 | .macro VECTOR_SP_MMU tbr_tt, vec |
150 | #ifdef CONFIG_MMU | |
151 | VECTOR_SOFTPROG \tbr_tt, \vec | |
152 | #else | |
153 | VECTOR_NMI \tbr_tt, 0 | |
154 | #endif | |
155 | .endm | |
156 | ||
157 | ||
158 | ############################################################################### | |
159 | # | |
160 | # specification of the vectors | |
161 | # - note: each macro inserts code into multiple sections | |
162 | # | |
163 | ############################################################################### | |
164 | VECTOR_SP_MMU TBR_TT_INSTR_MMU_MISS, __entry_insn_mmu_miss | |
165 | VECTOR_SOFTPROG TBR_TT_INSTR_ACC_ERROR, __entry_insn_access_error | |
166 | VECTOR_SOFTPROG TBR_TT_INSTR_ACC_EXCEP, __entry_insn_access_exception | |
167 | VECTOR_SOFTPROG TBR_TT_PRIV_INSTR, __entry_privileged_instruction | |
168 | VECTOR_SOFTPROG TBR_TT_ILLEGAL_INSTR, __entry_illegal_instruction | |
169 | VECTOR_SOFTPROG TBR_TT_FP_EXCEPTION, __entry_media_exception | |
170 | VECTOR_SOFTPROG TBR_TT_MP_EXCEPTION, __entry_media_exception | |
171 | VECTOR_SOFTPROG TBR_TT_DATA_ACC_ERROR, __entry_data_access_error | |
172 | VECTOR_SP_MMU TBR_TT_DATA_MMU_MISS, __entry_data_mmu_miss | |
173 | VECTOR_SOFTPROG TBR_TT_DATA_ACC_EXCEP, __entry_data_access_exception | |
174 | VECTOR_SOFTPROG TBR_TT_DATA_STR_ERROR, __entry_data_store_error | |
175 | VECTOR_SOFTPROG TBR_TT_DIVISION_EXCEP, __entry_division_exception | |
176 | ||
177 | #ifdef CONFIG_MMU | |
178 | .section .trap.user | |
179 | .org TBR_TT_INSTR_TLB_MISS | |
180 | .globl __trap_user_insn_tlb_miss | |
181 | __trap_user_insn_tlb_miss: | |
182 | movsg ear0,gr28 /* faulting address */ | |
183 | movsg scr0,gr31 /* get mapped PTD coverage start address */ | |
184 | xor.p gr28,gr31,gr31 /* compare addresses */ | |
185 | bra __entry_user_insn_tlb_miss | |
186 | ||
187 | .org TBR_TT_DATA_TLB_MISS | |
188 | .globl __trap_user_data_tlb_miss | |
189 | __trap_user_data_tlb_miss: | |
190 | movsg ear0,gr28 /* faulting address */ | |
191 | movsg scr1,gr31 /* get mapped PTD coverage start address */ | |
192 | xor.p gr28,gr31,gr31 /* compare addresses */ | |
193 | bra __entry_user_data_tlb_miss | |
194 | ||
195 | .section .trap.kernel | |
196 | .org TBR_TT_INSTR_TLB_MISS | |
197 | .globl __trap_kernel_insn_tlb_miss | |
198 | __trap_kernel_insn_tlb_miss: | |
199 | movsg ear0,gr29 /* faulting address */ | |
200 | movsg scr0,gr31 /* get mapped PTD coverage start address */ | |
201 | xor.p gr29,gr31,gr31 /* compare addresses */ | |
202 | bra __entry_kernel_insn_tlb_miss | |
203 | ||
204 | .org TBR_TT_DATA_TLB_MISS | |
205 | .globl __trap_kernel_data_tlb_miss | |
206 | __trap_kernel_data_tlb_miss: | |
207 | movsg ear0,gr29 /* faulting address */ | |
208 | movsg scr1,gr31 /* get mapped PTD coverage start address */ | |
209 | xor.p gr29,gr31,gr31 /* compare addresses */ | |
210 | bra __entry_kernel_data_tlb_miss | |
211 | ||
212 | .section .trap.fixup.user | |
213 | .org TBR_TT_INSTR_TLB_MISS >> 2 | |
214 | .globl __trap_fixup_user_insn_tlb_miss | |
215 | __trap_fixup_user_insn_tlb_miss: | |
216 | .long __break_user_insn_tlb_miss | |
217 | .org TBR_TT_DATA_TLB_MISS >> 2 | |
218 | .globl __trap_fixup_user_data_tlb_miss | |
219 | __trap_fixup_user_data_tlb_miss: | |
220 | .long __break_user_data_tlb_miss | |
221 | ||
222 | .section .trap.fixup.kernel | |
223 | .org TBR_TT_INSTR_TLB_MISS >> 2 | |
224 | .globl __trap_fixup_kernel_insn_tlb_miss | |
225 | __trap_fixup_kernel_insn_tlb_miss: | |
226 | .long __break_kernel_insn_tlb_miss | |
227 | .org TBR_TT_DATA_TLB_MISS >> 2 | |
228 | .globl __trap_fixup_kernel_data_tlb_miss | |
229 | __trap_fixup_kernel_data_tlb_miss: | |
230 | .long __break_kernel_data_tlb_miss | |
231 | ||
232 | .section .trap.vector | |
233 | .org TBR_TT_INSTR_TLB_MISS >> 2 | |
234 | .long __entry_insn_mmu_fault | |
235 | .org TBR_TT_DATA_TLB_MISS >> 2 | |
236 | .long __entry_data_mmu_fault | |
237 | #endif | |
238 | ||
239 | VECTOR_SP_MMU TBR_TT_DATA_DAT_EXCEP, __entry_data_dat_fault | |
240 | VECTOR_NMI TBR_TT_DECREMENT_TIMER, __entry_do_NMI | |
241 | VECTOR_SOFTPROG TBR_TT_COMPOUND_EXCEP, __entry_compound_exception | |
242 | VECTOR_IRQ TBR_TT_INTERRUPT_1, __entry_do_IRQ | |
243 | VECTOR_IRQ TBR_TT_INTERRUPT_2, __entry_do_IRQ | |
244 | VECTOR_IRQ TBR_TT_INTERRUPT_3, __entry_do_IRQ | |
245 | VECTOR_IRQ TBR_TT_INTERRUPT_4, __entry_do_IRQ | |
246 | VECTOR_IRQ TBR_TT_INTERRUPT_5, __entry_do_IRQ | |
247 | VECTOR_IRQ TBR_TT_INTERRUPT_6, __entry_do_IRQ | |
248 | VECTOR_IRQ TBR_TT_INTERRUPT_7, __entry_do_IRQ | |
249 | VECTOR_IRQ TBR_TT_INTERRUPT_8, __entry_do_IRQ | |
250 | VECTOR_IRQ TBR_TT_INTERRUPT_9, __entry_do_IRQ | |
251 | VECTOR_IRQ TBR_TT_INTERRUPT_10, __entry_do_IRQ | |
252 | VECTOR_IRQ TBR_TT_INTERRUPT_11, __entry_do_IRQ | |
253 | VECTOR_IRQ TBR_TT_INTERRUPT_12, __entry_do_IRQ | |
254 | VECTOR_IRQ TBR_TT_INTERRUPT_13, __entry_do_IRQ | |
255 | VECTOR_IRQ TBR_TT_INTERRUPT_14, __entry_do_IRQ | |
256 | VECTOR_NMI TBR_TT_INTERRUPT_15, __entry_do_NMI | |
257 | ||
258 | # miscellaneous user mode entry points | |
259 | .section .trap.user | |
260 | .org TBR_TT_TRAP0 | |
261 | .rept 127 | |
262 | bra __entry_uspace_softprog_interrupt | |
28baebae | 263 | .long 0,0,0 |
1da177e4 LT |
264 | .endr |
265 | .org TBR_TT_BREAK | |
266 | bra __entry_break | |
267 | .long 0,0,0 | |
268 | ||
28baebae DH |
269 | .section .trap.fixup.user |
270 | .org TBR_TT_TRAP0 >> 2 | |
271 | .rept 127 | |
272 | .long __break_step_uspace_softprog_interrupt | |
273 | .endr | |
274 | .org TBR_TT_BREAK >> 2 | |
275 | .long 0 | |
276 | ||
1da177e4 LT |
277 | # miscellaneous kernel mode entry points |
278 | .section .trap.kernel | |
279 | .org TBR_TT_TRAP0 | |
1da177e4 | 280 | bra __entry_kernel_softprog_interrupt |
28baebae DH |
281 | .org TBR_TT_TRAP1 |
282 | bra __entry_kernel_softprog_interrupt | |
283 | ||
284 | # trap #2 in kernel - reenable interrupts | |
285 | .org TBR_TT_TRAP2 | |
286 | bra __entry_kernel_external_interrupt_virtual_reenable | |
287 | ||
288 | # miscellaneous kernel traps | |
289 | .org TBR_TT_TRAP3 | |
290 | .rept 124 | |
291 | bra __entry_kernel_softprog_interrupt | |
292 | .long 0,0,0 | |
1da177e4 LT |
293 | .endr |
294 | .org TBR_TT_BREAK | |
295 | bra __entry_break | |
296 | .long 0,0,0 | |
297 | ||
28baebae DH |
298 | .section .trap.fixup.kernel |
299 | .org TBR_TT_TRAP0 >> 2 | |
300 | .long __break_step_kernel_softprog_interrupt | |
301 | .long __break_step_kernel_softprog_interrupt | |
302 | .long __break_step_kernel_external_interrupt_virtual_reenable | |
303 | .rept 124 | |
304 | .long __break_step_kernel_softprog_interrupt | |
305 | .endr | |
306 | .org TBR_TT_BREAK >> 2 | |
307 | .long 0 | |
308 | ||
1da177e4 LT |
309 | # miscellaneous debug mode entry points |
310 | .section .trap.break | |
311 | .org TBR_TT_BREAK | |
312 | movsg bpcsr,gr30 | |
313 | jmpl @(gr30,gr0) | |
314 | ||
315 | # miscellaneous vectors | |
316 | .section .trap.vector | |
317 | .org TBR_TT_TRAP0 >> 2 | |
318 | .long system_call | |
e31c243f | 319 | .rept 119 |
1da177e4 LT |
320 | .long __entry_unsupported_trap |
321 | .endr | |
e31c243f DH |
322 | |
323 | # userspace atomic op emulation, traps 120-126 | |
324 | .rept 7 | |
325 | .long __entry_atomic_op | |
326 | .endr | |
327 | ||
1da177e4 LT |
328 | .org TBR_TT_BREAK >> 2 |
329 | .long __entry_debug_exception |