aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm
diff options
context:
space:
mode:
authorHyok S. Choi <hyok.choi@samsung.com>2006-09-26 04:38:32 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-09-27 12:39:19 -0400
commitf37f46eb1c0bd0b11c34ef06c7365658be989d80 (patch)
tree1790995456cafc852899927140e5dd7523463fdb /arch/arm/mm
parentd60674eb5d961b2421db16cc373dc163f38cc105 (diff)
[ARM] nommu: add ARM946E-S core support
This patch adds ARM946E-S core support which has typically 8KB I&D cache. It has a MPU and supports ARMv5TE instruction set. Because the ARM946E-S core can be synthesizable with various cache size, CONFIG_CPU_DCACHE_SIZE is defined for vendor specific configurations. Signed-off-by: Hyok S. Choi <hyok.choi@samsung.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm')
-rw-r--r--arch/arm/mm/Kconfig34
-rw-r--r--arch/arm/mm/Makefile1
-rw-r--r--arch/arm/mm/proc-arm946.S424
3 files changed, 456 insertions, 3 deletions
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 34d00738293f..893d3fc8078f 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -200,6 +200,21 @@ config CPU_ARM940T
200 Say Y if you want support for the ARM940T processor. 200 Say Y if you want support for the ARM940T processor.
201 Otherwise, say N. 201 Otherwise, say N.
202 202
203# ARM946E-S
204config CPU_ARM946E
205 bool "Support ARM946E-S processor" if ARCH_INTEGRATOR
206 select CPU_32v5
207 select CPU_ABRT_EV5T
208 select CPU_CACHE_VIVT
209 select CPU_CP15_MPU
210 help
211 ARM946E-S is a member of the ARM9E-S family of high-
212 performance, 32-bit system-on-chip processor solutions.
213 The TCM and ARMv5TE 32-bit instruction set is supported.
214
215 Say Y if you want support for the ARM946E-S processor.
216 Otherwise, say N.
217
203# ARM1020 - needs validating 218# ARM1020 - needs validating
204config CPU_ARM1020 219config CPU_ARM1020
205 bool "Support ARM1020T (rev 0) processor" 220 bool "Support ARM1020T (rev 0) processor"
@@ -480,7 +495,7 @@ comment "Processor Features"
480 495
481config ARM_THUMB 496config ARM_THUMB
482 bool "Support Thumb user binaries" 497 bool "Support Thumb user binaries"
483 depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 498 depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6
484 default y 499 default y
485 help 500 help
486 Say Y if you want to include kernel support for running user space 501 Say Y if you want to include kernel support for running user space
@@ -515,9 +530,22 @@ config CPU_DCACHE_DISABLE
515 Say Y here to disable the processor data cache. Unless 530 Say Y here to disable the processor data cache. Unless
516 you have a reason not to or are unsure, say N. 531 you have a reason not to or are unsure, say N.
517 532
533config CPU_DCACHE_SIZE
534 hex
535 depends on CPU_ARM740T || CPU_ARM946E
536 default 0x00001000 if CPU_ARM740T
537 default 0x00002000 # default size for ARM946E-S
538 help
539 Some cores are synthesizable to have various sized cache. For
540 ARM946E-S case, it can vary from 0KB to 1MB.
541 To support such cache operations, it is efficient to know the size
542 before compile time.
543 If your SoC is configured to have a different size, define the value
544 here with proper conditions.
545
518config CPU_DCACHE_WRITETHROUGH 546config CPU_DCACHE_WRITETHROUGH
519 bool "Force write through D-cache" 547 bool "Force write through D-cache"
520 depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE 548 depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE
521 default y if CPU_ARM925T 549 default y if CPU_ARM925T
522 help 550 help
523 Say Y here to use the data cache in writethrough mode. Unless you 551 Say Y here to use the data cache in writethrough mode. Unless you
@@ -525,7 +553,7 @@ config CPU_DCACHE_WRITETHROUGH
525 553
526config CPU_CACHE_ROUND_ROBIN 554config CPU_CACHE_ROUND_ROBIN
527 bool "Round robin I and D cache replacement algorithm" 555 bool "Round robin I and D cache replacement algorithm"
528 depends on (CPU_ARM926T || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE) 556 depends on (CPU_ARM926T || CPU_ARM946E || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE)
529 help 557 help
530 Say Y here to use the predictable round-robin cache replacement 558 Say Y here to use the predictable round-robin cache replacement
531 policy. Unless you specifically require this or are unsure, say N. 559 policy. Unless you specifically require this or are unsure, say N.
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index f89fe1b2a4ad..ed81b9ef10cb 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -55,6 +55,7 @@ obj-$(CONFIG_CPU_ARM922T) += proc-arm922.o
55obj-$(CONFIG_CPU_ARM925T) += proc-arm925.o 55obj-$(CONFIG_CPU_ARM925T) += proc-arm925.o
56obj-$(CONFIG_CPU_ARM926T) += proc-arm926.o 56obj-$(CONFIG_CPU_ARM926T) += proc-arm926.o
57obj-$(CONFIG_CPU_ARM940T) += proc-arm940.o 57obj-$(CONFIG_CPU_ARM940T) += proc-arm940.o
58obj-$(CONFIG_CPU_ARM946E) += proc-arm946.o
58obj-$(CONFIG_CPU_ARM1020) += proc-arm1020.o 59obj-$(CONFIG_CPU_ARM1020) += proc-arm1020.o
59obj-$(CONFIG_CPU_ARM1020E) += proc-arm1020e.o 60obj-$(CONFIG_CPU_ARM1020E) += proc-arm1020e.o
60obj-$(CONFIG_CPU_ARM1022) += proc-arm1022.o 61obj-$(CONFIG_CPU_ARM1022) += proc-arm1022.o
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
new file mode 100644
index 000000000000..6dc7942c4cfe
--- /dev/null
+++ b/arch/arm/mm/proc-arm946.S
@@ -0,0 +1,424 @@
1/*
2 * linux/arch/arm/mm/arm946.S: utility functions for ARM946E-S
3 *
4 * Copyright (C) 2004-2006 Hyok S. Choi (hyok.choi@samsung.com)
5 *
6 * (Many of cache codes are from proc-arm926.S)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13#include <linux/linkage.h>
14#include <linux/init.h>
15#include <asm/assembler.h>
16#include <asm/pgtable-hwdef.h>
17#include <asm/pgtable.h>
18#include <asm/procinfo.h>
19#include <asm/ptrace.h>
20
21/*
22 * ARM946E-S is synthesizable to have 0KB to 1MB sized D-Cache,
23 * comprising 256 lines of 32 bytes (8 words).
24 */
25#define CACHE_DSIZE (CONFIG_CPU_DCACHE_SIZE) /* typically 8KB. */
26#define CACHE_DLINESIZE 32 /* fixed */
27#define CACHE_DSEGMENTS 4 /* fixed */
28#define CACHE_DENTRIES (CACHE_DSIZE / CACHE_DSEGMENTS / CACHE_DLINESIZE)
29#define CACHE_DLIMIT (CACHE_DSIZE * 4) /* benchmark needed */
30
31 .text
32/*
33 * cpu_arm946_proc_init()
34 * cpu_arm946_switch_mm()
35 *
36 * These are not required.
37 */
38ENTRY(cpu_arm946_proc_init)
39ENTRY(cpu_arm946_switch_mm)
40 mov pc, lr
41
42/*
43 * cpu_arm946_proc_fin()
44 */
45ENTRY(cpu_arm946_proc_fin)
46 stmfd sp!, {lr}
47 mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
48 msr cpsr_c, ip
49 bl arm946_flush_kern_cache_all
50 mrc p15, 0, r0, c1, c0, 0 @ ctrl register
51 bic r0, r0, #0x00001000 @ i-cache
52 bic r0, r0, #0x00000004 @ d-cache
53 mcr p15, 0, r0, c1, c0, 0 @ disable caches
54 ldmfd sp!, {pc}
55
56/*
57 * cpu_arm946_reset(loc)
58 * Params : r0 = address to jump to
59 * Notes : This sets up everything for a reset
60 */
61ENTRY(cpu_arm946_reset)
62 mov ip, #0
63 mcr p15, 0, ip, c7, c5, 0 @ flush I cache
64 mcr p15, 0, ip, c7, c6, 0 @ flush D cache
65 mcr p15, 0, ip, c7, c10, 4 @ drain WB
66 mrc p15, 0, ip, c1, c0, 0 @ ctrl register
67 bic ip, ip, #0x00000005 @ .............c.p
68 bic ip, ip, #0x00001000 @ i-cache
69 mcr p15, 0, ip, c1, c0, 0 @ ctrl register
70 mov pc, r0
71
72/*
73 * cpu_arm946_do_idle()
74 */
75 .align 5
76ENTRY(cpu_arm946_do_idle)
77 mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
78 mov pc, lr
79
80/*
81 * flush_user_cache_all()
82 */
83ENTRY(arm946_flush_user_cache_all)
84 /* FALLTHROUGH */
85
86/*
87 * flush_kern_cache_all()
88 *
89 * Clean and invalidate the entire cache.
90 */
91ENTRY(arm946_flush_kern_cache_all)
92 mov r2, #VM_EXEC
93 mov ip, #0
94__flush_whole_cache:
95#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
96 mcr p15, 0, ip, c7, c6, 0 @ flush D cache
97#else
98 mov r1, #(CACHE_DSEGMENTS - 1) << 29 @ 4 segments
991: orr r3, r1, #(CACHE_DENTRIES - 1) << 4 @ n entries
1002: mcr p15, 0, r3, c7, c14, 2 @ clean/flush D index
101 subs r3, r3, #1 << 4
102 bcs 2b @ entries n to 0
103 subs r1, r1, #1 << 29
104 bcs 1b @ segments 3 to 0
105#endif
106 tst r2, #VM_EXEC
107 mcrne p15, 0, ip, c7, c5, 0 @ flush I cache
108 mcrne p15, 0, ip, c7, c10, 4 @ drain WB
109 mov pc, lr
110
111/*
112 * flush_user_cache_range(start, end, flags)
113 *
114 * Clean and invalidate a range of cache entries in the
115 * specified address range.
116 *
117 * - start - start address (inclusive)
118 * - end - end address (exclusive)
119 * - flags - vm_flags describing address space
120 * (same as arm926)
121 */
122ENTRY(arm946_flush_user_cache_range)
123 mov ip, #0
124 sub r3, r1, r0 @ calculate total size
125 cmp r3, #CACHE_DLIMIT
126 bhs __flush_whole_cache
127
1281: tst r2, #VM_EXEC
129#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
130 mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
131 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
132 add r0, r0, #CACHE_DLINESIZE
133 mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
134 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
135 add r0, r0, #CACHE_DLINESIZE
136#else
137 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
138 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
139 add r0, r0, #CACHE_DLINESIZE
140 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
141 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
142 add r0, r0, #CACHE_DLINESIZE
143#endif
144 cmp r0, r1
145 blo 1b
146 tst r2, #VM_EXEC
147 mcrne p15, 0, ip, c7, c10, 4 @ drain WB
148 mov pc, lr
149
150/*
151 * coherent_kern_range(start, end)
152 *
153 * Ensure coherency between the Icache and the Dcache in the
154 * region described by start, end. If you have non-snooping
155 * Harvard caches, you need to implement this function.
156 *
157 * - start - virtual start address
158 * - end - virtual end address
159 */
160ENTRY(arm946_coherent_kern_range)
161 /* FALLTHROUGH */
162
163/*
164 * coherent_user_range(start, end)
165 *
166 * Ensure coherency between the Icache and the Dcache in the
167 * region described by start, end. If you have non-snooping
168 * Harvard caches, you need to implement this function.
169 *
170 * - start - virtual start address
171 * - end - virtual end address
172 * (same as arm926)
173 */
174ENTRY(arm946_coherent_user_range)
175 bic r0, r0, #CACHE_DLINESIZE - 1
1761: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
177 mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
178 add r0, r0, #CACHE_DLINESIZE
179 cmp r0, r1
180 blo 1b
181 mcr p15, 0, r0, c7, c10, 4 @ drain WB
182 mov pc, lr
183
184/*
185 * flush_kern_dcache_page(void *page)
186 *
187 * Ensure no D cache aliasing occurs, either with itself or
188 * the I cache
189 *
190 * - addr - page aligned address
191 * (same as arm926)
192 */
193ENTRY(arm946_flush_kern_dcache_page)
194 add r1, r0, #PAGE_SZ
1951: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
196 add r0, r0, #CACHE_DLINESIZE
197 cmp r0, r1
198 blo 1b
199 mov r0, #0
200 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
201 mcr p15, 0, r0, c7, c10, 4 @ drain WB
202 mov pc, lr
203
204/*
205 * dma_inv_range(start, end)
206 *
207 * Invalidate (discard) the specified virtual address range.
208 * May not write back any entries. If 'start' or 'end'
209 * are not cache line aligned, those lines must be written
210 * back.
211 *
212 * - start - virtual start address
213 * - end - virtual end address
214 * (same as arm926)
215 */
216ENTRY(arm946_dma_inv_range)
217#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
218 tst r0, #CACHE_DLINESIZE - 1
219 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
220 tst r1, #CACHE_DLINESIZE - 1
221 mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
222#endif
223 bic r0, r0, #CACHE_DLINESIZE - 1
2241: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
225 add r0, r0, #CACHE_DLINESIZE
226 cmp r0, r1
227 blo 1b
228 mcr p15, 0, r0, c7, c10, 4 @ drain WB
229 mov pc, lr
230
231/*
232 * dma_clean_range(start, end)
233 *
234 * Clean the specified virtual address range.
235 *
236 * - start - virtual start address
237 * - end - virtual end address
238 *
239 * (same as arm926)
240 */
241ENTRY(arm946_dma_clean_range)
242#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
243 bic r0, r0, #CACHE_DLINESIZE - 1
2441: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
245 add r0, r0, #CACHE_DLINESIZE
246 cmp r0, r1
247 blo 1b
248#endif
249 mcr p15, 0, r0, c7, c10, 4 @ drain WB
250 mov pc, lr
251
252/*
253 * dma_flush_range(start, end)
254 *
255 * Clean and invalidate the specified virtual address range.
256 *
257 * - start - virtual start address
258 * - end - virtual end address
259 *
260 * (same as arm926)
261 */
262ENTRY(arm946_dma_flush_range)
263 bic r0, r0, #CACHE_DLINESIZE - 1
2641:
265#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
266 mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
267#else
268 mcr p15, 0, r0, c7, c10, 1 @ clean D entry
269#endif
270 add r0, r0, #CACHE_DLINESIZE
271 cmp r0, r1
272 blo 1b
273 mcr p15, 0, r0, c7, c10, 4 @ drain WB
274 mov pc, lr
275
276ENTRY(arm946_cache_fns)
277 .long arm946_flush_kern_cache_all
278 .long arm946_flush_user_cache_all
279 .long arm946_flush_user_cache_range
280 .long arm946_coherent_kern_range
281 .long arm946_coherent_user_range
282 .long arm946_flush_kern_dcache_page
283 .long arm946_dma_inv_range
284 .long arm946_dma_clean_range
285 .long arm946_dma_flush_range
286
287
288ENTRY(cpu_arm946_dcache_clean_area)
289#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
2901: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
291 add r0, r0, #CACHE_DLINESIZE
292 subs r1, r1, #CACHE_DLINESIZE
293 bhi 1b
294#endif
295 mcr p15, 0, r0, c7, c10, 4 @ drain WB
296 mov pc, lr
297
298 __INIT
299
300 .type __arm946_setup, #function
301__arm946_setup:
302 mov r0, #0
303 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
304 mcr p15, 0, r0, c7, c6, 0 @ invalidate D cache
305 mcr p15, 0, r0, c7, c10, 4 @ drain WB
306
307 mcr p15, 0, r0, c6, c3, 0 @ disable memory region 3~7
308 mcr p15, 0, r0, c6, c4, 0
309 mcr p15, 0, r0, c6, c5, 0
310 mcr p15, 0, r0, c6, c6, 0
311 mcr p15, 0, r0, c6, c7, 0
312
313 mov r0, #0x0000003F @ base = 0, size = 4GB
314 mcr p15, 0, r0, c6, c0, 0 @ set region 0, default
315
316 ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM
317 ldr r1, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB)
318 mov r2, #10 @ 11 is the minimum (4KB)
3191: add r2, r2, #1 @ area size *= 2
320 mov r1, r1, lsr #1
321 bne 1b @ count not zero r-shift
322 orr r0, r0, r2, lsl #1 @ the region register value
323 orr r0, r0, #1 @ set enable bit
324 mcr p15, 0, r0, c6, c1, 0 @ set region 1, RAM
325
326 ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH
327 ldr r1, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB)
328 mov r2, #10 @ 11 is the minimum (4KB)
3291: add r2, r2, #1 @ area size *= 2
330 mov r1, r1, lsr #1
331 bne 1b @ count not zero r-shift
332 orr r0, r0, r2, lsl #1 @ the region register value
333 orr r0, r0, #1 @ set enable bit
334 mcr p15, 0, r0, c6, c2, 0 @ set region 2, ROM/FLASH
335
336 mov r0, #0x06
337 mcr p15, 0, r0, c2, c0, 0 @ region 1,2 d-cacheable
338 mcr p15, 0, r0, c2, c0, 1 @ region 1,2 i-cacheable
339#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
340 mov r0, #0x00 @ disable whole write buffer
341#else
342 mov r0, #0x02 @ region 1 write bufferred
343#endif
344 mcr p15, 0, r0, c3, c0, 0
345
346/*
347 * Access Permission Settings for future permission control by PU.
348 *
349 * priv. user
350 * region 0 (whole) rw -- : b0001
351 * region 1 (RAM) rw rw : b0011
352 * region 2 (FLASH) rw r- : b0010
353 * region 3~7 (none) -- -- : b0000
354 */
355 mov r0, #0x00000031
356 orr r0, r0, #0x00000200
357 mcr p15, 0, r0, c5, c0, 2 @ set data access permission
358 mcr p15, 0, r0, c5, c0, 3 @ set inst. access permission
359
360 mrc p15, 0, r0, c1, c0 @ get control register
361 orr r0, r0, #0x00001000 @ I-cache
362 orr r0, r0, #0x00000005 @ MPU/D-cache
363#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
364 orr r0, r0, #0x00004000 @ .1.. .... .... ....
365#endif
366 mov pc, lr
367
368 .size __arm946_setup, . - __arm946_setup
369
370 __INITDATA
371
372/*
373 * Purpose : Function pointers used to access above functions - all calls
374 * come through these
375 */
376 .type arm946_processor_functions, #object
377ENTRY(arm946_processor_functions)
378 .word v5t_early_abort
379 .word cpu_arm946_proc_init
380 .word cpu_arm946_proc_fin
381 .word cpu_arm946_reset
382 .word cpu_arm946_do_idle
383
384 .word cpu_arm946_dcache_clean_area
385 .word cpu_arm946_switch_mm
386 .word 0 @ cpu_*_set_pte
387 .size arm946_processor_functions, . - arm946_processor_functions
388
389 .section ".rodata"
390
391 .type cpu_arch_name, #object
392cpu_arch_name:
393 .asciz "armv5te"
394 .size cpu_arch_name, . - cpu_arch_name
395
396 .type cpu_elf_name, #object
397cpu_elf_name:
398 .asciz "v5t"
399 .size cpu_elf_name, . - cpu_elf_name
400
401 .type cpu_arm946_name, #object
402cpu_arm946_name:
403 .ascii "ARM946E-S"
404 .size cpu_arm946_name, . - cpu_arm946_name
405
406 .align
407
408 .section ".proc.info.init", #alloc, #execinstr
409 .type __arm946_proc_info,#object
410__arm946_proc_info:
411 .long 0x41009460
412 .long 0xff00fff0
413 .long 0
414 b __arm946_setup
415 .long cpu_arch_name
416 .long cpu_elf_name
417 .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
418 .long cpu_arm946_name
419 .long arm946_processor_functions
420 .long 0
421 .long 0
422 .long arm940_cache_fns
423 .size __arm946_proc_info, . - __arm946_proc_info
424