aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel/entry.S
diff options
context:
space:
mode:
authorMichal Simek <monstr@monstr.eu>2010-08-03 05:45:08 -0400
committerMichal Simek <monstr@monstr.eu>2010-08-04 04:45:17 -0400
commit2d5973cb5ac5d04662f86e19a06a4c52fa4c4ae3 (patch)
tree21ddc58eed5ccad856fc44dfb0ee794da41d5b16 /arch/microblaze/kernel/entry.S
parent751f1605e03533a6279ccf456e938e9595c7d888 (diff)
microblaze: Add KGDB support
Kgdb uses brki r16, 0x18 instruction to call low level _debug_exception function which save current state to pt_regs and call microblaze_kgdb_break function. _debug_exception should be called only from the kernel space. User space calling is not supported because user application debugging uses different handling. pt_regs_to_gdb_regs loads additional special registers which can't be changed * Enable KGDB in Kconfig * Remove ancient not-tested KGDB support * Remove ancient _debug_exception code from entry.S Only MMU KGDB support is supported. Signed-off-by: Michal Simek <monstr@monstr.eu> CC: Jason Wessel <jason.wessel@windriver.com> CC: John Williams <john.williams@petalogix.com> CC: Edgar E. Iglesias <edgar.iglesias@petalogix.com> CC: linux-kernel@vger.kernel.org Acked-by: Jason Wessel <jason.wessel@windriver.com>
Diffstat (limited to 'arch/microblaze/kernel/entry.S')
-rw-r--r--arch/microblaze/kernel/entry.S106
1 files changed, 57 insertions, 49 deletions
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 5a5cb5842938..304882e56459 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -745,11 +745,8 @@ IRQ_return: /* MS: Make global symbol for debugging */
745 nop 745 nop
746 746
747/* 747/*
748 * `Debug' trap 748 * Debug trap for KGDB. Enter to _debug_exception by brki r16, 0x18
749 * We enter dbtrap in "BIP" (breakpoint) mode. 749 * and call handling function with saved pt_regs
750 * So we exit the breakpoint mode with an 'rtbd' and proceed with the
751 * original dbtrap.
752 * however, wait to save state first
753 */ 750 */
754C_ENTRY(_debug_exception): 751C_ENTRY(_debug_exception):
755 /* BIP bit is set on entry, no interrupts can occur */ 752 /* BIP bit is set on entry, no interrupts can occur */
@@ -759,18 +756,44 @@ C_ENTRY(_debug_exception):
759 nop 756 nop
760 andi r1, r1, MSR_UMS 757 andi r1, r1, MSR_UMS
761 bnei r1, 1f 758 bnei r1, 1f
762 /* Kernel-mode state save. */ 759/* MS: Kernel-mode state save - kgdb */
763 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/ 760 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/
764 tophys(r1,r1);
765 761
766 addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */ 762 /* BIP bit is set on entry, no interrupts can occur */
763 addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE;
767 SAVE_REGS; 764 SAVE_REGS;
765 /* save all regs to pt_reg structure */
766 swi r0, r1, PTO+PT_R0; /* R0 must be saved too */
767 swi r14, r1, PTO+PT_R14 /* rewrite saved R14 value */
768 swi r16, r1, PTO+PT_R16
769 swi r16, r1, PTO+PT_PC; /* PC and r16 are the same */
770 swi r17, r1, PTO+PT_R17
771 /* save special purpose registers to pt_regs */
772 mfs r11, rear;
773 swi r11, r1, PTO+PT_EAR;
774 mfs r11, resr;
775 swi r11, r1, PTO+PT_ESR;
776 mfs r11, rfsr;
777 swi r11, r1, PTO+PT_FSR;
778
779 /* stack pointer is in physical address at it is decrease
780 * by STATE_SAVE_SIZE but we need to get correct R1 value */
781 addik r11, r1, CONFIG_KERNEL_START - CONFIG_KERNEL_BASE_ADDR + STATE_SAVE_SIZE;
782 swi r11, r1, PTO+PT_R1
783 /* MS: r31 - current pointer isn't changed */
784 tovirt(r1,r1)
785#ifdef CONFIG_KGDB
786 addi r5, r1, PTO /* pass pt_reg address as the first arg */
787 la r15, r0, dbtrap_call; /* return address */
788 rtbd r0, microblaze_kgdb_break
789 nop;
790#endif
791 /* MS: Place handler for brki from kernel space if KGDB is OFF.
792 * It is very unlikely that another brki instruction is called. */
793 bri 0
768 794
769 swi r1, r1, PTO + PT_MODE; 795/* MS: User-mode state save - gdb */
770 brid 2f; 7961: lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
771 nop; /* Fill delay slot */
7721: /* User-mode state save. */
773 lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
774 tophys(r1,r1); 797 tophys(r1,r1);
775 lwi r1, r1, TS_THREAD_INFO; /* get the thread info */ 798 lwi r1, r1, TS_THREAD_INFO; /* get the thread info */
776 addik r1, r1, THREAD_SIZE; /* calculate kernel stack pointer */ 799 addik r1, r1, THREAD_SIZE; /* calculate kernel stack pointer */
@@ -781,36 +804,32 @@ C_ENTRY(_debug_exception):
781 swi r17, r1, PTO+PT_R17; 804 swi r17, r1, PTO+PT_R17;
782 swi r16, r1, PTO+PT_R16; 805 swi r16, r1, PTO+PT_R16;
783 swi r16, r1, PTO+PT_PC; /* Save LP */ 806 swi r16, r1, PTO+PT_PC; /* Save LP */
784
785 swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */ 807 swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */
786 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 808 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
787 swi r11, r1, PTO+PT_R1; /* Store user SP. */ 809 swi r11, r1, PTO+PT_R1; /* Store user SP. */
7882: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); 810 lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
789 tovirt(r1,r1) 811 tovirt(r1,r1)
790
791 set_vms; 812 set_vms;
792 addik r5, r1, PTO; 813 addik r5, r1, PTO;
793 addik r15, r0, dbtrap_call; 814 addik r15, r0, dbtrap_call;
794dbtrap_call: /* return point for kernel/user entry */ 815dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
795 rtbd r0, sw_exception 816 rtbd r0, sw_exception
796 nop 817 nop
797 818
798 set_bip; /* Ints masked for state restore*/ 819 /* MS: The first instruction for the second part of the gdb/kgdb */
820 set_bip; /* Ints masked for state restore */
799 lwi r11, r1, PTO + PT_MODE; 821 lwi r11, r1, PTO + PT_MODE;
800 bnei r11, 2f; 822 bnei r11, 2f;
801 823/* MS: Return to user space - gdb */
802 /* Get current task ptr into r11 */ 824 /* Get current task ptr into r11 */
803 lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ 825 lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
804 lwi r11, r11, TI_FLAGS; /* get flags in thread info */ 826 lwi r11, r11, TI_FLAGS; /* get flags in thread info */
805 andi r11, r11, _TIF_NEED_RESCHED; 827 andi r11, r11, _TIF_NEED_RESCHED;
806 beqi r11, 5f; 828 beqi r11, 5f;
807 829
808/* Call the scheduler before returning from a syscall/trap. */ 830 /* Call the scheduler before returning from a syscall/trap. */
809
810 bralid r15, schedule; /* Call scheduler */ 831 bralid r15, schedule; /* Call scheduler */
811 nop; /* delay slot */ 832 nop; /* delay slot */
812 /* XXX Is PT_DTRACE handling needed here? */
813 /* XXX m68knommu also checks TASK_STATE & TASK_COUNTER here. */
814 833
815 /* Maybe handle a signal */ 834 /* Maybe handle a signal */
8165: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ 8355: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
@@ -818,48 +837,37 @@ dbtrap_call: /* return point for kernel/user entry */
818 andi r11, r11, _TIF_SIGPENDING; 837 andi r11, r11, _TIF_SIGPENDING;
819 beqi r11, 1f; /* Signals to handle, handle them */ 838 beqi r11, 1f; /* Signals to handle, handle them */
820 839
821/* Handle a signal return; Pending signals should be in r18. */
822 /* Not all registers are saved by the normal trap/interrupt entry
823 points (for instance, call-saved registers (because the normal
824 C-compiler calling sequence in the kernel makes sure they're
825 preserved), and call-clobbered registers in the case of
826 traps), but signal handlers may want to examine or change the
827 complete register state. Here we save anything not saved by
828 the normal entry sequence, so that it may be safely restored
829 (in a possibly modified form) after do_signal returns. */
830
831 addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ 840 addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */
832 addi r7, r0, 0; /* Arg 3: int in_syscall */ 841 addi r7, r0, 0; /* Arg 3: int in_syscall */
833 bralid r15, do_signal; /* Handle any signals */ 842 bralid r15, do_signal; /* Handle any signals */
834 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 843 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
835 844
836
837/* Finally, return to user state. */ 845/* Finally, return to user state. */
8381: 8461: swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
839 swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
840 VM_OFF; 847 VM_OFF;
841 tophys(r1,r1); 848 tophys(r1,r1);
842 849 /* MS: Restore all regs */
843 RESTORE_REGS 850 RESTORE_REGS
844 lwi r17, r1, PTO+PT_R17; 851 lwi r17, r1, PTO+PT_R17;
845 lwi r16, r1, PTO+PT_R16; 852 lwi r16, r1, PTO+PT_R16;
846 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ 853 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space */
847 854 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */
848 855DBTRAP_return_user: /* MS: Make global symbol for debugging */
849 lwi r1, r1, PT_R1 - PT_SIZE; 856 rtbd r16, 0; /* MS: Instructions to return from a debug trap */
850 /* Restore user stack pointer. */ 857 nop;
851 bri 6f;
852 858
853/* Return to kernel state. */ 859/* MS: Return to kernel state - kgdb */
8542: VM_OFF; 8602: VM_OFF;
855 tophys(r1,r1); 861 tophys(r1,r1);
862 /* MS: Restore all regs */
856 RESTORE_REGS 863 RESTORE_REGS
857 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ 864 lwi r14, r1, PTO+PT_R14;
858 865 lwi r16, r1, PTO+PT_PC;
866 lwi r17, r1, PTO+PT_R17;
867 addik r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */
859 tovirt(r1,r1); 868 tovirt(r1,r1);
8606: 869DBTRAP_return_kernel: /* MS: Make global symbol for debugging */
861DBTRAP_return: /* Make global symbol for debugging */ 870 rtbd r16, 0; /* MS: Instructions to return from a debug trap */
862 rtbd r16, 0; /* Instructions to return from an IRQ */
863 nop; 871 nop;
864 872
865 873