Merge git://www.denx.de/git/u-boot
[platform/kernel/u-boot.git] / post / cpu / ppc4xx / cache_4xx.S
1 /*
2  * (C) Copyright 2007
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * Author: Igor Lisitsin <igor@emcraft.com>
6  *
7  * See file CREDITS for list of people who contributed to this
8  * project.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23  * MA 02111-1307 USA
24  */
25
26 #include <config.h>
27
28 #ifdef CONFIG_POST
29
30 #include <post.h>
31 #include <ppc_asm.tmpl>
32 #include <ppc_defs.h>
33 #include <asm/cache.h>
34 #include <asm/mmu.h>
35
36 #if CONFIG_POST & CFG_POST_CACHE
37
38         .text
39
40         /*
41          * All 44x variants deal with cache management differently
42          * because they have the address translation always enabled.
43          * The 40x ppc's don't use address translation in U-Boot at all,
44          * so we have to distinguish here between 40x and 44x.
45          */
46 #ifdef CONFIG_440
47 /* void cache_post_disable (int tlb)
48  */
49 cache_post_disable:
50         tlbre   r0, r3, 0x0002
51         ori     r0, r0, TLB_WORD2_I_ENABLE@l
52         tlbwe   r0, r3, 0x0002
53         sync
54         isync
55         blr
56
57 /* void cache_post_wt (int tlb)
58  */
59 cache_post_wt:
60         tlbre   r0, r3, 0x0002
61         ori     r0, r0, TLB_WORD2_W_ENABLE@l
62         andi.   r0, r0, ~TLB_WORD2_I_ENABLE@l
63         tlbwe   r0, r3, 0x0002
64         sync
65         isync
66         blr
67
68 /* void cache_post_wb (int tlb)
69  */
70 cache_post_wb:
71         tlbre   r0, r3, 0x0002
72         andi.   r0, r0, ~TLB_WORD2_W_ENABLE@l
73         andi.   r0, r0, ~TLB_WORD2_I_ENABLE@l
74         tlbwe   r0, r3, 0x0002
75         sync
76         isync
77         blr
78 #else
79 /* void cache_post_disable (int tlb)
80  */
81 cache_post_disable:
82         lis     r0, 0x0000
83         ori     r0, r0, 0x0000
84         mtdccr  r0
85         sync
86         isync
87         blr
88
89 /* void cache_post_wt (int tlb)
90  */
91 cache_post_wt:
92         lis     r0, 0x8000
93         ori     r0, r0, 0x0000
94         mtdccr  r0
95         lis     r0, 0x8000
96         ori     r0, r0, 0x0000
97         mtdcwr  r0
98         sync
99         isync
100         blr
101
102 /* void cache_post_wb (int tlb)
103  */
104 cache_post_wb:
105         lis     r0, 0x8000
106         ori     r0, r0, 0x0000
107         mtdccr  r0
108         lis     r0, 0x0000
109         ori     r0, r0, 0x0000
110         mtdcwr  r0
111         sync
112         isync
113         blr
114 #endif
115
116 /* void cache_post_dinvalidate (void *p, int size)
117  */
118 cache_post_dinvalidate:
119         dcbi    r0, r3
120         addi    r3, r3, CFG_CACHELINE_SIZE
121         subic.  r4, r4, CFG_CACHELINE_SIZE
122         bgt     cache_post_dinvalidate
123         sync
124         blr
125
126 /* void cache_post_dstore (void *p, int size)
127  */
128 cache_post_dstore:
129         dcbst   r0, r3
130         addi    r3, r3, CFG_CACHELINE_SIZE
131         subic.  r4, r4, CFG_CACHELINE_SIZE
132         bgt     cache_post_dstore
133         sync
134         blr
135
136 /* void cache_post_dtouch (void *p, int size)
137  */
138 cache_post_dtouch:
139         dcbt    r0, r3
140         addi    r3, r3, CFG_CACHELINE_SIZE
141         subic.  r4, r4, CFG_CACHELINE_SIZE
142         bgt     cache_post_dtouch
143         sync
144         blr
145
146 /* void cache_post_iinvalidate (void)
147  */
148 cache_post_iinvalidate:
149         iccci   r0, r0
150         sync
151         blr
152
153 /* void cache_post_memset (void *p, int val, int size)
154  */
155 cache_post_memset:
156         mtctr   r5
157 1:
158         stb     r4, 0(r3)
159         addi    r3, r3, 1
160         bdnz    1b
161         blr
162
163 /* int cache_post_check (void *p, int size)
164  */
165 cache_post_check:
166         mtctr   r4
167 1:
168         lbz     r0, 0(r3)
169         addi    r3, r3, 1
170         cmpwi   r0, 0xff
171         bne     2f
172         bdnz    1b
173         li      r3, 0
174         blr
175 2:
176         li      r3, -1
177         blr
178
179 #define CACHE_POST_DISABLE()            \
180         mr      r3, r10;                \
181         bl      cache_post_disable
182
183 #define CACHE_POST_WT()                 \
184         mr      r3, r10;                \
185         bl      cache_post_wt
186
187 #define CACHE_POST_WB()                 \
188         mr      r3, r10;                \
189         bl      cache_post_wb
190
191 #define CACHE_POST_DINVALIDATE()        \
192         mr      r3, r11;                \
193         mr      r4, r12;                \
194         bl      cache_post_dinvalidate
195
196 #define CACHE_POST_DFLUSH()             \
197         mr      r3, r11;                \
198         mr      r4, r12;                \
199         bl      cache_post_dflush
200
201 #define CACHE_POST_DSTORE()             \
202         mr      r3, r11;                \
203         mr      r4, r12;                \
204         bl      cache_post_dstore
205
206 #define CACHE_POST_DTOUCH()             \
207         mr      r3, r11;                \
208         mr      r4, r12;                \
209         bl      cache_post_dtouch
210
211 #define CACHE_POST_IINVALIDATE()        \
212         bl      cache_post_iinvalidate
213
214 #define CACHE_POST_MEMSET(val)          \
215         mr      r3, r11;                \
216         li      r4, val;                \
217         mr      r5, r12;                \
218         bl      cache_post_memset
219
220 #define CACHE_POST_CHECK()              \
221         mr      r3, r11;                \
222         mr      r4, r12;                \
223         bl      cache_post_check;       \
224         mr      r13, r3
225
226 /*
227  * Write and read 0xff pattern with caching enabled.
228  */
229         .global cache_post_test1
230 cache_post_test1:
231         mflr    r9
232         mr      r10, r3         /* tlb          */
233         mr      r11, r4         /* p            */
234         mr      r12, r5         /* size         */
235
236         CACHE_POST_WB()
237         CACHE_POST_DINVALIDATE()
238
239         /* Write the negative pattern to the test area */
240         CACHE_POST_MEMSET(0xff)
241
242         /* Read the test area */
243         CACHE_POST_CHECK()
244
245         CACHE_POST_DINVALIDATE()
246         CACHE_POST_DISABLE()
247
248         mr      r3, r13
249         mtlr    r9
250         blr
251
252 /*
253  * Write zeroes with caching enabled.
254  * Write 0xff pattern with caching disabled.
255  * Read 0xff pattern with caching enabled.
256  */
257         .global cache_post_test2
258 cache_post_test2:
259         mflr    r9
260         mr      r10, r3         /* tlb          */
261         mr      r11, r4         /* p            */
262         mr      r12, r5         /* size         */
263
264         CACHE_POST_WB()
265         CACHE_POST_DINVALIDATE()
266
267         /* Write the zero pattern to the test area */
268         CACHE_POST_MEMSET(0)
269
270         CACHE_POST_DINVALIDATE()
271         CACHE_POST_DISABLE()
272
273         /* Write the negative pattern to the test area */
274         CACHE_POST_MEMSET(0xff)
275
276         CACHE_POST_WB()
277
278         /* Read the test area */
279         CACHE_POST_CHECK()
280
281         CACHE_POST_DINVALIDATE()
282         CACHE_POST_DISABLE()
283
284         mr      r3, r13
285         mtlr    r9
286         blr
287
288 /*
289  * Write-through mode test.
290  * Write zeroes, store the cache, write 0xff pattern.
291  * Invalidate the cache.
292  * Check that 0xff pattern is read.
293  */
294         .global cache_post_test3
295 cache_post_test3:
296         mflr    r9
297         mr      r10, r3         /* tlb          */
298         mr      r11, r4         /* p            */
299         mr      r12, r5         /* size         */
300
301         CACHE_POST_WT()
302         CACHE_POST_DINVALIDATE()
303
304         /* Cache the test area */
305         CACHE_POST_DTOUCH()
306
307         /* Write the zero pattern to the test area */
308         CACHE_POST_MEMSET(0)
309
310         CACHE_POST_DSTORE()
311
312         /* Write the negative pattern to the test area */
313         CACHE_POST_MEMSET(0xff)
314
315         CACHE_POST_DINVALIDATE()
316         CACHE_POST_DISABLE()
317
318         /* Read the test area */
319         CACHE_POST_CHECK()
320
321         mr      r3, r13
322         mtlr    r9
323         blr
324
325 /*
326  * Write-back mode test.
327  * Write 0xff pattern, store the cache, write zeroes.
328  * Invalidate the cache.
329  * Check that 0xff pattern is read.
330  */
331         .global cache_post_test4
332 cache_post_test4:
333         mflr    r9
334         mr      r10, r3         /* tlb          */
335         mr      r11, r4         /* p            */
336         mr      r12, r5         /* size         */
337
338         CACHE_POST_WB()
339         CACHE_POST_DINVALIDATE()
340
341         /* Cache the test area */
342         CACHE_POST_DTOUCH()
343
344         /* Write the negative pattern to the test area */
345         CACHE_POST_MEMSET(0xff)
346
347         CACHE_POST_DSTORE()
348
349         /* Write the zero pattern to the test area */
350         CACHE_POST_MEMSET(0)
351
352         CACHE_POST_DINVALIDATE()
353         CACHE_POST_DISABLE()
354
355         /* Read the test area */
356         CACHE_POST_CHECK()
357
358         mr      r3, r13
359         mtlr    r9
360         blr
361
362 /*
363  * Load the test instructions into the instruction cache.
364  * Replace the test instructions.
365  * Check that the original instructions are executed.
366  */
367         .global cache_post_test5
368 cache_post_test5:
369         mflr    r9
370         mr      r10, r3         /* tlb          */
371         mr      r11, r4         /* p            */
372         mr      r12, r5         /* size         */
373
374         CACHE_POST_WT()
375         CACHE_POST_IINVALIDATE()
376
377         /* Compute r13 = cache_post_test_inst */
378         bl      cache_post_test5_reloc
379 cache_post_test5_reloc:
380         mflr    r13
381         lis     r0, (cache_post_test_inst - cache_post_test5_reloc)@h
382         ori     r0, r0, (cache_post_test_inst - cache_post_test5_reloc)@l
383         add     r13, r13, r0
384
385         /* Copy the test instructions to the test area */
386         lwz     r0, 0(r13)
387         stw     r0, 0(r11)
388         lwz     r0, 8(r13)
389         stw     r0, 4(r11)
390         sync
391
392         /* Invalidate the cache line */
393         icbi    r0, r11
394         sync
395         isync
396
397         /* Execute the test instructions */
398         mtlr    r11
399         blrl
400
401         /* Replace the test instruction */
402         lwz     r0, 4(r13)
403         stw     r0, 0(r11)
404         sync
405
406         /* Do not invalidate the cache line */
407         isync
408
409         /* Execute the test instructions */
410         mtlr    r11
411         blrl
412         mr      r13, r3
413
414         CACHE_POST_IINVALIDATE()
415         CACHE_POST_DINVALIDATE()
416         CACHE_POST_DISABLE()
417
418         mr      r3, r13
419         mtlr    r9
420         blr
421
422 /*
423  * Load the test instructions into the instruction cache.
424  * Replace the test instructions and invalidate the cache.
425  * Check that the replaced instructions are executed.
426  */
427         .global cache_post_test6
428 cache_post_test6:
429         mflr    r9
430         mr      r10, r3         /* tlb          */
431         mr      r11, r4         /* p            */
432         mr      r12, r5         /* size         */
433
434         CACHE_POST_WT()
435         CACHE_POST_IINVALIDATE()
436
437         /* Compute r13 = cache_post_test_inst */
438         bl      cache_post_test6_reloc
439 cache_post_test6_reloc:
440         mflr    r13
441         lis     r0, (cache_post_test_inst - cache_post_test6_reloc)@h
442         ori     r0, r0, (cache_post_test_inst - cache_post_test6_reloc)@l
443         add     r13, r13, r0
444
445         /* Copy the test instructions to the test area */
446         lwz     r0, 4(r13)
447         stw     r0, 0(r11)
448         lwz     r0, 8(r13)
449         stw     r0, 4(r11)
450         sync
451
452         /* Invalidate the cache line */
453         icbi    r0, r11
454         sync
455         isync
456
457         /* Execute the test instructions */
458         mtlr    r11
459         blrl
460
461         /* Replace the test instruction */
462         lwz     r0, 0(r13)
463         stw     r0, 0(r11)
464         sync
465
466         /* Invalidate the cache line */
467         icbi    r0, r11
468         sync
469         isync
470
471         /* Execute the test instructions */
472         mtlr    r11
473         blrl
474         mr      r13, r3
475
476         CACHE_POST_IINVALIDATE()
477         CACHE_POST_DINVALIDATE()
478         CACHE_POST_DISABLE()
479
480         mr      r3, r13
481         mtlr    r9
482         blr
483
484 /* Test instructions.
485  */
486 cache_post_test_inst:
487         li      r3, 0
488         li      r3, -1
489         blr
490
491 #endif /* CONFIG_POST & CFG_POST_CACHE */
492 #endif /* CONFIG_POST */