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