aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S81
-rw-r--r--arch/powerpc/mm/fsl_booke_mmu.c2
-rw-r--r--arch/powerpc/mm/mmu_decl.h2
3 files changed, 85 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 19bd574bda9d..75f0223e6d0d 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -1157,6 +1157,87 @@ __secondary_hold_acknowledge:
1157#endif 1157#endif
1158 1158
1159/* 1159/*
1160 * Create a tlb entry with the same effective and physical address as
1161 * the tlb entry used by the current running code. But set the TS to 1.
1162 * Then switch to the address space 1. It will return with the r3 set to
1163 * the ESEL of the new created tlb.
1164 */
1165_GLOBAL(switch_to_as1)
1166 mflr r5
1167
1168 /* Find a entry not used */
1169 mfspr r3,SPRN_TLB1CFG
1170 andi. r3,r3,0xfff
1171 mfspr r4,SPRN_PID
1172 rlwinm r4,r4,16,0x3fff0000 /* turn PID into MAS6[SPID] */
1173 mtspr SPRN_MAS6,r4
11741: lis r4,0x1000 /* Set MAS0(TLBSEL) = 1 */
1175 addi r3,r3,-1
1176 rlwimi r4,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
1177 mtspr SPRN_MAS0,r4
1178 tlbre
1179 mfspr r4,SPRN_MAS1
1180 andis. r4,r4,MAS1_VALID@h
1181 bne 1b
1182
1183 /* Get the tlb entry used by the current running code */
1184 bl 0f
11850: mflr r4
1186 tlbsx 0,r4
1187
1188 mfspr r4,SPRN_MAS1
1189 ori r4,r4,MAS1_TS /* Set the TS = 1 */
1190 mtspr SPRN_MAS1,r4
1191
1192 mfspr r4,SPRN_MAS0
1193 rlwinm r4,r4,0,~MAS0_ESEL_MASK
1194 rlwimi r4,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
1195 mtspr SPRN_MAS0,r4
1196 tlbwe
1197 isync
1198 sync
1199
1200 mfmsr r4
1201 ori r4,r4,MSR_IS | MSR_DS
1202 mtspr SPRN_SRR0,r5
1203 mtspr SPRN_SRR1,r4
1204 sync
1205 rfi
1206
1207/*
1208 * Restore to the address space 0 and also invalidate the tlb entry created
1209 * by switch_to_as1.
1210*/
1211_GLOBAL(restore_to_as0)
1212 mflr r0
1213
1214 bl 0f
12150: mflr r9
1216 addi r9,r9,1f - 0b
1217
1218 mfmsr r7
1219 li r8,(MSR_IS | MSR_DS)
1220 andc r7,r7,r8
1221
1222 mtspr SPRN_SRR0,r9
1223 mtspr SPRN_SRR1,r7
1224 sync
1225 rfi
1226
1227 /* Invalidate the temporary tlb entry for AS1 */
12281: lis r9,0x1000 /* Set MAS0(TLBSEL) = 1 */
1229 rlwimi r9,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
1230 mtspr SPRN_MAS0,r9
1231 tlbre
1232 mfspr r9,SPRN_MAS1
1233 rlwinm r9,r9,0,2,31 /* Clear MAS1 Valid and IPPROT */
1234 mtspr SPRN_MAS1,r9
1235 tlbwe
1236 isync
1237 mtlr r0
1238 blr
1239
1240/*
1160 * We put a few things here that have to be page-aligned. This stuff 1241 * We put a few things here that have to be page-aligned. This stuff
1161 * goes at the beginning of the data segment, which is page-aligned. 1242 * goes at the beginning of the data segment, which is page-aligned.
1162 */ 1243 */
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index ce4a1163ddd3..1d54f6d35e71 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -222,7 +222,9 @@ void __init adjust_total_lowmem(void)
222 /* adjust lowmem size to __max_low_memory */ 222 /* adjust lowmem size to __max_low_memory */
223 ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem); 223 ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem);
224 224
225 i = switch_to_as1();
225 __max_low_memory = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM); 226 __max_low_memory = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM);
227 restore_to_as0(i);
226 228
227 pr_info("Memory CAM mapping: "); 229 pr_info("Memory CAM mapping: ");
228 for (i = 0; i < tlbcam_index - 1; i++) 230 for (i = 0; i < tlbcam_index - 1; i++)
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 83eb5d5f53d5..eefbf7bb4331 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -148,6 +148,8 @@ extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt,
148extern void MMU_init_hw(void); 148extern void MMU_init_hw(void);
149extern unsigned long mmu_mapin_ram(unsigned long top); 149extern unsigned long mmu_mapin_ram(unsigned long top);
150extern void adjust_total_lowmem(void); 150extern void adjust_total_lowmem(void);
151extern int switch_to_as1(void);
152extern void restore_to_as0(int esel);
151#endif 153#endif
152extern void loadcam_entry(unsigned int index); 154extern void loadcam_entry(unsigned int index);
153 155