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