diff options
Diffstat (limited to 'arch/frv/kernel/entry.S')
-rw-r--r-- | arch/frv/kernel/entry.S | 65 |
1 files changed, 58 insertions, 7 deletions
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index c69d499d28cf..1d21c8d34d8a 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S | |||
@@ -141,7 +141,10 @@ __entry_uspace_external_interrupt_reentry: | |||
141 | 141 | ||
142 | movsg gner0,gr4 | 142 | movsg gner0,gr4 |
143 | movsg gner1,gr5 | 143 | movsg gner1,gr5 |
144 | stdi gr4,@(gr28,#REG_GNER0) | 144 | stdi.p gr4,@(gr28,#REG_GNER0) |
145 | |||
146 | # interrupts start off fully disabled in the interrupt handler | ||
147 | subcc gr0,gr0,gr0,icc2 /* set Z and clear C */ | ||
145 | 148 | ||
146 | # set up kernel global registers | 149 | # set up kernel global registers |
147 | sethi.p %hi(__kernel_current_task),gr5 | 150 | sethi.p %hi(__kernel_current_task),gr5 |
@@ -193,9 +196,8 @@ __entry_uspace_external_interrupt_reentry: | |||
193 | .type __entry_kernel_external_interrupt,@function | 196 | .type __entry_kernel_external_interrupt,@function |
194 | __entry_kernel_external_interrupt: | 197 | __entry_kernel_external_interrupt: |
195 | LEDS 0x6210 | 198 | LEDS 0x6210 |
196 | 199 | // sub sp,gr15,gr31 | |
197 | sub sp,gr15,gr31 | 200 | // LEDS32 |
198 | LEDS32 | ||
199 | 201 | ||
200 | # set up the stack pointer | 202 | # set up the stack pointer |
201 | or.p sp,gr0,gr30 | 203 | or.p sp,gr0,gr30 |
@@ -231,7 +233,10 @@ __entry_kernel_external_interrupt_reentry: | |||
231 | stdi gr24,@(gr28,#REG_GR(24)) | 233 | stdi gr24,@(gr28,#REG_GR(24)) |
232 | stdi gr26,@(gr28,#REG_GR(26)) | 234 | stdi gr26,@(gr28,#REG_GR(26)) |
233 | sti gr29,@(gr28,#REG_GR(29)) | 235 | sti gr29,@(gr28,#REG_GR(29)) |
234 | stdi gr30,@(gr28,#REG_GR(30)) | 236 | stdi.p gr30,@(gr28,#REG_GR(30)) |
237 | |||
238 | # note virtual interrupts will be fully enabled upon return | ||
239 | subicc gr0,#1,gr0,icc2 /* clear Z, set C */ | ||
235 | 240 | ||
236 | movsg tbr ,gr20 | 241 | movsg tbr ,gr20 |
237 | movsg psr ,gr22 | 242 | movsg psr ,gr22 |
@@ -267,7 +272,10 @@ __entry_kernel_external_interrupt_reentry: | |||
267 | 272 | ||
268 | movsg gner0,gr4 | 273 | movsg gner0,gr4 |
269 | movsg gner1,gr5 | 274 | movsg gner1,gr5 |
270 | stdi gr4,@(gr28,#REG_GNER0) | 275 | stdi.p gr4,@(gr28,#REG_GNER0) |
276 | |||
277 | # interrupts start off fully disabled in the interrupt handler | ||
278 | subcc gr0,gr0,gr0,icc2 /* set Z and clear C */ | ||
271 | 279 | ||
272 | # set the return address | 280 | # set the return address |
273 | sethi.p %hi(__entry_return_from_kernel_interrupt),gr4 | 281 | sethi.p %hi(__entry_return_from_kernel_interrupt),gr4 |
@@ -291,6 +299,45 @@ __entry_kernel_external_interrupt_reentry: | |||
291 | 299 | ||
292 | .size __entry_kernel_external_interrupt,.-__entry_kernel_external_interrupt | 300 | .size __entry_kernel_external_interrupt,.-__entry_kernel_external_interrupt |
293 | 301 | ||
302 | ############################################################################### | ||
303 | # | ||
304 | # deal with interrupts that were actually virtually disabled | ||
305 | # - we need to really disable them, flag the fact and return immediately | ||
306 | # - if you change this, you must alter break.S also | ||
307 | # | ||
308 | ############################################################################### | ||
309 | .balign L1_CACHE_BYTES | ||
310 | .globl __entry_kernel_external_interrupt_virtually_disabled | ||
311 | .type __entry_kernel_external_interrupt_virtually_disabled,@function | ||
312 | __entry_kernel_external_interrupt_virtually_disabled: | ||
313 | movsg psr,gr30 | ||
314 | andi gr30,#~PSR_PIL,gr30 | ||
315 | ori gr30,#PSR_PIL_14,gr30 ; debugging interrupts only | ||
316 | movgs gr30,psr | ||
317 | subcc gr0,gr0,gr0,icc2 ; leave Z set, clear C | ||
318 | rett #0 | ||
319 | |||
320 | .size __entry_kernel_external_interrupt_virtually_disabled,.-__entry_kernel_external_interrupt_virtually_disabled | ||
321 | |||
322 | ############################################################################### | ||
323 | # | ||
324 | # deal with re-enablement of interrupts that were pending when virtually re-enabled | ||
325 | # - set ICC2.C, re-enable the real interrupts and return | ||
326 | # - we can clear ICC2.Z because we shouldn't be here if it's not 0 [due to TIHI] | ||
327 | # - if you change this, you must alter break.S also | ||
328 | # | ||
329 | ############################################################################### | ||
330 | .balign L1_CACHE_BYTES | ||
331 | .globl __entry_kernel_external_interrupt_virtual_reenable | ||
332 | .type __entry_kernel_external_interrupt_virtual_reenable,@function | ||
333 | __entry_kernel_external_interrupt_virtual_reenable: | ||
334 | movsg psr,gr30 | ||
335 | andi gr30,#~PSR_PIL,gr30 ; re-enable interrupts | ||
336 | movgs gr30,psr | ||
337 | subicc gr0,#1,gr0,icc2 ; clear Z, set C | ||
338 | rett #0 | ||
339 | |||
340 | .size __entry_kernel_external_interrupt_virtual_reenable,.-__entry_kernel_external_interrupt_virtual_reenable | ||
294 | 341 | ||
295 | ############################################################################### | 342 | ############################################################################### |
296 | # | 343 | # |
@@ -335,6 +382,7 @@ __entry_uspace_softprog_interrupt_reentry: | |||
335 | 382 | ||
336 | sethi.p %hi(__entry_return_from_user_exception),gr23 | 383 | sethi.p %hi(__entry_return_from_user_exception),gr23 |
337 | setlo %lo(__entry_return_from_user_exception),gr23 | 384 | setlo %lo(__entry_return_from_user_exception),gr23 |
385 | |||
338 | bra __entry_common | 386 | bra __entry_common |
339 | 387 | ||
340 | .size __entry_uspace_softprog_interrupt,.-__entry_uspace_softprog_interrupt | 388 | .size __entry_uspace_softprog_interrupt,.-__entry_uspace_softprog_interrupt |
@@ -495,7 +543,10 @@ __entry_common: | |||
495 | 543 | ||
496 | movsg gner0,gr4 | 544 | movsg gner0,gr4 |
497 | movsg gner1,gr5 | 545 | movsg gner1,gr5 |
498 | stdi gr4,@(gr28,#REG_GNER0) | 546 | stdi.p gr4,@(gr28,#REG_GNER0) |
547 | |||
548 | # set up virtual interrupt disablement | ||
549 | subicc gr0,#1,gr0,icc2 /* clear Z flag, set C flag */ | ||
499 | 550 | ||
500 | # set up kernel global registers | 551 | # set up kernel global registers |
501 | sethi.p %hi(__kernel_current_task),gr5 | 552 | sethi.p %hi(__kernel_current_task),gr5 |