aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/kernel/l2cr.S
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/ppc/kernel/l2cr.S
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/ppc/kernel/l2cr.S')
-rw-r--r--arch/ppc/kernel/l2cr.S442
1 files changed, 442 insertions, 0 deletions
diff --git a/arch/ppc/kernel/l2cr.S b/arch/ppc/kernel/l2cr.S
new file mode 100644
index 000000000000..c39441048266
--- /dev/null
+++ b/arch/ppc/kernel/l2cr.S
@@ -0,0 +1,442 @@
1/*
2 L2CR functions
3 Copyright © 1997-1998 by PowerLogix R & D, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19/*
20 Thur, Dec. 12, 1998.
21 - First public release, contributed by PowerLogix.
22 ***********
23 Sat, Aug. 7, 1999.
24 - Terry: Made sure code disabled interrupts before running. (Previously
25 it was assumed interrupts were already disabled).
26 - Terry: Updated for tentative G4 support. 4MB of memory is now flushed
27 instead of 2MB. (Prob. only 3 is necessary).
28 - Terry: Updated for workaround to HID0[DPM] processor bug
29 during global invalidates.
30 ***********
31 Thu, July 13, 2000.
32 - Terry: Added isync to correct for an errata.
33
34 22 August 2001.
35 - DanM: Finally added the 7450 patch I've had for the past
36 several months. The L2CR is similar, but I'm going
37 to assume the user of this functions knows what they
38 are doing.
39
40 Author: Terry Greeniaus (tgree@phys.ualberta.ca)
41 Please e-mail updates to this file to me, thanks!
42*/
43#include <linux/config.h>
44#include <asm/processor.h>
45#include <asm/cputable.h>
46#include <asm/ppc_asm.h>
47#include <asm/cache.h>
48#include <asm/page.h>
49
50/* Usage:
51
52 When setting the L2CR register, you must do a few special
53 things. If you are enabling the cache, you must perform a
54 global invalidate. If you are disabling the cache, you must
55 flush the cache contents first. This routine takes care of
56 doing these things. When first enabling the cache, make sure
57 you pass in the L2CR you want, as well as passing in the
58 global invalidate bit set. A global invalidate will only be
59 performed if the L2I bit is set in applyThis. When enabling
60 the cache, you should also set the L2E bit in applyThis. If
61 you want to modify the L2CR contents after the cache has been
62 enabled, the recommended procedure is to first call
63 __setL2CR(0) to disable the cache and then call it again with
64 the new values for L2CR. Examples:
65
66 _setL2CR(0) - disables the cache
67 _setL2CR(0xB3A04000) - enables my G3 upgrade card:
68 - L2E set to turn on the cache
69 - L2SIZ set to 1MB
70 - L2CLK set to 1:1
71 - L2RAM set to pipelined synchronous late-write
72 - L2I set to perform a global invalidation
73 - L2OH set to 0.5 nS
74 - L2DF set because this upgrade card
75 requires it
76
77 A similar call should work for your card. You need to know
78 the correct setting for your card and then place them in the
79 fields I have outlined above. Other fields support optional
80 features, such as L2DO which caches only data, or L2TS which
81 causes cache pushes from the L1 cache to go to the L2 cache
82 instead of to main memory.
83
84IMPORTANT:
85 Starting with the 7450, the bits in this register have moved
86 or behave differently. The Enable, Parity Enable, Size,
87 and L2 Invalidate are the only bits that have not moved.
88 The size is read-only for these processors with internal L2
89 cache, and the invalidate is a control as well as status.
90 -- Dan
91
92*/
93/*
94 * Summary: this procedure ignores the L2I bit in the value passed in,
95 * flushes the cache if it was already enabled, always invalidates the
96 * cache, then enables the cache if the L2E bit is set in the value
97 * passed in.
98 * -- paulus.
99 */
100_GLOBAL(_set_L2CR)
101 /* Make sure this is a 750 or 7400 chip */
102BEGIN_FTR_SECTION
103 li r3,-1
104 blr
105END_FTR_SECTION_IFCLR(CPU_FTR_L2CR)
106
107 mflr r9
108
109 /* Stop DST streams */
110BEGIN_FTR_SECTION
111 DSSALL
112 sync
113END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
114
115 /* Turn off interrupts and data relocation. */
116 mfmsr r7 /* Save MSR in r7 */
117 rlwinm r4,r7,0,17,15
118 rlwinm r4,r4,0,28,26 /* Turn off DR bit */
119 sync
120 mtmsr r4
121 isync
122
123 /* Before we perform the global invalidation, we must disable dynamic
124 * power management via HID0[DPM] to work around a processor bug where
125 * DPM can possibly interfere with the state machine in the processor
126 * that invalidates the L2 cache tags.
127 */
128 mfspr r8,SPRN_HID0 /* Save HID0 in r8 */
129 rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */
130 sync
131 mtspr SPRN_HID0,r4 /* Disable DPM */
132 sync
133
134 /* Get the current enable bit of the L2CR into r4 */
135 mfspr r4,SPRN_L2CR
136
137 /* Tweak some bits */
138 rlwinm r5,r3,0,0,0 /* r5 contains the new enable bit */
139 rlwinm r3,r3,0,11,9 /* Turn off the invalidate bit */
140 rlwinm r3,r3,0,1,31 /* Turn off the enable bit */
141
142 /* Check to see if we need to flush */
143 rlwinm. r4,r4,0,0,0
144 beq 2f
145
146 /* Flush the cache. First, read the first 4MB of memory (physical) to
147 * put new data in the cache. (Actually we only need
148 * the size of the L2 cache plus the size of the L1 cache, but 4MB will
149 * cover everything just to be safe).
150 */
151
152 /**** Might be a good idea to set L2DO here - to prevent instructions
153 from getting into the cache. But since we invalidate
154 the next time we enable the cache it doesn't really matter.
155 Don't do this unless you accomodate all processor variations.
156 The bit moved on the 7450.....
157 ****/
158
159 /* TODO: use HW flush assist when available */
160
161 lis r4,0x0002
162 mtctr r4
163 li r4,0
1641:
165 lwzx r0,r0,r4
166 addi r4,r4,32 /* Go to start of next cache line */
167 bdnz 1b
168 isync
169
170 /* Now, flush the first 4MB of memory */
171 lis r4,0x0002
172 mtctr r4
173 li r4,0
174 sync
1751:
176 dcbf 0,r4
177 addi r4,r4,32 /* Go to start of next cache line */
178 bdnz 1b
179
1802:
181 /* Set up the L2CR configuration bits (and switch L2 off) */
182 /* CPU errata: Make sure the mtspr below is already in the
183 * L1 icache
184 */
185 b 20f
186 .balign L1_CACHE_LINE_SIZE
18722:
188 sync
189 mtspr SPRN_L2CR,r3
190 sync
191 b 23f
19220:
193 b 21f
19421: sync
195 isync
196 b 22b
197
19823:
199 /* Perform a global invalidation */
200 oris r3,r3,0x0020
201 sync
202 mtspr SPRN_L2CR,r3
203 sync
204 isync /* For errata */
205
206BEGIN_FTR_SECTION
207 /* On the 7450, we wait for the L2I bit to clear......
208 */
20910: mfspr r3,SPRN_L2CR
210 andis. r4,r3,0x0020
211 bne 10b
212 b 11f
213END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
214
215 /* Wait for the invalidation to complete */
2163: mfspr r3,SPRN_L2CR
217 rlwinm. r4,r3,0,31,31
218 bne 3b
219
22011: rlwinm r3,r3,0,11,9 /* Turn off the L2I bit */
221 sync
222 mtspr SPRN_L2CR,r3
223 sync
224
225 /* See if we need to enable the cache */
226 cmplwi r5,0
227 beq 4f
228
229 /* Enable the cache */
230 oris r3,r3,0x8000
231 mtspr SPRN_L2CR,r3
232 sync
233
2344:
235
236 /* Restore HID0[DPM] to whatever it was before */
237 sync
238 mtspr 1008,r8
239 sync
240
241 /* Restore MSR (restores EE and DR bits to original state) */
242 SYNC
243 mtmsr r7
244 isync
245
246 mtlr r9
247 blr
248
249_GLOBAL(_get_L2CR)
250 /* Return the L2CR contents */
251 li r3,0
252BEGIN_FTR_SECTION
253 mfspr r3,SPRN_L2CR
254END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
255 blr
256
257
258/*
259 * Here is a similar routine for dealing with the L3 cache
260 * on the 745x family of chips
261 */
262
263_GLOBAL(_set_L3CR)
264 /* Make sure this is a 745x chip */
265BEGIN_FTR_SECTION
266 li r3,-1
267 blr
268END_FTR_SECTION_IFCLR(CPU_FTR_L3CR)
269
270 /* Turn off interrupts and data relocation. */
271 mfmsr r7 /* Save MSR in r7 */
272 rlwinm r4,r7,0,17,15
273 rlwinm r4,r4,0,28,26 /* Turn off DR bit */
274 sync
275 mtmsr r4
276 isync
277
278 /* Stop DST streams */
279 DSSALL
280 sync
281
282 /* Get the current enable bit of the L3CR into r4 */
283 mfspr r4,SPRN_L3CR
284
285 /* Tweak some bits */
286 rlwinm r5,r3,0,0,0 /* r5 contains the new enable bit */
287 rlwinm r3,r3,0,22,20 /* Turn off the invalidate bit */
288 rlwinm r3,r3,0,2,31 /* Turn off the enable & PE bits */
289 rlwinm r3,r3,0,5,3 /* Turn off the clken bit */
290 /* Check to see if we need to flush */
291 rlwinm. r4,r4,0,0,0
292 beq 2f
293
294 /* Flush the cache.
295 */
296
297 /* TODO: use HW flush assist */
298
299 lis r4,0x0008
300 mtctr r4
301 li r4,0
3021:
303 lwzx r0,r0,r4
304 dcbf 0,r4
305 addi r4,r4,32 /* Go to start of next cache line */
306 bdnz 1b
307
3082:
309 /* Set up the L3CR configuration bits (and switch L3 off) */
310 sync
311 mtspr SPRN_L3CR,r3
312 sync
313
314 oris r3,r3,L3CR_L3RES@h /* Set reserved bit 5 */
315 mtspr SPRN_L3CR,r3
316 sync
317 oris r3,r3,L3CR_L3CLKEN@h /* Set clken */
318 mtspr SPRN_L3CR,r3
319 sync
320
321 /* Wait for stabilize */
322 li r0,256
323 mtctr r0
3241: bdnz 1b
325
326 /* Perform a global invalidation */
327 ori r3,r3,0x0400
328 sync
329 mtspr SPRN_L3CR,r3
330 sync
331 isync
332
333 /* We wait for the L3I bit to clear...... */
33410: mfspr r3,SPRN_L3CR
335 andi. r4,r3,0x0400
336 bne 10b
337
338 /* Clear CLKEN */
339 rlwinm r3,r3,0,5,3 /* Turn off the clken bit */
340 mtspr SPRN_L3CR,r3
341 sync
342
343 /* Wait for stabilize */
344 li r0,256
345 mtctr r0
3461: bdnz 1b
347
348 /* See if we need to enable the cache */
349 cmplwi r5,0
350 beq 4f
351
352 /* Enable the cache */
353 oris r3,r3,(L3CR_L3E | L3CR_L3CLKEN)@h
354 mtspr SPRN_L3CR,r3
355 sync
356
357 /* Wait for stabilize */
358 li r0,256
359 mtctr r0
3601: bdnz 1b
361
362 /* Restore MSR (restores EE and DR bits to original state) */
3634: SYNC
364 mtmsr r7
365 isync
366 blr
367
368_GLOBAL(_get_L3CR)
369 /* Return the L3CR contents */
370 li r3,0
371BEGIN_FTR_SECTION
372 mfspr r3,SPRN_L3CR
373END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
374 blr
375
376/* --- End of PowerLogix code ---
377 */
378
379
380/* flush_disable_L1() - Flush and disable L1 cache
381 *
382 * clobbers r0, r3, ctr, cr0
383 * Must be called with interrupts disabled and MMU enabled.
384 */
385_GLOBAL(__flush_disable_L1)
386 /* Stop pending alitvec streams and memory accesses */
387BEGIN_FTR_SECTION
388 DSSALL
389END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
390 sync
391
392 /* Load counter to 0x4000 cache lines (512k) and
393 * load cache with datas
394 */
395 li r3,0x4000 /* 512kB / 32B */
396 mtctr r3
397 lis r3,KERNELBASE@h
3981:
399 lwz r0,0(r3)
400 addi r3,r3,0x0020 /* Go to start of next cache line */
401 bdnz 1b
402 isync
403 sync
404
405 /* Now flush those cache lines */
406 li r3,0x4000 /* 512kB / 32B */
407 mtctr r3
408 lis r3,KERNELBASE@h
4091:
410 dcbf 0,r3
411 addi r3,r3,0x0020 /* Go to start of next cache line */
412 bdnz 1b
413 sync
414
415 /* We can now disable the L1 cache (HID0:DCE, HID0:ICE) */
416 mfspr r3,SPRN_HID0
417 rlwinm r3,r3,0,18,15
418 mtspr SPRN_HID0,r3
419 sync
420 isync
421 blr
422
423/* inval_enable_L1 - Invalidate and enable L1 cache
424 *
425 * Assumes L1 is already disabled and MSR:EE is off
426 *
427 * clobbers r3
428 */
429_GLOBAL(__inval_enable_L1)
430 /* Enable and then Flash inval the instruction & data cache */
431 mfspr r3,SPRN_HID0
432 ori r3,r3, HID0_ICE|HID0_ICFI|HID0_DCE|HID0_DCI
433 sync
434 isync
435 mtspr SPRN_HID0,r3
436 xori r3,r3, HID0_ICFI|HID0_DCI
437 mtspr SPRN_HID0,r3
438 sync
439
440 blr
441
442