0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <linux/linkage.h>
0025 #include <linux/init.h>
0026 #include <linux/pgtable.h>
0027 #include <asm/assembler.h>
0028 #include <asm/hwcap.h>
0029 #include <asm/pgtable-hwdef.h>
0030 #include <asm/page.h>
0031 #include <asm/ptrace.h>
0032 #include "proc-macros.S"
0033
0034
0035
0036
0037
0038 #define MAX_AREA_SIZE 32768
0039
0040
0041
0042
0043 #define CACHELINESIZE 32
0044
0045
0046
0047
0048 #define CACHESIZE 32768
0049
0050
0051
0052
0053
0054
0055 .macro cpwait_ret, lr, rd
0056 mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15
0057 sub pc, \lr, \rd, LSR #32 @ wait for completion and
0058 @ flush instruction pipeline
0059 .endm
0060
0061
0062
0063
0064
0065 .macro clean_d_cache rd, rs
0066 mov \rd, #0x1f00
0067 orr \rd, \rd, #0x00e0
0068 1: mcr p15, 0, \rd, c7, c14, 2 @ clean/invalidate L1 D line
0069 adds \rd, \rd, #0x40000000
0070 bcc 1b
0071 subs \rd, \rd, #0x20
0072 bpl 1b
0073 .endm
0074
0075 .text
0076
0077
0078
0079
0080
0081
0082 ENTRY(cpu_xsc3_proc_init)
0083 ret lr
0084
0085
0086
0087
0088 ENTRY(cpu_xsc3_proc_fin)
0089 mrc p15, 0, r0, c1, c0, 0 @ ctrl register
0090 bic r0, r0, #0x1800 @ ...IZ...........
0091 bic r0, r0, #0x0006 @ .............CA.
0092 mcr p15, 0, r0, c1, c0, 0 @ disable caches
0093 ret lr
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 .align 5
0105 .pushsection .idmap.text, "ax"
0106 ENTRY(cpu_xsc3_reset)
0107 mov r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
0108 msr cpsr_c, r1 @ reset CPSR
0109 mrc p15, 0, r1, c1, c0, 0 @ ctrl register
0110 bic r1, r1, #0x3900 @ ..VIZ..S........
0111 bic r1, r1, #0x0086 @ ........B....CA.
0112 mcr p15, 0, r1, c1, c0, 0 @ ctrl register
0113 mcr p15, 0, ip, c7, c7, 0 @ invalidate L1 caches and BTB
0114 bic r1, r1, #0x0001 @ ...............M
0115 mcr p15, 0, r1, c1, c0, 0 @ ctrl register
0116 @ CAUTION: MMU turned off from this point. We count on the pipeline
0117 @ already containing those two last instructions to survive.
0118 mcr p15, 0, ip, c8, c7, 0 @ invalidate I and D TLBs
0119 ret r0
0120 ENDPROC(cpu_xsc3_reset)
0121 .popsection
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 .align 5
0134
0135 ENTRY(cpu_xsc3_do_idle)
0136 mov r0, #1
0137 mcr p14, 0, r0, c7, c0, 0 @ go to idle
0138 ret lr
0139
0140
0141
0142
0143
0144
0145
0146
0147 ENTRY(xsc3_flush_icache_all)
0148 mov r0, #0
0149 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
0150 ret lr
0151 ENDPROC(xsc3_flush_icache_all)
0152
0153
0154
0155
0156
0157
0158
0159 ENTRY(xsc3_flush_user_cache_all)
0160
0161
0162
0163
0164
0165
0166
0167 ENTRY(xsc3_flush_kern_cache_all)
0168 mov r2, #VM_EXEC
0169 mov ip, #0
0170 __flush_whole_cache:
0171 clean_d_cache r0, r1
0172 tst r2, #VM_EXEC
0173 mcrne p15, 0, ip, c7, c5, 0 @ invalidate L1 I cache and BTB
0174 mcrne p15, 0, ip, c7, c10, 4 @ data write barrier
0175 mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
0176 ret lr
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 .align 5
0189 ENTRY(xsc3_flush_user_cache_range)
0190 mov ip, #0
0191 sub r3, r1, r0 @ calculate total size
0192 cmp r3, #MAX_AREA_SIZE
0193 bhs __flush_whole_cache
0194
0195 1: tst r2, #VM_EXEC
0196 mcrne p15, 0, r0, c7, c5, 1 @ invalidate L1 I line
0197 mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line
0198 add r0, r0, #CACHELINESIZE
0199 cmp r0, r1
0200 blo 1b
0201 tst r2, #VM_EXEC
0202 mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB
0203 mcrne p15, 0, ip, c7, c10, 4 @ data write barrier
0204 mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
0205 ret lr
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220 ENTRY(xsc3_coherent_kern_range)
0221
0222 ENTRY(xsc3_coherent_user_range)
0223 bic r0, r0, #CACHELINESIZE - 1
0224 1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
0225 add r0, r0, #CACHELINESIZE
0226 cmp r0, r1
0227 blo 1b
0228 mov r0, #0
0229 mcr p15, 0, r0, c7, c5, 0 @ invalidate L1 I cache and BTB
0230 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
0231 mcr p15, 0, r0, c7, c5, 4 @ prefetch flush
0232 ret lr
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243 ENTRY(xsc3_flush_kern_dcache_area)
0244 add r1, r0, r1
0245 1: mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line
0246 add r0, r0, #CACHELINESIZE
0247 cmp r0, r1
0248 blo 1b
0249 mov r0, #0
0250 mcr p15, 0, r0, c7, c5, 0 @ invalidate L1 I cache and BTB
0251 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
0252 mcr p15, 0, r0, c7, c5, 4 @ prefetch flush
0253 ret lr
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266 xsc3_dma_inv_range:
0267 tst r0, #CACHELINESIZE - 1
0268 bic r0, r0, #CACHELINESIZE - 1
0269 mcrne p15, 0, r0, c7, c10, 1 @ clean L1 D line
0270 tst r1, #CACHELINESIZE - 1
0271 mcrne p15, 0, r1, c7, c10, 1 @ clean L1 D line
0272 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate L1 D line
0273 add r0, r0, #CACHELINESIZE
0274 cmp r0, r1
0275 blo 1b
0276 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
0277 ret lr
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287 xsc3_dma_clean_range:
0288 bic r0, r0, #CACHELINESIZE - 1
0289 1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
0290 add r0, r0, #CACHELINESIZE
0291 cmp r0, r1
0292 blo 1b
0293 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
0294 ret lr
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304 ENTRY(xsc3_dma_flush_range)
0305 bic r0, r0, #CACHELINESIZE - 1
0306 1: mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line
0307 add r0, r0, #CACHELINESIZE
0308 cmp r0, r1
0309 blo 1b
0310 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
0311 ret lr
0312
0313
0314
0315
0316
0317
0318
0319 ENTRY(xsc3_dma_map_area)
0320 add r1, r1, r0
0321 cmp r2, #DMA_TO_DEVICE
0322 beq xsc3_dma_clean_range
0323 bcs xsc3_dma_inv_range
0324 b xsc3_dma_flush_range
0325 ENDPROC(xsc3_dma_map_area)
0326
0327
0328
0329
0330
0331
0332
0333 ENTRY(xsc3_dma_unmap_area)
0334 ret lr
0335 ENDPROC(xsc3_dma_unmap_area)
0336
0337 .globl xsc3_flush_kern_cache_louis
0338 .equ xsc3_flush_kern_cache_louis, xsc3_flush_kern_cache_all
0339
0340 @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
0341 define_cache_functions xsc3
0342
0343 ENTRY(cpu_xsc3_dcache_clean_area)
0344 1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
0345 add r0, r0, #CACHELINESIZE
0346 subs r1, r1, #CACHELINESIZE
0347 bhi 1b
0348 ret lr
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359 .align 5
0360 ENTRY(cpu_xsc3_switch_mm)
0361 clean_d_cache r1, r2
0362 mcr p15, 0, ip, c7, c5, 0 @ invalidate L1 I cache and BTB
0363 mcr p15, 0, ip, c7, c10, 4 @ data write barrier
0364 mcr p15, 0, ip, c7, c5, 4 @ prefetch flush
0365 orr r0, r0, #0x18 @ cache the page table in L2
0366 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
0367 mcr p15, 0, ip, c8, c7, 0 @ invalidate I and D TLBs
0368 cpwait_ret lr, ip
0369
0370
0371
0372
0373
0374
0375 cpu_xsc3_mt_table:
0376 .long 0x00 @ L_PTE_MT_UNCACHED
0377 .long PTE_EXT_TEX(1) @ L_PTE_MT_BUFFERABLE
0378 .long PTE_EXT_TEX(5) | PTE_CACHEABLE @ L_PTE_MT_WRITETHROUGH
0379 .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEBACK
0380 .long PTE_EXT_TEX(1) | PTE_BUFFERABLE @ L_PTE_MT_DEV_SHARED
0381 .long 0x00 @ unused
0382 .long 0x00 @ L_PTE_MT_MINICACHE (not present)
0383 .long PTE_EXT_TEX(5) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEALLOC (not present?)
0384 .long 0x00 @ unused
0385 .long PTE_EXT_TEX(1) @ L_PTE_MT_DEV_WC
0386 .long 0x00 @ unused
0387 .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_DEV_CACHED
0388 .long PTE_EXT_TEX(2) @ L_PTE_MT_DEV_NONSHARED
0389 .long 0x00 @ unused
0390 .long 0x00 @ unused
0391 .long 0x00 @ unused
0392
0393 .align 5
0394 ENTRY(cpu_xsc3_set_pte_ext)
0395 xscale_set_pte_ext_prologue
0396
0397 tst r1, #L_PTE_SHARED @ shared?
0398 and r1, r1, #L_PTE_MT_MASK
0399 adr ip, cpu_xsc3_mt_table
0400 ldr ip, [ip, r1]
0401 orrne r2, r2, #PTE_EXT_COHERENT @ interlock: mask in coherent bit
0402 bic r2, r2, #0x0c @ clear old C,B bits
0403 orr r2, r2, ip
0404
0405 xscale_set_pte_ext_epilogue
0406 ret lr
0407
0408 .ltorg
0409 .align
0410
0411 .globl cpu_xsc3_suspend_size
0412 .equ cpu_xsc3_suspend_size, 4 * 6
0413 #ifdef CONFIG_ARM_CPU_SUSPEND
0414 ENTRY(cpu_xsc3_do_suspend)
0415 stmfd sp!, {r4 - r9, lr}
0416 mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
0417 mrc p15, 0, r5, c15, c1, 0 @ CP access reg
0418 mrc p15, 0, r6, c13, c0, 0 @ PID
0419 mrc p15, 0, r7, c3, c0, 0 @ domain ID
0420 mrc p15, 0, r8, c1, c0, 1 @ auxiliary control reg
0421 mrc p15, 0, r9, c1, c0, 0 @ control reg
0422 bic r4, r4, #2 @ clear frequency change bit
0423 stmia r0, {r4 - r9} @ store cp regs
0424 ldmia sp!, {r4 - r9, pc}
0425 ENDPROC(cpu_xsc3_do_suspend)
0426
0427 ENTRY(cpu_xsc3_do_resume)
0428 ldmia r0, {r4 - r9} @ load cp regs
0429 mov ip, #0
0430 mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
0431 mcr p15, 0, ip, c7, c10, 4 @ drain write (&fill) buffer
0432 mcr p15, 0, ip, c7, c5, 4 @ flush prefetch buffer
0433 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
0434 mcr p14, 0, r4, c6, c0, 0 @ clock configuration, turbo mode.
0435 mcr p15, 0, r5, c15, c1, 0 @ CP access reg
0436 mcr p15, 0, r6, c13, c0, 0 @ PID
0437 mcr p15, 0, r7, c3, c0, 0 @ domain ID
0438 orr r1, r1, #0x18 @ cache the page table in L2
0439 mcr p15, 0, r1, c2, c0, 0 @ translation table base addr
0440 mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg
0441 mov r0, r9 @ control register
0442 b cpu_resume_mmu
0443 ENDPROC(cpu_xsc3_do_resume)
0444 #endif
0445
0446 .type __xsc3_setup, #function
0447 __xsc3_setup:
0448 mov r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
0449 msr cpsr_c, r0
0450 mcr p15, 0, ip, c7, c7, 0 @ invalidate L1 caches and BTB
0451 mcr p15, 0, ip, c7, c10, 4 @ data write barrier
0452 mcr p15, 0, ip, c7, c5, 4 @ prefetch flush
0453 mcr p15, 0, ip, c8, c7, 0 @ invalidate I and D TLBs
0454 orr r4, r4, #0x18 @ cache the page table in L2
0455 mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
0456
0457 mov r0, #1 << 6 @ cp6 access for early sched_clock
0458 mcr p15, 0, r0, c15, c1, 0 @ write CP access register
0459
0460 mrc p15, 0, r0, c1, c0, 1 @ get auxiliary control reg
0461 and r0, r0, #2 @ preserve bit P bit setting
0462 orr r0, r0, #(1 << 10) @ enable L2 for LLR cache
0463 mcr p15, 0, r0, c1, c0, 1 @ set auxiliary control reg
0464
0465 adr r5, xsc3_crval
0466 ldmia r5, {r5, r6}
0467
0468 #ifdef CONFIG_CACHE_XSC3L2
0469 mrc p15, 1, r0, c0, c0, 1 @ get L2 present information
0470 ands r0, r0, #0xf8
0471 orrne r6, r6, #(1 << 26) @ enable L2 if present
0472 #endif
0473
0474 mrc p15, 0, r0, c1, c0, 0 @ get control register
0475 bic r0, r0, r5 @ ..V. ..R. .... ..A.
0476 orr r0, r0, r6 @ ..VI Z..S .... .C.M (mmu)
0477 @ ...I Z..S .... .... (uc)
0478 ret lr
0479
0480 .size __xsc3_setup, . - __xsc3_setup
0481
0482 .type xsc3_crval, #object
0483 xsc3_crval:
0484 crval clear=0x04002202, mmuset=0x00003905, ucset=0x00001900
0485
0486 __INITDATA
0487
0488 @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
0489 define_processor_functions xsc3, dabort=v5t_early_abort, pabort=legacy_pabort, suspend=1
0490
0491 .section ".rodata"
0492
0493 string cpu_arch_name, "armv5te"
0494 string cpu_elf_name, "v5"
0495 string cpu_xsc3_name, "XScale-V3 based processor"
0496
0497 .align
0498
0499 .section ".proc.info.init", "a"
0500
0501 .macro xsc3_proc_info name:req, cpu_val:req, cpu_mask:req
0502 .type __\name\()_proc_info,#object
0503 __\name\()_proc_info:
0504 .long \cpu_val
0505 .long \cpu_mask
0506 .long PMD_TYPE_SECT | \
0507 PMD_SECT_BUFFERABLE | \
0508 PMD_SECT_CACHEABLE | \
0509 PMD_SECT_AP_WRITE | \
0510 PMD_SECT_AP_READ
0511 .long PMD_TYPE_SECT | \
0512 PMD_SECT_AP_WRITE | \
0513 PMD_SECT_AP_READ
0514 initfn __xsc3_setup, __\name\()_proc_info
0515 .long cpu_arch_name
0516 .long cpu_elf_name
0517 .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
0518 .long cpu_xsc3_name
0519 .long xsc3_processor_functions
0520 .long v4wbi_tlb_fns
0521 .long xsc3_mc_user_fns
0522 .long xsc3_cache_fns
0523 .size __\name\()_proc_info, . - __\name\()_proc_info
0524 .endm
0525
0526 xsc3_proc_info xsc3, 0x69056000, 0xffffe000
0527
0528
0529 xsc3_proc_info xsc3_pxa935, 0x56056000, 0xffffe000