aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/proc-v7.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/proc-v7.S')
-rw-r--r--arch/arm/mm/proc-v7.S216
1 files changed, 156 insertions, 60 deletions
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 197f21bed5e9..089c0b5e454f 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -30,15 +30,13 @@
30#define TTB_IRGN_WT ((1 << 0) | (0 << 6)) 30#define TTB_IRGN_WT ((1 << 0) | (0 << 6))
31#define TTB_IRGN_WB ((1 << 0) | (1 << 6)) 31#define TTB_IRGN_WB ((1 << 0) | (1 << 6))
32 32
33#ifndef CONFIG_SMP
34/* PTWs cacheable, inner WB not shareable, outer WB not shareable */ 33/* PTWs cacheable, inner WB not shareable, outer WB not shareable */
35#define TTB_FLAGS TTB_IRGN_WB|TTB_RGN_OC_WB 34#define TTB_FLAGS_UP TTB_IRGN_WB|TTB_RGN_OC_WB
36#define PMD_FLAGS PMD_SECT_WB 35#define PMD_FLAGS_UP PMD_SECT_WB
37#else 36
38/* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */ 37/* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
39#define TTB_FLAGS TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA 38#define TTB_FLAGS_SMP TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA
40#define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S 39#define PMD_FLAGS_SMP PMD_SECT_WBWA|PMD_SECT_S
41#endif
42 40
43ENTRY(cpu_v7_proc_init) 41ENTRY(cpu_v7_proc_init)
44 mov pc, lr 42 mov pc, lr
@@ -105,14 +103,21 @@ ENTRY(cpu_v7_switch_mm)
105#ifdef CONFIG_MMU 103#ifdef CONFIG_MMU
106 mov r2, #0 104 mov r2, #0
107 ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id 105 ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id
108 orr r0, r0, #TTB_FLAGS 106 ALT_SMP(orr r0, r0, #TTB_FLAGS_SMP)
107 ALT_UP(orr r0, r0, #TTB_FLAGS_UP)
109#ifdef CONFIG_ARM_ERRATA_430973 108#ifdef CONFIG_ARM_ERRATA_430973
110 mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB 109 mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
111#endif 110#endif
111#ifdef CONFIG_ARM_ERRATA_754322
112 dsb
113#endif
112 mcr p15, 0, r2, c13, c0, 1 @ set reserved context ID 114 mcr p15, 0, r2, c13, c0, 1 @ set reserved context ID
113 isb 115 isb
1141: mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 1161: mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
115 isb 117 isb
118#ifdef CONFIG_ARM_ERRATA_754322
119 dsb
120#endif
116 mcr p15, 0, r1, c13, c0, 1 @ set context ID 121 mcr p15, 0, r1, c13, c0, 1 @ set context ID
117 isb 122 isb
118#endif 123#endif
@@ -125,15 +130,13 @@ ENDPROC(cpu_v7_switch_mm)
125 * Set a level 2 translation table entry. 130 * Set a level 2 translation table entry.
126 * 131 *
127 * - ptep - pointer to level 2 translation table entry 132 * - ptep - pointer to level 2 translation table entry
128 * (hardware version is stored at -1024 bytes) 133 * (hardware version is stored at +2048 bytes)
129 * - pte - PTE value to store 134 * - pte - PTE value to store
130 * - ext - value for extended PTE bits 135 * - ext - value for extended PTE bits
131 */ 136 */
132ENTRY(cpu_v7_set_pte_ext) 137ENTRY(cpu_v7_set_pte_ext)
133#ifdef CONFIG_MMU 138#ifdef CONFIG_MMU
134 ARM( str r1, [r0], #-2048 ) @ linux version 139 str r1, [r0] @ linux version
135 THUMB( str r1, [r0] ) @ linux version
136 THUMB( sub r0, r0, #2048 )
137 140
138 bic r3, r1, #0x000003f0 141 bic r3, r1, #0x000003f0
139 bic r3, r3, #PTE_TYPE_MASK 142 bic r3, r3, #PTE_TYPE_MASK
@@ -143,23 +146,28 @@ ENTRY(cpu_v7_set_pte_ext)
143 tst r1, #1 << 4 146 tst r1, #1 << 4
144 orrne r3, r3, #PTE_EXT_TEX(1) 147 orrne r3, r3, #PTE_EXT_TEX(1)
145 148
146 tst r1, #L_PTE_WRITE 149 eor r1, r1, #L_PTE_DIRTY
147 tstne r1, #L_PTE_DIRTY 150 tst r1, #L_PTE_RDONLY | L_PTE_DIRTY
148 orreq r3, r3, #PTE_EXT_APX 151 orrne r3, r3, #PTE_EXT_APX
149 152
150 tst r1, #L_PTE_USER 153 tst r1, #L_PTE_USER
151 orrne r3, r3, #PTE_EXT_AP1 154 orrne r3, r3, #PTE_EXT_AP1
155#ifdef CONFIG_CPU_USE_DOMAINS
156 @ allow kernel read/write access to read-only user pages
152 tstne r3, #PTE_EXT_APX 157 tstne r3, #PTE_EXT_APX
153 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 158 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
159#endif
154 160
155 tst r1, #L_PTE_EXEC 161 tst r1, #L_PTE_XN
156 orreq r3, r3, #PTE_EXT_XN 162 orrne r3, r3, #PTE_EXT_XN
157 163
158 tst r1, #L_PTE_YOUNG 164 tst r1, #L_PTE_YOUNG
159 tstne r1, #L_PTE_PRESENT 165 tstne r1, #L_PTE_PRESENT
160 moveq r3, #0 166 moveq r3, #0
161 167
162 str r3, [r0] 168 ARM( str r3, [r0, #2048]! )
169 THUMB( add r0, r0, #2048 )
170 THUMB( str r3, [r0] )
163 mcr p15, 0, r0, c7, c10, 1 @ flush_pte 171 mcr p15, 0, r0, c7, c10, 1 @ flush_pte
164#endif 172#endif
165 mov pc, lr 173 mov pc, lr
@@ -169,7 +177,92 @@ cpu_v7_name:
169 .ascii "ARMv7 Processor" 177 .ascii "ARMv7 Processor"
170 .align 178 .align
171 179
172 __INIT 180 /*
181 * Memory region attributes with SCTLR.TRE=1
182 *
183 * n = TEX[0],C,B
184 * TR = PRRR[2n+1:2n] - memory type
185 * IR = NMRR[2n+1:2n] - inner cacheable property
186 * OR = NMRR[2n+17:2n+16] - outer cacheable property
187 *
188 * n TR IR OR
189 * UNCACHED 000 00
190 * BUFFERABLE 001 10 00 00
191 * WRITETHROUGH 010 10 10 10
192 * WRITEBACK 011 10 11 11
193 * reserved 110
194 * WRITEALLOC 111 10 01 01
195 * DEV_SHARED 100 01
196 * DEV_NONSHARED 100 01
197 * DEV_WC 001 10
198 * DEV_CACHED 011 10
199 *
200 * Other attributes:
201 *
202 * DS0 = PRRR[16] = 0 - device shareable property
203 * DS1 = PRRR[17] = 1 - device shareable property
204 * NS0 = PRRR[18] = 0 - normal shareable property
205 * NS1 = PRRR[19] = 1 - normal shareable property
206 * NOS = PRRR[24+n] = 1 - not outer shareable
207 */
208.equ PRRR, 0xff0a81a8
209.equ NMRR, 0x40e040e0
210
211/* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
212.globl cpu_v7_suspend_size
213.equ cpu_v7_suspend_size, 4 * 9
214#ifdef CONFIG_PM_SLEEP
215ENTRY(cpu_v7_do_suspend)
216 stmfd sp!, {r4 - r11, lr}
217 mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
218 mrc p15, 0, r5, c13, c0, 1 @ Context ID
219 mrc p15, 0, r6, c13, c0, 3 @ User r/o thread ID
220 stmia r0!, {r4 - r6}
221 mrc p15, 0, r6, c3, c0, 0 @ Domain ID
222 mrc p15, 0, r7, c2, c0, 0 @ TTB 0
223 mrc p15, 0, r8, c2, c0, 1 @ TTB 1
224 mrc p15, 0, r9, c1, c0, 0 @ Control register
225 mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
226 mrc p15, 0, r11, c1, c0, 2 @ Co-processor access control
227 stmia r0, {r6 - r11}
228 ldmfd sp!, {r4 - r11, pc}
229ENDPROC(cpu_v7_do_suspend)
230
231ENTRY(cpu_v7_do_resume)
232 mov ip, #0
233 mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs
234 mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
235 ldmia r0!, {r4 - r6}
236 mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
237 mcr p15, 0, r5, c13, c0, 1 @ Context ID
238 mcr p15, 0, r6, c13, c0, 3 @ User r/o thread ID
239 ldmia r0, {r6 - r11}
240 mcr p15, 0, r6, c3, c0, 0 @ Domain ID
241 mcr p15, 0, r7, c2, c0, 0 @ TTB 0
242 mcr p15, 0, r8, c2, c0, 1 @ TTB 1
243 mcr p15, 0, ip, c2, c0, 2 @ TTB control register
244 mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register
245 mcr p15, 0, r11, c1, c0, 2 @ Co-processor access control
246 ldr r4, =PRRR @ PRRR
247 ldr r5, =NMRR @ NMRR
248 mcr p15, 0, r4, c10, c2, 0 @ write PRRR
249 mcr p15, 0, r5, c10, c2, 1 @ write NMRR
250 isb
251 mov r0, r9 @ control register
252 mov r2, r7, lsr #14 @ get TTB0 base
253 mov r2, r2, lsl #14
254 ldr r3, cpu_resume_l1_flags
255 b cpu_resume_mmu
256ENDPROC(cpu_v7_do_resume)
257cpu_resume_l1_flags:
258 ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
259 ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
260#else
261#define cpu_v7_do_suspend 0
262#define cpu_v7_do_resume 0
263#endif
264
265 __CPUINIT
173 266
174/* 267/*
175 * __v7_setup 268 * __v7_setup
@@ -188,7 +281,8 @@ cpu_v7_name:
188 */ 281 */
189__v7_ca9mp_setup: 282__v7_ca9mp_setup:
190#ifdef CONFIG_SMP 283#ifdef CONFIG_SMP
191 mrc p15, 0, r0, c1, c0, 1 284 ALT_SMP(mrc p15, 0, r0, c1, c0, 1)
285 ALT_UP(mov r0, #(1 << 6)) @ fake it for UP
192 tst r0, #(1 << 6) @ SMP/nAMP mode enabled? 286 tst r0, #(1 << 6) @ SMP/nAMP mode enabled?
193 orreq r0, r0, #(1 << 6) | (1 << 0) @ Enable SMP/nAMP mode and 287 orreq r0, r0, #(1 << 6) | (1 << 0) @ Enable SMP/nAMP mode and
194 mcreq p15, 0, r0, c1, c0, 1 @ TLB ops broadcasting 288 mcreq p15, 0, r0, c1, c0, 1 @ TLB ops broadcasting
@@ -261,6 +355,12 @@ __v7_setup:
261 orreq r10, r10, #1 << 6 @ set bit #6 355 orreq r10, r10, #1 << 6 @ set bit #6
262 mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register 356 mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register
263#endif 357#endif
358#ifdef CONFIG_ARM_ERRATA_751472
359 cmp r6, #0x30 @ present prior to r3p0
360 mrclt p15, 0, r10, c15, c0, 1 @ read diagnostic register
361 orrlt r10, r10, #1 << 11 @ set bit #11
362 mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register
363#endif
264 364
2653: mov r10, #0 3653: mov r10, #0
266#ifdef HARVARD_CACHE 366#ifdef HARVARD_CACHE
@@ -270,40 +370,13 @@ __v7_setup:
270#ifdef CONFIG_MMU 370#ifdef CONFIG_MMU
271 mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs 371 mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs
272 mcr p15, 0, r10, c2, c0, 2 @ TTB control register 372 mcr p15, 0, r10, c2, c0, 2 @ TTB control register
273 orr r4, r4, #TTB_FLAGS 373 ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP)
274 mcr p15, 0, r4, c2, c0, 1 @ load TTB1 374 ALT_UP(orr r4, r4, #TTB_FLAGS_UP)
275 mov r10, #0x1f @ domains 0, 1 = manager 375 ALT_SMP(orr r8, r8, #TTB_FLAGS_SMP)
276 mcr p15, 0, r10, c3, c0, 0 @ load domain access register 376 ALT_UP(orr r8, r8, #TTB_FLAGS_UP)
277 /* 377 mcr p15, 0, r8, c2, c0, 1 @ load TTB1
278 * Memory region attributes with SCTLR.TRE=1 378 ldr r5, =PRRR @ PRRR
279 * 379 ldr r6, =NMRR @ NMRR
280 * n = TEX[0],C,B
281 * TR = PRRR[2n+1:2n] - memory type
282 * IR = NMRR[2n+1:2n] - inner cacheable property
283 * OR = NMRR[2n+17:2n+16] - outer cacheable property
284 *
285 * n TR IR OR
286 * UNCACHED 000 00
287 * BUFFERABLE 001 10 00 00
288 * WRITETHROUGH 010 10 10 10
289 * WRITEBACK 011 10 11 11
290 * reserved 110
291 * WRITEALLOC 111 10 01 01
292 * DEV_SHARED 100 01
293 * DEV_NONSHARED 100 01
294 * DEV_WC 001 10
295 * DEV_CACHED 011 10
296 *
297 * Other attributes:
298 *
299 * DS0 = PRRR[16] = 0 - device shareable property
300 * DS1 = PRRR[17] = 1 - device shareable property
301 * NS0 = PRRR[18] = 0 - normal shareable property
302 * NS1 = PRRR[19] = 1 - normal shareable property
303 * NOS = PRRR[24+n] = 1 - not outer shareable
304 */
305 ldr r5, =0xff0a81a8 @ PRRR
306 ldr r6, =0x40e040e0 @ NMRR
307 mcr p15, 0, r5, c10, c2, 0 @ write PRRR 380 mcr p15, 0, r5, c10, c2, 0 @ write PRRR
308 mcr p15, 0, r6, c10, c2, 1 @ write NMRR 381 mcr p15, 0, r6, c10, c2, 1 @ write NMRR
309#endif 382#endif
@@ -312,6 +385,10 @@ __v7_setup:
312#ifdef CONFIG_CPU_ENDIAN_BE8 385#ifdef CONFIG_CPU_ENDIAN_BE8
313 orr r6, r6, #1 << 25 @ big-endian page tables 386 orr r6, r6, #1 << 25 @ big-endian page tables
314#endif 387#endif
388#ifdef CONFIG_SWP_EMULATE
389 orr r5, r5, #(1 << 10) @ set SW bit in "clear"
390 bic r6, r6, #(1 << 10) @ clear it in "mmuset"
391#endif
315 mrc p15, 0, r0, c1, c0, 0 @ read control register 392 mrc p15, 0, r0, c1, c0, 0 @ read control register
316 bic r0, r0, r5 @ clear bits them 393 bic r0, r0, r5 @ clear bits them
317 orr r0, r0, r6 @ set them 394 orr r0, r0, r6 @ set them
@@ -332,6 +409,8 @@ v7_crval:
332__v7_setup_stack: 409__v7_setup_stack:
333 .space 4 * 11 @ 11 registers 410 .space 4 * 11 @ 11 registers
334 411
412 __INITDATA
413
335 .type v7_processor_functions, #object 414 .type v7_processor_functions, #object
336ENTRY(v7_processor_functions) 415ENTRY(v7_processor_functions)
337 .word v7_early_abort 416 .word v7_early_abort
@@ -343,8 +422,13 @@ ENTRY(v7_processor_functions)
343 .word cpu_v7_dcache_clean_area 422 .word cpu_v7_dcache_clean_area
344 .word cpu_v7_switch_mm 423 .word cpu_v7_switch_mm
345 .word cpu_v7_set_pte_ext 424 .word cpu_v7_set_pte_ext
425 .word cpu_v7_suspend_size
426 .word cpu_v7_do_suspend
427 .word cpu_v7_do_resume
346 .size v7_processor_functions, . - v7_processor_functions 428 .size v7_processor_functions, . - v7_processor_functions
347 429
430 .section ".rodata"
431
348 .type cpu_arch_name, #object 432 .type cpu_arch_name, #object
349cpu_arch_name: 433cpu_arch_name:
350 .asciz "armv7" 434 .asciz "armv7"
@@ -362,15 +446,21 @@ cpu_elf_name:
362__v7_ca9mp_proc_info: 446__v7_ca9mp_proc_info:
363 .long 0x410fc090 @ Required ID value 447 .long 0x410fc090 @ Required ID value
364 .long 0xff0ffff0 @ Mask for ID 448 .long 0xff0ffff0 @ Mask for ID
365 .long PMD_TYPE_SECT | \ 449 ALT_SMP(.long \
450 PMD_TYPE_SECT | \
366 PMD_SECT_AP_WRITE | \ 451 PMD_SECT_AP_WRITE | \
367 PMD_SECT_AP_READ | \ 452 PMD_SECT_AP_READ | \
368 PMD_FLAGS 453 PMD_FLAGS_SMP)
454 ALT_UP(.long \
455 PMD_TYPE_SECT | \
456 PMD_SECT_AP_WRITE | \
457 PMD_SECT_AP_READ | \
458 PMD_FLAGS_UP)
369 .long PMD_TYPE_SECT | \ 459 .long PMD_TYPE_SECT | \
370 PMD_SECT_XN | \ 460 PMD_SECT_XN | \
371 PMD_SECT_AP_WRITE | \ 461 PMD_SECT_AP_WRITE | \
372 PMD_SECT_AP_READ 462 PMD_SECT_AP_READ
373 b __v7_ca9mp_setup 463 W(b) __v7_ca9mp_setup
374 .long cpu_arch_name 464 .long cpu_arch_name
375 .long cpu_elf_name 465 .long cpu_elf_name
376 .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS 466 .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
@@ -388,15 +478,21 @@ __v7_ca9mp_proc_info:
388__v7_proc_info: 478__v7_proc_info:
389 .long 0x000f0000 @ Required ID value 479 .long 0x000f0000 @ Required ID value
390 .long 0x000f0000 @ Mask for ID 480 .long 0x000f0000 @ Mask for ID
391 .long PMD_TYPE_SECT | \ 481 ALT_SMP(.long \
482 PMD_TYPE_SECT | \
483 PMD_SECT_AP_WRITE | \
484 PMD_SECT_AP_READ | \
485 PMD_FLAGS_SMP)
486 ALT_UP(.long \
487 PMD_TYPE_SECT | \
392 PMD_SECT_AP_WRITE | \ 488 PMD_SECT_AP_WRITE | \
393 PMD_SECT_AP_READ | \ 489 PMD_SECT_AP_READ | \
394 PMD_FLAGS 490 PMD_FLAGS_UP)
395 .long PMD_TYPE_SECT | \ 491 .long PMD_TYPE_SECT | \
396 PMD_SECT_XN | \ 492 PMD_SECT_XN | \
397 PMD_SECT_AP_WRITE | \ 493 PMD_SECT_AP_WRITE | \
398 PMD_SECT_AP_READ 494 PMD_SECT_AP_READ
399 b __v7_setup 495 W(b) __v7_setup
400 .long cpu_arch_name 496 .long cpu_arch_name
401 .long cpu_elf_name 497 .long cpu_elf_name
402 .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS 498 .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS