aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/kernel/entry.S
diff options
context:
space:
mode:
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/*