0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/linkage.h>
0013 #include <linux/init.h>
0014 #include <linux/pgtable.h>
0015 #include <asm/assembler.h>
0016 #include <asm/asm-offsets.h>
0017 #include <asm/hwcap.h>
0018 #include <asm/pgtable-hwdef.h>
0019 #include <asm/ptrace.h>
0020
0021 #include "proc-macros.S"
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #define MAX_AREA_SIZE 32768
0032
0033
0034
0035
0036 #define CACHE_DLINESIZE 32
0037
0038
0039
0040
0041 #define CACHE_DSEGMENTS 16
0042
0043
0044
0045
0046 #define CACHE_DENTRIES 64
0047
0048
0049
0050
0051
0052
0053 #define CACHE_DLIMIT 32768
0054
0055 .text
0056
0057
0058
0059 ENTRY(cpu_arm1022_proc_init)
0060 ret lr
0061
0062
0063
0064
0065 ENTRY(cpu_arm1022_proc_fin)
0066 mrc p15, 0, r0, c1, c0, 0 @ ctrl register
0067 bic r0, r0, #0x1000 @ ...i............
0068 bic r0, r0, #0x000e @ ............wca.
0069 mcr p15, 0, r0, c1, c0, 0 @ disable caches
0070 ret lr
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 .align 5
0082 .pushsection .idmap.text, "ax"
0083 ENTRY(cpu_arm1022_reset)
0084 mov ip, #0
0085 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
0086 mcr p15, 0, ip, c7, c10, 4 @ drain WB
0087 #ifdef CONFIG_MMU
0088 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
0089 #endif
0090 mrc p15, 0, ip, c1, c0, 0 @ ctrl register
0091 bic ip, ip, #0x000f @ ............wcam
0092 bic ip, ip, #0x1100 @ ...i...s........
0093 mcr p15, 0, ip, c1, c0, 0 @ ctrl register
0094 ret r0
0095 ENDPROC(cpu_arm1022_reset)
0096 .popsection
0097
0098
0099
0100
0101 .align 5
0102 ENTRY(cpu_arm1022_do_idle)
0103 mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
0104 ret lr
0105
0106
0107
0108 .align 5
0109
0110
0111
0112
0113
0114
0115 ENTRY(arm1022_flush_icache_all)
0116 #ifndef CONFIG_CPU_ICACHE_DISABLE
0117 mov r0, #0
0118 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
0119 #endif
0120 ret lr
0121 ENDPROC(arm1022_flush_icache_all)
0122
0123
0124
0125
0126
0127
0128
0129 ENTRY(arm1022_flush_user_cache_all)
0130
0131
0132
0133
0134
0135
0136 ENTRY(arm1022_flush_kern_cache_all)
0137 mov r2, #VM_EXEC
0138 mov ip, #0
0139 __flush_whole_cache:
0140 #ifndef CONFIG_CPU_DCACHE_DISABLE
0141 mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments
0142 1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
0143 2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index
0144 subs r3, r3, #1 << 26
0145 bcs 2b @ entries 63 to 0
0146 subs r1, r1, #1 << 5
0147 bcs 1b @ segments 15 to 0
0148 #endif
0149 tst r2, #VM_EXEC
0150 #ifndef CONFIG_CPU_ICACHE_DISABLE
0151 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
0152 #endif
0153 mcrne p15, 0, ip, c7, c10, 4 @ drain WB
0154 ret lr
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166 ENTRY(arm1022_flush_user_cache_range)
0167 mov ip, #0
0168 sub r3, r1, r0 @ calculate total size
0169 cmp r3, #CACHE_DLIMIT
0170 bhs __flush_whole_cache
0171
0172 #ifndef CONFIG_CPU_DCACHE_DISABLE
0173 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
0174 add r0, r0, #CACHE_DLINESIZE
0175 cmp r0, r1
0176 blo 1b
0177 #endif
0178 tst r2, #VM_EXEC
0179 #ifndef CONFIG_CPU_ICACHE_DISABLE
0180 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
0181 #endif
0182 mcrne p15, 0, ip, c7, c10, 4 @ drain WB
0183 ret lr
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195 ENTRY(arm1022_coherent_kern_range)
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208 ENTRY(arm1022_coherent_user_range)
0209 mov ip, #0
0210 bic r0, r0, #CACHE_DLINESIZE - 1
0211 1:
0212 #ifndef CONFIG_CPU_DCACHE_DISABLE
0213 mcr p15, 0, r0, c7, c10, 1 @ clean D entry
0214 #endif
0215 #ifndef CONFIG_CPU_ICACHE_DISABLE
0216 mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
0217 #endif
0218 add r0, r0, #CACHE_DLINESIZE
0219 cmp r0, r1
0220 blo 1b
0221 mcr p15, 0, ip, c7, c10, 4 @ drain WB
0222 mov r0, #0
0223 ret lr
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234 ENTRY(arm1022_flush_kern_dcache_area)
0235 mov ip, #0
0236 #ifndef CONFIG_CPU_DCACHE_DISABLE
0237 add r1, r0, r1
0238 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
0239 add r0, r0, #CACHE_DLINESIZE
0240 cmp r0, r1
0241 blo 1b
0242 #endif
0243 mcr p15, 0, ip, c7, c10, 4 @ drain WB
0244 ret lr
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259 arm1022_dma_inv_range:
0260 mov ip, #0
0261 #ifndef CONFIG_CPU_DCACHE_DISABLE
0262 tst r0, #CACHE_DLINESIZE - 1
0263 bic r0, r0, #CACHE_DLINESIZE - 1
0264 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
0265 tst r1, #CACHE_DLINESIZE - 1
0266 mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
0267 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
0268 add r0, r0, #CACHE_DLINESIZE
0269 cmp r0, r1
0270 blo 1b
0271 #endif
0272 mcr p15, 0, ip, c7, c10, 4 @ drain WB
0273 ret lr
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285 arm1022_dma_clean_range:
0286 mov ip, #0
0287 #ifndef CONFIG_CPU_DCACHE_DISABLE
0288 bic r0, r0, #CACHE_DLINESIZE - 1
0289 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
0290 add r0, r0, #CACHE_DLINESIZE
0291 cmp r0, r1
0292 blo 1b
0293 #endif
0294 mcr p15, 0, ip, c7, c10, 4 @ drain WB
0295 ret lr
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 ENTRY(arm1022_dma_flush_range)
0306 mov ip, #0
0307 #ifndef CONFIG_CPU_DCACHE_DISABLE
0308 bic r0, r0, #CACHE_DLINESIZE - 1
0309 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
0310 add r0, r0, #CACHE_DLINESIZE
0311 cmp r0, r1
0312 blo 1b
0313 #endif
0314 mcr p15, 0, ip, c7, c10, 4 @ drain WB
0315 ret lr
0316
0317
0318
0319
0320
0321
0322
0323 ENTRY(arm1022_dma_map_area)
0324 add r1, r1, r0
0325 cmp r2, #DMA_TO_DEVICE
0326 beq arm1022_dma_clean_range
0327 bcs arm1022_dma_inv_range
0328 b arm1022_dma_flush_range
0329 ENDPROC(arm1022_dma_map_area)
0330
0331
0332
0333
0334
0335
0336
0337 ENTRY(arm1022_dma_unmap_area)
0338 ret lr
0339 ENDPROC(arm1022_dma_unmap_area)
0340
0341 .globl arm1022_flush_kern_cache_louis
0342 .equ arm1022_flush_kern_cache_louis, arm1022_flush_kern_cache_all
0343
0344 @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
0345 define_cache_functions arm1022
0346
0347 .align 5
0348 ENTRY(cpu_arm1022_dcache_clean_area)
0349 #ifndef CONFIG_CPU_DCACHE_DISABLE
0350 mov ip, #0
0351 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
0352 add r0, r0, #CACHE_DLINESIZE
0353 subs r1, r1, #CACHE_DLINESIZE
0354 bhi 1b
0355 #endif
0356 ret lr
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367 .align 5
0368 ENTRY(cpu_arm1022_switch_mm)
0369 #ifdef CONFIG_MMU
0370 #ifndef CONFIG_CPU_DCACHE_DISABLE
0371 mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments
0372 1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
0373 2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index
0374 subs r3, r3, #1 << 26
0375 bcs 2b @ entries 63 to 0
0376 subs r1, r1, #1 << 5
0377 bcs 1b @ segments 15 to 0
0378 #endif
0379 mov r1, #0
0380 #ifndef CONFIG_CPU_ICACHE_DISABLE
0381 mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
0382 #endif
0383 mcr p15, 0, r1, c7, c10, 4 @ drain WB
0384 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
0385 mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
0386 #endif
0387 ret lr
0388
0389
0390
0391
0392
0393
0394 .align 5
0395 ENTRY(cpu_arm1022_set_pte_ext)
0396 #ifdef CONFIG_MMU
0397 armv3_set_pte_ext
0398 mov r0, r0
0399 #ifndef CONFIG_CPU_DCACHE_DISABLE
0400 mcr p15, 0, r0, c7, c10, 1 @ clean D entry
0401 #endif
0402 #endif
0403 ret lr
0404
0405 .type __arm1022_setup, #function
0406 __arm1022_setup:
0407 mov r0, #0
0408 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
0409 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
0410 #ifdef CONFIG_MMU
0411 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
0412 #endif
0413 adr r5, arm1022_crval
0414 ldmia r5, {r5, r6}
0415 mrc p15, 0, r0, c1, c0 @ get control register v4
0416 bic r0, r0, r5
0417 orr r0, r0, r6
0418 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
0419 orr r0, r0, #0x4000 @ .R..............
0420 #endif
0421 ret lr
0422 .size __arm1022_setup, . - __arm1022_setup
0423
0424
0425
0426
0427
0428
0429
0430 .type arm1022_crval, #object
0431 arm1022_crval:
0432 crval clear=0x00007f3f, mmuset=0x00003935, ucset=0x00001930
0433
0434 __INITDATA
0435 @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
0436 define_processor_functions arm1022, dabort=v4t_early_abort, pabort=legacy_pabort
0437
0438 .section ".rodata"
0439
0440 string cpu_arch_name, "armv5te"
0441 string cpu_elf_name, "v5"
0442 string cpu_arm1022_name, "ARM1022"
0443
0444 .align
0445
0446 .section ".proc.info.init", "a"
0447
0448 .type __arm1022_proc_info,#object
0449 __arm1022_proc_info:
0450 .long 0x4105a220 @ ARM 1022E (v5TE)
0451 .long 0xff0ffff0
0452 .long PMD_TYPE_SECT | \
0453 PMD_BIT4 | \
0454 PMD_SECT_AP_WRITE | \
0455 PMD_SECT_AP_READ
0456 .long PMD_TYPE_SECT | \
0457 PMD_BIT4 | \
0458 PMD_SECT_AP_WRITE | \
0459 PMD_SECT_AP_READ
0460 initfn __arm1022_setup, __arm1022_proc_info
0461 .long cpu_arch_name
0462 .long cpu_elf_name
0463 .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_EDSP
0464 .long cpu_arm1022_name
0465 .long arm1022_processor_functions
0466 .long v4wbi_tlb_fns
0467 .long v4wb_user_fns
0468 .long arm1022_cache_fns
0469 .size __arm1022_proc_info, . - __arm1022_proc_info