2 * linux/arch/arm/mm/proc-arm1026.S: MMU functions for ARM1026EJ-S
4 * Copyright (C) 2000 ARM Limited
5 * Copyright (C) 2000 Deep Blue Solutions Ltd.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
13 * These are the low level assembler for performing cache and TLB
14 * functions on the ARM1026EJ-S.
16 #include <linux/linkage.h>
17 #include <linux/config.h>
18 #include <linux/init.h>
19 #include <asm/assembler.h>
20 #include <asm/constants.h>
21 #include <asm/pgtable.h>
22 #include <asm/procinfo.h>
23 #include <asm/ptrace.h>
26 * This is the maximum size of an area which will be invalidated
27 * using the single invalidate entry instructions. Anything larger
28 * than this, and we go for the whole cache.
30 * This value should be chosen such that we choose the cheapest
33 #define MAX_AREA_SIZE 32768
36 * The size of one data cache line.
38 #define CACHE_DLINESIZE 32
41 * The number of data cache segments.
43 #define CACHE_DSEGMENTS 16
46 * The number of lines in a cache segment.
48 #define CACHE_DENTRIES 64
51 * This is the size at which it becomes more efficient to
52 * clean the whole cache, rather than using the individual
53 * cache line maintainence instructions.
55 #define CACHE_DLIMIT 32768
59 * cpu_arm1026_proc_init()
61 ENTRY(cpu_arm1026_proc_init)
65 * cpu_arm1026_proc_fin()
67 ENTRY(cpu_arm1026_proc_fin)
69 mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
71 bl arm1026_flush_kern_cache_all
72 mrc p15, 0, r0, c1, c0, 0 @ ctrl register
73 bic r0, r0, #0x1000 @ ...i............
74 bic r0, r0, #0x000e @ ............wca.
75 mcr p15, 0, r0, c1, c0, 0 @ disable caches
79 * cpu_arm1026_reset(loc)
81 * Perform a soft reset of the system. Put the CPU into the
82 * same state as it would be if it had been reset, and branch
83 * to what would be the reset vector.
85 * loc: location to jump to for soft reset
88 ENTRY(cpu_arm1026_reset)
90 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
91 mcr p15, 0, ip, c7, c10, 4 @ drain WB
92 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
93 mrc p15, 0, ip, c1, c0, 0 @ ctrl register
94 bic ip, ip, #0x000f @ ............wcam
95 bic ip, ip, #0x1100 @ ...i...s........
96 mcr p15, 0, ip, c1, c0, 0 @ ctrl register
100 * cpu_arm1026_do_idle()
103 ENTRY(cpu_arm1026_do_idle)
104 mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
107 /* ================================= CACHE ================================ */
111 * flush_user_cache_all()
113 * Invalidate all cache entries in a particular address
116 ENTRY(arm1026_flush_user_cache_all)
119 * flush_kern_cache_all()
121 * Clean and invalidate the entire cache.
123 ENTRY(arm1026_flush_kern_cache_all)
127 #ifndef CONFIG_CPU_DCACHE_DISABLE
128 1: mrc p15, 0, r15, c7, c14, 3 @ test, clean, invalidate
132 #ifndef CONFIG_CPU_ICACHE_DISABLE
133 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
135 mcrne p15, 0, ip, c7, c10, 4 @ drain WB
139 * flush_user_cache_range(start, end, flags)
141 * Invalidate a range of cache entries in the specified
144 * - start - start address (inclusive)
145 * - end - end address (exclusive)
146 * - flags - vm_flags for this space
148 ENTRY(arm1026_flush_user_cache_range)
150 sub r3, r1, r0 @ calculate total size
151 cmp r3, #CACHE_DLIMIT
152 bhs __flush_whole_cache
154 #ifndef CONFIG_CPU_DCACHE_DISABLE
155 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
156 add r0, r0, #CACHE_DLINESIZE
161 #ifndef CONFIG_CPU_ICACHE_DISABLE
162 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
164 mcrne p15, 0, ip, c7, c10, 4 @ drain WB
168 * coherent_kern_range(start, end)
170 * Ensure coherency between the Icache and the Dcache in the
171 * region described by start. If you have non-snooping
172 * Harvard caches, you need to implement this function.
174 * - start - virtual start address
175 * - end - virtual end address
177 ENTRY(arm1026_coherent_kern_range)
179 bic r0, r0, #CACHE_DLINESIZE - 1
181 #ifndef CONFIG_CPU_DCACHE_DISABLE
182 mcr p15, 0, r0, c7, c10, 1 @ clean D entry
184 #ifndef CONFIG_CPU_ICACHE_DISABLE
185 mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
187 add r0, r0, #CACHE_DLINESIZE
190 mcr p15, 0, ip, c7, c10, 4 @ drain WB
194 * flush_kern_dcache_page(void *page)
196 * Ensure no D cache aliasing occurs, either with itself or
199 * - page - page aligned address
201 ENTRY(arm1026_flush_kern_dcache_page)
203 #ifndef CONFIG_CPU_DCACHE_DISABLE
205 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
206 add r0, r0, #CACHE_DLINESIZE
210 mcr p15, 0, ip, c7, c10, 4 @ drain WB
214 * dma_inv_range(start, end)
216 * Invalidate (discard) the specified virtual address range.
217 * May not write back any entries. If 'start' or 'end'
218 * are not cache line aligned, those lines must be written
221 * - start - virtual start address
222 * - end - virtual end address
226 ENTRY(arm1026_dma_inv_range)
228 #ifndef CONFIG_CPU_DCACHE_DISABLE
229 tst r0, #CACHE_DLINESIZE - 1
230 bic r0, r0, #CACHE_DLINESIZE - 1
231 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
232 tst r1, #CACHE_DLINESIZE - 1
233 mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
234 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
235 add r0, r0, #CACHE_DLINESIZE
239 mcr p15, 0, ip, c7, c10, 4 @ drain WB
243 * dma_clean_range(start, end)
245 * Clean the specified virtual address range.
247 * - start - virtual start address
248 * - end - virtual end address
252 ENTRY(arm1026_dma_clean_range)
254 #ifndef CONFIG_CPU_DCACHE_DISABLE
255 bic r0, r0, #CACHE_DLINESIZE - 1
256 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
257 add r0, r0, #CACHE_DLINESIZE
261 mcr p15, 0, ip, c7, c10, 4 @ drain WB
265 * dma_flush_range(start, end)
267 * Clean and invalidate the specified virtual address range.
269 * - start - virtual start address
270 * - end - virtual end address
272 ENTRY(arm1026_dma_flush_range)
274 #ifndef CONFIG_CPU_DCACHE_DISABLE
275 bic r0, r0, #CACHE_DLINESIZE - 1
276 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
277 add r0, r0, #CACHE_DLINESIZE
281 mcr p15, 0, ip, c7, c10, 4 @ drain WB
284 ENTRY(arm1026_cache_fns)
285 .long arm1026_flush_kern_cache_all
286 .long arm1026_flush_user_cache_all
287 .long arm1026_flush_user_cache_range
288 .long arm1026_coherent_kern_range
289 .long arm1026_flush_kern_dcache_page
290 .long arm1026_dma_inv_range
291 .long arm1026_dma_clean_range
292 .long arm1026_dma_flush_range
295 ENTRY(cpu_arm1026_dcache_clean_area)
296 #ifndef CONFIG_CPU_DCACHE_DISABLE
298 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
299 add r0, r0, #CACHE_DLINESIZE
300 subs r1, r1, #CACHE_DLINESIZE
305 /* =============================== PageTable ============================== */
308 * cpu_arm1026_switch_mm(pgd)
310 * Set the translation base pointer to be as described by pgd.
312 * pgd: new page tables
315 ENTRY(cpu_arm1026_switch_mm)
317 #ifndef CONFIG_CPU_DCACHE_DISABLE
318 1: mrc p15, 0, r15, c7, c14, 3 @ test, clean, invalidate
321 #ifndef CONFIG_CPU_ICACHE_DISABLE
322 mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
324 mcr p15, 0, r1, c7, c10, 4 @ drain WB
325 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
326 mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
330 * cpu_arm1026_set_pte(ptep, pte)
332 * Set a PTE and flush it out
335 ENTRY(cpu_arm1026_set_pte)
336 str r1, [r0], #-2048 @ linux version
338 eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
340 bic r2, r1, #PTE_SMALL_AP_MASK
341 bic r2, r2, #PTE_TYPE_MASK
342 orr r2, r2, #PTE_TYPE_SMALL
344 tst r1, #L_PTE_USER @ User?
345 orrne r2, r2, #PTE_SMALL_AP_URO_SRW
347 tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty?
348 orreq r2, r2, #PTE_SMALL_AP_UNO_SRW
350 tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young?
353 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
354 eor r3, r1, #0x0a @ C & small page?
358 str r2, [r0] @ hardware version
360 #ifndef CONFIG_CPU_DCACHE_DISABLE
361 mcr p15, 0, r0, c7, c10, 1 @ clean D entry
368 .type __arm1026_setup, #function
371 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
372 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
373 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
374 mcr p15, 0, r4, c2, c0 @ load page table pointer
375 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
376 mov r0, #4 @ explicitly disable writeback
377 mcr p15, 7, r0, c15, c0, 0
379 mov r0, #0x1f @ Domains 0, 1 = client
380 mcr p15, 0, r0, c3, c0 @ load domain access register
381 mrc p15, 0, r0, c1, c0 @ get control register v4
383 * Clear out 'unwanted' bits (then put them in if we need them)
385 bic r0, r0, #0x1e00 @ ...i??r.........
386 bic r0, r0, #0x000e @ ............wca.
388 * Turn on what we want
390 orr r0, r0, #0x0031 @ ..........DP...M
391 orr r0, r0, #0x2100 @ ..V....S........
393 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
394 orr r0, r0, #0x4000 @ .R..............
396 #ifndef CONFIG_CPU_BPREDICT_DISABLE
397 orr r0, r0, #0x0800 @ ....Z...........
399 #ifndef CONFIG_CPU_DCACHE_DISABLE
400 orr r0, r0, #0x0004 @ .............C..
402 #ifndef CONFIG_CPU_ICACHE_DISABLE
403 orr r0, r0, #0x1000 @ ...I............
406 .size __arm1026_setup, . - __arm1026_setup
411 * Purpose : Function pointers used to access above functions - all calls
414 .type arm1026_processor_functions, #object
415 arm1026_processor_functions:
416 .word v5t_early_abort
417 .word cpu_arm1026_proc_init
418 .word cpu_arm1026_proc_fin
419 .word cpu_arm1026_reset
420 .word cpu_arm1026_do_idle
421 .word cpu_arm1026_dcache_clean_area
422 .word cpu_arm1026_switch_mm
423 .word cpu_arm1026_set_pte
424 .size arm1026_processor_functions, . - arm1026_processor_functions
428 .type cpu_arch_name, #object
431 .size cpu_arch_name, . - cpu_arch_name
433 .type cpu_elf_name, #object
436 .size cpu_elf_name, . - cpu_elf_name
439 .type cpu_arm1026_name, #object
442 #ifndef CONFIG_CPU_ICACHE_DISABLE
445 #ifndef CONFIG_CPU_DCACHE_DISABLE
447 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
453 #ifndef CONFIG_CPU_BPREDICT_DISABLE
456 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
460 .size cpu_arm1026_name, . - cpu_arm1026_name
464 .section ".proc.info", #alloc, #execinstr
466 .type __arm1026_proc_info,#object
468 .long 0x4106a260 @ ARM 1026EJ-S (v5TEJ)
470 .long 0x00000c12 @ mmuflags
474 .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT
475 .long cpu_arm1026_name
476 .long arm1026_processor_functions
479 .long arm1026_cache_fns
480 .size __arm1026_proc_info, . - __arm1026_proc_info