aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32/kernel/entry-avr32b.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/avr32/kernel/entry-avr32b.S')
-rw-r--r--arch/avr32/kernel/entry-avr32b.S275
1 files changed, 165 insertions, 110 deletions
diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S
index d7b93f12d8f7..df6c747658c1 100644
--- a/arch/avr32/kernel/entry-avr32b.S
+++ b/arch/avr32/kernel/entry-avr32b.S
@@ -264,16 +264,7 @@ syscall_exit_work:
264 264
2653: bld r1, TIF_BREAKPOINT 2653: bld r1, TIF_BREAKPOINT
266 brcc syscall_exit_cont 266 brcc syscall_exit_cont
267 mfsr r3, SYSREG_TLBEHI 267 rjmp enter_monitor_mode
268 lddsp r2, sp[REG_PC]
269 andl r3, 0xff, COH
270 lsl r3, 1
271 sbr r3, 30
272 sbr r3, 0
273 mtdr OCD_BWA2A, r2
274 mtdr OCD_BWC2A, r3
275 rjmp syscall_exit_cont
276
277 268
278 /* The slow path of the TLB miss handler */ 269 /* The slow path of the TLB miss handler */
279page_table_not_present: 270page_table_not_present:
@@ -288,11 +279,16 @@ page_not_present:
288 rjmp ret_from_exception 279 rjmp ret_from_exception
289 280
290 /* This function expects to find offending PC in SYSREG_RAR_EX */ 281 /* This function expects to find offending PC in SYSREG_RAR_EX */
282 .type save_full_context_ex, @function
283 .align 2
291save_full_context_ex: 284save_full_context_ex:
285 mfsr r11, SYSREG_RAR_EX
286 sub r9, pc, . - debug_trampoline
292 mfsr r8, SYSREG_RSR_EX 287 mfsr r8, SYSREG_RSR_EX
288 cp.w r9, r11
289 breq 3f
293 mov r12, r8 290 mov r12, r8
294 andh r8, (MODE_MASK >> 16), COH 291 andh r8, (MODE_MASK >> 16), COH
295 mfsr r11, SYSREG_RAR_EX
296 brne 2f 292 brne 2f
297 293
2981: pushm r11, r12 /* PC and SR */ 2941: pushm r11, r12 /* PC and SR */
@@ -303,6 +299,21 @@ save_full_context_ex:
303 stdsp sp[4], r10 /* replace saved SP */ 299 stdsp sp[4], r10 /* replace saved SP */
304 rjmp 1b 300 rjmp 1b
305 301
302 /*
303 * The debug handler set up a trampoline to make us
304 * automatically enter monitor mode upon return, but since
305 * we're saving the full context, we must assume that the
306 * exception handler might want to alter the return address
307 * and/or status register. So we need to restore the original
308 * context and enter monitor mode manually after the exception
309 * has been handled.
310 */
3113: get_thread_info r8
312 ld.w r11, r8[TI_rar_saved]
313 ld.w r12, r8[TI_rsr_saved]
314 rjmp 1b
315 .size save_full_context_ex, . - save_full_context_ex
316
306 /* Low-level exception handlers */ 317 /* Low-level exception handlers */
307handle_critical: 318handle_critical:
308 pushm r12 319 pushm r12
@@ -439,6 +450,7 @@ do_fpe_ll:
439ret_from_exception: 450ret_from_exception:
440 mask_interrupts 451 mask_interrupts
441 lddsp r4, sp[REG_SR] 452 lddsp r4, sp[REG_SR]
453
442 andh r4, (MODE_MASK >> 16), COH 454 andh r4, (MODE_MASK >> 16), COH
443 brne fault_resume_kernel 455 brne fault_resume_kernel
444 456
@@ -515,34 +527,76 @@ fault_exit_work:
515 527
5162: bld r1, TIF_BREAKPOINT 5282: bld r1, TIF_BREAKPOINT
517 brcc fault_resume_user 529 brcc fault_resume_user
518 mfsr r3, SYSREG_TLBEHI 530 rjmp enter_monitor_mode
519 lddsp r2, sp[REG_PC] 531
520 andl r3, 0xff, COH 532 .section .kprobes.text, "ax", @progbits
521 lsl r3, 1 533 .type handle_debug, @function
522 sbr r3, 30 534handle_debug:
523 sbr r3, 0 535 sub sp, 4 /* r12_orig */
524 mtdr OCD_BWA2A, r2 536 stmts --sp, r0-lr
525 mtdr OCD_BWC2A, r3 537 mfsr r8, SYSREG_RAR_DBG
526 rjmp fault_resume_user 538 mfsr r9, SYSREG_RSR_DBG
527 539 unmask_exceptions
528 /* If we get a debug trap from privileged context we end up here */ 540 pushm r8-r9
529handle_debug_priv: 541 bfextu r9, r9, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE
530 /* Fix up LR and SP in regs. r1 contains the mode we came from */ 542 brne debug_fixup_regs
531 mfsr r2, SYSREG_SR 543
532 mov r3, r2 544.Ldebug_fixup_cont:
533 bfins r2, r1, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE 545#ifdef CONFIG_TRACE_IRQFLAGS
534 mtsr SYSREG_SR, r2 546 rcall trace_hardirqs_off
547#endif
548 mov r12, sp
549 rcall do_debug
550 mov sp, r12
551
552 lddsp r2, sp[REG_SR]
553 bfextu r3, r2, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE
554 brne debug_resume_kernel
555
556 get_thread_info r0
557 ld.w r1, r0[TI_flags]
558 mov r2, _TIF_DBGWORK_MASK
559 tst r1, r2
560 brne debug_exit_work
561
562 bld r1, TIF_SINGLE_STEP
563 brcc 1f
564 mfdr r4, OCD_DC
565 sbr r4, OCD_DC_SS_BIT
566 mtdr OCD_DC, r4
567
5681: popm r10,r11
569 mask_exceptions
570 mtsr SYSREG_RSR_DBG, r11
571 mtsr SYSREG_RAR_DBG, r10
572#ifdef CONFIG_TRACE_IRQFLAGS
573 rcall trace_hardirqs_on
5741:
575#endif
576 ldmts sp++, r0-lr
577 sub sp, -4
578 retd
579 .size handle_debug, . - handle_debug
580
581 /* Mode of the trapped context is in r9 */
582 .type debug_fixup_regs, @function
583debug_fixup_regs:
584 mfsr r8, SYSREG_SR
585 mov r10, r8
586 bfins r8, r9, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE
587 mtsr SYSREG_SR, r8
535 sub pc, -2 588 sub pc, -2
536 stdsp sp[REG_LR], lr 589 stdsp sp[REG_LR], lr
537 mtsr SYSREG_SR, r3 590 mtsr SYSREG_SR, r10
538 sub pc, -2 591 sub pc, -2
539 sub r10, sp, -FRAME_SIZE_FULL 592 sub r8, sp, -FRAME_SIZE_FULL
540 stdsp sp[REG_SP], r10 593 stdsp sp[REG_SP], r8
541 mov r12, sp 594 rjmp .Ldebug_fixup_cont
542 rcall do_debug_priv 595 .size debug_fixup_regs, . - debug_fixup_regs
543 596
544 /* Now, put everything back */ 597 .type debug_resume_kernel, @function
545 ssrf SR_EM_BIT 598debug_resume_kernel:
599 mask_exceptions
546 popm r10, r11 600 popm r10, r11
547 mtsr SYSREG_RAR_DBG, r10 601 mtsr SYSREG_RAR_DBG, r10
548 mtsr SYSREG_RSR_DBG, r11 602 mtsr SYSREG_RSR_DBG, r11
@@ -553,93 +607,44 @@ handle_debug_priv:
5531: 6071:
554#endif 608#endif
555 mfsr r2, SYSREG_SR 609 mfsr r2, SYSREG_SR
556 mov r3, r2 610 mov r1, r2
557 bfins r2, r1, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE 611 bfins r2, r3, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE
558 mtsr SYSREG_SR, r2 612 mtsr SYSREG_SR, r2
559 sub pc, -2 613 sub pc, -2
560 popm lr 614 popm lr
561 mtsr SYSREG_SR, r3 615 mtsr SYSREG_SR, r1
562 sub pc, -2 616 sub pc, -2
563 sub sp, -4 /* skip SP */ 617 sub sp, -4 /* skip SP */
564 popm r0-r12 618 popm r0-r12
565 sub sp, -4 619 sub sp, -4
566 retd 620 retd
621 .size debug_resume_kernel, . - debug_resume_kernel
567 622
623 .type debug_exit_work, @function
624debug_exit_work:
568 /* 625 /*
569 * At this point, everything is masked, that is, interrupts, 626 * We must return from Monitor Mode using a retd, and we must
570 * exceptions and debugging traps. We might get called from 627 * not schedule since that involves the D bit in SR getting
571 * interrupt or exception context in some rare cases, but this 628 * cleared by something other than the debug hardware. This
572 * will be taken care of by do_debug(), so we're not going to 629 * may cause undefined behaviour according to the Architecture
573 * do a 100% correct context save here. 630 * manual.
631 *
632 * So we fix up the return address and status and return to a
633 * stub below in Exception mode. From there, we can follow the
634 * normal exception return path.
635 *
636 * The real return address and status registers are stored on
637 * the stack in the way the exception return path understands,
638 * so no need to fix anything up there.
574 */ 639 */
575handle_debug: 640 sub r8, pc, . - fault_exit_work
576 sub sp, 4 /* r12_orig */ 641 mtsr SYSREG_RAR_DBG, r8
577 stmts --sp, r0-lr 642 mov r9, 0
578 mfsr r0, SYSREG_RAR_DBG 643 orh r9, hi(SR_EM | SR_GM | MODE_EXCEPTION)
579 mfsr r1, SYSREG_RSR_DBG 644 mtsr SYSREG_RSR_DBG, r9
580#ifdef CONFIG_TRACE_IRQFLAGS 645 sub pc, -2
581 rcall trace_hardirqs_off
582#endif
583 unmask_exceptions
584 stm --sp, r0, r1
585 bfextu r1, r1, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE
586 brne handle_debug_priv
587
588 mov r12, sp
589 rcall do_debug
590
591 lddsp r10, sp[REG_SR]
592 andh r10, (MODE_MASK >> 16), COH
593 breq debug_resume_user
594
595debug_restore_all:
596 popm r10,r11
597 mask_exceptions
598 mtsr SYSREG_RSR_DBG, r11
599 mtsr SYSREG_RAR_DBG, r10
600#ifdef CONFIG_TRACE_IRQFLAGS
601 bld r11, SYSREG_GM_OFFSET
602 brcc 1f
603 rcall trace_hardirqs_on
6041:
605#endif
606 ldmts sp++, r0-lr
607 sub sp, -4
608 retd 646 retd
609 647 .size debug_exit_work, . - debug_exit_work
610debug_resume_user:
611 get_thread_info r0
612 mask_interrupts
613
614 ld.w r1, r0[TI_flags]
615 andl r1, _TIF_DBGWORK_MASK, COH
616 breq debug_restore_all
617
6181: bld r1, TIF_NEED_RESCHED
619 brcc 2f
620 unmask_interrupts
621 rcall schedule
622 mask_interrupts
623 ld.w r1, r0[TI_flags]
624 rjmp 1b
625
6262: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK
627 tst r1, r2
628 breq 3f
629 unmask_interrupts
630 mov r12, sp
631 mov r11, r0
632 rcall do_notify_resume
633 mask_interrupts
634 ld.w r1, r0[TI_flags]
635 rjmp 1b
636
6373: bld r1, TIF_SINGLE_STEP
638 brcc debug_restore_all
639 mfdr r2, OCD_DC
640 sbr r2, OCD_DC_SS_BIT
641 mtdr OCD_DC, r2
642 rjmp debug_restore_all
643 648
644 .set rsr_int0, SYSREG_RSR_INT0 649 .set rsr_int0, SYSREG_RSR_INT0
645 .set rsr_int1, SYSREG_RSR_INT1 650 .set rsr_int1, SYSREG_RSR_INT1
@@ -764,3 +769,53 @@ cpu_idle_enable_int_and_exit:
764 IRQ_LEVEL 1 769 IRQ_LEVEL 1
765 IRQ_LEVEL 2 770 IRQ_LEVEL 2
766 IRQ_LEVEL 3 771 IRQ_LEVEL 3
772
773 .section .kprobes.text, "ax", @progbits
774 .type enter_monitor_mode, @function
775enter_monitor_mode:
776 /*
777 * We need to enter monitor mode to do a single step. The
778 * monitor code will alter the return address so that we
779 * return directly to the user instead of returning here.
780 */
781 breakpoint
782 rjmp breakpoint_failed
783
784 .size enter_monitor_mode, . - enter_monitor_mode
785
786 .type debug_trampoline, @function
787 .global debug_trampoline
788debug_trampoline:
789 /*
790 * Save the registers on the stack so that the monitor code
791 * can find them easily.
792 */
793 sub sp, 4 /* r12_orig */
794 stmts --sp, r0-lr
795 get_thread_info r0
796 ld.w r8, r0[TI_rar_saved]
797 ld.w r9, r0[TI_rsr_saved]
798 pushm r8-r9
799
800 /*
801 * The monitor code will alter the return address so we don't
802 * return here.
803 */
804 breakpoint
805 rjmp breakpoint_failed
806 .size debug_trampoline, . - debug_trampoline
807
808 .type breakpoint_failed, @function
809breakpoint_failed:
810 /*
811 * Something went wrong. Perhaps the debug hardware isn't
812 * enabled?
813 */
814 lda.w r12, msg_breakpoint_failed
815 mov r11, sp
816 mov r10, 9 /* SIGKILL */
817 call die
8181: rjmp 1b
819
820msg_breakpoint_failed:
821 .asciz "Failed to enter Debug Mode"