]>
Commit | Line | Data |
---|---|---|
9b94ac61 SR |
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. */ | |
6d0f6bcf JCPV |
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 | |
9b94ac61 SR |
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 | |
8deafdc6 | 169 | .globl dcache_enable |
9b94ac61 SR |
170 | .globl icache_disable |
171 | .globl icache_enable | |
172 | dcache_disable: | |
8deafdc6 | 173 | dcache_enable: |
9b94ac61 SR |
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 */ |