Merge commit 'upstream/master'
[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 /* void cache_post_disable (int tlb)
41  */
42 cache_post_disable:
43         tlbre   r0, r3, 0x0002
44         ori     r0, r0, TLB_WORD2_I_ENABLE@l
45         tlbwe   r0, r3, 0x0002
46         sync
47         isync
48         blr
49
50 /* void cache_post_wt (int tlb)
51  */
52 cache_post_wt:
53         tlbre   r0, r3, 0x0002
54         ori     r0, r0, TLB_WORD2_W_ENABLE@l
55         andi.   r0, r0, ~TLB_WORD2_I_ENABLE@l
56         tlbwe   r0, r3, 0x0002
57         sync
58         isync
59         blr
60
61 /* void cache_post_wb (int tlb)
62  */
63 cache_post_wb:
64         tlbre   r0, r3, 0x0002
65         andi.   r0, r0, ~TLB_WORD2_W_ENABLE@l
66         andi.   r0, r0, ~TLB_WORD2_I_ENABLE@l
67         tlbwe   r0, r3, 0x0002
68         sync
69         isync
70         blr
71
72 /* void cache_post_dinvalidate (void *p, int size)
73  */
74 cache_post_dinvalidate:
75         dcbi    r0, r3
76         addi    r3, r3, CFG_CACHELINE_SIZE
77         subic.  r4, r4, CFG_CACHELINE_SIZE
78         bgt     cache_post_dinvalidate
79         sync
80         blr
81
82 /* void cache_post_dstore (void *p, int size)
83  */
84 cache_post_dstore:
85         dcbst   r0, r3
86         addi    r3, r3, CFG_CACHELINE_SIZE
87         subic.  r4, r4, CFG_CACHELINE_SIZE
88         bgt     cache_post_dstore
89         sync
90         blr
91
92 /* void cache_post_dtouch (void *p, int size)
93  */
94 cache_post_dtouch:
95         dcbt    r0, r3
96         addi    r3, r3, CFG_CACHELINE_SIZE
97         subic.  r4, r4, CFG_CACHELINE_SIZE
98         bgt     cache_post_dtouch
99         sync
100         blr
101
102 /* void cache_post_iinvalidate (void)
103  */
104 cache_post_iinvalidate:
105         iccci   r0, r0
106         sync
107         blr
108
109 /* void cache_post_memset (void *p, int val, int size)
110  */
111 cache_post_memset:
112         mtctr   r5
113 1:
114         stb     r4, 0(r3)
115         addi    r3, r3, 1
116         bdnz    1b
117         blr
118
119 /* int cache_post_check (void *p, int size)
120  */
121 cache_post_check:
122         mtctr   r4
123 1:
124         lbz     r0, 0(r3)
125         addi    r3, r3, 1
126         cmpwi   r0, 0xff
127         bne     2f
128         bdnz    1b
129         li      r3, 0
130         blr
131 2:
132         li      r3, -1
133         blr
134
135 #define CACHE_POST_DISABLE()            \
136         mr      r3, r10;                \
137         bl      cache_post_disable
138
139 #define CACHE_POST_WT()                 \
140         mr      r3, r10;                \
141         bl      cache_post_wt
142
143 #define CACHE_POST_WB()                 \
144         mr      r3, r10;                \
145         bl      cache_post_wb
146
147 #define CACHE_POST_DINVALIDATE()        \
148         mr      r3, r11;                \
149         mr      r4, r12;                \
150         bl      cache_post_dinvalidate
151
152 #define CACHE_POST_DFLUSH()             \
153         mr      r3, r11;                \
154         mr      r4, r12;                \
155         bl      cache_post_dflush
156
157 #define CACHE_POST_DSTORE()             \
158         mr      r3, r11;                \
159         mr      r4, r12;                \
160         bl      cache_post_dstore
161
162 #define CACHE_POST_DTOUCH()             \
163         mr      r3, r11;                \
164         mr      r4, r12;                \
165         bl      cache_post_dtouch
166
167 #define CACHE_POST_IINVALIDATE()        \
168         bl      cache_post_iinvalidate
169
170 #define CACHE_POST_MEMSET(val)          \
171         mr      r3, r11;                \
172         li      r4, val;                \
173         mr      r5, r12;                \
174         bl      cache_post_memset
175
176 #define CACHE_POST_CHECK()              \
177         mr      r3, r11;                \
178         mr      r4, r12;                \
179         bl      cache_post_check;       \
180         mr      r13, r3
181
182 /*
183  * Write and read 0xff pattern with caching enabled.
184  */
185         .global cache_post_test1
186 cache_post_test1:
187         mflr    r9
188         mr      r10, r3         /* tlb          */
189         mr      r11, r4         /* p            */
190         mr      r12, r5         /* size         */
191
192         CACHE_POST_WB()
193         CACHE_POST_DINVALIDATE()
194
195         /* Write the negative pattern to the test area */
196         CACHE_POST_MEMSET(0xff)
197
198         /* Read the test area */
199         CACHE_POST_CHECK()
200
201         CACHE_POST_DINVALIDATE()
202         CACHE_POST_DISABLE()
203
204         mr      r3, r13
205         mtlr    r9
206         blr
207
208 /*
209  * Write zeroes with caching enabled.
210  * Write 0xff pattern with caching disabled.
211  * Read 0xff pattern with caching enabled.
212  */
213         .global cache_post_test2
214 cache_post_test2:
215         mflr    r9
216         mr      r10, r3         /* tlb          */
217         mr      r11, r4         /* p            */
218         mr      r12, r5         /* size         */
219
220         CACHE_POST_WB()
221         CACHE_POST_DINVALIDATE()
222
223         /* Write the zero pattern to the test area */
224         CACHE_POST_MEMSET(0)
225
226         CACHE_POST_DINVALIDATE()
227         CACHE_POST_DISABLE()
228
229         /* Write the negative pattern to the test area */
230         CACHE_POST_MEMSET(0xff)
231
232         CACHE_POST_WB()
233
234         /* Read the test area */
235         CACHE_POST_CHECK()
236
237         CACHE_POST_DINVALIDATE()
238         CACHE_POST_DISABLE()
239
240         mr      r3, r13
241         mtlr    r9
242         blr
243
244 /*
245  * Write-through mode test.
246  * Write zeroes, store the cache, write 0xff pattern.
247  * Invalidate the cache.
248  * Check that 0xff pattern is read.
249  */
250         .global cache_post_test3
251 cache_post_test3:
252         mflr    r9
253         mr      r10, r3         /* tlb          */
254         mr      r11, r4         /* p            */
255         mr      r12, r5         /* size         */
256
257         CACHE_POST_WT()
258         CACHE_POST_DINVALIDATE()
259
260         /* Cache the test area */
261         CACHE_POST_DTOUCH()
262
263         /* Write the zero pattern to the test area */
264         CACHE_POST_MEMSET(0)
265
266         CACHE_POST_DSTORE()
267
268         /* Write the negative pattern to the test area */
269         CACHE_POST_MEMSET(0xff)
270
271         CACHE_POST_DINVALIDATE()
272         CACHE_POST_DISABLE()
273
274         /* Read the test area */
275         CACHE_POST_CHECK()
276
277         mr      r3, r13
278         mtlr    r9
279         blr
280
281 /*
282  * Write-back mode test.
283  * Write 0xff pattern, store the cache, write zeroes.
284  * Invalidate the cache.
285  * Check that 0xff pattern is read.
286  */
287         .global cache_post_test4
288 cache_post_test4:
289         mflr    r9
290         mr      r10, r3         /* tlb          */
291         mr      r11, r4         /* p            */
292         mr      r12, r5         /* size         */
293
294         CACHE_POST_WB()
295         CACHE_POST_DINVALIDATE()
296
297         /* Cache the test area */
298         CACHE_POST_DTOUCH()
299
300         /* Write the negative pattern to the test area */
301         CACHE_POST_MEMSET(0xff)
302
303         CACHE_POST_DSTORE()
304
305         /* Write the zero pattern to the test area */
306         CACHE_POST_MEMSET(0)
307
308         CACHE_POST_DINVALIDATE()
309         CACHE_POST_DISABLE()
310
311         /* Read the test area */
312         CACHE_POST_CHECK()
313
314         mr      r3, r13
315         mtlr    r9
316         blr
317
318 /*
319  * Load the test instructions into the instruction cache.
320  * Replace the test instructions.
321  * Check that the original instructions are executed.
322  */
323         .global cache_post_test5
324 cache_post_test5:
325         mflr    r9
326         mr      r10, r3         /* tlb          */
327         mr      r11, r4         /* p            */
328         mr      r12, r5         /* size         */
329
330         CACHE_POST_WT()
331         CACHE_POST_IINVALIDATE()
332
333         /* Compute r13 = cache_post_test_inst */
334         bl      cache_post_test5_reloc
335 cache_post_test5_reloc:
336         mflr    r13
337         lis     r0, (cache_post_test_inst - cache_post_test5_reloc)@h
338         ori     r0, r0, (cache_post_test_inst - cache_post_test5_reloc)@l
339         add     r13, r13, r0
340
341         /* Copy the test instructions to the test area */
342         lwz     r0, 0(r13)
343         stw     r0, 0(r11)
344         lwz     r0, 8(r13)
345         stw     r0, 4(r11)
346         sync
347
348         /* Invalidate the cache line */
349         icbi    r0, r11
350         sync
351         isync
352
353         /* Execute the test instructions */
354         mtlr    r11
355         blrl
356
357         /* Replace the test instruction */
358         lwz     r0, 4(r13)
359         stw     r0, 0(r11)
360         sync
361
362         /* Do not invalidate the cache line */
363         isync
364
365         /* Execute the test instructions */
366         mtlr    r11
367         blrl
368         mr      r13, r3
369
370         CACHE_POST_IINVALIDATE()
371         CACHE_POST_DINVALIDATE()
372         CACHE_POST_DISABLE()
373
374         mr      r3, r13
375         mtlr    r9
376         blr
377
378 /*
379  * Load the test instructions into the instruction cache.
380  * Replace the test instructions and invalidate the cache.
381  * Check that the replaced instructions are executed.
382  */
383         .global cache_post_test6
384 cache_post_test6:
385         mflr    r9
386         mr      r10, r3         /* tlb          */
387         mr      r11, r4         /* p            */
388         mr      r12, r5         /* size         */
389
390         CACHE_POST_WT()
391         CACHE_POST_IINVALIDATE()
392
393         /* Compute r13 = cache_post_test_inst */
394         bl      cache_post_test6_reloc
395 cache_post_test6_reloc:
396         mflr    r13
397         lis     r0, (cache_post_test_inst - cache_post_test6_reloc)@h
398         ori     r0, r0, (cache_post_test_inst - cache_post_test6_reloc)@l
399         add     r13, r13, r0
400
401         /* Copy the test instructions to the test area */
402         lwz     r0, 4(r13)
403         stw     r0, 0(r11)
404         lwz     r0, 8(r13)
405         stw     r0, 4(r11)
406         sync
407
408         /* Invalidate the cache line */
409         icbi    r0, r11
410         sync
411         isync
412
413         /* Execute the test instructions */
414         mtlr    r11
415         blrl
416
417         /* Replace the test instruction */
418         lwz     r0, 0(r13)
419         stw     r0, 0(r11)
420         sync
421
422         /* Invalidate the cache line */
423         icbi    r0, r11
424         sync
425         isync
426
427         /* Execute the test instructions */
428         mtlr    r11
429         blrl
430         mr      r13, r3
431
432         CACHE_POST_IINVALIDATE()
433         CACHE_POST_DINVALIDATE()
434         CACHE_POST_DISABLE()
435
436         mr      r3, r13
437         mtlr    r9
438         blr
439
440 /* Test instructions.
441  */
442 cache_post_test_inst:
443         li      r3, 0
444         li      r3, -1
445         blr
446
447 #endif /* CONFIG_POST & CFG_POST_CACHE */
448 #endif /* CONFIG_POST */