]>
Commit | Line | Data |
---|---|---|
75d90832 HC |
1 | /* |
2 | * linux/arch/arm/kernel/head-nommu.S | |
3 | * | |
4 | * Copyright (C) 1994-2002 Russell King | |
5 | * Copyright (C) 2003-2006 Hyok S. Choi | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License version 2 as | |
9 | * published by the Free Software Foundation. | |
10 | * | |
11 | * Common kernel startup code (non-paged MM) | |
75d90832 HC |
12 | * |
13 | */ | |
75d90832 HC |
14 | #include <linux/linkage.h> |
15 | #include <linux/init.h> | |
a0995c08 | 16 | #include <linux/errno.h> |
75d90832 HC |
17 | |
18 | #include <asm/assembler.h> | |
75d90832 | 19 | #include <asm/ptrace.h> |
2eb9d315 | 20 | #include <asm/asm-offsets.h> |
67c9845b | 21 | #include <asm/memory.h> |
15d07dc9 | 22 | #include <asm/cp15.h> |
3b920cef | 23 | #include <asm/thread_info.h> |
55bdd694 | 24 | #include <asm/v7m.h> |
67c9845b | 25 | #include <asm/mpu.h> |
9dfc28b6 | 26 | #include <asm/page.h> |
75d90832 | 27 | |
75d90832 HC |
28 | /* |
29 | * Kernel startup entry point. | |
30 | * --------------------------- | |
31 | * | |
32 | * This is normally called from the decompressor code. The requirements | |
33 | * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, | |
34 | * r1 = machine nr. | |
35 | * | |
36 | * See linux/arch/arm/tools/mach-types for the complete list of machine | |
37 | * numbers for r1. | |
38 | * | |
39 | */ | |
540b5738 | 40 | |
2abc1c50 | 41 | __HEAD |
bc7dea00 UKK |
42 | |
43 | #ifdef CONFIG_CPU_THUMBONLY | |
44 | .thumb | |
45 | ENTRY(stext) | |
46 | #else | |
47 | .arm | |
75d90832 | 48 | ENTRY(stext) |
540b5738 | 49 | |
14327c66 | 50 | THUMB( badr r9, 1f ) @ Kernel is always entered in ARM. |
540b5738 DM |
51 | THUMB( bx r9 ) @ If this is a Thumb-2 kernel, |
52 | THUMB( .thumb ) @ switch to Thumb now. | |
53 | THUMB(1: ) | |
bc7dea00 | 54 | #endif |
540b5738 | 55 | |
cbfc5619 VM |
56 | #ifdef CONFIG_ARM_VIRT_EXT |
57 | bl __hyp_stub_install | |
58 | #endif | |
59 | @ ensure svc mode and all interrupts masked | |
60 | safe_svcmode_maskall r9 | |
75d90832 | 61 | @ and irqs disabled |
55bdd694 | 62 | #if defined(CONFIG_CPU_CP15) |
75d90832 | 63 | mrc p15, 0, r9, c0, c0 @ get processor id |
55bdd694 CM |
64 | #elif defined(CONFIG_CPU_V7M) |
65 | ldr r9, =BASEADDR_V7M_SCB | |
66 | ldr r9, [r9, V7M_SCB_CPUID] | |
67 | #else | |
68 | ldr r9, =CONFIG_PROCESSOR_ID | |
f12d0d7c | 69 | #endif |
75d90832 HC |
70 | bl __lookup_processor_type @ r5=procinfo r9=cpuid |
71 | movs r10, r5 @ invalid processor (r5=0)? | |
72 | beq __error_p @ yes, error 'p' | |
75d90832 | 73 | |
67c9845b | 74 | #ifdef CONFIG_ARM_MPU |
67c9845b JA |
75 | bl __setup_mpu |
76 | #endif | |
970d96f9 | 77 | |
14327c66 | 78 | badr lr, 1f @ return (PIC) address |
0a9024e8 RK |
79 | ldr r12, [r10, #PROCINFO_INITFUNC] |
80 | add r12, r12, r10 | |
81 | ret r12 | |
22893aa2 VM |
82 | 1: ldr lr, =__mmap_switched |
83 | b __after_proc_init | |
93ed3970 | 84 | ENDPROC(stext) |
75d90832 | 85 | |
01fafcab | 86 | #ifdef CONFIG_SMP |
2449189b | 87 | .text |
01fafcab WD |
88 | ENTRY(secondary_startup) |
89 | /* | |
90 | * Common entry point for secondary CPUs. | |
91 | * | |
92 | * Ensure that we're in SVC mode, and IRQs are disabled. Lookup | |
93 | * the processor type - there is no need to check the machine type | |
94 | * as it has already been validated by the primary processor. | |
95 | */ | |
cbfc5619 VM |
96 | #ifdef CONFIG_ARM_VIRT_EXT |
97 | bl __hyp_stub_install_secondary | |
98 | #endif | |
99 | safe_svcmode_maskall r9 | |
100 | ||
01fafcab WD |
101 | #ifndef CONFIG_CPU_CP15 |
102 | ldr r9, =CONFIG_PROCESSOR_ID | |
103 | #else | |
104 | mrc p15, 0, r9, c0, c0 @ get processor id | |
105 | #endif | |
106 | bl __lookup_processor_type @ r5=procinfo r9=cpuid | |
107 | movs r10, r5 @ invalid processor? | |
108 | beq __error_p @ yes, error 'p' | |
109 | ||
970d96f9 | 110 | ldr r7, __secondary_data |
eb08375e JA |
111 | |
112 | #ifdef CONFIG_ARM_MPU | |
a0995c08 | 113 | bl __secondary_setup_mpu @ Initialize the MPU |
eb08375e JA |
114 | #endif |
115 | ||
970d96f9 | 116 | badr lr, 1f @ return (PIC) address |
0a9024e8 RK |
117 | ldr r12, [r10, #PROCINFO_INITFUNC] |
118 | add r12, r12, r10 | |
119 | ret r12 | |
970d96f9 | 120 | 1: bl __after_proc_init |
b2c3e38a | 121 | ldr sp, [r7, #12] @ set up the stack pointer |
01fafcab WD |
122 | mov fp, #0 |
123 | b secondary_start_kernel | |
970d96f9 | 124 | ENDPROC(secondary_startup) |
01fafcab WD |
125 | |
126 | .type __secondary_data, %object | |
127 | __secondary_data: | |
128 | .long secondary_data | |
01fafcab WD |
129 | #endif /* CONFIG_SMP */ |
130 | ||
75d90832 HC |
131 | /* |
132 | * Set the Control Register and Read the process ID. | |
133 | */ | |
22893aa2 | 134 | .text |
75d90832 | 135 | __after_proc_init: |
3c241210 VM |
136 | #ifdef CONFIG_ARM_MPU |
137 | M_CLASS(movw r12, #:lower16:BASEADDR_V7M_SCB) | |
138 | M_CLASS(movt r12, #:upper16:BASEADDR_V7M_SCB) | |
139 | M_CLASS(ldr r3, [r12, 0x50]) | |
140 | AR_CLASS(mrc p15, 0, r3, c0, c1, 4) @ Read ID_MMFR0 | |
141 | and r3, r3, #(MMFR0_PMSA) @ PMSA field | |
142 | teq r3, #(MMFR0_PMSAv7) @ PMSA v7 | |
046835b4 VM |
143 | beq 1f |
144 | teq r3, #(MMFR0_PMSAv8) @ PMSA v8 | |
145 | /* | |
146 | * Memory region attributes for PMSAv8: | |
147 | * | |
148 | * n = AttrIndx[2:0] | |
149 | * n MAIR | |
150 | * DEVICE_nGnRnE 000 00000000 | |
151 | * NORMAL 001 11111111 | |
152 | */ | |
153 | ldreq r3, =PMSAv8_MAIR(0x00, PMSAv8_RGN_DEVICE_nGnRnE) | \ | |
154 | PMSAv8_MAIR(0xff, PMSAv8_RGN_NORMAL) | |
155 | AR_CLASS(mcreq p15, 0, r3, c10, c2, 0) @ MAIR 0 | |
156 | M_CLASS(streq r3, [r12, #PMSAv8_MAIR0]) | |
157 | moveq r3, #0 | |
158 | AR_CLASS(mcreq p15, 0, r3, c10, c2, 1) @ MAIR 1 | |
159 | M_CLASS(streq r3, [r12, #PMSAv8_MAIR1]) | |
160 | ||
161 | 1: | |
3c241210 | 162 | #endif |
f12d0d7c | 163 | #ifdef CONFIG_CPU_CP15 |
05efde9d CM |
164 | /* |
165 | * CP15 system control register value returned in r0 from | |
166 | * the CPU init function. | |
167 | */ | |
3c241210 VM |
168 | |
169 | #ifdef CONFIG_ARM_MPU | |
170 | biceq r0, r0, #CR_BR @ Disable the 'default mem-map' | |
171 | orreq r0, r0, #CR_M @ Set SCTRL.M (MPU on) | |
172 | #endif | |
76e09204 | 173 | #if defined(CONFIG_ALIGNMENT_TRAP) && __LINUX_ARM_ARCH__ < 6 |
75d90832 HC |
174 | orr r0, r0, #CR_A |
175 | #else | |
176 | bic r0, r0, #CR_A | |
177 | #endif | |
178 | #ifdef CONFIG_CPU_DCACHE_DISABLE | |
179 | bic r0, r0, #CR_C | |
180 | #endif | |
181 | #ifdef CONFIG_CPU_BPREDICT_DISABLE | |
182 | bic r0, r0, #CR_Z | |
183 | #endif | |
184 | #ifdef CONFIG_CPU_ICACHE_DISABLE | |
185 | bic r0, r0, #CR_I | |
186 | #endif | |
187 | mcr p15, 0, r0, c1, c0, 0 @ write control reg | |
cea39477 | 188 | instr_sync |
bc0ee9d2 | 189 | #elif defined (CONFIG_CPU_V7M) |
3c241210 VM |
190 | #ifdef CONFIG_ARM_MPU |
191 | ldreq r3, [r12, MPU_CTRL] | |
192 | biceq r3, #MPU_CTRL_PRIVDEFENA | |
193 | orreq r3, #MPU_CTRL_ENABLE | |
194 | streq r3, [r12, MPU_CTRL] | |
195 | isb | |
196 | #endif | |
bc0ee9d2 JA |
197 | /* For V7M systems we want to modify the CCR similarly to the SCTLR */ |
198 | #ifdef CONFIG_CPU_DCACHE_DISABLE | |
199 | bic r0, r0, #V7M_SCB_CCR_DC | |
200 | #endif | |
201 | #ifdef CONFIG_CPU_BPREDICT_DISABLE | |
202 | bic r0, r0, #V7M_SCB_CCR_BP | |
203 | #endif | |
204 | #ifdef CONFIG_CPU_ICACHE_DISABLE | |
205 | bic r0, r0, #V7M_SCB_CCR_IC | |
206 | #endif | |
3c241210 | 207 | str r0, [r12, V7M_SCB_CCR] |
bc0ee9d2 | 208 | #endif /* CONFIG_CPU_CP15 elif CONFIG_CPU_V7M */ |
970d96f9 | 209 | ret lr |
93ed3970 | 210 | ENDPROC(__after_proc_init) |
3b920cef | 211 | .ltorg |
75d90832 | 212 | |
67c9845b JA |
213 | #ifdef CONFIG_ARM_MPU |
214 | ||
215 | ||
9fcb01a9 | 216 | #ifndef CONFIG_CPU_V7M |
67c9845b | 217 | /* Set which MPU region should be programmed */ |
9fcb01a9 | 218 | .macro set_region_nr tmp, rgnr, unused |
67c9845b JA |
219 | mov \tmp, \rgnr @ Use static region numbers |
220 | mcr p15, 0, \tmp, c6, c2, 0 @ Write RGNR | |
221 | .endm | |
222 | ||
223 | /* Setup a single MPU region, either D or I side (D-side for unified) */ | |
9cfb541a | 224 | .macro setup_region bar, acr, sr, side = PMSAv7_DATA_SIDE, unused |
67c9845b JA |
225 | mcr p15, 0, \bar, c6, c1, (0 + \side) @ I/DRBAR |
226 | mcr p15, 0, \acr, c6, c1, (4 + \side) @ I/DRACR | |
227 | mcr p15, 0, \sr, c6, c1, (2 + \side) @ I/DRSR | |
228 | .endm | |
9fcb01a9 VM |
229 | #else |
230 | .macro set_region_nr tmp, rgnr, base | |
231 | mov \tmp, \rgnr | |
9cfb541a | 232 | str \tmp, [\base, #PMSAv7_RNR] |
9fcb01a9 VM |
233 | .endm |
234 | ||
235 | .macro setup_region bar, acr, sr, unused, base | |
236 | lsl \acr, \acr, #16 | |
237 | orr \acr, \acr, \sr | |
9cfb541a VM |
238 | str \bar, [\base, #PMSAv7_RBAR] |
239 | str \acr, [\base, #PMSAv7_RASR] | |
9fcb01a9 | 240 | .endm |
67c9845b | 241 | |
9fcb01a9 | 242 | #endif |
67c9845b JA |
243 | /* |
244 | * Setup the MPU and initial MPU Regions. We create the following regions: | |
245 | * Region 0: Use this for probing the MPU details, so leave disabled. | |
246 | * Region 1: Background region - covers the whole of RAM as strongly ordered | |
247 | * Region 2: Normal, Shared, cacheable for RAM. From PHYS_OFFSET, size from r6 | |
9dfc28b6 | 248 | * Region 3: Normal, shared, inaccessible from PL0 to protect the vectors page |
67c9845b | 249 | * |
9cfb541a | 250 | * r6: Value to be written to DRSR (and IRSR if required) for PMSAv7_RAM_REGION |
67c9845b | 251 | */ |
22893aa2 | 252 | __HEAD |
67c9845b JA |
253 | |
254 | ENTRY(__setup_mpu) | |
255 | ||
256 | /* Probe for v7 PMSA compliance */ | |
9fcb01a9 VM |
257 | M_CLASS(movw r12, #:lower16:BASEADDR_V7M_SCB) |
258 | M_CLASS(movt r12, #:upper16:BASEADDR_V7M_SCB) | |
259 | ||
260 | AR_CLASS(mrc p15, 0, r0, c0, c1, 4) @ Read ID_MMFR0 | |
261 | M_CLASS(ldr r0, [r12, 0x50]) | |
67c9845b JA |
262 | and r0, r0, #(MMFR0_PMSA) @ PMSA field |
263 | teq r0, #(MMFR0_PMSAv7) @ PMSA v7 | |
9cfb541a | 264 | beq __setup_pmsa_v7 |
046835b4 VM |
265 | teq r0, #(MMFR0_PMSAv8) @ PMSA v8 |
266 | beq __setup_pmsa_v8 | |
9cfb541a VM |
267 | |
268 | ret lr | |
269 | ENDPROC(__setup_mpu) | |
270 | ||
271 | ENTRY(__setup_pmsa_v7) | |
272 | /* Calculate the size of a region covering just the kernel */ | |
273 | ldr r5, =PLAT_PHYS_OFFSET @ Region start: PHYS_OFFSET | |
274 | ldr r6, =(_end) @ Cover whole kernel | |
275 | sub r6, r6, r5 @ Minimum size of region to map | |
276 | clz r6, r6 @ Region size must be 2^N... | |
277 | rsb r6, r6, #31 @ ...so round up region size | |
278 | lsl r6, r6, #PMSAv7_RSR_SZ @ Put size in right field | |
279 | orr r6, r6, #(1 << PMSAv7_RSR_EN) @ Set region enabled bit | |
67c9845b JA |
280 | |
281 | /* Determine whether the D/I-side memory map is unified. We set the | |
282 | * flags here and continue to use them for the rest of this function */ | |
9fcb01a9 VM |
283 | AR_CLASS(mrc p15, 0, r0, c0, c0, 4) @ MPUIR |
284 | M_CLASS(ldr r0, [r12, #MPU_TYPE]) | |
67c9845b | 285 | ands r5, r0, #MPUIR_DREGION_SZMASK @ 0 size d region => No MPU |
a0995c08 | 286 | bxeq lr |
67c9845b JA |
287 | tst r0, #MPUIR_nU @ MPUIR_nU = 0 for unified |
288 | ||
289 | /* Setup second region first to free up r6 */ | |
9cfb541a | 290 | set_region_nr r0, #PMSAv7_RAM_REGION, r12 |
67c9845b JA |
291 | isb |
292 | /* Full access from PL0, PL1, shared for CONFIG_SMP, cacheable */ | |
b713aa0b | 293 | ldr r0, =PLAT_PHYS_OFFSET @ RAM starts at PHYS_OFFSET |
9cfb541a | 294 | ldr r5,=(PMSAv7_AP_PL1RW_PL0RW | PMSAv7_RGN_NORMAL) |
67c9845b | 295 | |
9cfb541a | 296 | setup_region r0, r5, r6, PMSAv7_DATA_SIDE, r12 @ PHYS_OFFSET, shared, enabled |
9fcb01a9 | 297 | beq 1f @ Memory-map not unified |
9cfb541a | 298 | setup_region r0, r5, r6, PMSAv7_INSTR_SIDE, r12 @ PHYS_OFFSET, shared, enabled |
67c9845b JA |
299 | 1: isb |
300 | ||
301 | /* First/background region */ | |
9cfb541a | 302 | set_region_nr r0, #PMSAv7_BG_REGION, r12 |
67c9845b JA |
303 | isb |
304 | /* Execute Never, strongly ordered, inaccessible to PL0, rw PL1 */ | |
305 | mov r0, #0 @ BG region starts at 0x0 | |
9cfb541a VM |
306 | ldr r5,=(PMSAv7_ACR_XN | PMSAv7_RGN_STRONGLY_ORDERED | PMSAv7_AP_PL1RW_PL0NA) |
307 | mov r6, #PMSAv7_RSR_ALL_MEM @ 4GB region, enabled | |
67c9845b | 308 | |
9cfb541a | 309 | setup_region r0, r5, r6, PMSAv7_DATA_SIDE, r12 @ 0x0, BG region, enabled |
9fcb01a9 | 310 | beq 2f @ Memory-map not unified |
9cfb541a | 311 | setup_region r0, r5, r6, PMSAv7_INSTR_SIDE r12 @ 0x0, BG region, enabled |
67c9845b JA |
312 | 2: isb |
313 | ||
21621830 | 314 | #ifdef CONFIG_XIP_KERNEL |
9cfb541a | 315 | set_region_nr r0, #PMSAv7_ROM_REGION, r12 |
21621830 VM |
316 | isb |
317 | ||
9cfb541a | 318 | ldr r5,=(PMSAv7_AP_PL1RO_PL0NA | PMSAv7_RGN_NORMAL) |
21621830 VM |
319 | |
320 | ldr r0, =CONFIG_XIP_PHYS_ADDR @ ROM start | |
321 | ldr r6, =(_exiprom) @ ROM end | |
322 | sub r6, r6, r0 @ Minimum size of region to map | |
323 | clz r6, r6 @ Region size must be 2^N... | |
324 | rsb r6, r6, #31 @ ...so round up region size | |
9cfb541a VM |
325 | lsl r6, r6, #PMSAv7_RSR_SZ @ Put size in right field |
326 | orr r6, r6, #(1 << PMSAv7_RSR_EN) @ Set region enabled bit | |
21621830 | 327 | |
9cfb541a | 328 | setup_region r0, r5, r6, PMSAv7_DATA_SIDE, r12 @ XIP_PHYS_ADDR, shared, enabled |
21621830 | 329 | beq 3f @ Memory-map not unified |
9cfb541a | 330 | setup_region r0, r5, r6, PMSAv7_INSTR_SIDE, r12 @ XIP_PHYS_ADDR, shared, enabled |
21621830 VM |
331 | 3: isb |
332 | #endif | |
a0995c08 | 333 | ret lr |
9cfb541a | 334 | ENDPROC(__setup_pmsa_v7) |
a0995c08 | 335 | |
046835b4 VM |
336 | ENTRY(__setup_pmsa_v8) |
337 | mov r0, #0 | |
338 | AR_CLASS(mcr p15, 0, r0, c6, c2, 1) @ PRSEL | |
339 | M_CLASS(str r0, [r12, #PMSAv8_RNR]) | |
340 | isb | |
341 | ||
342 | #ifdef CONFIG_XIP_KERNEL | |
343 | ldr r5, =CONFIG_XIP_PHYS_ADDR @ ROM start | |
344 | ldr r6, =(_exiprom) @ ROM end | |
345 | sub r6, r6, #1 | |
346 | bic r6, r6, #(PMSAv8_MINALIGN - 1) | |
347 | ||
348 | orr r5, r5, #(PMSAv8_AP_PL1RW_PL0NA | PMSAv8_RGN_SHARED) | |
349 | orr r6, r6, #(PMSAv8_LAR_IDX(PMSAv8_RGN_NORMAL) | PMSAv8_LAR_EN) | |
350 | ||
351 | AR_CLASS(mcr p15, 0, r5, c6, c8, 0) @ PRBAR0 | |
352 | AR_CLASS(mcr p15, 0, r6, c6, c8, 1) @ PRLAR0 | |
353 | M_CLASS(str r5, [r12, #PMSAv8_RBAR_A(0)]) | |
354 | M_CLASS(str r6, [r12, #PMSAv8_RLAR_A(0)]) | |
355 | #endif | |
356 | ||
357 | ldr r5, =KERNEL_START | |
358 | ldr r6, =KERNEL_END | |
359 | sub r6, r6, #1 | |
360 | bic r6, r6, #(PMSAv8_MINALIGN - 1) | |
361 | ||
362 | orr r5, r5, #(PMSAv8_AP_PL1RW_PL0NA | PMSAv8_RGN_SHARED) | |
363 | orr r6, r6, #(PMSAv8_LAR_IDX(PMSAv8_RGN_NORMAL) | PMSAv8_LAR_EN) | |
364 | ||
365 | AR_CLASS(mcr p15, 0, r5, c6, c8, 4) @ PRBAR1 | |
366 | AR_CLASS(mcr p15, 0, r6, c6, c8, 5) @ PRLAR1 | |
367 | M_CLASS(str r5, [r12, #PMSAv8_RBAR_A(1)]) | |
368 | M_CLASS(str r6, [r12, #PMSAv8_RLAR_A(1)]) | |
369 | ||
370 | /* Setup Background: 0x0 - min(KERNEL_START, XIP_PHYS_ADDR) */ | |
371 | #ifdef CONFIG_XIP_KERNEL | |
372 | ldr r6, =KERNEL_START | |
373 | ldr r5, =CONFIG_XIP_PHYS_ADDR | |
374 | cmp r6, r5 | |
375 | movcs r6, r5 | |
376 | #else | |
377 | ldr r6, =KERNEL_START | |
378 | #endif | |
379 | cmp r6, #0 | |
380 | beq 1f | |
381 | ||
382 | mov r5, #0 | |
383 | sub r6, r6, #1 | |
384 | bic r6, r6, #(PMSAv8_MINALIGN - 1) | |
385 | ||
386 | orr r5, r5, #(PMSAv8_AP_PL1RW_PL0NA | PMSAv8_RGN_SHARED | PMSAv8_BAR_XN) | |
387 | orr r6, r6, #(PMSAv8_LAR_IDX(PMSAv8_RGN_DEVICE_nGnRnE) | PMSAv8_LAR_EN) | |
388 | ||
389 | AR_CLASS(mcr p15, 0, r5, c6, c9, 0) @ PRBAR2 | |
390 | AR_CLASS(mcr p15, 0, r6, c6, c9, 1) @ PRLAR2 | |
391 | M_CLASS(str r5, [r12, #PMSAv8_RBAR_A(2)]) | |
392 | M_CLASS(str r6, [r12, #PMSAv8_RLAR_A(2)]) | |
393 | ||
394 | 1: | |
395 | /* Setup Background: max(KERNEL_END, _exiprom) - 0xffffffff */ | |
396 | #ifdef CONFIG_XIP_KERNEL | |
397 | ldr r5, =KERNEL_END | |
398 | ldr r6, =(_exiprom) | |
399 | cmp r5, r6 | |
400 | movcc r5, r6 | |
401 | #else | |
402 | ldr r5, =KERNEL_END | |
403 | #endif | |
404 | mov r6, #0xffffffff | |
405 | bic r6, r6, #(PMSAv8_MINALIGN - 1) | |
406 | ||
407 | orr r5, r5, #(PMSAv8_AP_PL1RW_PL0NA | PMSAv8_RGN_SHARED | PMSAv8_BAR_XN) | |
408 | orr r6, r6, #(PMSAv8_LAR_IDX(PMSAv8_RGN_DEVICE_nGnRnE) | PMSAv8_LAR_EN) | |
409 | ||
410 | AR_CLASS(mcr p15, 0, r5, c6, c9, 4) @ PRBAR3 | |
411 | AR_CLASS(mcr p15, 0, r6, c6, c9, 5) @ PRLAR3 | |
412 | M_CLASS(str r5, [r12, #PMSAv8_RBAR_A(3)]) | |
413 | M_CLASS(str r6, [r12, #PMSAv8_RLAR_A(3)]) | |
414 | ||
415 | #ifdef CONFIG_XIP_KERNEL | |
416 | /* Setup Background: min(_exiprom, KERNEL_END) - max(KERNEL_START, XIP_PHYS_ADDR) */ | |
417 | ldr r5, =(_exiprom) | |
418 | ldr r6, =KERNEL_END | |
419 | cmp r5, r6 | |
420 | movcs r5, r6 | |
421 | ||
422 | ldr r6, =KERNEL_START | |
423 | ldr r0, =CONFIG_XIP_PHYS_ADDR | |
424 | cmp r6, r0 | |
425 | movcc r6, r0 | |
426 | ||
427 | sub r6, r6, #1 | |
428 | bic r6, r6, #(PMSAv8_MINALIGN - 1) | |
429 | ||
430 | orr r5, r5, #(PMSAv8_AP_PL1RW_PL0NA | PMSAv8_RGN_SHARED | PMSAv8_BAR_XN) | |
431 | orr r6, r6, #(PMSAv8_LAR_IDX(PMSAv8_RGN_DEVICE_nGnRnE) | PMSAv8_LAR_EN) | |
432 | ||
433 | #ifdef CONFIG_CPU_V7M | |
434 | /* There is no alias for n == 4 */ | |
435 | mov r0, #4 | |
436 | str r0, [r12, #PMSAv8_RNR] @ PRSEL | |
437 | isb | |
438 | ||
439 | str r5, [r12, #PMSAv8_RBAR_A(0)] | |
440 | str r6, [r12, #PMSAv8_RLAR_A(0)] | |
441 | #else | |
d410a8a4 VM |
442 | mcr p15, 0, r5, c6, c10, 0 @ PRBAR4 |
443 | mcr p15, 0, r6, c6, c10, 1 @ PRLAR4 | |
046835b4 VM |
444 | #endif |
445 | #endif | |
446 | ret lr | |
447 | ENDPROC(__setup_pmsa_v8) | |
448 | ||
a0995c08 VM |
449 | #ifdef CONFIG_SMP |
450 | /* | |
451 | * r6: pointer at mpu_rgn_info | |
452 | */ | |
453 | ||
22893aa2 | 454 | .text |
a0995c08 | 455 | ENTRY(__secondary_setup_mpu) |
9cfb541a VM |
456 | /* Use MPU region info supplied by __cpu_up */ |
457 | ldr r6, [r7] @ get secondary_data.mpu_rgn_info | |
458 | ||
a0995c08 VM |
459 | /* Probe for v7 PMSA compliance */ |
460 | mrc p15, 0, r0, c0, c1, 4 @ Read ID_MMFR0 | |
461 | and r0, r0, #(MMFR0_PMSA) @ PMSA field | |
462 | teq r0, #(MMFR0_PMSAv7) @ PMSA v7 | |
9cfb541a | 463 | beq __secondary_setup_pmsa_v7 |
046835b4 VM |
464 | teq r0, #(MMFR0_PMSAv8) @ PMSA v8 |
465 | beq __secondary_setup_pmsa_v8 | |
9cfb541a VM |
466 | b __error_p |
467 | ENDPROC(__secondary_setup_mpu) | |
a0995c08 | 468 | |
9cfb541a VM |
469 | /* |
470 | * r6: pointer at mpu_rgn_info | |
471 | */ | |
472 | ENTRY(__secondary_setup_pmsa_v7) | |
a0995c08 VM |
473 | /* Determine whether the D/I-side memory map is unified. We set the |
474 | * flags here and continue to use them for the rest of this function */ | |
475 | mrc p15, 0, r0, c0, c0, 4 @ MPUIR | |
476 | ands r5, r0, #MPUIR_DREGION_SZMASK @ 0 size d region => No MPU | |
477 | beq __error_p | |
478 | ||
479 | ldr r4, [r6, #MPU_RNG_INFO_USED] | |
480 | mov r5, #MPU_RNG_SIZE | |
481 | add r3, r6, #MPU_RNG_INFO_RNGS | |
482 | mla r3, r4, r5, r3 | |
483 | ||
484 | 1: | |
485 | tst r0, #MPUIR_nU @ MPUIR_nU = 0 for unified | |
486 | sub r3, r3, #MPU_RNG_SIZE | |
487 | sub r4, r4, #1 | |
488 | ||
489 | set_region_nr r0, r4 | |
9dfc28b6 | 490 | isb |
9dfc28b6 | 491 | |
a0995c08 VM |
492 | ldr r0, [r3, #MPU_RGN_DRBAR] |
493 | ldr r6, [r3, #MPU_RGN_DRSR] | |
494 | ldr r5, [r3, #MPU_RGN_DRACR] | |
495 | ||
9cfb541a | 496 | setup_region r0, r5, r6, PMSAv7_DATA_SIDE |
a0995c08 | 497 | beq 2f |
9cfb541a | 498 | setup_region r0, r5, r6, PMSAv7_INSTR_SIDE |
a0995c08 VM |
499 | 2: isb |
500 | ||
501 | mrc p15, 0, r0, c0, c0, 4 @ Reevaluate the MPUIR | |
502 | cmp r4, #0 | |
503 | bgt 1b | |
9dfc28b6 | 504 | |
6ebbf2ce | 505 | ret lr |
9cfb541a | 506 | ENDPROC(__secondary_setup_pmsa_v7) |
a0995c08 | 507 | |
046835b4 VM |
508 | ENTRY(__secondary_setup_pmsa_v8) |
509 | ldr r4, [r6, #MPU_RNG_INFO_USED] | |
510 | #ifndef CONFIG_XIP_KERNEL | |
511 | add r4, r4, #1 | |
512 | #endif | |
513 | mov r5, #MPU_RNG_SIZE | |
514 | add r3, r6, #MPU_RNG_INFO_RNGS | |
515 | mla r3, r4, r5, r3 | |
516 | ||
517 | 1: | |
518 | sub r3, r3, #MPU_RNG_SIZE | |
519 | sub r4, r4, #1 | |
520 | ||
521 | mcr p15, 0, r4, c6, c2, 1 @ PRSEL | |
522 | isb | |
523 | ||
524 | ldr r5, [r3, #MPU_RGN_PRBAR] | |
525 | ldr r6, [r3, #MPU_RGN_PRLAR] | |
526 | ||
527 | mcr p15, 0, r5, c6, c3, 0 @ PRBAR | |
528 | mcr p15, 0, r6, c6, c3, 1 @ PRLAR | |
529 | ||
530 | cmp r4, #0 | |
531 | bgt 1b | |
532 | ||
533 | ret lr | |
534 | ENDPROC(__secondary_setup_pmsa_v8) | |
a0995c08 VM |
535 | #endif /* CONFIG_SMP */ |
536 | #endif /* CONFIG_ARM_MPU */ | |
75d90832 | 537 | #include "head-common.S" |