blob: ecaa1727f906d79ef141943cd2146e2770176f53 [file] [log] [blame]
GuanXuetao10c9c102011-01-15 18:18:29 +08001/*
2 * linux/arch/unicore32/mm/cache-ucv2.S
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
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 * This is the "shell" of the UniCore-v2 processor support.
13 */
14#include <linux/linkage.h>
15#include <linux/init.h>
16#include <asm/assembler.h>
17#include <asm/page.h>
18
19#include "proc-macros.S"
20
21/*
22 * __cpuc_flush_icache_all()
23 * __cpuc_flush_kern_all()
24 * __cpuc_flush_user_all()
25 *
26 * Flush the entire cache.
27 */
28ENTRY(__cpuc_flush_icache_all)
29 /*FALLTHROUGH*/
30ENTRY(__cpuc_flush_kern_all)
31 /*FALLTHROUGH*/
32ENTRY(__cpuc_flush_user_all)
33 mov r0, #0
34 movc p0.c5, r0, #14 @ Dcache flush all
35 nop8
36
37 mov r0, #0
38 movc p0.c5, r0, #20 @ Icache invalidate all
39 nop8
40
41 mov pc, lr
42
43/*
44 * __cpuc_flush_user_range(start, end, flags)
45 *
46 * Flush a range of TLB entries in the specified address space.
47 *
48 * - start - start address (may not be aligned)
49 * - end - end address (exclusive, may not be aligned)
50 * - flags - vm_area_struct flags describing address space
51 */
52ENTRY(__cpuc_flush_user_range)
53 cxor.a r2, #0
54 beq __cpuc_dma_flush_range
55
56#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
57 andn r0, r0, #CACHE_LINESIZE - 1 @ Safety check
58 sub r1, r1, r0
59 csub.a r1, #MAX_AREA_SIZE
60 bsg 2f
61
62 andn r1, r1, #CACHE_LINESIZE - 1
63 add r1, r1, #CACHE_LINESIZE
64
65101: dcacheline_flush r0, r11, r12
66
67 add r0, r0, #CACHE_LINESIZE
68 sub.a r1, r1, #CACHE_LINESIZE
69 bns 101b
70 b 3f
71#endif
722: mov ip, #0
73 movc p0.c5, ip, #14 @ Dcache flush all
74 nop8
75
763: mov ip, #0
77 movc p0.c5, ip, #20 @ Icache invalidate all
78 nop8
79
80 mov pc, lr
81
82/*
83 * __cpuc_coherent_kern_range(start,end)
84 * __cpuc_coherent_user_range(start,end)
85 *
86 * Ensure that the I and D caches are coherent within specified
87 * region. This is typically used when code has been written to
88 * a memory region, and will be executed.
89 *
90 * - start - virtual start address of region
91 * - end - virtual end address of region
92 */
93ENTRY(__cpuc_coherent_kern_range)
94 /* FALLTHROUGH */
95ENTRY(__cpuc_coherent_user_range)
96#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
97 andn r0, r0, #CACHE_LINESIZE - 1 @ Safety check
98 sub r1, r1, r0
99 csub.a r1, #MAX_AREA_SIZE
100 bsg 2f
101
102 andn r1, r1, #CACHE_LINESIZE - 1
103 add r1, r1, #CACHE_LINESIZE
104
105 @ r0 va2pa r10
106 mov r9, #PAGE_SZ
107 sub r9, r9, #1 @ PAGE_MASK
108101: va2pa r0, r10, r11, r12, r13, 2f @ r10 is PA
109 b 103f
110102: cand.a r0, r9
111 beq 101b
112
113103: movc p0.c5, r10, #11 @ Dcache clean line of R10
114 nop8
115
116 add r0, r0, #CACHE_LINESIZE
117 add r10, r10, #CACHE_LINESIZE
118 sub.a r1, r1, #CACHE_LINESIZE
119 bns 102b
120 b 3f
121#endif
1222: mov ip, #0
123 movc p0.c5, ip, #10 @ Dcache clean all
124 nop8
125
1263: mov ip, #0
127 movc p0.c5, ip, #20 @ Icache invalidate all
128 nop8
129
130 mov pc, lr
131
132/*
133 * __cpuc_flush_kern_dcache_area(void *addr, size_t size)
134 *
135 * - addr - kernel address
136 * - size - region size
137 */
138ENTRY(__cpuc_flush_kern_dcache_area)
139 mov ip, #0
140 movc p0.c5, ip, #14 @ Dcache flush all
141 nop8
142 mov pc, lr
143
144/*
145 * __cpuc_dma_clean_range(start,end)
146 * - start - virtual start address of region
147 * - end - virtual end address of region
148 */
149ENTRY(__cpuc_dma_clean_range)
150#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
151 andn r0, r0, #CACHE_LINESIZE - 1
152 sub r1, r1, r0
153 andn r1, r1, #CACHE_LINESIZE - 1
154 add r1, r1, #CACHE_LINESIZE
155
156 csub.a r1, #MAX_AREA_SIZE
157 bsg 2f
158
159 @ r0 va2pa r10
160 mov r9, #PAGE_SZ
161 sub r9, r9, #1 @ PAGE_MASK
162101: va2pa r0, r10, r11, r12, r13, 2f @ r10 is PA
163 b 1f
164102: cand.a r0, r9
165 beq 101b
166
1671: movc p0.c5, r10, #11 @ Dcache clean line of R10
168 nop8
169 add r0, r0, #CACHE_LINESIZE
170 add r10, r10, #CACHE_LINESIZE
171 sub.a r1, r1, #CACHE_LINESIZE
172 bns 102b
173 mov pc, lr
174#endif
1752: mov ip, #0
176 movc p0.c5, ip, #10 @ Dcache clean all
177 nop8
178
179 mov pc, lr
180
181/*
182 * __cpuc_dma_inv_range(start,end)
183 * __cpuc_dma_flush_range(start,end)
184 * - start - virtual start address of region
185 * - end - virtual end address of region
186 */
187__cpuc_dma_inv_range:
188 /* FALLTHROUGH */
189ENTRY(__cpuc_dma_flush_range)
190#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
191 andn r0, r0, #CACHE_LINESIZE - 1
192 sub r1, r1, r0
193 andn r1, r1, #CACHE_LINESIZE - 1
194 add r1, r1, #CACHE_LINESIZE
195
196 csub.a r1, #MAX_AREA_SIZE
197 bsg 2f
198
199 @ r0 va2pa r10
200101: dcacheline_flush r0, r11, r12
201
202 add r0, r0, #CACHE_LINESIZE
203 sub.a r1, r1, #CACHE_LINESIZE
204 bns 101b
205 mov pc, lr
206#endif
2072: mov ip, #0
208 movc p0.c5, ip, #14 @ Dcache flush all
209 nop8
210
211 mov pc, lr
212