0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/linkage.h>
0015 #include <linux/init.h>
0016 #include <linux/pgtable.h>
0017 #include <asm/assembler.h>
0018 #include <asm/hwcap.h>
0019 #include <asm/pgtable-hwdef.h>
0020 #include <asm/page.h>
0021 #include <asm/ptrace.h>
0022 #include "proc-macros.S"
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #define CACHE_DLIMIT 16384
0033
0034
0035
0036
0037 #define CACHE_DLINESIZE 32
0038
0039 .text
0040
0041
0042
0043 ENTRY(cpu_arm926_proc_init)
0044 ret lr
0045
0046
0047
0048
0049 ENTRY(cpu_arm926_proc_fin)
0050 mrc p15, 0, r0, c1, c0, 0 @ ctrl register
0051 bic r0, r0, #0x1000 @ ...i............
0052 bic r0, r0, #0x000e @ ............wca.
0053 mcr p15, 0, r0, c1, c0, 0 @ disable caches
0054 ret lr
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 .align 5
0066 .pushsection .idmap.text, "ax"
0067 ENTRY(cpu_arm926_reset)
0068 mov ip, #0
0069 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
0070 mcr p15, 0, ip, c7, c10, 4 @ drain WB
0071 #ifdef CONFIG_MMU
0072 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
0073 #endif
0074 mrc p15, 0, ip, c1, c0, 0 @ ctrl register
0075 bic ip, ip, #0x000f @ ............wcam
0076 bic ip, ip, #0x1100 @ ...i...s........
0077 mcr p15, 0, ip, c1, c0, 0 @ ctrl register
0078 ret r0
0079 ENDPROC(cpu_arm926_reset)
0080 .popsection
0081
0082
0083
0084
0085
0086
0087 .align 10
0088 ENTRY(cpu_arm926_do_idle)
0089 mov r0, #0
0090 mrc p15, 0, r1, c1, c0, 0 @ Read control register
0091 mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer
0092 bic r2, r1, #1 << 12
0093 mrs r3, cpsr @ Disable FIQs while Icache
0094 orr ip, r3, #PSR_F_BIT @ is disabled
0095 msr cpsr_c, ip
0096 mcr p15, 0, r2, c1, c0, 0 @ Disable I cache
0097 mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
0098 mcr p15, 0, r1, c1, c0, 0 @ Restore ICache enable
0099 msr cpsr_c, r3 @ Restore FIQ state
0100 ret lr
0101
0102
0103
0104
0105
0106
0107 ENTRY(arm926_flush_icache_all)
0108 mov r0, #0
0109 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
0110 ret lr
0111 ENDPROC(arm926_flush_icache_all)
0112
0113
0114
0115
0116
0117
0118
0119 ENTRY(arm926_flush_user_cache_all)
0120
0121
0122
0123
0124
0125
0126
0127 ENTRY(arm926_flush_kern_cache_all)
0128 mov r2, #VM_EXEC
0129 mov ip, #0
0130 __flush_whole_cache:
0131 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
0132 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
0133 #else
0134 1: mrc p15, 0, APSR_nzcv, c7, c14, 3 @ test,clean,invalidate
0135 bne 1b
0136 #endif
0137 tst r2, #VM_EXEC
0138 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
0139 mcrne p15, 0, ip, c7, c10, 4 @ drain WB
0140 ret lr
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152 ENTRY(arm926_flush_user_cache_range)
0153 mov ip, #0
0154 sub r3, r1, r0 @ calculate total size
0155 cmp r3, #CACHE_DLIMIT
0156 bgt __flush_whole_cache
0157 1: tst r2, #VM_EXEC
0158 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
0159 mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
0160 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
0161 add r0, r0, #CACHE_DLINESIZE
0162 mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
0163 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
0164 add r0, r0, #CACHE_DLINESIZE
0165 #else
0166 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
0167 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
0168 add r0, r0, #CACHE_DLINESIZE
0169 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
0170 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
0171 add r0, r0, #CACHE_DLINESIZE
0172 #endif
0173 cmp r0, r1
0174 blo 1b
0175 tst r2, #VM_EXEC
0176 mcrne p15, 0, ip, c7, c10, 4 @ drain WB
0177 ret lr
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189 ENTRY(arm926_coherent_kern_range)
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202 ENTRY(arm926_coherent_user_range)
0203 bic r0, r0, #CACHE_DLINESIZE - 1
0204 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
0205 mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
0206 add r0, r0, #CACHE_DLINESIZE
0207 cmp r0, r1
0208 blo 1b
0209 mcr p15, 0, r0, c7, c10, 4 @ drain WB
0210 mov r0, #0
0211 ret lr
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222 ENTRY(arm926_flush_kern_dcache_area)
0223 add r1, r0, r1
0224 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
0225 add r0, r0, #CACHE_DLINESIZE
0226 cmp r0, r1
0227 blo 1b
0228 mov r0, #0
0229 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
0230 mcr p15, 0, r0, c7, c10, 4 @ drain WB
0231 ret lr
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246 arm926_dma_inv_range:
0247 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
0248 tst r0, #CACHE_DLINESIZE - 1
0249 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
0250 tst r1, #CACHE_DLINESIZE - 1
0251 mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
0252 #endif
0253 bic r0, r0, #CACHE_DLINESIZE - 1
0254 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
0255 add r0, r0, #CACHE_DLINESIZE
0256 cmp r0, r1
0257 blo 1b
0258 mcr p15, 0, r0, c7, c10, 4 @ drain WB
0259 ret lr
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271 arm926_dma_clean_range:
0272 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
0273 bic r0, r0, #CACHE_DLINESIZE - 1
0274 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
0275 add r0, r0, #CACHE_DLINESIZE
0276 cmp r0, r1
0277 blo 1b
0278 #endif
0279 mcr p15, 0, r0, c7, c10, 4 @ drain WB
0280 ret lr
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290 ENTRY(arm926_dma_flush_range)
0291 bic r0, r0, #CACHE_DLINESIZE - 1
0292 1:
0293 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
0294 mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
0295 #else
0296 mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
0297 #endif
0298 add r0, r0, #CACHE_DLINESIZE
0299 cmp r0, r1
0300 blo 1b
0301 mcr p15, 0, r0, c7, c10, 4 @ drain WB
0302 ret lr
0303
0304
0305
0306
0307
0308
0309
0310 ENTRY(arm926_dma_map_area)
0311 add r1, r1, r0
0312 cmp r2, #DMA_TO_DEVICE
0313 beq arm926_dma_clean_range
0314 bcs arm926_dma_inv_range
0315 b arm926_dma_flush_range
0316 ENDPROC(arm926_dma_map_area)
0317
0318
0319
0320
0321
0322
0323
0324 ENTRY(arm926_dma_unmap_area)
0325 ret lr
0326 ENDPROC(arm926_dma_unmap_area)
0327
0328 .globl arm926_flush_kern_cache_louis
0329 .equ arm926_flush_kern_cache_louis, arm926_flush_kern_cache_all
0330
0331 @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
0332 define_cache_functions arm926
0333
0334 ENTRY(cpu_arm926_dcache_clean_area)
0335 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
0336 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
0337 add r0, r0, #CACHE_DLINESIZE
0338 subs r1, r1, #CACHE_DLINESIZE
0339 bhi 1b
0340 #endif
0341 mcr p15, 0, r0, c7, c10, 4 @ drain WB
0342 ret lr
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353 .align 5
0354 ENTRY(cpu_arm926_switch_mm)
0355 #ifdef CONFIG_MMU
0356 mov ip, #0
0357 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
0358 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
0359 #else
0360 @ && 'Clean & Invalidate whole DCache'
0361 1: mrc p15, 0, APSR_nzcv, c7, c14, 3 @ test,clean,invalidate
0362 bne 1b
0363 #endif
0364 mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
0365 mcr p15, 0, ip, c7, c10, 4 @ drain WB
0366 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
0367 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
0368 #endif
0369 ret lr
0370
0371
0372
0373
0374
0375
0376 .align 5
0377 ENTRY(cpu_arm926_set_pte_ext)
0378 #ifdef CONFIG_MMU
0379 armv3_set_pte_ext
0380 mov r0, r0
0381 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
0382 mcr p15, 0, r0, c7, c10, 1 @ clean D entry
0383 #endif
0384 mcr p15, 0, r0, c7, c10, 4 @ drain WB
0385 #endif
0386 ret lr
0387
0388
0389 .globl cpu_arm926_suspend_size
0390 .equ cpu_arm926_suspend_size, 4 * 3
0391 #ifdef CONFIG_ARM_CPU_SUSPEND
0392 ENTRY(cpu_arm926_do_suspend)
0393 stmfd sp!, {r4 - r6, lr}
0394 mrc p15, 0, r4, c13, c0, 0 @ PID
0395 mrc p15, 0, r5, c3, c0, 0 @ Domain ID
0396 mrc p15, 0, r6, c1, c0, 0 @ Control register
0397 stmia r0, {r4 - r6}
0398 ldmfd sp!, {r4 - r6, pc}
0399 ENDPROC(cpu_arm926_do_suspend)
0400
0401 ENTRY(cpu_arm926_do_resume)
0402 mov ip, #0
0403 mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
0404 mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
0405 ldmia r0, {r4 - r6}
0406 mcr p15, 0, r4, c13, c0, 0 @ PID
0407 mcr p15, 0, r5, c3, c0, 0 @ Domain ID
0408 mcr p15, 0, r1, c2, c0, 0 @ TTB address
0409 mov r0, r6 @ control register
0410 b cpu_resume_mmu
0411 ENDPROC(cpu_arm926_do_resume)
0412 #endif
0413
0414 .type __arm926_setup, #function
0415 __arm926_setup:
0416 mov r0, #0
0417 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
0418 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
0419 #ifdef CONFIG_MMU
0420 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
0421 #endif
0422
0423
0424 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
0425 mov r0, #4 @ disable write-back on caches explicitly
0426 mcr p15, 7, r0, c15, c0, 0
0427 #endif
0428
0429 adr r5, arm926_crval
0430 ldmia r5, {r5, r6}
0431 mrc p15, 0, r0, c1, c0 @ get control register v4
0432 bic r0, r0, r5
0433 orr r0, r0, r6
0434 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
0435 orr r0, r0, #0x4000 @ .1.. .... .... ....
0436 #endif
0437 ret lr
0438 .size __arm926_setup, . - __arm926_setup
0439
0440
0441
0442
0443
0444
0445
0446 .type arm926_crval, #object
0447 arm926_crval:
0448 crval clear=0x00007f3f, mmuset=0x00003135, ucset=0x00001134
0449
0450 __INITDATA
0451
0452 @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
0453 define_processor_functions arm926, dabort=v5tj_early_abort, pabort=legacy_pabort, suspend=1
0454
0455 .section ".rodata"
0456
0457 string cpu_arch_name, "armv5tej"
0458 string cpu_elf_name, "v5"
0459 string cpu_arm926_name, "ARM926EJ-S"
0460
0461 .align
0462
0463 .section ".proc.info.init", "a"
0464
0465 .type __arm926_proc_info,#object
0466 __arm926_proc_info:
0467 .long 0x41069260 @ ARM926EJ-S (v5TEJ)
0468 .long 0xff0ffff0
0469 .long PMD_TYPE_SECT | \
0470 PMD_SECT_BUFFERABLE | \
0471 PMD_SECT_CACHEABLE | \
0472 PMD_BIT4 | \
0473 PMD_SECT_AP_WRITE | \
0474 PMD_SECT_AP_READ
0475 .long PMD_TYPE_SECT | \
0476 PMD_BIT4 | \
0477 PMD_SECT_AP_WRITE | \
0478 PMD_SECT_AP_READ
0479 initfn __arm926_setup, __arm926_proc_info
0480 .long cpu_arch_name
0481 .long cpu_elf_name
0482 .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
0483 .long cpu_arm926_name
0484 .long arm926_processor_functions
0485 .long v4wbi_tlb_fns
0486 .long v4wb_user_fns
0487 .long arm926_cache_fns
0488 .size __arm926_proc_info, . - __arm926_proc_info