diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2015-02-21 04:39:32 -0500 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2015-06-19 08:39:38 -0400 |
commit | 6d1a20b1d237db29878ae54142e39c87a36d0e95 (patch) | |
tree | 6fd222067223aee7f6b95db5041fb1e01f680006 | |
parent | c10d6969b0958e151c9dd6cfae70ce8db9db3c7e (diff) |
ARC: entry.S: split into ARCompact ISA specific, common bits
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r-- | arch/arc/include/asm/entry-compact.h | 306 | ||||
-rw-r--r-- | arch/arc/include/asm/entry.h | 300 | ||||
-rw-r--r-- | arch/arc/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/arc/kernel/entry-compact.S | 393 | ||||
-rw-r--r-- | arch/arc/kernel/entry.S | 389 |
5 files changed, 711 insertions, 681 deletions
diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h new file mode 100644 index 000000000000..6c0a81b598d2 --- /dev/null +++ b/arch/arc/include/asm/entry-compact.h | |||
@@ -0,0 +1,306 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com) | ||
3 | * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * Vineetg: March 2009 (Supporting 2 levels of Interrupts) | ||
10 | * Stack switching code can no longer reliably rely on the fact that | ||
11 | * if we are NOT in user mode, stack is switched to kernel mode. | ||
12 | * e.g. L2 IRQ interrupted a L1 ISR which had not yet completed | ||
13 | * it's prologue including stack switching from user mode | ||
14 | * | ||
15 | * Vineetg: Aug 28th 2008: Bug #94984 | ||
16 | * -Zero Overhead Loop Context shd be cleared when entering IRQ/EXcp/Trap | ||
17 | * Normally CPU does this automatically, however when doing FAKE rtie, | ||
18 | * we also need to explicitly do this. The problem in macros | ||
19 | * FAKE_RET_FROM_EXCPN and FAKE_RET_FROM_EXCPN_LOCK_IRQ was that this bit | ||
20 | * was being "CLEARED" rather then "SET". Actually "SET" clears ZOL context | ||
21 | * | ||
22 | * Vineetg: May 5th 2008 | ||
23 | * -Modified CALLEE_REG save/restore macros to handle the fact that | ||
24 | * r25 contains the kernel current task ptr | ||
25 | * - Defined Stack Switching Macro to be reused in all intr/excp hdlrs | ||
26 | * - Shaved off 11 instructions from RESTORE_ALL_INT1 by using the | ||
27 | * address Write back load ld.ab instead of seperate ld/add instn | ||
28 | * | ||
29 | * Amit Bhor, Sameer Dhavale: Codito Technologies 2004 | ||
30 | */ | ||
31 | |||
32 | #ifndef __ASM_ARC_ENTRY_COMPACT_H | ||
33 | #define __ASM_ARC_ENTRY_COMPACT_H | ||
34 | |||
35 | #include <asm/asm-offsets.h> | ||
36 | #include <asm/thread_info.h> /* For THREAD_SIZE */ | ||
37 | |||
38 | /*-------------------------------------------------------------- | ||
39 | * Switch to Kernel Mode stack if SP points to User Mode stack | ||
40 | * | ||
41 | * Entry : r9 contains pre-IRQ/exception/trap status32 | ||
42 | * Exit : SP is set to kernel mode stack pointer | ||
43 | * If CURR_IN_REG, r25 set to "current" task pointer | ||
44 | * Clobbers: r9 | ||
45 | *-------------------------------------------------------------*/ | ||
46 | |||
47 | .macro SWITCH_TO_KERNEL_STK | ||
48 | |||
49 | /* User Mode when this happened ? Yes: Proceed to switch stack */ | ||
50 | bbit1 r9, STATUS_U_BIT, 88f | ||
51 | |||
52 | /* OK we were already in kernel mode when this event happened, thus can | ||
53 | * assume SP is kernel mode SP. _NO_ need to do any stack switching | ||
54 | */ | ||
55 | |||
56 | #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS | ||
57 | /* However.... | ||
58 | * If Level 2 Interrupts enabled, we may end up with a corner case: | ||
59 | * 1. User Task executing | ||
60 | * 2. L1 IRQ taken, ISR starts (CPU auto-switched to KERNEL mode) | ||
61 | * 3. But before it could switch SP from USER to KERNEL stack | ||
62 | * a L2 IRQ "Interrupts" L1 | ||
63 | * Thay way although L2 IRQ happened in Kernel mode, stack is still | ||
64 | * not switched. | ||
65 | * To handle this, we may need to switch stack even if in kernel mode | ||
66 | * provided SP has values in range of USER mode stack ( < 0x7000_0000 ) | ||
67 | */ | ||
68 | brlo sp, VMALLOC_START, 88f | ||
69 | |||
70 | /* TODO: vineetg: | ||
71 | * We need to be a bit more cautious here. What if a kernel bug in | ||
72 | * L1 ISR, caused SP to go whaco (some small value which looks like | ||
73 | * USER stk) and then we take L2 ISR. | ||
74 | * Above brlo alone would treat it as a valid L1-L2 sceanrio | ||
75 | * instead of shouting alound | ||
76 | * The only feasible way is to make sure this L2 happened in | ||
77 | * L1 prelogue ONLY i.e. ilink2 is less than a pre-set marker in | ||
78 | * L1 ISR before it switches stack | ||
79 | */ | ||
80 | |||
81 | #endif | ||
82 | |||
83 | /* Save Pre Intr/Exception KERNEL MODE SP on kernel stack | ||
84 | * safe-keeping not really needed, but it keeps the epilogue code | ||
85 | * (SP restore) simpler/uniform. | ||
86 | */ | ||
87 | b.d 66f | ||
88 | mov r9, sp | ||
89 | |||
90 | 88: /*------Intr/Ecxp happened in user mode, "switch" stack ------ */ | ||
91 | |||
92 | GET_CURR_TASK_ON_CPU r9 | ||
93 | |||
94 | /* With current tsk in r9, get it's kernel mode stack base */ | ||
95 | GET_TSK_STACK_BASE r9, r9 | ||
96 | |||
97 | 66: | ||
98 | #ifdef CONFIG_ARC_CURR_IN_REG | ||
99 | /* | ||
100 | * Treat r25 as scratch reg, save it on stack first | ||
101 | * Load it with current task pointer | ||
102 | */ | ||
103 | st r25, [r9, -4] | ||
104 | GET_CURR_TASK_ON_CPU r25 | ||
105 | #endif | ||
106 | |||
107 | /* Save Pre Intr/Exception User SP on kernel stack */ | ||
108 | st.a sp, [r9, -16] ; Make room for orig_r0, ECR, user_r25 | ||
109 | |||
110 | /* CAUTION: | ||
111 | * SP should be set at the very end when we are done with everything | ||
112 | * In case of 2 levels of interrupt we depend on value of SP to assume | ||
113 | * that everything else is done (loading r25 etc) | ||
114 | */ | ||
115 | |||
116 | /* set SP to point to kernel mode stack */ | ||
117 | mov sp, r9 | ||
118 | |||
119 | /* ----- Stack Switched to kernel Mode, Now save REG FILE ----- */ | ||
120 | |||
121 | .endm | ||
122 | |||
123 | /*------------------------------------------------------------ | ||
124 | * "FAKE" a rtie to return from CPU Exception context | ||
125 | * This is to re-enable Exceptions within exception | ||
126 | * Look at EV_ProtV to see how this is actually used | ||
127 | *-------------------------------------------------------------*/ | ||
128 | |||
129 | .macro FAKE_RET_FROM_EXCPN | ||
130 | |||
131 | ld r9, [sp, PT_status32] | ||
132 | bic r9, r9, (STATUS_U_MASK|STATUS_DE_MASK) | ||
133 | bset r9, r9, STATUS_L_BIT | ||
134 | sr r9, [erstatus] | ||
135 | mov r9, 55f | ||
136 | sr r9, [eret] | ||
137 | |||
138 | rtie | ||
139 | 55: | ||
140 | .endm | ||
141 | |||
142 | /*-------------------------------------------------------------- | ||
143 | * For early Exception/ISR Prologue, a core reg is temporarily needed to | ||
144 | * code the rest of prolog (stack switching). This is done by stashing | ||
145 | * it to memory (non-SMP case) or SCRATCH0 Aux Reg (SMP). | ||
146 | * | ||
147 | * Before saving the full regfile - this reg is restored back, only | ||
148 | * to be saved again on kernel mode stack, as part of pt_regs. | ||
149 | *-------------------------------------------------------------*/ | ||
150 | .macro PROLOG_FREEUP_REG reg, mem | ||
151 | #ifdef CONFIG_SMP | ||
152 | sr \reg, [ARC_REG_SCRATCH_DATA0] | ||
153 | #else | ||
154 | st \reg, [\mem] | ||
155 | #endif | ||
156 | .endm | ||
157 | |||
158 | .macro PROLOG_RESTORE_REG reg, mem | ||
159 | #ifdef CONFIG_SMP | ||
160 | lr \reg, [ARC_REG_SCRATCH_DATA0] | ||
161 | #else | ||
162 | ld \reg, [\mem] | ||
163 | #endif | ||
164 | .endm | ||
165 | |||
166 | /*-------------------------------------------------------------- | ||
167 | * Exception Entry prologue | ||
168 | * -Switches stack to K mode (if not already) | ||
169 | * -Saves the register file | ||
170 | * | ||
171 | * After this it is safe to call the "C" handlers | ||
172 | *-------------------------------------------------------------*/ | ||
173 | .macro EXCEPTION_PROLOGUE | ||
174 | |||
175 | /* Need at least 1 reg to code the early exception prologue */ | ||
176 | PROLOG_FREEUP_REG r9, @ex_saved_reg1 | ||
177 | |||
178 | /* U/K mode at time of exception (stack not switched if already K) */ | ||
179 | lr r9, [erstatus] | ||
180 | |||
181 | /* ARC700 doesn't provide auto-stack switching */ | ||
182 | SWITCH_TO_KERNEL_STK | ||
183 | |||
184 | lr r9, [ecr] | ||
185 | st r9, [sp, 8] /* ECR */ | ||
186 | st r0, [sp, 4] /* orig_r0, needed only for sys calls */ | ||
187 | |||
188 | /* Restore r9 used to code the early prologue */ | ||
189 | PROLOG_RESTORE_REG r9, @ex_saved_reg1 | ||
190 | |||
191 | SAVE_R0_TO_R12 | ||
192 | PUSH gp | ||
193 | PUSH fp | ||
194 | PUSH blink | ||
195 | PUSHAX eret | ||
196 | PUSHAX erstatus | ||
197 | PUSH lp_count | ||
198 | PUSHAX lp_end | ||
199 | PUSHAX lp_start | ||
200 | PUSHAX erbta | ||
201 | .endm | ||
202 | |||
203 | /*-------------------------------------------------------------- | ||
204 | * Restore all registers used by system call or Exceptions | ||
205 | * SP should always be pointing to the next free stack element | ||
206 | * when entering this macro. | ||
207 | * | ||
208 | * NOTE: | ||
209 | * | ||
210 | * It is recommended that lp_count/ilink1/ilink2 not be used as a dest reg | ||
211 | * for memory load operations. If used in that way interrupts are deffered | ||
212 | * by hardware and that is not good. | ||
213 | *-------------------------------------------------------------*/ | ||
214 | .macro EXCEPTION_EPILOGUE | ||
215 | POPAX erbta | ||
216 | POPAX lp_start | ||
217 | POPAX lp_end | ||
218 | |||
219 | POP r9 | ||
220 | mov lp_count, r9 ;LD to lp_count is not allowed | ||
221 | |||
222 | POPAX erstatus | ||
223 | POPAX eret | ||
224 | POP blink | ||
225 | POP fp | ||
226 | POP gp | ||
227 | RESTORE_R12_TO_R0 | ||
228 | |||
229 | ld sp, [sp] /* restore original sp */ | ||
230 | /* orig_r0, ECR, user_r25 skipped automatically */ | ||
231 | .endm | ||
232 | |||
233 | /* Dummy ECR values for Interrupts */ | ||
234 | #define event_IRQ1 0x0031abcd | ||
235 | #define event_IRQ2 0x0032abcd | ||
236 | |||
237 | .macro INTERRUPT_PROLOGUE LVL | ||
238 | |||
239 | /* free up r9 as scratchpad */ | ||
240 | PROLOG_FREEUP_REG r9, @int\LVL\()_saved_reg | ||
241 | |||
242 | /* Which mode (user/kernel) was the system in when intr occured */ | ||
243 | lr r9, [status32_l\LVL\()] | ||
244 | |||
245 | SWITCH_TO_KERNEL_STK | ||
246 | |||
247 | /* restore original r9 */ | ||
248 | PROLOG_RESTORE_REG r9, @int\LVL\()_saved_reg | ||
249 | |||
250 | /* now we are ready to save the remaining context */ | ||
251 | st 0x003\LVL\()abcd, [sp, 8] /* Dummy ECR */ | ||
252 | st 0, [sp, 4] /* orig_r0 , N/A for IRQ */ | ||
253 | |||
254 | SAVE_R0_TO_R12 | ||
255 | PUSH gp | ||
256 | PUSH fp | ||
257 | PUSH blink | ||
258 | PUSH ilink\LVL\() | ||
259 | PUSHAX status32_l\LVL\() | ||
260 | PUSH lp_count | ||
261 | PUSHAX lp_end | ||
262 | PUSHAX lp_start | ||
263 | PUSHAX bta_l\LVL\() | ||
264 | .endm | ||
265 | |||
266 | /*-------------------------------------------------------------- | ||
267 | * Restore all registers used by interrupt handlers. | ||
268 | * | ||
269 | * NOTE: | ||
270 | * | ||
271 | * It is recommended that lp_count/ilink1/ilink2 not be used as a dest reg | ||
272 | * for memory load operations. If used in that way interrupts are deffered | ||
273 | * by hardware and that is not good. | ||
274 | *-------------------------------------------------------------*/ | ||
275 | .macro INTERRUPT_EPILOGUE LVL | ||
276 | POPAX bta_l\LVL\() | ||
277 | POPAX lp_start | ||
278 | POPAX lp_end | ||
279 | |||
280 | POP r9 | ||
281 | mov lp_count, r9 ;LD to lp_count is not allowed | ||
282 | |||
283 | POPAX status32_l\LVL\() | ||
284 | POP ilink\LVL\() | ||
285 | POP blink | ||
286 | POP fp | ||
287 | POP gp | ||
288 | RESTORE_R12_TO_R0 | ||
289 | |||
290 | ld sp, [sp] /* restore original sp */ | ||
291 | /* orig_r0, ECR, user_r25 skipped automatically */ | ||
292 | .endm | ||
293 | |||
294 | /* Get thread_info of "current" tsk */ | ||
295 | .macro GET_CURR_THR_INFO_FROM_SP reg | ||
296 | bic \reg, sp, (THREAD_SIZE - 1) | ||
297 | .endm | ||
298 | |||
299 | /* Get CPU-ID of this core */ | ||
300 | .macro GET_CPU_ID reg | ||
301 | lr \reg, [identity] | ||
302 | lsr \reg, \reg, 8 | ||
303 | bmsk \reg, \reg, 7 | ||
304 | .endm | ||
305 | |||
306 | #endif /* __ASM_ARC_ENTRY_COMPACT_H */ | ||
diff --git a/arch/arc/include/asm/entry.h b/arch/arc/include/asm/entry.h index 408a71378b5e..f61032c53d51 100644 --- a/arch/arc/include/asm/entry.h +++ b/arch/arc/include/asm/entry.h | |||
@@ -1,45 +1,23 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com) | ||
2 | * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) | 3 | * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) |
3 | * | 4 | * |
4 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License version 2 as | 6 | * it under the terms of the GNU General Public License version 2 as |
6 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
7 | * | ||
8 | * Vineetg: March 2009 (Supporting 2 levels of Interrupts) | ||
9 | * Stack switching code can no longer reliably rely on the fact that | ||
10 | * if we are NOT in user mode, stack is switched to kernel mode. | ||
11 | * e.g. L2 IRQ interrupted a L1 ISR which had not yet completed | ||
12 | * it's prologue including stack switching from user mode | ||
13 | * | ||
14 | * Vineetg: Aug 28th 2008: Bug #94984 | ||
15 | * -Zero Overhead Loop Context shd be cleared when entering IRQ/EXcp/Trap | ||
16 | * Normally CPU does this automatically, however when doing FAKE rtie, | ||
17 | * we also need to explicitly do this. The problem in macros | ||
18 | * FAKE_RET_FROM_EXCPN and FAKE_RET_FROM_EXCPN_LOCK_IRQ was that this bit | ||
19 | * was being "CLEARED" rather then "SET". Actually "SET" clears ZOL context | ||
20 | * | ||
21 | * Vineetg: May 5th 2008 | ||
22 | * -Modified CALLEE_REG save/restore macros to handle the fact that | ||
23 | * r25 contains the kernel current task ptr | ||
24 | * - Defined Stack Switching Macro to be reused in all intr/excp hdlrs | ||
25 | * - Shaved off 11 instructions from RESTORE_ALL_INT1 by using the | ||
26 | * address Write back load ld.ab instead of seperate ld/add instn | ||
27 | * | ||
28 | * Amit Bhor, Sameer Dhavale: Codito Technologies 2004 | ||
29 | */ | 8 | */ |
30 | 9 | ||
31 | #ifndef __ASM_ARC_ENTRY_H | 10 | #ifndef __ASM_ARC_ENTRY_H |
32 | #define __ASM_ARC_ENTRY_H | 11 | #define __ASM_ARC_ENTRY_H |
33 | 12 | ||
34 | #ifdef __ASSEMBLY__ | ||
35 | #include <asm/unistd.h> /* For NR_syscalls defination */ | 13 | #include <asm/unistd.h> /* For NR_syscalls defination */ |
36 | #include <asm/asm-offsets.h> | ||
37 | #include <asm/arcregs.h> | 14 | #include <asm/arcregs.h> |
38 | #include <asm/ptrace.h> | 15 | #include <asm/ptrace.h> |
39 | #include <asm/processor.h> /* For VMALLOC_START */ | 16 | #include <asm/processor.h> /* For VMALLOC_START */ |
40 | #include <asm/thread_info.h> /* For THREAD_SIZE */ | ||
41 | #include <asm/mmu.h> | 17 | #include <asm/mmu.h> |
42 | 18 | ||
19 | #include <asm/entry-compact.h> /* ISA specific bits */ | ||
20 | |||
43 | /* Note on the LD/ST addr modes with addr reg wback | 21 | /* Note on the LD/ST addr modes with addr reg wback |
44 | * | 22 | * |
45 | * LD.a same as LD.aw | 23 | * LD.a same as LD.aw |
@@ -240,117 +218,6 @@ | |||
240 | 218 | ||
241 | .endm | 219 | .endm |
242 | 220 | ||
243 | /*-------------------------------------------------------------- | ||
244 | * Switch to Kernel Mode stack if SP points to User Mode stack | ||
245 | * | ||
246 | * Entry : r9 contains pre-IRQ/exception/trap status32 | ||
247 | * Exit : SP is set to kernel mode stack pointer | ||
248 | * If CURR_IN_REG, r25 set to "current" task pointer | ||
249 | * Clobbers: r9 | ||
250 | *-------------------------------------------------------------*/ | ||
251 | |||
252 | .macro SWITCH_TO_KERNEL_STK | ||
253 | |||
254 | /* User Mode when this happened ? Yes: Proceed to switch stack */ | ||
255 | bbit1 r9, STATUS_U_BIT, 88f | ||
256 | |||
257 | /* OK we were already in kernel mode when this event happened, thus can | ||
258 | * assume SP is kernel mode SP. _NO_ need to do any stack switching | ||
259 | */ | ||
260 | |||
261 | #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS | ||
262 | /* However.... | ||
263 | * If Level 2 Interrupts enabled, we may end up with a corner case: | ||
264 | * 1. User Task executing | ||
265 | * 2. L1 IRQ taken, ISR starts (CPU auto-switched to KERNEL mode) | ||
266 | * 3. But before it could switch SP from USER to KERNEL stack | ||
267 | * a L2 IRQ "Interrupts" L1 | ||
268 | * Thay way although L2 IRQ happened in Kernel mode, stack is still | ||
269 | * not switched. | ||
270 | * To handle this, we may need to switch stack even if in kernel mode | ||
271 | * provided SP has values in range of USER mode stack ( < 0x7000_0000 ) | ||
272 | */ | ||
273 | brlo sp, VMALLOC_START, 88f | ||
274 | |||
275 | /* TODO: vineetg: | ||
276 | * We need to be a bit more cautious here. What if a kernel bug in | ||
277 | * L1 ISR, caused SP to go whaco (some small value which looks like | ||
278 | * USER stk) and then we take L2 ISR. | ||
279 | * Above brlo alone would treat it as a valid L1-L2 sceanrio | ||
280 | * instead of shouting alound | ||
281 | * The only feasible way is to make sure this L2 happened in | ||
282 | * L1 prelogue ONLY i.e. ilink2 is less than a pre-set marker in | ||
283 | * L1 ISR before it switches stack | ||
284 | */ | ||
285 | |||
286 | #endif | ||
287 | |||
288 | /* Save Pre Intr/Exception KERNEL MODE SP on kernel stack | ||
289 | * safe-keeping not really needed, but it keeps the epilogue code | ||
290 | * (SP restore) simpler/uniform. | ||
291 | */ | ||
292 | b.d 66f | ||
293 | mov r9, sp | ||
294 | |||
295 | 88: /*------Intr/Ecxp happened in user mode, "switch" stack ------ */ | ||
296 | |||
297 | GET_CURR_TASK_ON_CPU r9 | ||
298 | |||
299 | /* With current tsk in r9, get it's kernel mode stack base */ | ||
300 | GET_TSK_STACK_BASE r9, r9 | ||
301 | |||
302 | 66: | ||
303 | #ifdef CONFIG_ARC_CURR_IN_REG | ||
304 | /* | ||
305 | * Treat r25 as scratch reg, save it on stack first | ||
306 | * Load it with current task pointer | ||
307 | */ | ||
308 | st r25, [r9, -4] | ||
309 | GET_CURR_TASK_ON_CPU r25 | ||
310 | #endif | ||
311 | |||
312 | /* Save Pre Intr/Exception User SP on kernel stack */ | ||
313 | st.a sp, [r9, -16] ; Make room for orig_r0, ECR, user_r25 | ||
314 | |||
315 | /* CAUTION: | ||
316 | * SP should be set at the very end when we are done with everything | ||
317 | * In case of 2 levels of interrupt we depend on value of SP to assume | ||
318 | * that everything else is done (loading r25 etc) | ||
319 | */ | ||
320 | |||
321 | /* set SP to point to kernel mode stack */ | ||
322 | mov sp, r9 | ||
323 | |||
324 | /* ----- Stack Switched to kernel Mode, Now save REG FILE ----- */ | ||
325 | |||
326 | .endm | ||
327 | |||
328 | /*------------------------------------------------------------ | ||
329 | * "FAKE" a rtie to return from CPU Exception context | ||
330 | * This is to re-enable Exceptions within exception | ||
331 | * Look at EV_ProtV to see how this is actually used | ||
332 | *-------------------------------------------------------------*/ | ||
333 | |||
334 | .macro FAKE_RET_FROM_EXCPN | ||
335 | |||
336 | ld r9, [sp, PT_status32] | ||
337 | bic r9, r9, (STATUS_U_MASK|STATUS_DE_MASK) | ||
338 | bset r9, r9, STATUS_L_BIT | ||
339 | sr r9, [erstatus] | ||
340 | mov r9, 55f | ||
341 | sr r9, [eret] | ||
342 | |||
343 | rtie | ||
344 | 55: | ||
345 | .endm | ||
346 | |||
347 | /* | ||
348 | * @reg [OUT] &thread_info of "current" | ||
349 | */ | ||
350 | .macro GET_CURR_THR_INFO_FROM_SP reg | ||
351 | bic \reg, sp, (THREAD_SIZE - 1) | ||
352 | .endm | ||
353 | |||
354 | /* | 221 | /* |
355 | * @reg [OUT] thread_info->flags of "current" | 222 | * @reg [OUT] thread_info->flags of "current" |
356 | */ | 223 | */ |
@@ -359,165 +226,6 @@ | |||
359 | ld \reg, [\reg, THREAD_INFO_FLAGS] | 226 | ld \reg, [\reg, THREAD_INFO_FLAGS] |
360 | .endm | 227 | .endm |
361 | 228 | ||
362 | /*-------------------------------------------------------------- | ||
363 | * For early Exception/ISR Prologue, a core reg is temporarily needed to | ||
364 | * code the rest of prolog (stack switching). This is done by stashing | ||
365 | * it to memory (non-SMP case) or SCRATCH0 Aux Reg (SMP). | ||
366 | * | ||
367 | * Before saving the full regfile - this reg is restored back, only | ||
368 | * to be saved again on kernel mode stack, as part of pt_regs. | ||
369 | *-------------------------------------------------------------*/ | ||
370 | .macro PROLOG_FREEUP_REG reg, mem | ||
371 | #ifdef CONFIG_SMP | ||
372 | sr \reg, [ARC_REG_SCRATCH_DATA0] | ||
373 | #else | ||
374 | st \reg, [\mem] | ||
375 | #endif | ||
376 | .endm | ||
377 | |||
378 | .macro PROLOG_RESTORE_REG reg, mem | ||
379 | #ifdef CONFIG_SMP | ||
380 | lr \reg, [ARC_REG_SCRATCH_DATA0] | ||
381 | #else | ||
382 | ld \reg, [\mem] | ||
383 | #endif | ||
384 | .endm | ||
385 | |||
386 | /*-------------------------------------------------------------- | ||
387 | * Exception Entry prologue | ||
388 | * -Switches stack to K mode (if not already) | ||
389 | * -Saves the register file | ||
390 | * | ||
391 | * After this it is safe to call the "C" handlers | ||
392 | *-------------------------------------------------------------*/ | ||
393 | .macro EXCEPTION_PROLOGUE | ||
394 | |||
395 | /* Need at least 1 reg to code the early exception prologue */ | ||
396 | PROLOG_FREEUP_REG r9, @ex_saved_reg1 | ||
397 | |||
398 | /* U/K mode at time of exception (stack not switched if already K) */ | ||
399 | lr r9, [erstatus] | ||
400 | |||
401 | /* ARC700 doesn't provide auto-stack switching */ | ||
402 | SWITCH_TO_KERNEL_STK | ||
403 | |||
404 | lr r9, [ecr] | ||
405 | st r9, [sp, 8] /* ECR */ | ||
406 | st r0, [sp, 4] /* orig_r0, needed only for sys calls */ | ||
407 | |||
408 | /* Restore r9 used to code the early prologue */ | ||
409 | PROLOG_RESTORE_REG r9, @ex_saved_reg1 | ||
410 | |||
411 | SAVE_R0_TO_R12 | ||
412 | PUSH gp | ||
413 | PUSH fp | ||
414 | PUSH blink | ||
415 | PUSHAX eret | ||
416 | PUSHAX erstatus | ||
417 | PUSH lp_count | ||
418 | PUSHAX lp_end | ||
419 | PUSHAX lp_start | ||
420 | PUSHAX erbta | ||
421 | .endm | ||
422 | |||
423 | /*-------------------------------------------------------------- | ||
424 | * Restore all registers used by system call or Exceptions | ||
425 | * SP should always be pointing to the next free stack element | ||
426 | * when entering this macro. | ||
427 | * | ||
428 | * NOTE: | ||
429 | * | ||
430 | * It is recommended that lp_count/ilink1/ilink2 not be used as a dest reg | ||
431 | * for memory load operations. If used in that way interrupts are deffered | ||
432 | * by hardware and that is not good. | ||
433 | *-------------------------------------------------------------*/ | ||
434 | .macro EXCEPTION_EPILOGUE | ||
435 | POPAX erbta | ||
436 | POPAX lp_start | ||
437 | POPAX lp_end | ||
438 | |||
439 | POP r9 | ||
440 | mov lp_count, r9 ;LD to lp_count is not allowed | ||
441 | |||
442 | POPAX erstatus | ||
443 | POPAX eret | ||
444 | POP blink | ||
445 | POP fp | ||
446 | POP gp | ||
447 | RESTORE_R12_TO_R0 | ||
448 | |||
449 | ld sp, [sp] /* restore original sp */ | ||
450 | /* orig_r0, ECR, user_r25 skipped automatically */ | ||
451 | .endm | ||
452 | |||
453 | /* Dummy ECR values for Interrupts */ | ||
454 | #define event_IRQ1 0x0031abcd | ||
455 | #define event_IRQ2 0x0032abcd | ||
456 | |||
457 | .macro INTERRUPT_PROLOGUE LVL | ||
458 | |||
459 | /* free up r9 as scratchpad */ | ||
460 | PROLOG_FREEUP_REG r9, @int\LVL\()_saved_reg | ||
461 | |||
462 | /* Which mode (user/kernel) was the system in when intr occurred */ | ||
463 | lr r9, [status32_l\LVL\()] | ||
464 | |||
465 | SWITCH_TO_KERNEL_STK | ||
466 | |||
467 | /* restore original r9 */ | ||
468 | PROLOG_RESTORE_REG r9, @int\LVL\()_saved_reg | ||
469 | |||
470 | /* now we are ready to save the remaining context */ | ||
471 | st 0x003\LVL\()abcd, [sp, 8] /* Dummy ECR */ | ||
472 | st 0, [sp, 4] /* orig_r0 , N/A for IRQ */ | ||
473 | |||
474 | SAVE_R0_TO_R12 | ||
475 | PUSH gp | ||
476 | PUSH fp | ||
477 | PUSH blink | ||
478 | PUSH ilink\LVL\() | ||
479 | PUSHAX status32_l\LVL\() | ||
480 | PUSH lp_count | ||
481 | PUSHAX lp_end | ||
482 | PUSHAX lp_start | ||
483 | PUSHAX bta_l\LVL\() | ||
484 | .endm | ||
485 | |||
486 | /*-------------------------------------------------------------- | ||
487 | * Restore all registers used by interrupt handlers. | ||
488 | * | ||
489 | * NOTE: | ||
490 | * | ||
491 | * It is recommended that lp_count/ilink1/ilink2 not be used as a dest reg | ||
492 | * for memory load operations. If used in that way interrupts are deffered | ||
493 | * by hardware and that is not good. | ||
494 | *-------------------------------------------------------------*/ | ||
495 | .macro INTERRUPT_EPILOGUE LVL | ||
496 | POPAX bta_l\LVL\() | ||
497 | POPAX lp_start | ||
498 | POPAX lp_end | ||
499 | |||
500 | POP r9 | ||
501 | mov lp_count, r9 ;LD to lp_count is not allowed | ||
502 | |||
503 | POPAX status32_l\LVL\() | ||
504 | POP ilink\LVL\() | ||
505 | POP blink | ||
506 | POP fp | ||
507 | POP gp | ||
508 | RESTORE_R12_TO_R0 | ||
509 | |||
510 | ld sp, [sp] /* restore original sp */ | ||
511 | /* orig_r0, ECR, user_r25 skipped automatically */ | ||
512 | .endm | ||
513 | |||
514 | /* Get CPU-ID of this core */ | ||
515 | .macro GET_CPU_ID reg | ||
516 | lr \reg, [identity] | ||
517 | lsr \reg, \reg, 8 | ||
518 | bmsk \reg, \reg, 7 | ||
519 | .endm | ||
520 | |||
521 | #ifdef CONFIG_SMP | 229 | #ifdef CONFIG_SMP |
522 | 230 | ||
523 | /*------------------------------------------------- | 231 | /*------------------------------------------------- |
@@ -586,6 +294,4 @@ | |||
586 | 294 | ||
587 | #endif /* CONFIG_ARC_CURR_IN_REG */ | 295 | #endif /* CONFIG_ARC_CURR_IN_REG */ |
588 | 296 | ||
589 | #endif /* __ASSEMBLY__ */ | ||
590 | |||
591 | #endif /* __ASM_ARC_ENTRY_H */ | 297 | #endif /* __ASM_ARC_ENTRY_H */ |
diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile index 113f2033da9f..024a63e90b72 100644 --- a/arch/arc/kernel/Makefile +++ b/arch/arc/kernel/Makefile | |||
@@ -8,9 +8,9 @@ | |||
8 | # Pass UTS_MACHINE for user_regset definition | 8 | # Pass UTS_MACHINE for user_regset definition |
9 | CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' | 9 | CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' |
10 | 10 | ||
11 | obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o entry.o process.o | 11 | obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o |
12 | obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o clk.o | 12 | obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o clk.o |
13 | obj-y += devtree.o | 13 | obj-y += entry-compact.o |
14 | 14 | ||
15 | obj-$(CONFIG_MODULES) += arcksyms.o module.o | 15 | obj-$(CONFIG_MODULES) += arcksyms.o module.o |
16 | obj-$(CONFIG_SMP) += smp.o | 16 | obj-$(CONFIG_SMP) += smp.o |
diff --git a/arch/arc/kernel/entry-compact.S b/arch/arc/kernel/entry-compact.S new file mode 100644 index 000000000000..bf611ec9a017 --- /dev/null +++ b/arch/arc/kernel/entry-compact.S | |||
@@ -0,0 +1,393 @@ | |||
1 | /* | ||
2 | * Low Level Interrupts/Traps/Exceptions(non-TLB) Handling for ARCompact ISA | ||
3 | * | ||
4 | * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com) | ||
5 | * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * vineetg: May 2011 | ||
12 | * -Userspace unaligned access emulation | ||
13 | * | ||
14 | * vineetg: Feb 2011 (ptrace low level code fixes) | ||
15 | * -traced syscall return code (r0) was not saved into pt_regs for restoring | ||
16 | * into user reg-file when traded task rets to user space. | ||
17 | * -syscalls needing arch-wrappers (mainly for passing sp as pt_regs) | ||
18 | * were not invoking post-syscall trace hook (jumping directly into | ||
19 | * ret_from_system_call) | ||
20 | * | ||
21 | * vineetg: Nov 2010: | ||
22 | * -Vector table jumps (@8 bytes) converted into branches (@4 bytes) | ||
23 | * -To maintain the slot size of 8 bytes/vector, added nop, which is | ||
24 | * not executed at runtime. | ||
25 | * | ||
26 | * vineetg: Nov 2009 (Everything needed for TIF_RESTORE_SIGMASK) | ||
27 | * -do_signal()invoked upon TIF_RESTORE_SIGMASK as well | ||
28 | * -Wrappers for sys_{,rt_}sigsuspend() nolonger needed as they don't | ||
29 | * need ptregs anymore | ||
30 | * | ||
31 | * Vineetg: Oct 2009 | ||
32 | * -In a rare scenario, Process gets a Priv-V exception and gets scheduled | ||
33 | * out. Since we don't do FAKE RTIE for Priv-V, CPU excpetion state remains | ||
34 | * active (AE bit enabled). This causes a double fault for a subseq valid | ||
35 | * exception. Thus FAKE RTIE needed in low level Priv-Violation handler. | ||
36 | * Instr Error could also cause similar scenario, so same there as well. | ||
37 | * | ||
38 | * Vineetg: March 2009 (Supporting 2 levels of Interrupts) | ||
39 | * | ||
40 | * Vineetg: Aug 28th 2008: Bug #94984 | ||
41 | * -Zero Overhead Loop Context shd be cleared when entering IRQ/EXcp/Trap | ||
42 | * Normally CPU does this automatically, however when doing FAKE rtie, | ||
43 | * we need to explicitly do this. The problem in macros | ||
44 | * FAKE_RET_FROM_EXCPN and FAKE_RET_FROM_EXCPN_LOCK_IRQ was that this bit | ||
45 | * was being "CLEARED" rather then "SET". Since it is Loop INHIBIT Bit, | ||
46 | * setting it and not clearing it clears ZOL context | ||
47 | * | ||
48 | * Vineetg: May 16th, 2008 | ||
49 | * - r25 now contains the Current Task when in kernel | ||
50 | * | ||
51 | * Vineetg: Dec 22, 2007 | ||
52 | * Minor Surgery of Low Level ISR to make it SMP safe | ||
53 | * - MMU_SCRATCH0 Reg used for freeing up r9 in Level 1 ISR | ||
54 | * - _current_task is made an array of NR_CPUS | ||
55 | * - Access of _current_task wrapped inside a macro so that if hardware | ||
56 | * team agrees for a dedicated reg, no other code is touched | ||
57 | * | ||
58 | * Amit Bhor, Rahul Trivedi, Kanika Nema, Sameer Dhavale : Codito Tech 2004 | ||
59 | */ | ||
60 | |||
61 | #include <linux/errno.h> | ||
62 | #include <linux/linkage.h> /* {EXTRY,EXIT} */ | ||
63 | #include <asm/entry.h> | ||
64 | #include <asm/irqflags.h> | ||
65 | |||
66 | .cpu A7 | ||
67 | |||
68 | ;############################ Vector Table ################################# | ||
69 | |||
70 | .macro VECTOR lbl | ||
71 | #if 1 /* Just in case, build breaks */ | ||
72 | j \lbl | ||
73 | #else | ||
74 | b \lbl | ||
75 | nop | ||
76 | #endif | ||
77 | .endm | ||
78 | |||
79 | .section .vector, "ax",@progbits | ||
80 | .align 4 | ||
81 | |||
82 | /* Each entry in the vector table must occupy 2 words. Since it is a jump | ||
83 | * across sections (.vector to .text) we are gauranteed that 'j somewhere' | ||
84 | * will use the 'j limm' form of the intrsuction as long as somewhere is in | ||
85 | * a section other than .vector. | ||
86 | */ | ||
87 | |||
88 | ; ********* Critical System Events ********************** | ||
89 | VECTOR res_service ; 0x0, Restart Vector (0x0) | ||
90 | VECTOR mem_service ; 0x8, Mem exception (0x1) | ||
91 | VECTOR instr_service ; 0x10, Instrn Error (0x2) | ||
92 | |||
93 | ; ******************** Device ISRs ********************** | ||
94 | #ifdef CONFIG_ARC_IRQ3_LV2 | ||
95 | VECTOR handle_interrupt_level2 | ||
96 | #else | ||
97 | VECTOR handle_interrupt_level1 | ||
98 | #endif | ||
99 | |||
100 | VECTOR handle_interrupt_level1 | ||
101 | |||
102 | #ifdef CONFIG_ARC_IRQ5_LV2 | ||
103 | VECTOR handle_interrupt_level2 | ||
104 | #else | ||
105 | VECTOR handle_interrupt_level1 | ||
106 | #endif | ||
107 | |||
108 | #ifdef CONFIG_ARC_IRQ6_LV2 | ||
109 | VECTOR handle_interrupt_level2 | ||
110 | #else | ||
111 | VECTOR handle_interrupt_level1 | ||
112 | #endif | ||
113 | |||
114 | .rept 25 | ||
115 | VECTOR handle_interrupt_level1 ; Other devices | ||
116 | .endr | ||
117 | |||
118 | /* FOR ARC600: timer = 0x3, uart = 0x8, emac = 0x10 */ | ||
119 | |||
120 | ; ******************** Exceptions ********************** | ||
121 | VECTOR EV_MachineCheck ; 0x100, Fatal Machine check (0x20) | ||
122 | VECTOR EV_TLBMissI ; 0x108, Intruction TLB miss (0x21) | ||
123 | VECTOR EV_TLBMissD ; 0x110, Data TLB miss (0x22) | ||
124 | VECTOR EV_TLBProtV ; 0x118, Protection Violation (0x23) | ||
125 | ; or Misaligned Access | ||
126 | VECTOR EV_PrivilegeV ; 0x120, Privilege Violation (0x24) | ||
127 | VECTOR EV_Trap ; 0x128, Trap exception (0x25) | ||
128 | VECTOR EV_Extension ; 0x130, Extn Intruction Excp (0x26) | ||
129 | |||
130 | .rept 24 | ||
131 | VECTOR reserved ; Reserved Exceptions | ||
132 | .endr | ||
133 | |||
134 | |||
135 | ;##################### Scratch Mem for IRQ stack switching ############# | ||
136 | |||
137 | ARCFP_DATA int1_saved_reg | ||
138 | .align 32 | ||
139 | .type int1_saved_reg, @object | ||
140 | .size int1_saved_reg, 4 | ||
141 | int1_saved_reg: | ||
142 | .zero 4 | ||
143 | |||
144 | /* Each Interrupt level needs its own scratch */ | ||
145 | #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS | ||
146 | |||
147 | ARCFP_DATA int2_saved_reg | ||
148 | .type int2_saved_reg, @object | ||
149 | .size int2_saved_reg, 4 | ||
150 | int2_saved_reg: | ||
151 | .zero 4 | ||
152 | |||
153 | #endif | ||
154 | |||
155 | ; --------------------------------------------- | ||
156 | .section .text, "ax",@progbits | ||
157 | |||
158 | res_service: ; processor restart | ||
159 | flag 0x1 ; not implemented | ||
160 | nop | ||
161 | nop | ||
162 | |||
163 | reserved: ; processor restart | ||
164 | rtie ; jump to processor initializations | ||
165 | |||
166 | ;##################### Interrupt Handling ############################## | ||
167 | |||
168 | #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS | ||
169 | ; --------------------------------------------- | ||
170 | ; Level 2 ISR: Can interrupt a Level 1 ISR | ||
171 | ; --------------------------------------------- | ||
172 | ENTRY(handle_interrupt_level2) | ||
173 | |||
174 | INTERRUPT_PROLOGUE 2 | ||
175 | |||
176 | ;------------------------------------------------------ | ||
177 | ; if L2 IRQ interrupted a L1 ISR, disable preemption | ||
178 | ;------------------------------------------------------ | ||
179 | |||
180 | ld r9, [sp, PT_status32] ; get statu32_l2 (saved in pt_regs) | ||
181 | bbit0 r9, STATUS_A1_BIT, 1f ; L1 not active when L2 IRQ, so normal | ||
182 | |||
183 | ; A1 is set in status32_l2 | ||
184 | ; bump thread_info->preempt_count (Disable preemption) | ||
185 | GET_CURR_THR_INFO_FROM_SP r10 | ||
186 | ld r9, [r10, THREAD_INFO_PREEMPT_COUNT] | ||
187 | add r9, r9, 1 | ||
188 | st r9, [r10, THREAD_INFO_PREEMPT_COUNT] | ||
189 | |||
190 | 1: | ||
191 | ;------------------------------------------------------ | ||
192 | ; setup params for Linux common ISR and invoke it | ||
193 | ;------------------------------------------------------ | ||
194 | lr r0, [icause2] | ||
195 | and r0, r0, 0x1f | ||
196 | |||
197 | bl.d @arch_do_IRQ | ||
198 | mov r1, sp | ||
199 | |||
200 | mov r8,0x2 | ||
201 | sr r8, [AUX_IRQ_LV12] ; clear bit in Sticky Status Reg | ||
202 | |||
203 | b ret_from_exception | ||
204 | |||
205 | END(handle_interrupt_level2) | ||
206 | |||
207 | #endif | ||
208 | |||
209 | ; --------------------------------------------- | ||
210 | ; Level 1 ISR | ||
211 | ; --------------------------------------------- | ||
212 | ENTRY(handle_interrupt_level1) | ||
213 | |||
214 | INTERRUPT_PROLOGUE 1 | ||
215 | |||
216 | lr r0, [icause1] | ||
217 | and r0, r0, 0x1f | ||
218 | |||
219 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
220 | ; icause1 needs to be read early, before calling tracing, which | ||
221 | ; can clobber scratch regs, hence use of stack to stash it | ||
222 | push r0 | ||
223 | TRACE_ASM_IRQ_DISABLE | ||
224 | pop r0 | ||
225 | #endif | ||
226 | |||
227 | bl.d @arch_do_IRQ | ||
228 | mov r1, sp | ||
229 | |||
230 | mov r8,0x1 | ||
231 | sr r8, [AUX_IRQ_LV12] ; clear bit in Sticky Status Reg | ||
232 | |||
233 | b ret_from_exception | ||
234 | END(handle_interrupt_level1) | ||
235 | |||
236 | ;################### Non TLB Exception Handling ############################# | ||
237 | |||
238 | ; --------------------------------------------- | ||
239 | ; Protection Violation Exception Handler | ||
240 | ; --------------------------------------------- | ||
241 | |||
242 | ENTRY(EV_TLBProtV) | ||
243 | |||
244 | EXCEPTION_PROLOGUE | ||
245 | |||
246 | lr r2, [ecr] | ||
247 | lr r0, [efa] ; Faulting Data address (not part of pt_regs saved above) | ||
248 | |||
249 | ; Exception auto-disables further Intr/exceptions. | ||
250 | ; Re-enable them by pretending to return from exception | ||
251 | ; (so rest of handler executes in pure K mode) | ||
252 | |||
253 | FAKE_RET_FROM_EXCPN | ||
254 | |||
255 | mov r1, sp ; Handle to pt_regs | ||
256 | |||
257 | ;------ (5) Type of Protection Violation? ---------- | ||
258 | ; | ||
259 | ; ProtV Hardware Exception is triggered for Access Faults of 2 types | ||
260 | ; -Access Violaton : 00_23_(00|01|02|03)_00 | ||
261 | ; x r w r+w | ||
262 | ; -Unaligned Access : 00_23_04_00 | ||
263 | ; | ||
264 | bbit1 r2, ECR_C_BIT_PROTV_MISALIG_DATA, 4f | ||
265 | |||
266 | ;========= (6a) Access Violation Processing ======== | ||
267 | bl do_page_fault | ||
268 | b ret_from_exception | ||
269 | |||
270 | ;========== (6b) Non aligned access ============ | ||
271 | 4: | ||
272 | |||
273 | SAVE_CALLEE_SAVED_USER | ||
274 | mov r2, sp ; callee_regs | ||
275 | |||
276 | bl do_misaligned_access | ||
277 | |||
278 | ; TBD: optimize - do this only if a callee reg was involved | ||
279 | ; either a dst of emulated LD/ST or src with address-writeback | ||
280 | RESTORE_CALLEE_SAVED_USER | ||
281 | |||
282 | b ret_from_exception | ||
283 | |||
284 | END(EV_TLBProtV) | ||
285 | |||
286 | ; Wrapper for Linux page fault handler called from EV_TLBMiss* | ||
287 | ; Very similar to ProtV handler case (6a) above, but avoids the extra checks | ||
288 | ; for Misaligned access | ||
289 | ; | ||
290 | ENTRY(call_do_page_fault) | ||
291 | |||
292 | EXCEPTION_PROLOGUE | ||
293 | lr r0, [efa] ; Faulting Data address | ||
294 | mov r1, sp | ||
295 | FAKE_RET_FROM_EXCPN | ||
296 | |||
297 | mov blink, ret_from_exception | ||
298 | b do_page_fault | ||
299 | |||
300 | END(call_do_page_fault) | ||
301 | |||
302 | ;############# Common Handlers for ARCompact and ARCv2 ############## | ||
303 | |||
304 | #include "entry.S" | ||
305 | |||
306 | ;############# Return from Intr/Excp/Trap (ARC Specifics) ############## | ||
307 | ; | ||
308 | ; Restore the saved sys context (common exit-path for EXCPN/IRQ/Trap) | ||
309 | ; IRQ shd definitely not happen between now and rtie | ||
310 | ; All 2 entry points to here already disable interrupts | ||
311 | |||
312 | .Lrestore_regs: | ||
313 | |||
314 | TRACE_ASM_IRQ_ENABLE | ||
315 | |||
316 | lr r10, [status32] | ||
317 | |||
318 | ; Restore REG File. In case multiple Events outstanding, | ||
319 | ; use the same priorty as rtie: EXCPN, L2 IRQ, L1 IRQ, None | ||
320 | ; Note that we use realtime STATUS32 (not pt_regs->status32) to | ||
321 | ; decide that. | ||
322 | |||
323 | ; if Returning from Exception | ||
324 | bbit0 r10, STATUS_AE_BIT, not_exception | ||
325 | EXCEPTION_EPILOGUE | ||
326 | rtie | ||
327 | |||
328 | ; Not Exception so maybe Interrupts (Level 1 or 2) | ||
329 | |||
330 | not_exception: | ||
331 | |||
332 | #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS | ||
333 | |||
334 | ; Level 2 interrupt return Path - from hardware standpoint | ||
335 | bbit0 r10, STATUS_A2_BIT, not_level2_interrupt | ||
336 | |||
337 | ;------------------------------------------------------------------ | ||
338 | ; However the context returning might not have taken L2 intr itself | ||
339 | ; e.g. Task'A' user-code -> L2 intr -> schedule -> 'B' user-code ret | ||
340 | ; Special considerations needed for the context which took L2 intr | ||
341 | |||
342 | ld r9, [sp, PT_event] ; Ensure this is L2 intr context | ||
343 | brne r9, event_IRQ2, 149f | ||
344 | |||
345 | ;------------------------------------------------------------------ | ||
346 | ; if L2 IRQ interrupted an L1 ISR, we'd disabled preemption earlier | ||
347 | ; so that sched doesn't move to new task, causing L1 to be delayed | ||
348 | ; undeterministically. Now that we've achieved that, let's reset | ||
349 | ; things to what they were, before returning from L2 context | ||
350 | ;---------------------------------------------------------------- | ||
351 | |||
352 | ld r9, [sp, PT_status32] ; get statu32_l2 (saved in pt_regs) | ||
353 | bbit0 r9, STATUS_A1_BIT, 149f ; L1 not active when L2 IRQ, so normal | ||
354 | |||
355 | ; decrement thread_info->preempt_count (re-enable preemption) | ||
356 | GET_CURR_THR_INFO_FROM_SP r10 | ||
357 | ld r9, [r10, THREAD_INFO_PREEMPT_COUNT] | ||
358 | |||
359 | ; paranoid check, given A1 was active when A2 happened, preempt count | ||
360 | ; must not be 0 because we would have incremented it. | ||
361 | ; If this does happen we simply HALT as it means a BUG !!! | ||
362 | cmp r9, 0 | ||
363 | bnz 2f | ||
364 | flag 1 | ||
365 | |||
366 | 2: | ||
367 | sub r9, r9, 1 | ||
368 | st r9, [r10, THREAD_INFO_PREEMPT_COUNT] | ||
369 | |||
370 | 149: | ||
371 | ;return from level 2 | ||
372 | INTERRUPT_EPILOGUE 2 | ||
373 | debug_marker_l2: | ||
374 | rtie | ||
375 | |||
376 | not_level2_interrupt: | ||
377 | |||
378 | #endif | ||
379 | |||
380 | bbit0 r10, STATUS_A1_BIT, not_level1_interrupt | ||
381 | |||
382 | ;return from level 1 | ||
383 | INTERRUPT_EPILOGUE 1 | ||
384 | debug_marker_l1: | ||
385 | rtie | ||
386 | |||
387 | not_level1_interrupt: | ||
388 | |||
389 | ;this case is for syscalls or Exceptions (with fake rtie) | ||
390 | |||
391 | EXCEPTION_EPILOGUE | ||
392 | debug_marker_syscall: | ||
393 | rtie | ||
diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S index 286d7dc0723b..75cdc56351d9 100644 --- a/arch/arc/kernel/entry.S +++ b/arch/arc/kernel/entry.S | |||
@@ -1,60 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * Low Level Interrupts/Traps/Exceptions(non-TLB) Handling for ARC | 2 | * Common Low Level Interrupts/Traps/Exceptions(non-TLB) Handling for ARC |
3 | * (included from entry-<isa>.S | ||
3 | * | 4 | * |
5 | * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com) | ||
4 | * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) | 6 | * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) |
5 | * | 7 | * |
6 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
9 | * | ||
10 | * vineetg: May 2011 | ||
11 | * -Userspace unaligned access emulation | ||
12 | * | ||
13 | * vineetg: Feb 2011 (ptrace low level code fixes) | ||
14 | * -traced syscall return code (r0) was not saved into pt_regs for restoring | ||
15 | * into user reg-file when traded task rets to user space. | ||
16 | * -syscalls needing arch-wrappers (mainly for passing sp as pt_regs) | ||
17 | * were not invoking post-syscall trace hook (jumping directly into | ||
18 | * ret_from_system_call) | ||
19 | * | ||
20 | * vineetg: Nov 2010: | ||
21 | * -Vector table jumps (@8 bytes) converted into branches (@4 bytes) | ||
22 | * -To maintain the slot size of 8 bytes/vector, added nop, which is | ||
23 | * not executed at runtime. | ||
24 | * | ||
25 | * vineetg: Nov 2009 (Everything needed for TIF_RESTORE_SIGMASK) | ||
26 | * -do_signal()invoked upon TIF_RESTORE_SIGMASK as well | ||
27 | * -Wrappers for sys_{,rt_}sigsuspend() nolonger needed as they don't | ||
28 | * need ptregs anymore | ||
29 | * | ||
30 | * Vineetg: Oct 2009 | ||
31 | * -In a rare scenario, Process gets a Priv-V exception and gets scheduled | ||
32 | * out. Since we don't do FAKE RTIE for Priv-V, CPU excpetion state remains | ||
33 | * active (AE bit enabled). This causes a double fault for a subseq valid | ||
34 | * exception. Thus FAKE RTIE needed in low level Priv-Violation handler. | ||
35 | * Instr Error could also cause similar scenario, so same there as well. | ||
36 | * | ||
37 | * Vineetg: March 2009 (Supporting 2 levels of Interrupts) | ||
38 | * | ||
39 | * Vineetg: Aug 28th 2008: Bug #94984 | ||
40 | * -Zero Overhead Loop Context shd be cleared when entering IRQ/EXcp/Trap | ||
41 | * Normally CPU does this automatically, however when doing FAKE rtie, | ||
42 | * we need to explicitly do this. The problem in macros | ||
43 | * FAKE_RET_FROM_EXCPN and FAKE_RET_FROM_EXCPN_LOCK_IRQ was that this bit | ||
44 | * was being "CLEARED" rather then "SET". Since it is Loop INHIBIT Bit, | ||
45 | * setting it and not clearing it clears ZOL context | ||
46 | * | ||
47 | * Vineetg: May 16th, 2008 | ||
48 | * - r25 now contains the Current Task when in kernel | ||
49 | * | ||
50 | * Vineetg: Dec 22, 2007 | ||
51 | * Minor Surgery of Low Level ISR to make it SMP safe | ||
52 | * - MMU_SCRATCH0 Reg used for freeing up r9 in Level 1 ISR | ||
53 | * - _current_task is made an array of NR_CPUS | ||
54 | * - Access of _current_task wrapped inside a macro so that if hardware | ||
55 | * team agrees for a dedicated reg, no other code is touched | ||
56 | * | ||
57 | * Amit Bhor, Rahul Trivedi, Kanika Nema, Sameer Dhavale : Codito Tech 2004 | ||
58 | */ | 11 | */ |
59 | 12 | ||
60 | /*------------------------------------------------------------------ | 13 | /*------------------------------------------------------------------ |
@@ -67,187 +20,10 @@ | |||
67 | * Global Pointer (gp) r26 | 20 | * Global Pointer (gp) r26 |
68 | * Frame Pointer (fp) r27 | 21 | * Frame Pointer (fp) r27 |
69 | * Stack Pointer (sp) r28 | 22 | * Stack Pointer (sp) r28 |
70 | * Interrupt link register (ilink1) r29 | ||
71 | * Interrupt link register (ilink2) r30 | ||
72 | * Branch link register (blink) r31 | 23 | * Branch link register (blink) r31 |
73 | *------------------------------------------------------------------ | 24 | *------------------------------------------------------------------ |
74 | */ | 25 | */ |
75 | 26 | ||
76 | .cpu A7 | ||
77 | |||
78 | ;############################ Vector Table ################################# | ||
79 | |||
80 | .macro VECTOR lbl | ||
81 | #if 1 /* Just in case, build breaks */ | ||
82 | j \lbl | ||
83 | #else | ||
84 | b \lbl | ||
85 | nop | ||
86 | #endif | ||
87 | .endm | ||
88 | |||
89 | .section .vector, "ax",@progbits | ||
90 | .align 4 | ||
91 | |||
92 | /* Each entry in the vector table must occupy 2 words. Since it is a jump | ||
93 | * across sections (.vector to .text) we are gauranteed that 'j somewhere' | ||
94 | * will use the 'j limm' form of the intrsuction as long as somewhere is in | ||
95 | * a section other than .vector. | ||
96 | */ | ||
97 | |||
98 | ; ********* Critical System Events ********************** | ||
99 | VECTOR res_service ; 0x0, Restart Vector (0x0) | ||
100 | VECTOR mem_service ; 0x8, Mem exception (0x1) | ||
101 | VECTOR instr_service ; 0x10, Instrn Error (0x2) | ||
102 | |||
103 | ; ******************** Device ISRs ********************** | ||
104 | #ifdef CONFIG_ARC_IRQ3_LV2 | ||
105 | VECTOR handle_interrupt_level2 | ||
106 | #else | ||
107 | VECTOR handle_interrupt_level1 | ||
108 | #endif | ||
109 | |||
110 | VECTOR handle_interrupt_level1 | ||
111 | |||
112 | #ifdef CONFIG_ARC_IRQ5_LV2 | ||
113 | VECTOR handle_interrupt_level2 | ||
114 | #else | ||
115 | VECTOR handle_interrupt_level1 | ||
116 | #endif | ||
117 | |||
118 | #ifdef CONFIG_ARC_IRQ6_LV2 | ||
119 | VECTOR handle_interrupt_level2 | ||
120 | #else | ||
121 | VECTOR handle_interrupt_level1 | ||
122 | #endif | ||
123 | |||
124 | .rept 25 | ||
125 | VECTOR handle_interrupt_level1 ; Other devices | ||
126 | .endr | ||
127 | |||
128 | /* FOR ARC600: timer = 0x3, uart = 0x8, emac = 0x10 */ | ||
129 | |||
130 | ; ******************** Exceptions ********************** | ||
131 | VECTOR EV_MachineCheck ; 0x100, Fatal Machine check (0x20) | ||
132 | VECTOR EV_TLBMissI ; 0x108, Intruction TLB miss (0x21) | ||
133 | VECTOR EV_TLBMissD ; 0x110, Data TLB miss (0x22) | ||
134 | VECTOR EV_TLBProtV ; 0x118, Protection Violation (0x23) | ||
135 | ; or Misaligned Access | ||
136 | VECTOR EV_PrivilegeV ; 0x120, Privilege Violation (0x24) | ||
137 | VECTOR EV_Trap ; 0x128, Trap exception (0x25) | ||
138 | VECTOR EV_Extension ; 0x130, Extn Intruction Excp (0x26) | ||
139 | |||
140 | .rept 24 | ||
141 | VECTOR reserved ; Reserved Exceptions | ||
142 | .endr | ||
143 | |||
144 | #include <linux/linkage.h> /* {EXTRY,EXIT} */ | ||
145 | #include <asm/entry.h> /* SAVE_ALL_{INT1,INT2,SYS...} */ | ||
146 | #include <asm/errno.h> | ||
147 | #include <asm/arcregs.h> | ||
148 | #include <asm/irqflags.h> | ||
149 | |||
150 | ;##################### Scratch Mem for IRQ stack switching ############# | ||
151 | |||
152 | ARCFP_DATA int1_saved_reg | ||
153 | .align 32 | ||
154 | .type int1_saved_reg, @object | ||
155 | .size int1_saved_reg, 4 | ||
156 | int1_saved_reg: | ||
157 | .zero 4 | ||
158 | |||
159 | /* Each Interrupt level needs its own scratch */ | ||
160 | #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS | ||
161 | |||
162 | ARCFP_DATA int2_saved_reg | ||
163 | .type int2_saved_reg, @object | ||
164 | .size int2_saved_reg, 4 | ||
165 | int2_saved_reg: | ||
166 | .zero 4 | ||
167 | |||
168 | #endif | ||
169 | |||
170 | ; --------------------------------------------- | ||
171 | .section .text, "ax",@progbits | ||
172 | |||
173 | res_service: ; processor restart | ||
174 | flag 0x1 ; not implemented | ||
175 | nop | ||
176 | nop | ||
177 | |||
178 | reserved: ; processor restart | ||
179 | rtie ; jump to processor initializations | ||
180 | |||
181 | ;##################### Interrupt Handling ############################## | ||
182 | |||
183 | #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS | ||
184 | ; --------------------------------------------- | ||
185 | ; Level 2 ISR: Can interrupt a Level 1 ISR | ||
186 | ; --------------------------------------------- | ||
187 | ENTRY(handle_interrupt_level2) | ||
188 | |||
189 | INTERRUPT_PROLOGUE 2 | ||
190 | |||
191 | ;------------------------------------------------------ | ||
192 | ; if L2 IRQ interrupted a L1 ISR, disable preemption | ||
193 | ;------------------------------------------------------ | ||
194 | |||
195 | ld r9, [sp, PT_status32] ; get statu32_l2 (saved in pt_regs) | ||
196 | bbit0 r9, STATUS_A1_BIT, 1f ; L1 not active when L2 IRQ, so normal | ||
197 | |||
198 | ; A1 is set in status32_l2 | ||
199 | ; bump thread_info->preempt_count (Disable preemption) | ||
200 | GET_CURR_THR_INFO_FROM_SP r10 | ||
201 | ld r9, [r10, THREAD_INFO_PREEMPT_COUNT] | ||
202 | add r9, r9, 1 | ||
203 | st r9, [r10, THREAD_INFO_PREEMPT_COUNT] | ||
204 | |||
205 | 1: | ||
206 | ;------------------------------------------------------ | ||
207 | ; setup params for Linux common ISR and invoke it | ||
208 | ;------------------------------------------------------ | ||
209 | lr r0, [icause2] | ||
210 | and r0, r0, 0x1f | ||
211 | |||
212 | bl.d @arch_do_IRQ | ||
213 | mov r1, sp | ||
214 | |||
215 | mov r8,0x2 | ||
216 | sr r8, [AUX_IRQ_LV12] ; clear bit in Sticky Status Reg | ||
217 | |||
218 | b ret_from_exception | ||
219 | |||
220 | END(handle_interrupt_level2) | ||
221 | |||
222 | #endif | ||
223 | |||
224 | ; --------------------------------------------- | ||
225 | ; Level 1 ISR | ||
226 | ; --------------------------------------------- | ||
227 | ENTRY(handle_interrupt_level1) | ||
228 | |||
229 | INTERRUPT_PROLOGUE 1 | ||
230 | |||
231 | lr r0, [icause1] | ||
232 | and r0, r0, 0x1f | ||
233 | |||
234 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
235 | ; icause1 needs to be read early, before calling tracing, which | ||
236 | ; can clobber scratch regs, hence use of stack to stash it | ||
237 | push r0 | ||
238 | TRACE_ASM_IRQ_DISABLE | ||
239 | pop r0 | ||
240 | #endif | ||
241 | |||
242 | bl.d @arch_do_IRQ | ||
243 | mov r1, sp | ||
244 | |||
245 | mov r8,0x1 | ||
246 | sr r8, [AUX_IRQ_LV12] ; clear bit in Sticky Status Reg | ||
247 | |||
248 | b ret_from_exception | ||
249 | END(handle_interrupt_level1) | ||
250 | |||
251 | ;################### Non TLB Exception Handling ############################# | 27 | ;################### Non TLB Exception Handling ############################# |
252 | 28 | ||
253 | ; --------------------------------------------- | 29 | ; --------------------------------------------- |
@@ -315,70 +91,6 @@ ENTRY(EV_MachineCheck) | |||
315 | END(EV_MachineCheck) | 91 | END(EV_MachineCheck) |
316 | 92 | ||
317 | ; --------------------------------------------- | 93 | ; --------------------------------------------- |
318 | ; Protection Violation Exception Handler | ||
319 | ; --------------------------------------------- | ||
320 | |||
321 | ENTRY(EV_TLBProtV) | ||
322 | |||
323 | EXCEPTION_PROLOGUE | ||
324 | |||
325 | lr r2, [ecr] | ||
326 | lr r0, [efa] ; Faulting Data addr (not part of pt_regs saved above) | ||
327 | |||
328 | ; Exception auto-disables further Intr/exceptions. | ||
329 | ; Re-enable them by pretending to return from exception | ||
330 | ; (so rest of handler executes in pure K mode) | ||
331 | |||
332 | FAKE_RET_FROM_EXCPN | ||
333 | |||
334 | mov r1, sp ; Handle to pt_regs | ||
335 | |||
336 | ;------ (5) Type of Protection Violation? ---------- | ||
337 | ; | ||
338 | ; ProtV Hardware Exception is triggered for Access Faults of 2 types | ||
339 | ; -Access Violaton : 00_23_(00|01|02|03)_00 | ||
340 | ; x r w r+w | ||
341 | ; -Unaligned Access : 00_23_04_00 | ||
342 | ; | ||
343 | bbit1 r2, ECR_C_BIT_PROTV_MISALIG_DATA, 4f | ||
344 | |||
345 | ;========= (6a) Access Violation Processing ======== | ||
346 | bl do_page_fault | ||
347 | b ret_from_exception | ||
348 | |||
349 | ;========== (6b) Non aligned access ============ | ||
350 | 4: | ||
351 | |||
352 | SAVE_CALLEE_SAVED_USER | ||
353 | mov r2, sp ; callee_regs | ||
354 | |||
355 | bl do_misaligned_access | ||
356 | |||
357 | ; TBD: optimize - do this only if a callee reg was involved | ||
358 | ; either a dst of emulated LD/ST or src with address-writeback | ||
359 | RESTORE_CALLEE_SAVED_USER | ||
360 | |||
361 | b ret_from_exception | ||
362 | |||
363 | END(EV_TLBProtV) | ||
364 | |||
365 | ; Wrapper for Linux page fault handler called from EV_TLBMiss* | ||
366 | ; Very similar to ProtV handler case (6a) above, but avoids the extra checks | ||
367 | ; for Misaligned access | ||
368 | ; | ||
369 | ENTRY(call_do_page_fault) | ||
370 | |||
371 | EXCEPTION_PROLOGUE | ||
372 | lr r0, [efa] ; Faulting Data address | ||
373 | mov r1, sp | ||
374 | FAKE_RET_FROM_EXCPN | ||
375 | |||
376 | mov blink, ret_from_exception | ||
377 | b do_page_fault | ||
378 | |||
379 | END(call_do_page_fault) | ||
380 | |||
381 | ; --------------------------------------------- | ||
382 | ; Privilege Violation Exception Handler | 94 | ; Privilege Violation Exception Handler |
383 | ; --------------------------------------------- | 95 | ; --------------------------------------------- |
384 | ENTRY(EV_PrivilegeV) | 96 | ENTRY(EV_PrivilegeV) |
@@ -625,97 +337,7 @@ resume_kernel_mode: | |||
625 | ; preempt_schedule_irq() always returns with IRQ disabled | 337 | ; preempt_schedule_irq() always returns with IRQ disabled |
626 | #endif | 338 | #endif |
627 | 339 | ||
628 | ; fall through | 340 | b .Lrestore_regs |
629 | |||
630 | ;############# Return from Intr/Excp/Trap (ARC Specifics) ############## | ||
631 | ; | ||
632 | ; Restore the saved sys context (common exit-path for EXCPN/IRQ/Trap) | ||
633 | ; IRQ shd definitely not happen between now and rtie | ||
634 | ; All 2 entry points to here already disable interrupts | ||
635 | |||
636 | .Lrestore_regs: | ||
637 | |||
638 | TRACE_ASM_IRQ_ENABLE | ||
639 | |||
640 | lr r10, [status32] | ||
641 | |||
642 | ; Restore REG File. In case multiple Events outstanding, | ||
643 | ; use the same priorty as rtie: EXCPN, L2 IRQ, L1 IRQ, None | ||
644 | ; Note that we use realtime STATUS32 (not pt_regs->status32) to | ||
645 | ; decide that. | ||
646 | |||
647 | ; if Returning from Exception | ||
648 | bbit0 r10, STATUS_AE_BIT, not_exception | ||
649 | EXCEPTION_EPILOGUE | ||
650 | rtie | ||
651 | |||
652 | ; Not Exception so maybe Interrupts (Level 1 or 2) | ||
653 | |||
654 | not_exception: | ||
655 | |||
656 | #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS | ||
657 | |||
658 | ; Level 2 interrupt return Path - from hardware standpoint | ||
659 | bbit0 r10, STATUS_A2_BIT, not_level2_interrupt | ||
660 | |||
661 | ;------------------------------------------------------------------ | ||
662 | ; However the context returning might not have taken L2 intr itself | ||
663 | ; e.g. Task'A' user-code -> L2 intr -> schedule -> 'B' user-code ret | ||
664 | ; Special considerations needed for the context which took L2 intr | ||
665 | |||
666 | ld r9, [sp, PT_event] ; Ensure this is L2 intr context | ||
667 | brne r9, event_IRQ2, 149f | ||
668 | |||
669 | ;------------------------------------------------------------------ | ||
670 | ; if L2 IRQ interrupted an L1 ISR, we'd disabled preemption earlier | ||
671 | ; so that sched doesn't move to new task, causing L1 to be delayed | ||
672 | ; undeterministically. Now that we've achieved that, let's reset | ||
673 | ; things to what they were, before returning from L2 context | ||
674 | ;---------------------------------------------------------------- | ||
675 | |||
676 | ld r9, [sp, PT_status32] ; get statu32_l2 (saved in pt_regs) | ||
677 | bbit0 r9, STATUS_A1_BIT, 149f ; L1 not active when L2 IRQ, so normal | ||
678 | |||
679 | ; decrement thread_info->preempt_count (re-enable preemption) | ||
680 | GET_CURR_THR_INFO_FROM_SP r10 | ||
681 | ld r9, [r10, THREAD_INFO_PREEMPT_COUNT] | ||
682 | |||
683 | ; paranoid check, given A1 was active when A2 happened, preempt count | ||
684 | ; must not be 0 because we would have incremented it. | ||
685 | ; If this does happen we simply HALT as it means a BUG !!! | ||
686 | cmp r9, 0 | ||
687 | bnz 2f | ||
688 | flag 1 | ||
689 | |||
690 | 2: | ||
691 | sub r9, r9, 1 | ||
692 | st r9, [r10, THREAD_INFO_PREEMPT_COUNT] | ||
693 | |||
694 | 149: | ||
695 | ;return from level 2 | ||
696 | INTERRUPT_EPILOGUE 2 | ||
697 | debug_marker_l2: | ||
698 | rtie | ||
699 | |||
700 | not_level2_interrupt: | ||
701 | |||
702 | #endif | ||
703 | |||
704 | bbit0 r10, STATUS_A1_BIT, not_level1_interrupt | ||
705 | |||
706 | ;return from level 1 | ||
707 | INTERRUPT_EPILOGUE 1 | ||
708 | debug_marker_l1: | ||
709 | rtie | ||
710 | |||
711 | not_level1_interrupt: | ||
712 | |||
713 | ;this case is for syscalls or Exceptions (with fake rtie) | ||
714 | |||
715 | EXCEPTION_EPILOGUE | ||
716 | debug_marker_syscall: | ||
717 | rtie | ||
718 | |||
719 | END(ret_from_exception) | 341 | END(ret_from_exception) |
720 | 342 | ||
721 | ENTRY(ret_from_fork) | 343 | ENTRY(ret_from_fork) |
@@ -762,4 +384,7 @@ END(sys_clone_wrapper) | |||
762 | ; This also fixes STAR 9000487933 where the prev-workaround (objcopy --setflag) | 384 | ; This also fixes STAR 9000487933 where the prev-workaround (objcopy --setflag) |
763 | ; would not work after a clean build due to kernel build system dependencies. | 385 | ; would not work after a clean build due to kernel build system dependencies. |
764 | .section .debug_frame, "wa",@progbits | 386 | .section .debug_frame, "wa",@progbits |
387 | |||
388 | ; Reset to .text as this file is included in entry-<isa>.S | ||
389 | .section .text, "ax",@progbits | ||
765 | #endif | 390 | #endif |