aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/misc_32.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/misc_32.S')
-rw-r--r--arch/powerpc/kernel/misc_32.S171
1 files changed, 171 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 998a1002860..f7d760ab5ca 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -8,6 +8,8 @@
8 * kexec bits: 8 * kexec bits:
9 * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com> 9 * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com>
10 * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz 10 * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
11 * PPC44x port. Copyright (C) 2011, IBM Corporation
12 * Author: Suzuki Poulose <suzuki@in.ibm.com>
11 * 13 *
12 * This program is free software; you can redistribute it and/or 14 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 15 * modify it under the terms of the GNU General Public License
@@ -736,6 +738,175 @@ relocate_new_kernel:
736 mr r5, r31 738 mr r5, r31
737 739
738 li r0, 0 740 li r0, 0
741#elif defined(CONFIG_44x) && !defined(CONFIG_47x)
742
743/*
744 * Code for setting up 1:1 mapping for PPC440x for KEXEC
745 *
746 * We cannot switch off the MMU on PPC44x.
747 * So we:
748 * 1) Invalidate all the mappings except the one we are running from.
749 * 2) Create a tmp mapping for our code in the other address space(TS) and
750 * jump to it. Invalidate the entry we started in.
751 * 3) Create a 1:1 mapping for 0-2GiB in chunks of 256M in original TS.
752 * 4) Jump to the 1:1 mapping in original TS.
753 * 5) Invalidate the tmp mapping.
754 *
755 * - Based on the kexec support code for FSL BookE
756 * - Doesn't support 47x yet.
757 *
758 */
759 /* Save our parameters */
760 mr r29, r3
761 mr r30, r4
762 mr r31, r5
763
764 /* Load our MSR_IS and TID to MMUCR for TLB search */
765 mfspr r3,SPRN_PID
766 mfmsr r4
767 andi. r4,r4,MSR_IS@l
768 beq wmmucr
769 oris r3,r3,PPC44x_MMUCR_STS@h
770wmmucr:
771 mtspr SPRN_MMUCR,r3
772 sync
773
774 /*
775 * Invalidate all the TLB entries except the current entry
776 * where we are running from
777 */
778 bl 0f /* Find our address */
7790: mflr r5 /* Make it accessible */
780 tlbsx r23,0,r5 /* Find entry we are in */
781 li r4,0 /* Start at TLB entry 0 */
782 li r3,0 /* Set PAGEID inval value */
7831: cmpw r23,r4 /* Is this our entry? */
784 beq skip /* If so, skip the inval */
785 tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */
786skip:
787 addi r4,r4,1 /* Increment */
788 cmpwi r4,64 /* Are we done? */
789 bne 1b /* If not, repeat */
790 isync
791
792 /* Create a temp mapping and jump to it */
793 andi. r6, r23, 1 /* Find the index to use */
794 addi r24, r6, 1 /* r24 will contain 1 or 2 */
795
796 mfmsr r9 /* get the MSR */
797 rlwinm r5, r9, 27, 31, 31 /* Extract the MSR[IS] */
798 xori r7, r5, 1 /* Use the other address space */
799
800 /* Read the current mapping entries */
801 tlbre r3, r23, PPC44x_TLB_PAGEID
802 tlbre r4, r23, PPC44x_TLB_XLAT
803 tlbre r5, r23, PPC44x_TLB_ATTRIB
804
805 /* Save our current XLAT entry */
806 mr r25, r4
807
808 /* Extract the TLB PageSize */
809 li r10, 1 /* r10 will hold PageSize */
810 rlwinm r11, r3, 0, 24, 27 /* bits 24-27 */
811
812 /* XXX: As of now we use 256M, 4K pages */
813 cmpwi r11, PPC44x_TLB_256M
814 bne tlb_4k
815 rotlwi r10, r10, 28 /* r10 = 256M */
816 b write_out
817tlb_4k:
818 cmpwi r11, PPC44x_TLB_4K
819 bne default
820 rotlwi r10, r10, 12 /* r10 = 4K */
821 b write_out
822default:
823 rotlwi r10, r10, 10 /* r10 = 1K */
824
825write_out:
826 /*
827 * Write out the tmp 1:1 mapping for this code in other address space
828 * Fixup EPN = RPN , TS=other address space
829 */
830 insrwi r3, r7, 1, 23 /* Bit 23 is TS for PAGEID field */
831
832 /* Write out the tmp mapping entries */
833 tlbwe r3, r24, PPC44x_TLB_PAGEID
834 tlbwe r4, r24, PPC44x_TLB_XLAT
835 tlbwe r5, r24, PPC44x_TLB_ATTRIB
836
837 subi r11, r10, 1 /* PageOffset Mask = PageSize - 1 */
838 not r10, r11 /* Mask for PageNum */
839
840 /* Switch to other address space in MSR */
841 insrwi r9, r7, 1, 26 /* Set MSR[IS] = r7 */
842
843 bl 1f
8441: mflr r8
845 addi r8, r8, (2f-1b) /* Find the target offset */
846
847 /* Jump to the tmp mapping */
848 mtspr SPRN_SRR0, r8
849 mtspr SPRN_SRR1, r9
850 rfi
851
8522:
853 /* Invalidate the entry we were executing from */
854 li r3, 0
855 tlbwe r3, r23, PPC44x_TLB_PAGEID
856
857 /* attribute fields. rwx for SUPERVISOR mode */
858 li r5, 0
859 ori r5, r5, (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G)
860
861 /* Create 1:1 mapping in 256M pages */
862 xori r7, r7, 1 /* Revert back to Original TS */
863
864 li r8, 0 /* PageNumber */
865 li r6, 3 /* TLB Index, start at 3 */
866
867next_tlb:
868 rotlwi r3, r8, 28 /* Create EPN (bits 0-3) */
869 mr r4, r3 /* RPN = EPN */
870 ori r3, r3, (PPC44x_TLB_VALID | PPC44x_TLB_256M) /* SIZE = 256M, Valid */
871 insrwi r3, r7, 1, 23 /* Set TS from r7 */
872
873 tlbwe r3, r6, PPC44x_TLB_PAGEID /* PageID field : EPN, V, SIZE */
874 tlbwe r4, r6, PPC44x_TLB_XLAT /* Address translation : RPN */
875 tlbwe r5, r6, PPC44x_TLB_ATTRIB /* Attributes */
876
877 addi r8, r8, 1 /* Increment PN */
878 addi r6, r6, 1 /* Increment TLB Index */
879 cmpwi r8, 8 /* Are we done ? */
880 bne next_tlb
881 isync
882
883 /* Jump to the new mapping 1:1 */
884 li r9,0
885 insrwi r9, r7, 1, 26 /* Set MSR[IS] = r7 */
886
887 bl 1f
8881: mflr r8
889 and r8, r8, r11 /* Get our offset within page */
890 addi r8, r8, (2f-1b)
891
892 and r5, r25, r10 /* Get our target PageNum */
893 or r8, r8, r5 /* Target jump address */
894
895 mtspr SPRN_SRR0, r8
896 mtspr SPRN_SRR1, r9
897 rfi
8982:
899 /* Invalidate the tmp entry we used */
900 li r3, 0
901 tlbwe r3, r24, PPC44x_TLB_PAGEID
902 sync
903
904 /* Restore the parameters */
905 mr r3, r29
906 mr r4, r30
907 mr r5, r31
908
909 li r0, 0
739#else 910#else
740 li r0, 0 911 li r0, 0
741 912