diff options
Diffstat (limited to 'arch/ppc/kernel/entry.S')
-rw-r--r-- | arch/ppc/kernel/entry.S | 164 |
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 |
50 | mcheck_transfer_to_handler: | 59 | mcheck_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 |
61 | crit_transfer_to_handler: | 64 | crit_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 | ||
787 | ret_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 | ||
834 | ret_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 |
842 | ret_from_mcheck_exc: | 839 | ret_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 | /* |