0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/linkage.h>
0010 #include <linux/init.h>
0011 #include <linux/pgtable.h>
0012 #include <asm/assembler.h>
0013 #include <asm/hwcap.h>
0014 #include <asm/pgtable-hwdef.h>
0015 #include <asm/ptrace.h>
0016 #include "proc-macros.S"
0017
0018
0019
0020
0021
0022 #define CACHE_DSIZE (CONFIG_CPU_DCACHE_SIZE)
0023 #define CACHE_DLINESIZE 32
0024 #define CACHE_DSEGMENTS 4
0025 #define CACHE_DENTRIES (CACHE_DSIZE / CACHE_DSEGMENTS / CACHE_DLINESIZE)
0026 #define CACHE_DLIMIT (CACHE_DSIZE * 4)
0027
0028 .text
0029
0030
0031
0032
0033
0034
0035 ENTRY(cpu_arm946_proc_init)
0036 ENTRY(cpu_arm946_switch_mm)
0037 ret lr
0038
0039
0040
0041
0042 ENTRY(cpu_arm946_proc_fin)
0043 mrc p15, 0, r0, c1, c0, 0 @ ctrl register
0044 bic r0, r0, #0x00001000 @ i-cache
0045 bic r0, r0, #0x00000004 @ d-cache
0046 mcr p15, 0, r0, c1, c0, 0 @ disable caches
0047 ret lr
0048
0049
0050
0051
0052
0053
0054 .pushsection .idmap.text, "ax"
0055 ENTRY(cpu_arm946_reset)
0056 mov ip, #0
0057 mcr p15, 0, ip, c7, c5, 0 @ flush I cache
0058 mcr p15, 0, ip, c7, c6, 0 @ flush D cache
0059 mcr p15, 0, ip, c7, c10, 4 @ drain WB
0060 mrc p15, 0, ip, c1, c0, 0 @ ctrl register
0061 bic ip, ip, #0x00000005 @ .............c.p
0062 bic ip, ip, #0x00001000 @ i-cache
0063 mcr p15, 0, ip, c1, c0, 0 @ ctrl register
0064 ret r0
0065 ENDPROC(cpu_arm946_reset)
0066 .popsection
0067
0068
0069
0070
0071 .align 5
0072 ENTRY(cpu_arm946_do_idle)
0073 mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
0074 ret lr
0075
0076
0077
0078
0079
0080
0081 ENTRY(arm946_flush_icache_all)
0082 mov r0, #0
0083 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
0084 ret lr
0085 ENDPROC(arm946_flush_icache_all)
0086
0087
0088
0089
0090 ENTRY(arm946_flush_user_cache_all)
0091
0092
0093
0094
0095
0096
0097
0098 ENTRY(arm946_flush_kern_cache_all)
0099 mov r2, #VM_EXEC
0100 mov ip, #0
0101 __flush_whole_cache:
0102 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
0103 mcr p15, 0, ip, c7, c6, 0 @ flush D cache
0104 #else
0105 mov r1, #(CACHE_DSEGMENTS - 1) << 29 @ 4 segments
0106 1: orr r3, r1, #(CACHE_DENTRIES - 1) << 4 @ n entries
0107 2: mcr p15, 0, r3, c7, c14, 2 @ clean/flush D index
0108 subs r3, r3, #1 << 4
0109 bcs 2b @ entries n to 0
0110 subs r1, r1, #1 << 29
0111 bcs 1b @ segments 3 to 0
0112 #endif
0113 tst r2, #VM_EXEC
0114 mcrne p15, 0, ip, c7, c5, 0 @ flush I cache
0115 mcrne p15, 0, ip, c7, c10, 4 @ drain WB
0116 ret lr
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129 ENTRY(arm946_flush_user_cache_range)
0130 mov ip, #0
0131 sub r3, r1, r0 @ calculate total size
0132 cmp r3, #CACHE_DLIMIT
0133 bhs __flush_whole_cache
0134
0135 1: tst r2, #VM_EXEC
0136 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
0137 mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
0138 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
0139 add r0, r0, #CACHE_DLINESIZE
0140 mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
0141 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
0142 add r0, r0, #CACHE_DLINESIZE
0143 #else
0144 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
0145 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
0146 add r0, r0, #CACHE_DLINESIZE
0147 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
0148 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
0149 add r0, r0, #CACHE_DLINESIZE
0150 #endif
0151 cmp r0, r1
0152 blo 1b
0153 tst r2, #VM_EXEC
0154 mcrne p15, 0, ip, c7, c10, 4 @ drain WB
0155 ret lr
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167 ENTRY(arm946_coherent_kern_range)
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 ENTRY(arm946_coherent_user_range)
0182 bic r0, r0, #CACHE_DLINESIZE - 1
0183 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
0184 mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
0185 add r0, r0, #CACHE_DLINESIZE
0186 cmp r0, r1
0187 blo 1b
0188 mcr p15, 0, r0, c7, c10, 4 @ drain WB
0189 mov r0, #0
0190 ret lr
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202 ENTRY(arm946_flush_kern_dcache_area)
0203 add r1, r0, r1
0204 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
0205 add r0, r0, #CACHE_DLINESIZE
0206 cmp r0, r1
0207 blo 1b
0208 mov r0, #0
0209 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
0210 mcr p15, 0, r0, c7, c10, 4 @ drain WB
0211 ret lr
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225 arm946_dma_inv_range:
0226 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
0227 tst r0, #CACHE_DLINESIZE - 1
0228 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
0229 tst r1, #CACHE_DLINESIZE - 1
0230 mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
0231 #endif
0232 bic r0, r0, #CACHE_DLINESIZE - 1
0233 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
0234 add r0, r0, #CACHE_DLINESIZE
0235 cmp r0, r1
0236 blo 1b
0237 mcr p15, 0, r0, c7, c10, 4 @ drain WB
0238 ret lr
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250 arm946_dma_clean_range:
0251 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
0252 bic r0, r0, #CACHE_DLINESIZE - 1
0253 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
0254 add r0, r0, #CACHE_DLINESIZE
0255 cmp r0, r1
0256 blo 1b
0257 #endif
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 ENTRY(arm946_dma_flush_range)
0272 bic r0, r0, #CACHE_DLINESIZE - 1
0273 1:
0274 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
0275 mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
0276 #else
0277 mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
0278 #endif
0279 add r0, r0, #CACHE_DLINESIZE
0280 cmp r0, r1
0281 blo 1b
0282 mcr p15, 0, r0, c7, c10, 4 @ drain WB
0283 ret lr
0284
0285
0286
0287
0288
0289
0290
0291 ENTRY(arm946_dma_map_area)
0292 add r1, r1, r0
0293 cmp r2, #DMA_TO_DEVICE
0294 beq arm946_dma_clean_range
0295 bcs arm946_dma_inv_range
0296 b arm946_dma_flush_range
0297 ENDPROC(arm946_dma_map_area)
0298
0299
0300
0301
0302
0303
0304
0305 ENTRY(arm946_dma_unmap_area)
0306 ret lr
0307 ENDPROC(arm946_dma_unmap_area)
0308
0309 .globl arm946_flush_kern_cache_louis
0310 .equ arm946_flush_kern_cache_louis, arm946_flush_kern_cache_all
0311
0312 @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
0313 define_cache_functions arm946
0314
0315 ENTRY(cpu_arm946_dcache_clean_area)
0316 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
0317 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
0318 add r0, r0, #CACHE_DLINESIZE
0319 subs r1, r1, #CACHE_DLINESIZE
0320 bhi 1b
0321 #endif
0322 mcr p15, 0, r0, c7, c10, 4 @ drain WB
0323 ret lr
0324
0325 .type __arm946_setup, #function
0326 __arm946_setup:
0327 mov r0, #0
0328 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
0329 mcr p15, 0, r0, c7, c6, 0 @ invalidate D cache
0330 mcr p15, 0, r0, c7, c10, 4 @ drain WB
0331
0332 mcr p15, 0, r0, c6, c3, 0 @ disable memory region 3~7
0333 mcr p15, 0, r0, c6, c4, 0
0334 mcr p15, 0, r0, c6, c5, 0
0335 mcr p15, 0, r0, c6, c6, 0
0336 mcr p15, 0, r0, c6, c7, 0
0337
0338 mov r0, #0x0000003F @ base = 0, size = 4GB
0339 mcr p15, 0, r0, c6, c0, 0 @ set region 0, default
0340
0341 ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM
0342 ldr r7, =CONFIG_DRAM_SIZE @ size of RAM (must be >= 4KB)
0343 pr_val r3, r0, r7, #1
0344 mcr p15, 0, r3, c6, c1, 0
0345
0346 ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH
0347 ldr r7, =CONFIG_FLASH_SIZE @ size of FLASH (must be >= 4KB)
0348 pr_val r3, r0, r7, #1
0349 mcr p15, 0, r3, c6, c2, 0
0350
0351 mov r0, #0x06
0352 mcr p15, 0, r0, c2, c0, 0 @ region 1,2 d-cacheable
0353 mcr p15, 0, r0, c2, c0, 1 @ region 1,2 i-cacheable
0354 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
0355 mov r0, #0x00 @ disable whole write buffer
0356 #else
0357 mov r0, #0x02 @ region 1 write bufferred
0358 #endif
0359 mcr p15, 0, r0, c3, c0, 0
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370 mov r0, #0x00000031
0371 orr r0, r0, #0x00000200
0372 mcr p15, 0, r0, c5, c0, 2 @ set data access permission
0373 mcr p15, 0, r0, c5, c0, 3 @ set inst. access permission
0374
0375 mrc p15, 0, r0, c1, c0 @ get control register
0376 orr r0, r0, #0x00001000 @ I-cache
0377 orr r0, r0, #0x00000005 @ MPU/D-cache
0378 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
0379 orr r0, r0, #0x00004000 @ .1.. .... .... ....
0380 #endif
0381 ret lr
0382
0383 .size __arm946_setup, . - __arm946_setup
0384
0385 __INITDATA
0386
0387 @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
0388 define_processor_functions arm946, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1
0389
0390 .section ".rodata"
0391
0392 string cpu_arch_name, "armv5te"
0393 string cpu_elf_name, "v5t"
0394 string cpu_arm946_name, "ARM946E-S"
0395
0396 .align
0397
0398 .section ".proc.info.init", "a"
0399 .type __arm946_proc_info,#object
0400 __arm946_proc_info:
0401 .long 0x41009460
0402 .long 0xff00fff0
0403 .long 0
0404 .long 0
0405 initfn __arm946_setup, __arm946_proc_info
0406 .long cpu_arch_name
0407 .long cpu_elf_name
0408 .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
0409 .long cpu_arm946_name
0410 .long arm946_processor_functions
0411 .long 0
0412 .long 0
0413 .long arm946_cache_fns
0414 .size __arm946_proc_info, . - __arm946_proc_info
0415