aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mn10300/mm/Kconfig.cache13
-rw-r--r--arch/mn10300/mm/Makefile2
-rw-r--r--arch/mn10300/mm/cache-flush-by-reg.S308
-rw-r--r--arch/mn10300/mm/cache-inv-by-reg.S356
4 files changed, 678 insertions, 1 deletions
diff --git a/arch/mn10300/mm/Kconfig.cache b/arch/mn10300/mm/Kconfig.cache
index aa6ff0791138..97adc06e7128 100644
--- a/arch/mn10300/mm/Kconfig.cache
+++ b/arch/mn10300/mm/Kconfig.cache
@@ -37,7 +37,8 @@ config MN10300_CACHE_ENABLED
37 37
38choice 38choice
39 prompt "CPU cache flush/invalidate method" 39 prompt "CPU cache flush/invalidate method"
40 default MN10300_CACHE_MANAGE_BY_TAG 40 default MN10300_CACHE_MANAGE_BY_TAG if !AM34_2
41 default MN10300_CACHE_MANAGE_BY_REG if AM34_2
41 depends on MN10300_CACHE_ENABLED 42 depends on MN10300_CACHE_ENABLED
42 help 43 help
43 This determines the method by which CPU cache flushing and 44 This determines the method by which CPU cache flushing and
@@ -46,10 +47,20 @@ choice
46config MN10300_CACHE_MANAGE_BY_TAG 47config MN10300_CACHE_MANAGE_BY_TAG
47 bool "Use the cache tag registers directly" 48 bool "Use the cache tag registers directly"
48 49
50config MN10300_CACHE_MANAGE_BY_REG
51 bool "Flush areas by way of automatic purge registers (AM34 only)"
52 depends on AM34_2
53
49endchoice 54endchoice
50 55
51config MN10300_CACHE_INV_BY_TAG 56config MN10300_CACHE_INV_BY_TAG
52 def_bool y if MN10300_CACHE_MANAGE_BY_TAG && MN10300_CACHE_ENABLED 57 def_bool y if MN10300_CACHE_MANAGE_BY_TAG && MN10300_CACHE_ENABLED
53 58
59config MN10300_CACHE_INV_BY_REG
60 def_bool y if MN10300_CACHE_MANAGE_BY_REG && MN10300_CACHE_ENABLED
61
54config MN10300_CACHE_FLUSH_BY_TAG 62config MN10300_CACHE_FLUSH_BY_TAG
55 def_bool y if MN10300_CACHE_MANAGE_BY_TAG && MN10300_CACHE_WBACK 63 def_bool y if MN10300_CACHE_MANAGE_BY_TAG && MN10300_CACHE_WBACK
64
65config MN10300_CACHE_FLUSH_BY_REG
66 def_bool y if MN10300_CACHE_MANAGE_BY_REG && MN10300_CACHE_WBACK
diff --git a/arch/mn10300/mm/Makefile b/arch/mn10300/mm/Makefile
index dc4b9f0ea65c..7b997236ed20 100644
--- a/arch/mn10300/mm/Makefile
+++ b/arch/mn10300/mm/Makefile
@@ -4,7 +4,9 @@
4 4
5cacheflush-y := cache.o 5cacheflush-y := cache.o
6cacheflush-$(CONFIG_MN10300_CACHE_INV_BY_TAG) += cache-inv-by-tag.o 6cacheflush-$(CONFIG_MN10300_CACHE_INV_BY_TAG) += cache-inv-by-tag.o
7cacheflush-$(CONFIG_MN10300_CACHE_INV_BY_REG) += cache-inv-by-reg.o
7cacheflush-$(CONFIG_MN10300_CACHE_FLUSH_BY_TAG) += cache-flush-by-tag.o 8cacheflush-$(CONFIG_MN10300_CACHE_FLUSH_BY_TAG) += cache-flush-by-tag.o
9cacheflush-$(CONFIG_MN10300_CACHE_FLUSH_BY_REG) += cache-flush-by-reg.o
8 10
9cacheflush-$(CONFIG_MN10300_CACHE_DISABLED) := cache-disabled.o 11cacheflush-$(CONFIG_MN10300_CACHE_DISABLED) := cache-disabled.o
10 12
diff --git a/arch/mn10300/mm/cache-flush-by-reg.S b/arch/mn10300/mm/cache-flush-by-reg.S
new file mode 100644
index 000000000000..1dcae0211671
--- /dev/null
+++ b/arch/mn10300/mm/cache-flush-by-reg.S
@@ -0,0 +1,308 @@
1/* MN10300 CPU core caching routines, using indirect regs on cache controller
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#include <linux/sys.h>
13#include <linux/linkage.h>
14#include <asm/smp.h>
15#include <asm/page.h>
16#include <asm/cache.h>
17#include <asm/irqflags.h>
18
19 .am33_2
20
21#ifndef CONFIG_SMP
22 .globl mn10300_dcache_flush
23 .globl mn10300_dcache_flush_page
24 .globl mn10300_dcache_flush_range
25 .globl mn10300_dcache_flush_range2
26 .globl mn10300_dcache_flush_inv
27 .globl mn10300_dcache_flush_inv_page
28 .globl mn10300_dcache_flush_inv_range
29 .globl mn10300_dcache_flush_inv_range2
30
31mn10300_dcache_flush = mn10300_local_dcache_flush
32mn10300_dcache_flush_page = mn10300_local_dcache_flush_page
33mn10300_dcache_flush_range = mn10300_local_dcache_flush_range
34mn10300_dcache_flush_range2 = mn10300_local_dcache_flush_range2
35mn10300_dcache_flush_inv = mn10300_local_dcache_flush_inv
36mn10300_dcache_flush_inv_page = mn10300_local_dcache_flush_inv_page
37mn10300_dcache_flush_inv_range = mn10300_local_dcache_flush_inv_range
38mn10300_dcache_flush_inv_range2 = mn10300_local_dcache_flush_inv_range2
39
40#endif /* !CONFIG_SMP */
41
42###############################################################################
43#
44# void mn10300_local_dcache_flush(void)
45# Flush the entire data cache back to RAM
46#
47###############################################################################
48 ALIGN
49 .globl mn10300_local_dcache_flush
50 .type mn10300_local_dcache_flush,@function
51mn10300_local_dcache_flush:
52 movhu (CHCTR),d0
53 btst CHCTR_DCEN,d0
54 beq mn10300_local_dcache_flush_end
55
56 mov DCPGCR,a0
57
58 LOCAL_CLI_SAVE(d1)
59
60 # wait for busy bit of area purge
61 setlb
62 mov (a0),d0
63 btst DCPGCR_DCPGBSY,d0
64 lne
65
66 # set mask
67 clr d0
68 mov d0,(DCPGMR)
69
70 # area purge
71 #
72 # DCPGCR = DCPGCR_DCP
73 #
74 mov DCPGCR_DCP,d0
75 mov d0,(a0)
76
77 # wait for busy bit of area purge
78 setlb
79 mov (a0),d0
80 btst DCPGCR_DCPGBSY,d0
81 lne
82
83 LOCAL_IRQ_RESTORE(d1)
84
85mn10300_local_dcache_flush_end:
86 ret [],0
87 .size mn10300_local_dcache_flush,.-mn10300_local_dcache_flush
88
89###############################################################################
90#
91# void mn10300_local_dcache_flush_page(unsigned long start)
92# void mn10300_local_dcache_flush_range(unsigned long start, unsigned long end)
93# void mn10300_local_dcache_flush_range2(unsigned long start, unsigned long size)
94# Flush a range of addresses on a page in the dcache
95#
96###############################################################################
97 ALIGN
98 .globl mn10300_local_dcache_flush_page
99 .globl mn10300_local_dcache_flush_range
100 .globl mn10300_local_dcache_flush_range2
101 .type mn10300_local_dcache_flush_page,@function
102 .type mn10300_local_dcache_flush_range,@function
103 .type mn10300_local_dcache_flush_range2,@function
104mn10300_local_dcache_flush_page:
105 and ~(PAGE_SIZE-1),d0
106 mov PAGE_SIZE,d1
107mn10300_local_dcache_flush_range2:
108 add d0,d1
109mn10300_local_dcache_flush_range:
110 movm [d2,d3,a2],(sp)
111
112 movhu (CHCTR),d2
113 btst CHCTR_DCEN,d2
114 beq mn10300_local_dcache_flush_range_end
115
116 # calculate alignsize
117 #
118 # alignsize = L1_CACHE_BYTES;
119 # for (i = (end - start - 1) / L1_CACHE_BYTES ; i > 0; i >>= 1)
120 # alignsize <<= 1;
121 # d2 = alignsize;
122 #
123 mov L1_CACHE_BYTES,d2
124 sub d0,d1,d3
125 add -1,d3
126 lsr L1_CACHE_SHIFT,d3
127 beq 2f
1281:
129 add d2,d2
130 lsr 1,d3
131 bne 1b
1322:
133 mov d1,a1 # a1 = end
134
135 LOCAL_CLI_SAVE(d3)
136 mov DCPGCR,a0
137
138 # wait for busy bit of area purge
139 setlb
140 mov (a0),d1
141 btst DCPGCR_DCPGBSY,d1
142 lne
143
144 # determine the mask
145 mov d2,d1
146 add -1,d1
147 not d1 # d1 = mask = ~(alignsize-1)
148 mov d1,(DCPGMR)
149
150 and d1,d0,a2 # a2 = mask & start
151
152dcpgloop:
153 # area purge
154 mov a2,d0
155 or DCPGCR_DCP,d0
156 mov d0,(a0) # DCPGCR = (mask & start) | DCPGCR_DCP
157
158 # wait for busy bit of area purge
159 setlb
160 mov (a0),d1
161 btst DCPGCR_DCPGBSY,d1
162 lne
163
164 # check purge of end address
165 add d2,a2 # a2 += alignsize
166 cmp a1,a2 # if (a2 < end) goto dcpgloop
167 bns dcpgloop
168
169 LOCAL_IRQ_RESTORE(d3)
170
171mn10300_local_dcache_flush_range_end:
172 ret [d2,d3,a2],12
173
174 .size mn10300_local_dcache_flush_page,.-mn10300_local_dcache_flush_page
175 .size mn10300_local_dcache_flush_range,.-mn10300_local_dcache_flush_range
176 .size mn10300_local_dcache_flush_range2,.-mn10300_local_dcache_flush_range2
177
178###############################################################################
179#
180# void mn10300_local_dcache_flush_inv(void)
181# Flush the entire data cache and invalidate all entries
182#
183###############################################################################
184 ALIGN
185 .globl mn10300_local_dcache_flush_inv
186 .type mn10300_local_dcache_flush_inv,@function
187mn10300_local_dcache_flush_inv:
188 movhu (CHCTR),d0
189 btst CHCTR_DCEN,d0
190 beq mn10300_local_dcache_flush_inv_end
191
192 mov DCPGCR,a0
193
194 LOCAL_CLI_SAVE(d1)
195
196 # wait for busy bit of area purge & invalidate
197 setlb
198 mov (a0),d0
199 btst DCPGCR_DCPGBSY,d0
200 lne
201
202 # set the mask to cover everything
203 clr d0
204 mov d0,(DCPGMR)
205
206 # area purge & invalidate
207 mov DCPGCR_DCP|DCPGCR_DCI,d0
208 mov d0,(a0)
209
210 # wait for busy bit of area purge & invalidate
211 setlb
212 mov (a0),d0
213 btst DCPGCR_DCPGBSY,d0
214 lne
215
216 LOCAL_IRQ_RESTORE(d1)
217
218mn10300_local_dcache_flush_inv_end:
219 ret [],0
220 .size mn10300_local_dcache_flush_inv,.-mn10300_local_dcache_flush_inv
221
222###############################################################################
223#
224# void mn10300_local_dcache_flush_inv_page(unsigned long start)
225# void mn10300_local_dcache_flush_inv_range(unsigned long start, unsigned long end)
226# void mn10300_local_dcache_flush_inv_range2(unsigned long start, unsigned long size)
227# Flush and invalidate a range of addresses on a page in the dcache
228#
229###############################################################################
230 ALIGN
231 .globl mn10300_local_dcache_flush_inv_page
232 .globl mn10300_local_dcache_flush_inv_range
233 .globl mn10300_local_dcache_flush_inv_range2
234 .type mn10300_local_dcache_flush_inv_page,@function
235 .type mn10300_local_dcache_flush_inv_range,@function
236 .type mn10300_local_dcache_flush_inv_range2,@function
237mn10300_local_dcache_flush_inv_page:
238 and ~(PAGE_SIZE-1),d0
239 mov PAGE_SIZE,d1
240mn10300_local_dcache_flush_inv_range2:
241 add d0,d1
242mn10300_local_dcache_flush_inv_range:
243 movm [d2,d3,a2],(sp)
244
245 movhu (CHCTR),d2
246 btst CHCTR_DCEN,d2
247 beq mn10300_local_dcache_flush_inv_range_end
248
249 # calculate alignsize
250 #
251 # alignsize = L1_CACHE_BYTES;
252 # for (i = (end - start - 1) / L1_CACHE_BYTES; i > 0; i >>= 1)
253 # alignsize <<= 1;
254 # d2 = alignsize
255 #
256 mov L1_CACHE_BYTES,d2
257 sub d0,d1,d3
258 add -1,d3
259 lsr L1_CACHE_SHIFT,d3
260 beq 2f
2611:
262 add d2,d2
263 lsr 1,d3
264 bne 1b
2652:
266 mov d1,a1 # a1 = end
267
268 LOCAL_CLI_SAVE(d3)
269 mov DCPGCR,a0
270
271 # wait for busy bit of area purge & invalidate
272 setlb
273 mov (a0),d1
274 btst DCPGCR_DCPGBSY,d1
275 lne
276
277 # set the mask
278 mov d2,d1
279 add -1,d1
280 not d1 # d1 = mask = ~(alignsize-1)
281 mov d1,(DCPGMR)
282
283 and d1,d0,a2 # a2 = mask & start
284
285dcpgivloop:
286 # area purge & invalidate
287 mov a2,d0
288 or DCPGCR_DCP|DCPGCR_DCI,d0
289 mov d0,(a0) # DCPGCR = (mask & start)|DCPGCR_DCP|DCPGCR_DCI
290
291 # wait for busy bit of area purge & invalidate
292 setlb
293 mov (a0),d1
294 btst DCPGCR_DCPGBSY,d1
295 lne
296
297 # check purge & invalidate of end address
298 add d2,a2 # a2 += alignsize
299 cmp a1,a2 # if (a2 < end) goto dcpgivloop
300 bns dcpgivloop
301
302 LOCAL_IRQ_RESTORE(d3)
303
304mn10300_local_dcache_flush_inv_range_end:
305 ret [d2,d3,a2],12
306 .size mn10300_local_dcache_flush_inv_page,.-mn10300_local_dcache_flush_inv_page
307 .size mn10300_local_dcache_flush_inv_range,.-mn10300_local_dcache_flush_inv_range
308 .size mn10300_local_dcache_flush_inv_range2,.-mn10300_local_dcache_flush_inv_range2
diff --git a/arch/mn10300/mm/cache-inv-by-reg.S b/arch/mn10300/mm/cache-inv-by-reg.S
new file mode 100644
index 000000000000..c8950861ed77
--- /dev/null
+++ b/arch/mn10300/mm/cache-inv-by-reg.S
@@ -0,0 +1,356 @@
1/* MN10300 CPU cache invalidation routines, using automatic purge registers
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11#include <linux/sys.h>
12#include <linux/linkage.h>
13#include <asm/smp.h>
14#include <asm/page.h>
15#include <asm/cache.h>
16#include <asm/irqflags.h>
17#include <asm/cacheflush.h>
18
19#define mn10300_local_dcache_inv_range_intr_interval \
20 +((1 << MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL) - 1)
21
22#if mn10300_local_dcache_inv_range_intr_interval > 0xff
23#error MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL must be 8 or less
24#endif
25
26 .am33_2
27
28#ifndef CONFIG_SMP
29 .globl mn10300_icache_inv
30 .globl mn10300_icache_inv_page
31 .globl mn10300_icache_inv_range
32 .globl mn10300_icache_inv_range2
33 .globl mn10300_dcache_inv
34 .globl mn10300_dcache_inv_page
35 .globl mn10300_dcache_inv_range
36 .globl mn10300_dcache_inv_range2
37
38mn10300_icache_inv = mn10300_local_icache_inv
39mn10300_icache_inv_page = mn10300_local_icache_inv_page
40mn10300_icache_inv_range = mn10300_local_icache_inv_range
41mn10300_icache_inv_range2 = mn10300_local_icache_inv_range2
42mn10300_dcache_inv = mn10300_local_dcache_inv
43mn10300_dcache_inv_page = mn10300_local_dcache_inv_page
44mn10300_dcache_inv_range = mn10300_local_dcache_inv_range
45mn10300_dcache_inv_range2 = mn10300_local_dcache_inv_range2
46
47#endif /* !CONFIG_SMP */
48
49###############################################################################
50#
51# void mn10300_local_icache_inv(void)
52# Invalidate the entire icache
53#
54###############################################################################
55 ALIGN
56 .globl mn10300_local_icache_inv
57 .type mn10300_local_icache_inv,@function
58mn10300_local_icache_inv:
59 mov CHCTR,a0
60
61 movhu (a0),d0
62 btst CHCTR_ICEN,d0
63 beq mn10300_local_icache_inv_end
64
65 # invalidate
66 or CHCTR_ICINV,d0
67 movhu d0,(a0)
68 movhu (a0),d0
69
70mn10300_local_icache_inv_end:
71 ret [],0
72 .size mn10300_local_icache_inv,.-mn10300_local_icache_inv
73
74###############################################################################
75#
76# void mn10300_local_dcache_inv(void)
77# Invalidate the entire dcache
78#
79###############################################################################
80 ALIGN
81 .globl mn10300_local_dcache_inv
82 .type mn10300_local_dcache_inv,@function
83mn10300_local_dcache_inv:
84 mov CHCTR,a0
85
86 movhu (a0),d0
87 btst CHCTR_DCEN,d0
88 beq mn10300_local_dcache_inv_end
89
90 # invalidate
91 or CHCTR_DCINV,d0
92 movhu d0,(a0)
93 movhu (a0),d0
94
95mn10300_local_dcache_inv_end:
96 ret [],0
97 .size mn10300_local_dcache_inv,.-mn10300_local_dcache_inv
98
99###############################################################################
100#
101# void mn10300_local_dcache_inv_range(unsigned long start, unsigned long end)
102# void mn10300_local_dcache_inv_range2(unsigned long start, unsigned long size)
103# void mn10300_local_dcache_inv_page(unsigned long start)
104# Invalidate a range of addresses on a page in the dcache
105#
106###############################################################################
107 ALIGN
108 .globl mn10300_local_dcache_inv_page
109 .globl mn10300_local_dcache_inv_range
110 .globl mn10300_local_dcache_inv_range2
111 .type mn10300_local_dcache_inv_page,@function
112 .type mn10300_local_dcache_inv_range,@function
113 .type mn10300_local_dcache_inv_range2,@function
114mn10300_local_dcache_inv_page:
115 and ~(PAGE_SIZE-1),d0
116 mov PAGE_SIZE,d1
117mn10300_local_dcache_inv_range2:
118 add d0,d1
119mn10300_local_dcache_inv_range:
120 # If we are in writeback mode we check the start and end alignments,
121 # and if they're not cacheline-aligned, we must flush any bits outside
122 # the range that share cachelines with stuff inside the range
123#ifdef CONFIG_MN10300_CACHE_WBACK
124 btst ~(L1_CACHE_BYTES-1),d0
125 bne 1f
126 btst ~(L1_CACHE_BYTES-1),d1
127 beq 2f
1281:
129 bra mn10300_local_dcache_flush_inv_range
1302:
131#endif /* CONFIG_MN10300_CACHE_WBACK */
132
133 movm [d2,d3,a2],(sp)
134
135 mov CHCTR,a0
136 movhu (a0),d2
137 btst CHCTR_DCEN,d2
138 beq mn10300_local_dcache_inv_range_end
139
140 # round the addresses out to be full cachelines, unless we're in
141 # writeback mode, in which case we would be in flush and invalidate by
142 # now
143#ifndef CONFIG_MN10300_CACHE_WBACK
144 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start
145 # addr down
146
147 mov L1_CACHE_BYTES-1,d2
148 add d2,d1
149 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 # round end addr up
150#endif /* !CONFIG_MN10300_CACHE_WBACK */
151
152 sub d0,d1,d2 # calculate the total size
153 mov d0,a2 # A2 = start address
154 mov d1,a1 # A1 = end address
155
156 LOCAL_CLI_SAVE(d3)
157
158 mov DCPGCR,a0 # make sure the purger isn't busy
159 setlb
160 mov (a0),d0
161 btst DCPGCR_DCPGBSY,d0
162 lne
163
164 # skip initial address alignment calculation if address is zero
165 mov d2,d1
166 cmp 0,a2
167 beq 1f
168
169dcivloop:
170 /* calculate alignsize
171 *
172 * alignsize = L1_CACHE_BYTES;
173 * while (! start & alignsize) {
174 * alignsize <<=1;
175 * }
176 * d1 = alignsize;
177 */
178 mov L1_CACHE_BYTES,d1
179 lsr 1,d1
180 setlb
181 add d1,d1
182 mov d1,d0
183 and a2,d0
184 leq
185
1861:
187 /* calculate invsize
188 *
189 * if (totalsize > alignsize) {
190 * invsize = alignsize;
191 * } else {
192 * invsize = totalsize;
193 * tmp = 0x80000000;
194 * while (! invsize & tmp) {
195 * tmp >>= 1;
196 * }
197 * invsize = tmp;
198 * }
199 * d1 = invsize
200 */
201 cmp d2,d1
202 bns 2f
203 mov d2,d1
204
205 mov 0x80000000,d0 # start from 31bit=1
206 setlb
207 lsr 1,d0
208 mov d0,e0
209 and d1,e0
210 leq
211 mov d0,d1
212
2132:
214 /* set mask
215 *
216 * mask = ~(invsize-1);
217 * DCPGMR = mask;
218 */
219 mov d1,d0
220 add -1,d0
221 not d0
222 mov d0,(DCPGMR)
223
224 # invalidate area
225 mov a2,d0
226 or DCPGCR_DCI,d0
227 mov d0,(a0) # DCPGCR = (mask & start) | DCPGCR_DCI
228
229 setlb # wait for the purge to complete
230 mov (a0),d0
231 btst DCPGCR_DCPGBSY,d0
232 lne
233
234 sub d1,d2 # decrease size remaining
235 add d1,a2 # increase next start address
236
237 /* check invalidating of end address
238 *
239 * a2 = a2 + invsize
240 * if (a2 < end) {
241 * goto dcivloop;
242 * } */
243 cmp a1,a2
244 bns dcivloop
245
246 LOCAL_IRQ_RESTORE(d3)
247
248mn10300_local_dcache_inv_range_end:
249 ret [d2,d3,a2],12
250 .size mn10300_local_dcache_inv_page,.-mn10300_local_dcache_inv_page
251 .size mn10300_local_dcache_inv_range,.-mn10300_local_dcache_inv_range
252 .size mn10300_local_dcache_inv_range2,.-mn10300_local_dcache_inv_range2
253
254###############################################################################
255#
256# void mn10300_local_icache_inv_page(unsigned long start)
257# void mn10300_local_icache_inv_range2(unsigned long start, unsigned long size)
258# void mn10300_local_icache_inv_range(unsigned long start, unsigned long end)
259# Invalidate a range of addresses on a page in the icache
260#
261###############################################################################
262 ALIGN
263 .globl mn10300_local_icache_inv_page
264 .globl mn10300_local_icache_inv_range
265 .globl mn10300_local_icache_inv_range2
266 .type mn10300_local_icache_inv_page,@function
267 .type mn10300_local_icache_inv_range,@function
268 .type mn10300_local_icache_inv_range2,@function
269mn10300_local_icache_inv_page:
270 and ~(PAGE_SIZE-1),d0
271 mov PAGE_SIZE,d1
272mn10300_local_icache_inv_range2:
273 add d0,d1
274mn10300_local_icache_inv_range:
275 movm [d2,d3,a2],(sp)
276
277 mov CHCTR,a0
278 movhu (a0),d2
279 btst CHCTR_ICEN,d2
280 beq mn10300_local_icache_inv_range_reg_end
281
282 /* calculate alignsize
283 *
284 * alignsize = L1_CACHE_BYTES;
285 * for (i = (end - start - 1) / L1_CACHE_BYTES ; i > 0; i >>= 1) {
286 * alignsize <<= 1;
287 * }
288 * d2 = alignsize;
289 */
290 mov L1_CACHE_BYTES,d2
291 sub d0,d1,d3
292 add -1,d3
293 lsr L1_CACHE_SHIFT,d3
294 beq 2f
2951:
296 add d2,d2
297 lsr 1,d3
298 bne 1b
2992:
300
301 /* a1 = end */
302 mov d1,a1
303
304 LOCAL_CLI_SAVE(d3)
305
306 mov ICIVCR,a0
307 /* wait for busy bit of area invalidation */
308 setlb
309 mov (a0),d1
310 btst ICIVCR_ICIVBSY,d1
311 lne
312
313 /* set mask
314 *
315 * mask = ~(alignsize-1);
316 * ICIVMR = mask;
317 */
318 mov d2,d1
319 add -1,d1
320 not d1
321 mov d1,(ICIVMR)
322 /* a2 = mask & start */
323 and d1,d0,a2
324
325icivloop:
326 /* area invalidate
327 *
328 * ICIVCR = (mask & start) | ICIVCR_ICI
329 */
330 mov a2,d0
331 or ICIVCR_ICI,d0
332 mov d0,(a0)
333
334 /* wait for busy bit of area invalidation */
335 setlb
336 mov (a0),d1
337 btst ICIVCR_ICIVBSY,d1
338 lne
339
340 /* check invalidating of end address
341 *
342 * a2 = a2 + alignsize
343 * if (a2 < end) {
344 * goto icivloop;
345 * } */
346 add d2,a2
347 cmp a1,a2
348 bns icivloop
349
350 LOCAL_IRQ_RESTORE(d3)
351
352mn10300_local_icache_inv_range_reg_end:
353 ret [d2,d3,a2],12
354 .size mn10300_local_icache_inv_page,.-mn10300_local_icache_inv_page
355 .size mn10300_local_icache_inv_range,.-mn10300_local_icache_inv_range
356 .size mn10300_local_icache_inv_range2,.-mn10300_local_icache_inv_range2