]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/powerpc/cpu/ppc4xx/cache.S
Merge branch 'master' of git://git.denx.de/u-boot-arm
[karo-tx-uboot.git] / arch / powerpc / cpu / ppc4xx / cache.S
1 /*
2  * This file contains miscellaneous low-level functions.
3  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
4  *
5  * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
6  * and Paul Mackerras.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version
11  * 2 of the License, or (at your option) any later version.
12  *
13  */
14
15 #include <config.h>
16 #include <config.h>
17 #include <ppc4xx.h>
18 #include <ppc_asm.tmpl>
19 #include <ppc_defs.h>
20 #include <asm/cache.h>
21 #include <asm/mmu.h>
22
23 /*
24  * Flush instruction cache.
25  */
26 _GLOBAL(invalidate_icache)
27         iccci   r0,r0
28         isync
29         blr
30
31 /*
32  * Write any modified data cache blocks out to memory
33  * and invalidate the corresponding instruction cache blocks.
34  *
35  * flush_icache_range(unsigned long start, unsigned long stop)
36  */
37 _GLOBAL(flush_icache_range)
38         li      r5,L1_CACHE_BYTES-1
39         andc    r3,r3,r5
40         subf    r4,r3,r4
41         add     r4,r4,r5
42         srwi.   r4,r4,L1_CACHE_SHIFT
43         beqlr
44         mtctr   r4
45         mr      r6,r3
46 1:      dcbst   0,r3
47         addi    r3,r3,L1_CACHE_BYTES
48         bdnz    1b
49         sync                            /* wait for dcbst's to get to ram */
50         mtctr   r4
51 2:      icbi    0,r6
52         addi    r6,r6,L1_CACHE_BYTES
53         bdnz    2b
54         sync                            /* additional sync needed on g4 */
55         isync
56         blr
57
58 /*
59  * Write any modified data cache blocks out to memory.
60  * Does not invalidate the corresponding cache lines (especially for
61  * any corresponding instruction cache).
62  *
63  * clean_dcache_range(unsigned long start, unsigned long stop)
64  */
65 _GLOBAL(clean_dcache_range)
66         li      r5,L1_CACHE_BYTES-1
67         andc    r3,r3,r5
68         subf    r4,r3,r4
69         add     r4,r4,r5
70         srwi.   r4,r4,L1_CACHE_SHIFT
71         beqlr
72         mtctr   r4
73
74 1:      dcbst   0,r3
75         addi    r3,r3,L1_CACHE_BYTES
76         bdnz    1b
77         sync                            /* wait for dcbst's to get to ram */
78         blr
79
80 /*
81  * Write any modified data cache blocks out to memory and invalidate them.
82  * Does not invalidate the corresponding instruction cache blocks.
83  *
84  * flush_dcache_range(unsigned long start, unsigned long stop)
85  */
86 _GLOBAL(flush_dcache_range)
87         li      r5,L1_CACHE_BYTES-1
88         andc    r3,r3,r5
89         subf    r4,r3,r4
90         add     r4,r4,r5
91         srwi.   r4,r4,L1_CACHE_SHIFT
92         beqlr
93         mtctr   r4
94
95 1:      dcbf    0,r3
96         addi    r3,r3,L1_CACHE_BYTES
97         bdnz    1b
98         sync                            /* wait for dcbst's to get to ram */
99         blr
100
101 /*
102  * Like above, but invalidate the D-cache.  This is used by the 8xx
103  * to invalidate the cache so the PPC core doesn't get stale data
104  * from the CPM (no cache snooping here :-).
105  *
106  * invalidate_dcache_range(unsigned long start, unsigned long stop)
107  */
108 _GLOBAL(invalidate_dcache_range)
109         li      r5,L1_CACHE_BYTES-1
110         andc    r3,r3,r5
111         subf    r4,r3,r4
112         add     r4,r4,r5
113         srwi.   r4,r4,L1_CACHE_SHIFT
114         beqlr
115         mtctr   r4
116
117 1:      dcbi    0,r3
118         addi    r3,r3,L1_CACHE_BYTES
119         bdnz    1b
120         sync                            /* wait for dcbi's to get to ram */
121         blr
122
123 /*
124  * 40x cores have 8K or 16K dcache and 32 byte line size.
125  * 44x has a 32K dcache and 32 byte line size.
126  * 8xx has 1, 2, 4, 8K variants.
127  * For now, cover the worst case of the 44x.
128  * Must be called with external interrupts disabled.
129  */
130 #define CACHE_NWAYS     64
131 #define CACHE_NLINES    32
132
133 _GLOBAL(flush_dcache)
134         li      r4,(2 * CACHE_NWAYS * CACHE_NLINES)
135         mtctr   r4
136         lis     r5,0
137 1:      lwz     r3,0(r5)                /* Load one word from every line */
138         addi    r5,r5,L1_CACHE_BYTES
139         bdnz    1b
140         sync
141         blr
142
143 _GLOBAL(invalidate_dcache)
144         addi    r6,0,0x0000             /* clear GPR 6 */
145         /* Do loop for # of dcache congruence classes. */
146         lis     r7,(CONFIG_SYS_DCACHE_SIZE / L1_CACHE_BYTES / 2)@ha     /* TBS for large sized cache */
147         ori     r7,r7,(CONFIG_SYS_DCACHE_SIZE / L1_CACHE_BYTES / 2)@l
148                                         /* NOTE: dccci invalidates both */
149         mtctr   r7                      /* ways in the D cache */
150 ..dcloop:
151         dccci   0,r6                    /* invalidate line */
152         addi    r6,r6,L1_CACHE_BYTES    /* bump to next line */
153         bdnz    ..dcloop
154         sync
155         blr
156
157 /*
158  * Cache functions.
159  *
160  * NOTE: currently the 440s run with dcache _disabled_ once relocated to DRAM,
161  * although for some cache-ralated calls stubs have to be provided to satisfy
162  * symbols resolution.
163  * Icache-related functions are used in POST framework.
164  *
165  */
166 #ifdef CONFIG_440
167
168        .globl  dcache_disable
169        .globl  dcache_enable
170        .globl  icache_disable
171        .globl  icache_enable
172 dcache_disable:
173 dcache_enable:
174 icache_disable:
175 icache_enable:
176         blr
177
178         .globl  dcache_status
179         .globl  icache_status
180 dcache_status:
181 icache_status:
182         mr      r3,  0
183         blr
184
185 #else /* CONFIG_440 */
186
187         .globl  icache_enable
188 icache_enable:
189         mflr    r8
190         bl      invalidate_icache
191         mtlr    r8
192         isync
193         addis   r3,r0, 0xc000         /* set bit 0 */
194         mticcr  r3
195         blr
196
197         .globl  icache_disable
198 icache_disable:
199         addis   r3,r0, 0x0000         /* clear bit 0 */
200         mticcr  r3
201         isync
202         blr
203
204         .globl  icache_status
205 icache_status:
206         mficcr  r3
207         srwi    r3, r3, 31      /* >>31 => select bit 0 */
208         blr
209
210         .globl  dcache_enable
211 dcache_enable:
212         mflr    r8
213         bl      invalidate_dcache
214         mtlr    r8
215         isync
216         addis   r3,r0, 0x8000         /* set bit 0 */
217         mtdccr  r3
218         blr
219
220         .globl  dcache_disable
221 dcache_disable:
222         mflr    r8
223         bl      flush_dcache
224         mtlr    r8
225         addis   r3,r0, 0x0000         /* clear bit 0 */
226         mtdccr  r3
227         blr
228
229         .globl  dcache_status
230 dcache_status:
231         mfdccr  r3
232         srwi    r3, r3, 31      /* >>31 => select bit 0 */
233         blr
234
235 #endif /* CONFIG_440 */