blob: 34968c604d7b28bb7273b3f58db23c713f8b608f [file] [log] [blame]
Jon Loeliger5c8aa972006-04-26 17:58:56 -05001#include <config.h>
2#include <mpc86xx.h>
Jon Loeliger5c8aa972006-04-26 17:58:56 -05003
4#include <ppc_asm.tmpl>
5#include <ppc_defs.h>
6
7#include <asm/cache.h>
8#include <asm/mmu.h>
9
10#ifndef CACHE_LINE_SIZE
11# define CACHE_LINE_SIZE L1_CACHE_BYTES
12#endif
13
14#if CACHE_LINE_SIZE == 128
15#define LG_CACHE_LINE_SIZE 7
16#elif CACHE_LINE_SIZE == 32
17#define LG_CACHE_LINE_SIZE 5
18#elif CACHE_LINE_SIZE == 16
19#define LG_CACHE_LINE_SIZE 4
20#elif CACHE_LINE_SIZE == 8
21#define LG_CACHE_LINE_SIZE 3
22#else
23# error "Invalid cache line size!"
24#endif
25
26/*
27 * Most of this code is taken from 74xx_7xx/cache.S
28 * and then cleaned up a bit
29 */
Jon Loeliger124f7d42006-05-19 13:14:15 -050030
Jon Loeliger5c8aa972006-04-26 17:58:56 -050031/*
32 * Invalidate L1 instruction cache.
33 */
34_GLOBAL(invalidate_l1_instruction_cache)
35 /* use invalidate-all bit in HID0 */
36 mfspr r3,HID0
37 ori r3,r3,HID0_ICFI
38 mtspr HID0,r3
39 isync
40 blr
41
42/*
43 * Invalidate L1 data cache.
44 */
45_GLOBAL(invalidate_l1_data_cache)
46 mfspr r3,HID0
47 ori r3,r3,HID0_DCFI
48 mtspr HID0,r3
49 isync
50 blr
51
52/*
53 * Flush data cache.
54 */
Kumar Gala8aee9352008-10-13 14:12:55 -050055_GLOBAL(flush_dcache)
Jon Loeliger5c8aa972006-04-26 17:58:56 -050056 lis r3,0
57 lis r5,CACHE_LINE_SIZE
58flush:
59 cmp 0,1,r3,r5
60 bge done
61 lwz r5,0(r3)
62 lis r5,CACHE_LINE_SIZE
63 addi r3,r3,0x4
64 b flush
65done:
66 blr
67/*
68 * Write any modified data cache blocks out to memory
69 * and invalidate the corresponding instruction cache blocks.
70 * This is a no-op on the 601.
71 *
72 * flush_icache_range(unsigned long start, unsigned long stop)
73 */
74_GLOBAL(flush_icache_range)
75 li r5,CACHE_LINE_SIZE-1
76 andc r3,r3,r5
77 subf r4,r3,r4
78 add r4,r4,r5
79 srwi. r4,r4,LG_CACHE_LINE_SIZE
80 beqlr
81 mtctr r4
82 mr r6,r3
831: dcbst 0,r3
84 addi r3,r3,CACHE_LINE_SIZE
85 bdnz 1b
86 sync /* wait for dcbst's to get to ram */
87 mtctr r4
882: icbi 0,r6
89 addi r6,r6,CACHE_LINE_SIZE
90 bdnz 2b
91 sync /* additional sync needed on g4 */
92 isync
93 blr
94/*
95 * Write any modified data cache blocks out to memory.
96 * Does not invalidate the corresponding cache lines (especially for
97 * any corresponding instruction cache).
98 *
99 * clean_dcache_range(unsigned long start, unsigned long stop)
100 */
101_GLOBAL(clean_dcache_range)
102 li r5,CACHE_LINE_SIZE-1
103 andc r3,r3,r5 /* align r3 down to cache line */
104 subf r4,r3,r4 /* r4 = offset of stop from start of cache line */
105 add r4,r4,r5 /* r4 += cache_line_size-1 */
106 srwi. r4,r4,LG_CACHE_LINE_SIZE /* r4 = number of cache lines to flush */
107 beqlr /* if r4 == 0 return */
108 mtctr r4 /* ctr = r4 */
109
110 sync
1111: dcbst 0,r3
112 addi r3,r3,CACHE_LINE_SIZE
113 bdnz 1b
114 sync /* wait for dcbst's to get to ram */
115 blr
116
117/*
Jon Loeliger5c8aa972006-04-26 17:58:56 -0500118 * Flush a particular page from the data cache to RAM.
119 * Note: this is necessary because the instruction cache does *not*
120 * snoop from the data cache.
121 *
122 * void __flush_page_to_ram(void *page)
123 */
124_GLOBAL(__flush_page_to_ram)
125 rlwinm r3,r3,0,0,19 /* Get page base address */
126 li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
127 mtctr r4
128 mr r6,r3
1290: dcbst 0,r3 /* Write line to ram */
130 addi r3,r3,CACHE_LINE_SIZE
131 bdnz 0b
132 sync
133 mtctr r4
1341: icbi 0,r6
135 addi r6,r6,CACHE_LINE_SIZE
136 bdnz 1b
137 sync
138 isync
139 blr
140
141/*
142 * Flush a particular page from the instruction cache.
143 * Note: this is necessary because the instruction cache does *not*
144 * snoop from the data cache.
145 *
146 * void __flush_icache_page(void *page)
147 */
148_GLOBAL(__flush_icache_page)
149 li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
150 mtctr r4
1511: icbi 0,r3
152 addi r3,r3,CACHE_LINE_SIZE
153 bdnz 1b
154 sync
155 isync
156 blr
157
158/*
159 * Clear a page using the dcbz instruction, which doesn't cause any
160 * memory traffic (except to write out any cache lines which get
161 * displaced). This only works on cacheable memory.
162 */
163_GLOBAL(clear_page)
164 li r0,4096/CACHE_LINE_SIZE
165 mtctr r0
1661: dcbz 0,r3
167 addi r3,r3,CACHE_LINE_SIZE
168 bdnz 1b
169 blr
170
171/*
172 * Enable L1 Instruction cache
173 */
174_GLOBAL(icache_enable)
175 mfspr r3, HID0
176 li r5, HID0_ICFI|HID0_ILOCK
177 andc r3, r3, r5
178 ori r3, r3, HID0_ICE
179 ori r5, r3, HID0_ICFI
180 mtspr HID0, r5
181 mtspr HID0, r3
182 isync
183 blr
184
185/*
186 * Disable L1 Instruction cache
187 */
188_GLOBAL(icache_disable)
Kumar Gala0687e302008-08-15 08:24:32 -0500189 mflr r4
190 bl invalidate_l1_instruction_cache /* uses r3 */
191 sync
192 mtlr r4
Jon Loeliger5c8aa972006-04-26 17:58:56 -0500193 mfspr r3, HID0
194 li r5, 0
195 ori r5, r5, HID0_ICE
196 andc r3, r3, r5
197 mtspr HID0, r3
198 isync
199 blr
200
201/*
202 * Is instruction cache enabled?
203 */
204_GLOBAL(icache_status)
205 mfspr r3, HID0
206 andi. r3, r3, HID0_ICE
207 blr
208
209
210_GLOBAL(l1dcache_enable)
211 mfspr r3, HID0
212 li r5, HID0_DCFI|HID0_DLOCK
213 andc r3, r3, r5
214 mtspr HID0, r3 /* no invalidate, unlock */
215 ori r3, r3, HID0_DCE
216 ori r5, r3, HID0_DCFI
217 mtspr HID0, r5 /* enable + invalidate */
218 mtspr HID0, r3 /* enable */
219 sync
220 blr
221
222/*
223 * Enable data cache(s) - L1 and optionally L2
224 * Calls l2cache_enable. LR saved in r5
225 */
226_GLOBAL(dcache_enable)
227 mfspr r3, HID0
228 li r5, HID0_DCFI|HID0_DLOCK
229 andc r3, r3, r5
230 mtspr HID0, r3 /* no invalidate, unlock */
231 ori r3, r3, HID0_DCE
232 ori r5, r3, HID0_DCFI
233 mtspr HID0, r5 /* enable + invalidate */
234 mtspr HID0, r3 /* enable */
235 sync
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200236#ifdef CONFIG_SYS_L2
Jon Loeliger5c8aa972006-04-26 17:58:56 -0500237 mflr r5
238 bl l2cache_enable /* uses r3 and r4 */
239 sync
240 mtlr r5
241#endif
242 blr
243
244
245/*
246 * Disable data cache(s) - L1 and optionally L2
Kumar Gala8aee9352008-10-13 14:12:55 -0500247 * Calls flush_dcache and l2cache_disable_no_flush.
Jon Loeliger5c8aa972006-04-26 17:58:56 -0500248 * LR saved in r4
249 */
250_GLOBAL(dcache_disable)
251 mflr r4 /* save link register */
Kumar Gala8aee9352008-10-13 14:12:55 -0500252 bl flush_dcache /* uses r3 and r5 */
Jon Loeliger5c8aa972006-04-26 17:58:56 -0500253 sync
254 mfspr r3, HID0
255 li r5, HID0_DCFI|HID0_DLOCK
256 andc r3, r3, r5
257 mtspr HID0, r3 /* no invalidate, unlock */
258 li r5, HID0_DCE|HID0_DCFI
259 andc r3, r3, r5 /* no enable, no invalidate */
260 mtspr HID0, r3
261 sync
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200262#ifdef CONFIG_SYS_L2
Jon Loeliger5c8aa972006-04-26 17:58:56 -0500263 bl l2cache_disable_no_flush /* uses r3 */
264#endif
265 mtlr r4 /* restore link register */
266 blr
267
268/*
269 * Is data cache enabled?
270 */
271_GLOBAL(dcache_status)
272 mfspr r3, HID0
273 andi. r3, r3, HID0_DCE
274 blr
275
276/*
Jon Loeliger124f7d42006-05-19 13:14:15 -0500277 * Invalidate L2 cache using L2I, assume L2 is enabled
Jon Loeliger5c8aa972006-04-26 17:58:56 -0500278 */
279_GLOBAL(l2cache_invalidate)
Jon Loeliger124f7d42006-05-19 13:14:15 -0500280 mfspr r3, l2cr
281 rlwinm. r3, r3, 0, 0, 0
282 beq 1f
283
284 mfspr r3, l2cr
285 rlwinm r3, r3, 0, 1, 31
286
287#ifdef CONFIG_ALTIVEC
288 dssall
289#endif
Jon Loeliger5c8aa972006-04-26 17:58:56 -0500290 sync
291 mtspr l2cr, r3
292 sync
Jon Loeliger124f7d42006-05-19 13:14:15 -05002931: mfspr r3, l2cr
294 oris r3, r3, L2CR_L2I@h
295 mtspr l2cr, r3
296
Jon Loeliger5c8aa972006-04-26 17:58:56 -0500297invl2:
298 mfspr r3, l2cr
Wheatley Travisd86e17e2008-05-02 13:35:15 -0700299 andis. r3, r3, L2CR_L2I@h
Jon Loeliger5c8aa972006-04-26 17:58:56 -0500300 bne invl2
Jon Loeliger5c8aa972006-04-26 17:58:56 -0500301 blr
302
303/*
304 * Enable L2 cache
305 * Calls l2cache_invalidate. LR is saved in r4
306 */
307_GLOBAL(l2cache_enable)
308 mflr r4 /* save link register */
309 bl l2cache_invalidate /* uses r3 */
310 sync
311 lis r3, L2_ENABLE@h
312 ori r3, r3, L2_ENABLE@l
313 mtspr l2cr, r3
314 isync
315 mtlr r4 /* restore link register */
316 blr
317
318/*
319 * Disable L2 cache
Kumar Gala8aee9352008-10-13 14:12:55 -0500320 * Calls flush_dcache. LR is saved in r4
Jon Loeliger5c8aa972006-04-26 17:58:56 -0500321 */
322_GLOBAL(l2cache_disable)
323 mflr r4 /* save link register */
Kumar Gala8aee9352008-10-13 14:12:55 -0500324 bl flush_dcache /* uses r3 and r5 */
Jon Loeliger5c8aa972006-04-26 17:58:56 -0500325 sync
326 mtlr r4 /* restore link register */
327l2cache_disable_no_flush: /* provide way to disable L2 w/o flushing */
328 lis r3, L2_INIT@h
329 ori r3, r3, L2_INIT@l
330 mtspr l2cr, r3
331 isync
332 blr