blob: 3f3e5850f9cc13bbcaf45e7d3ee1303df51933a0 [file] [log] [blame]
Sergei Poselenovb4489622007-07-05 08:17:37 +02001/*
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
Sergei Poselenovb4489622007-07-05 08:17:37 +020028#include <post.h>
29#include <ppc_asm.tmpl>
30#include <ppc_defs.h>
31#include <asm/cache.h>
32#include <asm/mmu.h>
33
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020034#if CONFIG_POST & CONFIG_SYS_POST_CACHE
Sergei Poselenovb4489622007-07-05 08:17:37 +020035
36 .text
37
Stefan Roeseeb2b4012007-08-14 14:39:44 +020038 /*
39 * All 44x variants deal with cache management differently
40 * because they have the address translation always enabled.
41 * The 40x ppc's don't use address translation in U-Boot at all,
42 * so we have to distinguish here between 40x and 44x.
43 */
44#ifdef CONFIG_440
Sergei Poselenovb4489622007-07-05 08:17:37 +020045/* void cache_post_disable (int tlb)
46 */
47cache_post_disable:
48 tlbre r0, r3, 0x0002
49 ori r0, r0, TLB_WORD2_I_ENABLE@l
50 tlbwe r0, r3, 0x0002
51 sync
52 isync
53 blr
54
55/* void cache_post_wt (int tlb)
56 */
57cache_post_wt:
58 tlbre r0, r3, 0x0002
59 ori r0, r0, TLB_WORD2_W_ENABLE@l
60 andi. r0, r0, ~TLB_WORD2_I_ENABLE@l
61 tlbwe r0, r3, 0x0002
62 sync
63 isync
64 blr
65
66/* void cache_post_wb (int tlb)
67 */
68cache_post_wb:
69 tlbre r0, r3, 0x0002
70 andi. r0, r0, ~TLB_WORD2_W_ENABLE@l
71 andi. r0, r0, ~TLB_WORD2_I_ENABLE@l
72 tlbwe r0, r3, 0x0002
73 sync
74 isync
75 blr
Stefan Roeseeb2b4012007-08-14 14:39:44 +020076#else
77/* void cache_post_disable (int tlb)
78 */
79cache_post_disable:
80 lis r0, 0x0000
81 ori r0, r0, 0x0000
82 mtdccr r0
83 sync
84 isync
85 blr
86
87/* void cache_post_wt (int tlb)
88 */
89cache_post_wt:
90 lis r0, 0x8000
91 ori r0, r0, 0x0000
92 mtdccr r0
93 lis r0, 0x8000
94 ori r0, r0, 0x0000
95 mtdcwr r0
96 sync
97 isync
98 blr
99
100/* void cache_post_wb (int tlb)
101 */
102cache_post_wb:
103 lis r0, 0x8000
104 ori r0, r0, 0x0000
105 mtdccr r0
106 lis r0, 0x0000
107 ori r0, r0, 0x0000
108 mtdcwr r0
109 sync
110 isync
111 blr
112#endif
Sergei Poselenovb4489622007-07-05 08:17:37 +0200113
114/* void cache_post_dinvalidate (void *p, int size)
115 */
116cache_post_dinvalidate:
117 dcbi r0, r3
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200118 addi r3, r3, CONFIG_SYS_CACHELINE_SIZE
119 subic. r4, r4, CONFIG_SYS_CACHELINE_SIZE
Sergei Poselenovb4489622007-07-05 08:17:37 +0200120 bgt cache_post_dinvalidate
121 sync
122 blr
123
124/* void cache_post_dstore (void *p, int size)
125 */
126cache_post_dstore:
127 dcbst r0, r3
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200128 addi r3, r3, CONFIG_SYS_CACHELINE_SIZE
129 subic. r4, r4, CONFIG_SYS_CACHELINE_SIZE
Sergei Poselenovb4489622007-07-05 08:17:37 +0200130 bgt cache_post_dstore
131 sync
132 blr
133
134/* void cache_post_dtouch (void *p, int size)
135 */
136cache_post_dtouch:
137 dcbt r0, r3
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200138 addi r3, r3, CONFIG_SYS_CACHELINE_SIZE
139 subic. r4, r4, CONFIG_SYS_CACHELINE_SIZE
Sergei Poselenovb4489622007-07-05 08:17:37 +0200140 bgt cache_post_dtouch
141 sync
142 blr
143
144/* void cache_post_iinvalidate (void)
145 */
146cache_post_iinvalidate:
147 iccci r0, r0
148 sync
149 blr
150
151/* void cache_post_memset (void *p, int val, int size)
152 */
153cache_post_memset:
154 mtctr r5
1551:
156 stb r4, 0(r3)
157 addi r3, r3, 1
158 bdnz 1b
159 blr
160
161/* int cache_post_check (void *p, int size)
162 */
163cache_post_check:
164 mtctr r4
1651:
166 lbz r0, 0(r3)
167 addi r3, r3, 1
168 cmpwi r0, 0xff
169 bne 2f
170 bdnz 1b
171 li r3, 0
172 blr
1732:
174 li r3, -1
175 blr
176
177#define CACHE_POST_DISABLE() \
178 mr r3, r10; \
179 bl cache_post_disable
180
181#define CACHE_POST_WT() \
182 mr r3, r10; \
183 bl cache_post_wt
184
185#define CACHE_POST_WB() \
186 mr r3, r10; \
187 bl cache_post_wb
188
189#define CACHE_POST_DINVALIDATE() \
190 mr r3, r11; \
191 mr r4, r12; \
192 bl cache_post_dinvalidate
193
194#define CACHE_POST_DFLUSH() \
195 mr r3, r11; \
196 mr r4, r12; \
197 bl cache_post_dflush
198
199#define CACHE_POST_DSTORE() \
200 mr r3, r11; \
201 mr r4, r12; \
202 bl cache_post_dstore
203
204#define CACHE_POST_DTOUCH() \
205 mr r3, r11; \
206 mr r4, r12; \
207 bl cache_post_dtouch
208
209#define CACHE_POST_IINVALIDATE() \
210 bl cache_post_iinvalidate
211
212#define CACHE_POST_MEMSET(val) \
213 mr r3, r11; \
214 li r4, val; \
215 mr r5, r12; \
216 bl cache_post_memset
217
218#define CACHE_POST_CHECK() \
219 mr r3, r11; \
220 mr r4, r12; \
221 bl cache_post_check; \
222 mr r13, r3
223
224/*
225 * Write and read 0xff pattern with caching enabled.
226 */
227 .global cache_post_test1
228cache_post_test1:
229 mflr r9
230 mr r10, r3 /* tlb */
231 mr r11, r4 /* p */
232 mr r12, r5 /* size */
233
234 CACHE_POST_WB()
235 CACHE_POST_DINVALIDATE()
236
237 /* Write the negative pattern to the test area */
238 CACHE_POST_MEMSET(0xff)
239
240 /* Read the test area */
241 CACHE_POST_CHECK()
242
243 CACHE_POST_DINVALIDATE()
244 CACHE_POST_DISABLE()
245
246 mr r3, r13
247 mtlr r9
248 blr
249
250/*
251 * Write zeroes with caching enabled.
252 * Write 0xff pattern with caching disabled.
253 * Read 0xff pattern with caching enabled.
254 */
255 .global cache_post_test2
256cache_post_test2:
257 mflr r9
258 mr r10, r3 /* tlb */
259 mr r11, r4 /* p */
260 mr r12, r5 /* size */
261
262 CACHE_POST_WB()
263 CACHE_POST_DINVALIDATE()
264
265 /* Write the zero pattern to the test area */
266 CACHE_POST_MEMSET(0)
267
268 CACHE_POST_DINVALIDATE()
269 CACHE_POST_DISABLE()
270
271 /* Write the negative pattern to the test area */
272 CACHE_POST_MEMSET(0xff)
273
274 CACHE_POST_WB()
275
276 /* Read the test area */
277 CACHE_POST_CHECK()
278
279 CACHE_POST_DINVALIDATE()
280 CACHE_POST_DISABLE()
281
282 mr r3, r13
283 mtlr r9
284 blr
285
286/*
287 * Write-through mode test.
288 * Write zeroes, store the cache, write 0xff pattern.
289 * Invalidate the cache.
290 * Check that 0xff pattern is read.
291 */
292 .global cache_post_test3
293cache_post_test3:
294 mflr r9
295 mr r10, r3 /* tlb */
296 mr r11, r4 /* p */
297 mr r12, r5 /* size */
298
299 CACHE_POST_WT()
300 CACHE_POST_DINVALIDATE()
301
302 /* Cache the test area */
303 CACHE_POST_DTOUCH()
304
305 /* Write the zero pattern to the test area */
306 CACHE_POST_MEMSET(0)
307
308 CACHE_POST_DSTORE()
309
310 /* Write the negative pattern to the test area */
311 CACHE_POST_MEMSET(0xff)
312
313 CACHE_POST_DINVALIDATE()
314 CACHE_POST_DISABLE()
315
316 /* Read the test area */
317 CACHE_POST_CHECK()
318
319 mr r3, r13
320 mtlr r9
321 blr
322
323/*
324 * Write-back mode test.
325 * Write 0xff pattern, store the cache, write zeroes.
326 * Invalidate the cache.
327 * Check that 0xff pattern is read.
328 */
329 .global cache_post_test4
330cache_post_test4:
331 mflr r9
332 mr r10, r3 /* tlb */
333 mr r11, r4 /* p */
334 mr r12, r5 /* size */
335
336 CACHE_POST_WB()
337 CACHE_POST_DINVALIDATE()
338
339 /* Cache the test area */
340 CACHE_POST_DTOUCH()
341
342 /* Write the negative pattern to the test area */
343 CACHE_POST_MEMSET(0xff)
344
345 CACHE_POST_DSTORE()
346
347 /* Write the zero pattern to the test area */
348 CACHE_POST_MEMSET(0)
349
350 CACHE_POST_DINVALIDATE()
351 CACHE_POST_DISABLE()
352
353 /* Read the test area */
354 CACHE_POST_CHECK()
355
356 mr r3, r13
357 mtlr r9
358 blr
359
360/*
361 * Load the test instructions into the instruction cache.
362 * Replace the test instructions.
363 * Check that the original instructions are executed.
364 */
365 .global cache_post_test5
366cache_post_test5:
367 mflr r9
368 mr r10, r3 /* tlb */
369 mr r11, r4 /* p */
370 mr r12, r5 /* size */
371
372 CACHE_POST_WT()
373 CACHE_POST_IINVALIDATE()
374
375 /* Compute r13 = cache_post_test_inst */
376 bl cache_post_test5_reloc
377cache_post_test5_reloc:
378 mflr r13
379 lis r0, (cache_post_test_inst - cache_post_test5_reloc)@h
380 ori r0, r0, (cache_post_test_inst - cache_post_test5_reloc)@l
381 add r13, r13, r0
382
383 /* Copy the test instructions to the test area */
384 lwz r0, 0(r13)
385 stw r0, 0(r11)
386 lwz r0, 8(r13)
387 stw r0, 4(r11)
388 sync
389
390 /* Invalidate the cache line */
391 icbi r0, r11
392 sync
393 isync
394
395 /* Execute the test instructions */
396 mtlr r11
397 blrl
398
399 /* Replace the test instruction */
400 lwz r0, 4(r13)
401 stw r0, 0(r11)
402 sync
403
404 /* Do not invalidate the cache line */
405 isync
406
407 /* Execute the test instructions */
408 mtlr r11
409 blrl
410 mr r13, r3
411
412 CACHE_POST_IINVALIDATE()
413 CACHE_POST_DINVALIDATE()
414 CACHE_POST_DISABLE()
415
416 mr r3, r13
417 mtlr r9
418 blr
419
420/*
421 * Load the test instructions into the instruction cache.
422 * Replace the test instructions and invalidate the cache.
423 * Check that the replaced instructions are executed.
424 */
425 .global cache_post_test6
426cache_post_test6:
427 mflr r9
428 mr r10, r3 /* tlb */
429 mr r11, r4 /* p */
430 mr r12, r5 /* size */
431
432 CACHE_POST_WT()
433 CACHE_POST_IINVALIDATE()
434
435 /* Compute r13 = cache_post_test_inst */
436 bl cache_post_test6_reloc
437cache_post_test6_reloc:
438 mflr r13
439 lis r0, (cache_post_test_inst - cache_post_test6_reloc)@h
440 ori r0, r0, (cache_post_test_inst - cache_post_test6_reloc)@l
441 add r13, r13, r0
442
443 /* Copy the test instructions to the test area */
444 lwz r0, 4(r13)
445 stw r0, 0(r11)
446 lwz r0, 8(r13)
447 stw r0, 4(r11)
448 sync
449
450 /* Invalidate the cache line */
451 icbi r0, r11
452 sync
453 isync
454
455 /* Execute the test instructions */
456 mtlr r11
457 blrl
458
459 /* Replace the test instruction */
460 lwz r0, 0(r13)
461 stw r0, 0(r11)
462 sync
463
464 /* Invalidate the cache line */
465 icbi r0, r11
466 sync
467 isync
468
469 /* Execute the test instructions */
470 mtlr r11
471 blrl
472 mr r13, r3
473
474 CACHE_POST_IINVALIDATE()
475 CACHE_POST_DINVALIDATE()
476 CACHE_POST_DISABLE()
477
478 mr r3, r13
479 mtlr r9
480 blr
481
482/* Test instructions.
Wolfgang Denk4ef218f2007-07-10 00:01:28 +0200483 */
Sergei Poselenovb4489622007-07-05 08:17:37 +0200484cache_post_test_inst:
485 li r3, 0
486 li r3, -1
487 blr
488
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200489#endif /* CONFIG_POST & CONFIG_SYS_POST_CACHE */