aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/kernel/entry.S
diff options
context:
space:
mode:
authorKumar Gala <galak@freescale.com>2005-06-21 20:15:27 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-21 21:46:25 -0400
commit1492ec8069ea6f82bc32df27cabbec72e554e2b8 (patch)
tree09e52d150482a105a63dc4b71758a7aa99ecb28c /arch/ppc/kernel/entry.S
parent5be061eee931db2718feecaf10df17610386202b (diff)
[PATCH] ppc32: Factor out common exception code into macro's for 4xx/Book-E
4xx and Book-E PPC's have several exception levels. The code to handle each level is fairly regular. Turning the code into macro's will ease the handling of future exception levels (debug) in forth coming chips. Signed-off-by: Kumar Gala <kumar.gala@freescale.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc/kernel/entry.S')
-rw-r--r--arch/ppc/kernel/entry.S164
1 files changed, 63 insertions, 101 deletions
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 661523707e8c..8377b6ca26da 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -46,26 +46,23 @@
46 46
47#ifdef CONFIG_BOOKE 47#ifdef CONFIG_BOOKE
48#include "head_booke.h" 48#include "head_booke.h"
49#define TRANSFER_TO_HANDLER_EXC_LEVEL(exc_level) \
50 mtspr exc_level##_SPRG,r8; \
51 BOOKE_LOAD_EXC_LEVEL_STACK(exc_level); \
52 lwz r0,GPR10-INT_FRAME_SIZE(r8); \
53 stw r0,GPR10(r11); \
54 lwz r0,GPR11-INT_FRAME_SIZE(r8); \
55 stw r0,GPR11(r11); \
56 mfspr r8,exc_level##_SPRG
57
49 .globl mcheck_transfer_to_handler 58 .globl mcheck_transfer_to_handler
50mcheck_transfer_to_handler: 59mcheck_transfer_to_handler:
51 mtspr MCHECK_SPRG,r8 60 TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK)
52 BOOKE_LOAD_MCHECK_STACK
53 lwz r0,GPR10-INT_FRAME_SIZE(r8)
54 stw r0,GPR10(r11)
55 lwz r0,GPR11-INT_FRAME_SIZE(r8)
56 stw r0,GPR11(r11)
57 mfspr r8,MCHECK_SPRG
58 b transfer_to_handler_full 61 b transfer_to_handler_full
59 62
60 .globl crit_transfer_to_handler 63 .globl crit_transfer_to_handler
61crit_transfer_to_handler: 64crit_transfer_to_handler:
62 mtspr CRIT_SPRG,r8 65 TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT)
63 BOOKE_LOAD_CRIT_STACK
64 lwz r0,GPR10-INT_FRAME_SIZE(r8)
65 stw r0,GPR10(r11)
66 lwz r0,GPR11-INT_FRAME_SIZE(r8)
67 stw r0,GPR11(r11)
68 mfspr r8,CRIT_SPRG
69 /* fall through */ 66 /* fall through */
70#endif 67#endif
71 68
@@ -783,99 +780,64 @@ exc_exit_restart_end:
783 * time of the critical interrupt. 780 * time of the critical interrupt.
784 * 781 *
785 */ 782 */
786 .globl ret_from_crit_exc
787ret_from_crit_exc:
788 REST_NVGPRS(r1)
789 lwz r3,_MSR(r1)
790 andi. r3,r3,MSR_PR
791 LOAD_MSR_KERNEL(r10,MSR_KERNEL)
792 bne user_exc_return
793
794 lwz r0,GPR0(r1)
795 lwz r2,GPR2(r1)
796 REST_4GPRS(3, r1)
797 REST_2GPRS(7, r1)
798
799 lwz r10,_XER(r1)
800 lwz r11,_CTR(r1)
801 mtspr SPRN_XER,r10
802 mtctr r11
803
804 PPC405_ERR77(0,r1)
805 stwcx. r0,0,r1 /* to clear the reservation */
806
807 lwz r11,_LINK(r1)
808 mtlr r11
809 lwz r10,_CCR(r1)
810 mtcrf 0xff,r10
811#ifdef CONFIG_40x 783#ifdef CONFIG_40x
812 /* avoid any possible TLB misses here by turning off MSR.DR, we 784#define PPC_40x_TURN_OFF_MSR_DR \
813 * assume the instructions here are mapped by a pinned TLB entry */ 785 /* avoid any possible TLB misses here by turning off MSR.DR, we \
814 li r10,MSR_IR 786 * assume the instructions here are mapped by a pinned TLB entry */ \
815 mtmsr r10 787 li r10,MSR_IR; \
816 isync 788 mtmsr r10; \
817 tophys(r1, r1) 789 isync; \
790 tophys(r1, r1);
791#else
792#define PPC_40x_TURN_OFF_MSR_DR
818#endif 793#endif
819 lwz r9,_DEAR(r1) 794
820 lwz r10,_ESR(r1) 795#define RET_FROM_EXC_LEVEL(exc_lvl_srr0, exc_lvl_srr1, exc_lvl_rfi) \
821 mtspr SPRN_DEAR,r9 796 REST_NVGPRS(r1); \
822 mtspr SPRN_ESR,r10 797 lwz r3,_MSR(r1); \
823 lwz r11,_NIP(r1) 798 andi. r3,r3,MSR_PR; \
824 lwz r12,_MSR(r1) 799 LOAD_MSR_KERNEL(r10,MSR_KERNEL); \
825 mtspr SPRN_CSRR0,r11 800 bne user_exc_return; \
826 mtspr SPRN_CSRR1,r12 801 lwz r0,GPR0(r1); \
827 lwz r9,GPR9(r1) 802 lwz r2,GPR2(r1); \
828 lwz r12,GPR12(r1) 803 REST_4GPRS(3, r1); \
829 lwz r10,GPR10(r1) 804 REST_2GPRS(7, r1); \
830 lwz r11,GPR11(r1) 805 lwz r10,_XER(r1); \
831 lwz r1,GPR1(r1) 806 lwz r11,_CTR(r1); \
832 PPC405_ERR77_SYNC 807 mtspr SPRN_XER,r10; \
833 rfci 808 mtctr r11; \
834 b . /* prevent prefetch past rfci */ 809 PPC405_ERR77(0,r1); \
810 stwcx. r0,0,r1; /* to clear the reservation */ \
811 lwz r11,_LINK(r1); \
812 mtlr r11; \
813 lwz r10,_CCR(r1); \
814 mtcrf 0xff,r10; \
815 PPC_40x_TURN_OFF_MSR_DR; \
816 lwz r9,_DEAR(r1); \
817 lwz r10,_ESR(r1); \
818 mtspr SPRN_DEAR,r9; \
819 mtspr SPRN_ESR,r10; \
820 lwz r11,_NIP(r1); \
821 lwz r12,_MSR(r1); \
822 mtspr exc_lvl_srr0,r11; \
823 mtspr exc_lvl_srr1,r12; \
824 lwz r9,GPR9(r1); \
825 lwz r12,GPR12(r1); \
826 lwz r10,GPR10(r1); \
827 lwz r11,GPR11(r1); \
828 lwz r1,GPR1(r1); \
829 PPC405_ERR77_SYNC; \
830 exc_lvl_rfi; \
831 b .; /* prevent prefetch past exc_lvl_rfi */
832
833 .globl ret_from_crit_exc
834ret_from_crit_exc:
835 RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI)
835 836
836#ifdef CONFIG_BOOKE 837#ifdef CONFIG_BOOKE
837/*
838 * Return from a machine check interrupt, similar to a critical
839 * interrupt.
840 */
841 .globl ret_from_mcheck_exc 838 .globl ret_from_mcheck_exc
842ret_from_mcheck_exc: 839ret_from_mcheck_exc:
843 REST_NVGPRS(r1) 840 RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI)
844 lwz r3,_MSR(r1)
845 andi. r3,r3,MSR_PR
846 LOAD_MSR_KERNEL(r10,MSR_KERNEL)
847 bne user_exc_return
848
849 lwz r0,GPR0(r1)
850 lwz r2,GPR2(r1)
851 REST_4GPRS(3, r1)
852 REST_2GPRS(7, r1)
853
854 lwz r10,_XER(r1)
855 lwz r11,_CTR(r1)
856 mtspr SPRN_XER,r10
857 mtctr r11
858
859 stwcx. r0,0,r1 /* to clear the reservation */
860
861 lwz r11,_LINK(r1)
862 mtlr r11
863 lwz r10,_CCR(r1)
864 mtcrf 0xff,r10
865 lwz r9,_DEAR(r1)
866 lwz r10,_ESR(r1)
867 mtspr SPRN_DEAR,r9
868 mtspr SPRN_ESR,r10
869 lwz r11,_NIP(r1)
870 lwz r12,_MSR(r1)
871 mtspr SPRN_MCSRR0,r11
872 mtspr SPRN_MCSRR1,r12
873 lwz r9,GPR9(r1)
874 lwz r12,GPR12(r1)
875 lwz r10,GPR10(r1)
876 lwz r11,GPR11(r1)
877 lwz r1,GPR1(r1)
878 RFMCI
879#endif /* CONFIG_BOOKE */ 841#endif /* CONFIG_BOOKE */
880 842
881/* 843/*