aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorSuzuki Poulose <suzuki@in.ibm.com>2012-04-15 18:27:18 -0400
committerJosh Boyer <jwboyer@gmail.com>2012-05-03 08:40:23 -0400
commit68343020031585f861d93e2f25589598feadaff3 (patch)
tree4045fe3442f3ace10f2f9225bf9c6f3f7ecb67a9 /arch/powerpc
parentf13bfcc6961a5c9f511c401292db522edcd0b061 (diff)
powerpc/47x: Kernel support for KEXEC
This patch adds support for creating 1:1 mapping for the PPC_47x during a KEXEC. The implementation is similar to that of the PPC440x which is described here : http://patchwork.ozlabs.org/patch/104323/ PPC_47x MMU : The 47x uses Unified TLB 1024 entries, with 4-way associative mapping (4 x 256 entries). The index to be used is calculated by the MMU by hashing the PID, EPN and TS. The software can choose to specify the way by setting bit 0(enable way select) and the way in bits 1-2 in the TLB Word 0. Implementation: The patch erases all the UTLB entries which includes the tlb covering the mapping for our code. The shadow TLB caches the mapping for the running code which helps us to continue the execution until we do isync/rfi. We then create a tmp mapping for the current code in the other address space (TS) and switch to it. Then we create a 1:1 mapping(EPN=RPN) for 0-2GiB in the original address space and switch to the new mapping. TODO: Add SMP support. Signed-off-by: Suzuki K. Poulose <suzuki@in.ibm.com> Signed-off-by: Josh Boyer <jwboyer@gmail.com>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/Kconfig2
-rw-r--r--arch/powerpc/kernel/misc_32.S195
2 files changed, 190 insertions, 7 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index feab3bad6d0f..e588bac91059 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -353,7 +353,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE
353 353
354config KEXEC 354config KEXEC
355 bool "kexec system call (EXPERIMENTAL)" 355 bool "kexec system call (EXPERIMENTAL)"
356 depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP && !PPC_47x)) && EXPERIMENTAL 356 depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP)) && EXPERIMENTAL
357 help 357 help
358 kexec is a system call that implements the ability to shutdown your 358 kexec is a system call that implements the ability to shutdown your
359 current kernel, and to start another kernel. It is like a reboot 359 current kernel, and to start another kernel. It is like a reboot
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index d7e05d20b55c..386d57f66f28 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -738,8 +738,23 @@ relocate_new_kernel:
738 mr r5, r31 738 mr r5, r31
739 739
740 li r0, 0 740 li r0, 0
741#elif defined(CONFIG_44x) && !defined(CONFIG_PPC_47x) 741#elif defined(CONFIG_44x)
742 742
743 /* Save our parameters */
744 mr r29, r3
745 mr r30, r4
746 mr r31, r5
747
748#ifdef CONFIG_PPC_47x
749 /* Check for 47x cores */
750 mfspr r3,SPRN_PVR
751 srwi r3,r3,16
752 cmplwi cr0,r3,PVR_476@h
753 beq setup_map_47x
754 cmplwi cr0,r3,PVR_476_ISS@h
755 beq setup_map_47x
756#endif /* CONFIG_PPC_47x */
757
743/* 758/*
744 * Code for setting up 1:1 mapping for PPC440x for KEXEC 759 * Code for setting up 1:1 mapping for PPC440x for KEXEC
745 * 760 *
@@ -753,13 +768,8 @@ relocate_new_kernel:
753 * 5) Invalidate the tmp mapping. 768 * 5) Invalidate the tmp mapping.
754 * 769 *
755 * - Based on the kexec support code for FSL BookE 770 * - Based on the kexec support code for FSL BookE
756 * - Doesn't support 47x yet.
757 * 771 *
758 */ 772 */
759 /* Save our parameters */
760 mr r29, r3
761 mr r30, r4
762 mr r31, r5
763 773
764 /* 774 /*
765 * Load the PID with kernel PID (0). 775 * Load the PID with kernel PID (0).
@@ -904,6 +914,179 @@ next_tlb:
904 li r3, 0 914 li r3, 0
905 tlbwe r3, r24, PPC44x_TLB_PAGEID 915 tlbwe r3, r24, PPC44x_TLB_PAGEID
906 sync 916 sync
917 b ppc44x_map_done
918
919#ifdef CONFIG_PPC_47x
920
921 /* 1:1 mapping for 47x */
922
923setup_map_47x:
924
925 /*
926 * Load the kernel pid (0) to PID and also to MMUCR[TID].
927 * Also set the MSR IS->MMUCR STS
928 */
929 li r3, 0
930 mtspr SPRN_PID, r3 /* Set PID */
931 mfmsr r4 /* Get MSR */
932 andi. r4, r4, MSR_IS@l /* TS=1? */
933 beq 1f /* If not, leave STS=0 */
934 oris r3, r3, PPC47x_MMUCR_STS@h /* Set STS=1 */
9351: mtspr SPRN_MMUCR, r3 /* Put MMUCR */
936 sync
937
938 /* Find the entry we are running from */
939 bl 2f
9402: mflr r23
941 tlbsx r23, 0, r23
942 tlbre r24, r23, 0 /* TLB Word 0 */
943 tlbre r25, r23, 1 /* TLB Word 1 */
944 tlbre r26, r23, 2 /* TLB Word 2 */
945
946
947 /*
948 * Invalidates all the tlb entries by writing to 256 RPNs(r4)
949 * of 4k page size in all 4 ways (0-3 in r3).
950 * This would invalidate the entire UTLB including the one we are
951 * running from. However the shadow TLB entries would help us
952 * to continue the execution, until we flush them (rfi/isync).
953 */
954 addis r3, 0, 0x8000 /* specify the way */
955 addi r4, 0, 0 /* TLB Word0 = (EPN=0, VALID = 0) */
956 addi r5, 0, 0
957 b clear_utlb_entry
958
959 /* Align the loop to speed things up. from head_44x.S */
960 .align 6
961
962clear_utlb_entry:
963
964 tlbwe r4, r3, 0
965 tlbwe r5, r3, 1
966 tlbwe r5, r3, 2
967 addis r3, r3, 0x2000 /* Increment the way */
968 cmpwi r3, 0
969 bne clear_utlb_entry
970 addis r3, 0, 0x8000
971 addis r4, r4, 0x100 /* Increment the EPN */
972 cmpwi r4, 0
973 bne clear_utlb_entry
974
975 /* Create the entries in the other address space */
976 mfmsr r5
977 rlwinm r7, r5, 27, 31, 31 /* Get the TS (Bit 26) from MSR */
978 xori r7, r7, 1 /* r7 = !TS */
979
980 insrwi r24, r7, 1, 21 /* Change the TS in the saved TLB word 0 */
981
982 /*
983 * write out the TLB entries for the tmp mapping
984 * Use way '0' so that we could easily invalidate it later.
985 */
986 lis r3, 0x8000 /* Way '0' */
987
988 tlbwe r24, r3, 0
989 tlbwe r25, r3, 1
990 tlbwe r26, r3, 2
991
992 /* Update the msr to the new TS */
993 insrwi r5, r7, 1, 26
994
995 bl 1f
9961: mflr r6
997 addi r6, r6, (2f-1b)
998
999 mtspr SPRN_SRR0, r6
1000 mtspr SPRN_SRR1, r5
1001 rfi
1002
1003 /*
1004 * Now we are in the tmp address space.
1005 * Create a 1:1 mapping for 0-2GiB in the original TS.
1006 */
10072:
1008 li r3, 0
1009 li r4, 0 /* TLB Word 0 */
1010 li r5, 0 /* TLB Word 1 */
1011 li r6, 0
1012 ori r6, r6, PPC47x_TLB2_S_RWX /* TLB word 2 */
1013
1014 li r8, 0 /* PageIndex */
1015
1016 xori r7, r7, 1 /* revert back to original TS */
1017
1018write_utlb:
1019 rotlwi r5, r8, 28 /* RPN = PageIndex * 256M */
1020 /* ERPN = 0 as we don't use memory above 2G */
1021
1022 mr r4, r5 /* EPN = RPN */
1023 ori r4, r4, (PPC47x_TLB0_VALID | PPC47x_TLB0_256M)
1024 insrwi r4, r7, 1, 21 /* Insert the TS to Word 0 */
1025
1026 tlbwe r4, r3, 0 /* Write out the entries */
1027 tlbwe r5, r3, 1
1028 tlbwe r6, r3, 2
1029 addi r8, r8, 1
1030 cmpwi r8, 8 /* Have we completed ? */
1031 bne write_utlb
1032
1033 /* make sure we complete the TLB write up */
1034 isync
1035
1036 /*
1037 * Prepare to jump to the 1:1 mapping.
1038 * 1) Extract page size of the tmp mapping
1039 * DSIZ = TLB_Word0[22:27]
1040 * 2) Calculate the physical address of the address
1041 * to jump to.
1042 */
1043 rlwinm r10, r24, 0, 22, 27
1044
1045 cmpwi r10, PPC47x_TLB0_4K
1046 bne 0f
1047 li r10, 0x1000 /* r10 = 4k */
1048 bl 1f
1049
10500:
1051 /* Defaults to 256M */
1052 lis r10, 0x1000
1053
1054 bl 1f
10551: mflr r4
1056 addi r4, r4, (2f-1b) /* virtual address of 2f */
1057
1058 subi r11, r10, 1 /* offsetmask = Pagesize - 1 */
1059 not r10, r11 /* Pagemask = ~(offsetmask) */
1060
1061 and r5, r25, r10 /* Physical page */
1062 and r6, r4, r11 /* offset within the current page */
1063
1064 or r5, r5, r6 /* Physical address for 2f */
1065
1066 /* Switch the TS in MSR to the original one */
1067 mfmsr r8
1068 insrwi r8, r7, 1, 26
1069
1070 mtspr SPRN_SRR1, r8
1071 mtspr SPRN_SRR0, r5
1072 rfi
1073
10742:
1075 /* Invalidate the tmp mapping */
1076 lis r3, 0x8000 /* Way '0' */
1077
1078 clrrwi r24, r24, 12 /* Clear the valid bit */
1079 tlbwe r24, r3, 0
1080 tlbwe r25, r3, 1
1081 tlbwe r26, r3, 2
1082
1083 /* Make sure we complete the TLB write and flush the shadow TLB */
1084 isync
1085
1086#endif
1087
1088ppc44x_map_done:
1089
907 1090
908 /* Restore the parameters */ 1091 /* Restore the parameters */
909 mr r3, r29 1092 mr r3, r29