diff options
Diffstat (limited to 'arch/powerpc/kernel/head_fsl_booke.S')
-rw-r--r-- | arch/powerpc/kernel/head_fsl_booke.S | 200 |
1 files changed, 3 insertions, 197 deletions
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index edd4a57fd29e..4faeba247854 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S | |||
@@ -94,204 +94,10 @@ _ENTRY(_start); | |||
94 | */ | 94 | */ |
95 | 95 | ||
96 | _ENTRY(__early_start) | 96 | _ENTRY(__early_start) |
97 | /* 1. Find the index of the entry we're executing in */ | ||
98 | bl invstr /* Find our address */ | ||
99 | invstr: mflr r6 /* Make it accessible */ | ||
100 | mfmsr r7 | ||
101 | rlwinm r4,r7,27,31,31 /* extract MSR[IS] */ | ||
102 | mfspr r7, SPRN_PID0 | ||
103 | slwi r7,r7,16 | ||
104 | or r7,r7,r4 | ||
105 | mtspr SPRN_MAS6,r7 | ||
106 | tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */ | ||
107 | mfspr r7,SPRN_MAS1 | ||
108 | andis. r7,r7,MAS1_VALID@h | ||
109 | bne match_TLB | ||
110 | |||
111 | mfspr r7,SPRN_MMUCFG | ||
112 | rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */ | ||
113 | cmpwi r7,3 | ||
114 | bne match_TLB /* skip if NPIDS != 3 */ | ||
115 | |||
116 | mfspr r7,SPRN_PID1 | ||
117 | slwi r7,r7,16 | ||
118 | or r7,r7,r4 | ||
119 | mtspr SPRN_MAS6,r7 | ||
120 | tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */ | ||
121 | mfspr r7,SPRN_MAS1 | ||
122 | andis. r7,r7,MAS1_VALID@h | ||
123 | bne match_TLB | ||
124 | mfspr r7, SPRN_PID2 | ||
125 | slwi r7,r7,16 | ||
126 | or r7,r7,r4 | ||
127 | mtspr SPRN_MAS6,r7 | ||
128 | tlbsx 0,r6 /* Fall through, we had to match */ | ||
129 | |||
130 | match_TLB: | ||
131 | mfspr r7,SPRN_MAS0 | ||
132 | rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */ | ||
133 | |||
134 | mfspr r7,SPRN_MAS1 /* Insure IPROT set */ | ||
135 | oris r7,r7,MAS1_IPROT@h | ||
136 | mtspr SPRN_MAS1,r7 | ||
137 | tlbwe | ||
138 | |||
139 | /* 2. Invalidate all entries except the entry we're executing in */ | ||
140 | mfspr r9,SPRN_TLB1CFG | ||
141 | andi. r9,r9,0xfff | ||
142 | li r6,0 /* Set Entry counter to 0 */ | ||
143 | 1: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | ||
144 | rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */ | ||
145 | mtspr SPRN_MAS0,r7 | ||
146 | tlbre | ||
147 | mfspr r7,SPRN_MAS1 | ||
148 | rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */ | ||
149 | cmpw r3,r6 | ||
150 | beq skpinv /* Dont update the current execution TLB */ | ||
151 | mtspr SPRN_MAS1,r7 | ||
152 | tlbwe | ||
153 | isync | ||
154 | skpinv: addi r6,r6,1 /* Increment */ | ||
155 | cmpw r6,r9 /* Are we done? */ | ||
156 | bne 1b /* If not, repeat */ | ||
157 | |||
158 | /* Invalidate TLB0 */ | ||
159 | li r6,0x04 | ||
160 | tlbivax 0,r6 | ||
161 | TLBSYNC | ||
162 | /* Invalidate TLB1 */ | ||
163 | li r6,0x0c | ||
164 | tlbivax 0,r6 | ||
165 | TLBSYNC | ||
166 | |||
167 | /* 3. Setup a temp mapping and jump to it */ | ||
168 | andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */ | ||
169 | addi r5, r5, 0x1 | ||
170 | lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | ||
171 | rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ | ||
172 | mtspr SPRN_MAS0,r7 | ||
173 | tlbre | ||
174 | |||
175 | /* grab and fixup the RPN */ | ||
176 | mfspr r6,SPRN_MAS1 /* extract MAS1[SIZE] */ | ||
177 | rlwinm r6,r6,25,27,31 | ||
178 | li r8,-1 | ||
179 | addi r6,r6,10 | ||
180 | slw r6,r8,r6 /* convert to mask */ | ||
181 | |||
182 | bl 1f /* Find our address */ | ||
183 | 1: mflr r7 | ||
184 | |||
185 | mfspr r8,SPRN_MAS3 | ||
186 | #ifdef CONFIG_PHYS_64BIT | ||
187 | mfspr r23,SPRN_MAS7 | ||
188 | #endif | ||
189 | and r8,r6,r8 | ||
190 | subfic r9,r6,-4096 | ||
191 | and r9,r9,r7 | ||
192 | |||
193 | or r25,r8,r9 | ||
194 | ori r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR) | ||
195 | |||
196 | /* Just modify the entry ID and EPN for the temp mapping */ | ||
197 | lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | ||
198 | rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ | ||
199 | mtspr SPRN_MAS0,r7 | ||
200 | xori r6,r4,1 /* Setup TMP mapping in the other Address space */ | ||
201 | slwi r6,r6,12 | ||
202 | oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h | ||
203 | ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l | ||
204 | mtspr SPRN_MAS1,r6 | ||
205 | mfspr r6,SPRN_MAS2 | ||
206 | li r7,0 /* temp EPN = 0 */ | ||
207 | rlwimi r7,r6,0,20,31 | ||
208 | mtspr SPRN_MAS2,r7 | ||
209 | mtspr SPRN_MAS3,r8 | ||
210 | tlbwe | ||
211 | |||
212 | xori r6,r4,1 | ||
213 | slwi r6,r6,5 /* setup new context with other address space */ | ||
214 | bl 1f /* Find our address */ | ||
215 | 1: mflr r9 | ||
216 | rlwimi r7,r9,0,20,31 | ||
217 | addi r7,r7,(2f - 1b) | ||
218 | mtspr SPRN_SRR0,r7 | ||
219 | mtspr SPRN_SRR1,r6 | ||
220 | rfi | ||
221 | 2: | ||
222 | /* 4. Clear out PIDs & Search info */ | ||
223 | li r6,0 | ||
224 | mtspr SPRN_MAS6,r6 | ||
225 | mtspr SPRN_PID0,r6 | ||
226 | |||
227 | mfspr r7,SPRN_MMUCFG | ||
228 | rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */ | ||
229 | cmpwi r7,3 | ||
230 | bne 2f /* skip if NPIDS != 3 */ | ||
231 | 97 | ||
232 | mtspr SPRN_PID1,r6 | 98 | #define ENTRY_MAPPING_BOOT_SETUP |
233 | mtspr SPRN_PID2,r6 | 99 | #include "fsl_booke_entry_mapping.S" |
234 | 100 | #undef ENTRY_MAPPING_BOOT_SETUP | |
235 | /* 5. Invalidate mapping we started in */ | ||
236 | 2: | ||
237 | lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | ||
238 | rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ | ||
239 | mtspr SPRN_MAS0,r7 | ||
240 | tlbre | ||
241 | mfspr r6,SPRN_MAS1 | ||
242 | rlwinm r6,r6,0,2,0 /* clear IPROT */ | ||
243 | mtspr SPRN_MAS1,r6 | ||
244 | tlbwe | ||
245 | /* Invalidate TLB1 */ | ||
246 | li r9,0x0c | ||
247 | tlbivax 0,r9 | ||
248 | TLBSYNC | ||
249 | |||
250 | /* The mapping only needs to be cache-coherent on SMP */ | ||
251 | #ifdef CONFIG_SMP | ||
252 | #define M_IF_SMP MAS2_M | ||
253 | #else | ||
254 | #define M_IF_SMP 0 | ||
255 | #endif | ||
256 | |||
257 | /* 6. Setup KERNELBASE mapping in TLB1[0] */ | ||
258 | lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ | ||
259 | mtspr SPRN_MAS0,r6 | ||
260 | lis r6,(MAS1_VALID|MAS1_IPROT)@h | ||
261 | ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l | ||
262 | mtspr SPRN_MAS1,r6 | ||
263 | lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h | ||
264 | ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l | ||
265 | mtspr SPRN_MAS2,r6 | ||
266 | mtspr SPRN_MAS3,r8 | ||
267 | tlbwe | ||
268 | |||
269 | /* 7. Jump to KERNELBASE mapping */ | ||
270 | lis r6,(KERNELBASE & ~0xfff)@h | ||
271 | ori r6,r6,(KERNELBASE & ~0xfff)@l | ||
272 | lis r7,MSR_KERNEL@h | ||
273 | ori r7,r7,MSR_KERNEL@l | ||
274 | bl 1f /* Find our address */ | ||
275 | 1: mflr r9 | ||
276 | rlwimi r6,r9,0,20,31 | ||
277 | addi r6,r6,(2f - 1b) | ||
278 | mtspr SPRN_SRR0,r6 | ||
279 | mtspr SPRN_SRR1,r7 | ||
280 | rfi /* start execution out of TLB1[0] entry */ | ||
281 | |||
282 | /* 8. Clear out the temp mapping */ | ||
283 | 2: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | ||
284 | rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ | ||
285 | mtspr SPRN_MAS0,r7 | ||
286 | tlbre | ||
287 | mfspr r8,SPRN_MAS1 | ||
288 | rlwinm r8,r8,0,2,0 /* clear IPROT */ | ||
289 | mtspr SPRN_MAS1,r8 | ||
290 | tlbwe | ||
291 | /* Invalidate TLB1 */ | ||
292 | li r9,0x0c | ||
293 | tlbivax 0,r9 | ||
294 | TLBSYNC | ||
295 | 101 | ||
296 | /* Establish the interrupt vector offsets */ | 102 | /* Establish the interrupt vector offsets */ |
297 | SET_IVOR(0, CriticalInput); | 103 | SET_IVOR(0, CriticalInput); |