blob: d5cb075d6b57074cdf7cf8177664b2be1e27c9d9 [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
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
Stefan Roeseeb2b4012007-08-14 14:39:44 +020040 /*
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
Sergei Poselenovb4489622007-07-05 08:17:37 +020047/* void cache_post_disable (int tlb)
48 */
49cache_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 */
59cache_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 */
70cache_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
Stefan Roeseeb2b4012007-08-14 14:39:44 +020078#else
79/* void cache_post_disable (int tlb)
80 */
81cache_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 */
91cache_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 */
104cache_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
Sergei Poselenovb4489622007-07-05 08:17:37 +0200115
116/* void cache_post_dinvalidate (void *p, int size)
117 */
118cache_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 */
128cache_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 */
138cache_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 */
148cache_post_iinvalidate:
149 iccci r0, r0
150 sync
151 blr
152
153/* void cache_post_memset (void *p, int val, int size)
154 */
155cache_post_memset:
156 mtctr r5
1571:
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 */
165cache_post_check:
166 mtctr r4
1671:
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
1752:
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
230cache_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
258cache_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
295cache_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
332cache_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
368cache_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
379cache_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
428cache_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
439cache_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.
Wolfgang Denk4ef218f2007-07-10 00:01:28 +0200485 */
Sergei Poselenovb4489622007-07-05 08:17:37 +0200486cache_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 */