1 /* *********************************************************************
2 * SB1250 Board Support Package
4 * L1 Cache initialization File: sb1250_l1cache.S
6 * This module contains code to initialize the L1 cache.
8 * Note: all the routines in this module rely on registers only,
9 * since DRAM may not be active yet.
11 * Author: Mitch Lichtenberg (mpl@broadcom.com)
13 *********************************************************************
15 * Copyright 2000,2001,2002,2003
16 * Broadcom Corporation. All rights reserved.
18 * This software is furnished under license and may be used and
19 * copied only in accordance with the following terms and
20 * conditions. Subject to these conditions, you may download,
21 * copy, install, use, modify and distribute modified or unmodified
22 * copies of this software in source and/or binary form. No title
23 * or ownership is transferred hereby.
25 * 1) Any source code used, modified or distributed must reproduce
26 * and retain this copyright notice and list of conditions
27 * as they appear in the source file.
29 * 2) No right is granted to use any trade name, trademark, or
30 * logo of Broadcom Corporation. The "Broadcom Corporation"
31 * name may not be used to endorse or promote products derived
32 * from this software without the prior written permission of
33 * Broadcom Corporation.
35 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
36 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
37 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
39 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
40 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
41 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
42 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
43 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
44 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
45 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
46 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
47 * THE POSSIBILITY OF SUCH DAMAGE.
48 ********************************************************************* */
51 #include "mipsmacros.h"
52 #include "sb1250_defs.h"
53 #include "sb1250_regs.h"
54 #include "sb1250_scd.h"
55 #include "sb1250_wid.h"
58 * This lets us override the WID by poking values into our PromICE
61 #undef A_SCD_SYSTEM_REVISION
62 #define A_SCD_SYSTEM_REVISION 0x1FC00508
70 /* *********************************************************************
72 ********************************************************************* */
74 #define L1CACHE_NUMWAYS 4
75 #define L1CACHE_NUMIDX 256
76 #define L1CACHE_LINESIZE 32
77 #define L1CACHE_IDXHIGH (L1CACHE_LINESIZE*L1CACHE_NUMWAYS*L1CACHE_NUMIDX)
79 #define L1CACHEOP(cachename,op) ((cachename) | ((op) << 2))
81 #define L1C_OP_IDXINVAL 0
82 #define L1C_OP_IDXLOADTAG 1
83 #define L1C_OP_IDXSTORETAG 2
84 #define L1C_OP_IMPLRSVD 3
85 #define L1C_OP_HITINVAL 4
87 #define L1C_OP_HITWRITEBACK 6
88 #define L1C_OP_FETCHLOCK 7
94 * CP0 C0_TAGHI values for cache freezing/way elimination
97 #define L1C_LRU_FREEZE0 (1<<22)|(3<<20)|(2<<18)|(1<<16)|(0<<14) /* 3,2,1,0[F] */
98 #define L1C_LRU_FREEZE1 (1<<22)|(3<<20)|(2<<18)|(0<<16)|(1<<14) /* 3,2,0,1[F] */
99 #define L1C_LRU_FREEZE2 (1<<22)|(3<<20)|(0<<18)|(1<<16)|(2<<14) /* 3,0,1,2[F] */
100 #define L1C_LRU_FREEZE3 (1<<22)|(2<<20)|(1<<18)|(0<<16)|(3<<14) /* 2,1,0,3[F] */
102 #define L1C_LRU_REMOVE0 (1<<22)|(3<<20)|(2<<18)|(1<<16)|(3<<14) /* 3,2,1,3 */
103 #define L1C_LRU_REMOVE1 (1<<22)|(3<<20)|(2<<18)|(0<<16)|(2<<14) /* 3,2,0,2 */
104 #define L1C_LRU_REMOVE2 (1<<22)|(3<<20)|(0<<18)|(1<<16)|(1<<14) /* 3,0,1,1 */
105 #define L1C_LRU_REMOVE3 (1<<22)|(2<<20)|(1<<18)|(0<<16)|(0<<14) /* 2,1,0,0 */
108 * Macro to test bin numbers
111 #define HAZARD ssnop ; ssnop ; ssnop ; ssnop ; ssnop ; ssnop ; ssnop
113 #define IF_BIN(binreg,binmask,label) \
115 andi AT,binreg,binmask ; \
116 bne AT,zero,label ; \
119 #define IF_CPU1(label) \
124 bne AT,zero,label ; \
127 /* *********************************************************************
128 * SB1250_L1CACHE_DISABLETABLE
130 * This table maps the bits in the diagnostic result
131 * register (part of WID) to which ways we want to enable/remove
134 * The format of the table is:
138 * Where X is one for 1/4 (way indicated is the GOOD way)
139 * or X is zero for 3/4 (way indicated is the BAD way)
143 * DD is the way number for the DCache
144 * II is the way number for the ICache
146 * there are 32 64-bit entries in this table.
147 ********************************************************************* */
149 #define L1DISTBL(d,i) (d),(i)
151 sb1250_l1cache_disabletable:
153 .word L1DISTBL(L1C_LRU_REMOVE0, L1C_LRU_REMOVE0)
154 .word L1DISTBL(L1C_LRU_REMOVE0, L1C_LRU_REMOVE1)
155 .word L1DISTBL(L1C_LRU_REMOVE0, L1C_LRU_REMOVE2)
156 .word L1DISTBL(L1C_LRU_REMOVE0, L1C_LRU_REMOVE3)
158 .word L1DISTBL(L1C_LRU_REMOVE1, L1C_LRU_REMOVE0)
159 .word L1DISTBL(L1C_LRU_REMOVE1, L1C_LRU_REMOVE1)
160 .word L1DISTBL(L1C_LRU_REMOVE1, L1C_LRU_REMOVE2)
161 .word L1DISTBL(L1C_LRU_REMOVE1, L1C_LRU_REMOVE3)
163 .word L1DISTBL(L1C_LRU_REMOVE2, L1C_LRU_REMOVE0)
164 .word L1DISTBL(L1C_LRU_REMOVE2, L1C_LRU_REMOVE1)
165 .word L1DISTBL(L1C_LRU_REMOVE2, L1C_LRU_REMOVE2)
166 .word L1DISTBL(L1C_LRU_REMOVE2, L1C_LRU_REMOVE3)
168 .word L1DISTBL(L1C_LRU_REMOVE3, L1C_LRU_REMOVE0)
169 .word L1DISTBL(L1C_LRU_REMOVE3, L1C_LRU_REMOVE1)
170 .word L1DISTBL(L1C_LRU_REMOVE3, L1C_LRU_REMOVE2)
171 .word L1DISTBL(L1C_LRU_REMOVE3, L1C_LRU_REMOVE3)
173 .word L1DISTBL(L1C_LRU_FREEZE0, L1C_LRU_FREEZE0)
174 .word L1DISTBL(L1C_LRU_FREEZE0, L1C_LRU_FREEZE1)
175 .word L1DISTBL(L1C_LRU_FREEZE0, L1C_LRU_FREEZE2)
176 .word L1DISTBL(L1C_LRU_FREEZE0, L1C_LRU_FREEZE3)
178 .word L1DISTBL(L1C_LRU_FREEZE1, L1C_LRU_FREEZE0)
179 .word L1DISTBL(L1C_LRU_FREEZE1, L1C_LRU_FREEZE1)
180 .word L1DISTBL(L1C_LRU_FREEZE1, L1C_LRU_FREEZE2)
181 .word L1DISTBL(L1C_LRU_FREEZE1, L1C_LRU_FREEZE3)
183 .word L1DISTBL(L1C_LRU_FREEZE2, L1C_LRU_FREEZE0)
184 .word L1DISTBL(L1C_LRU_FREEZE2, L1C_LRU_FREEZE1)
185 .word L1DISTBL(L1C_LRU_FREEZE2, L1C_LRU_FREEZE2)
186 .word L1DISTBL(L1C_LRU_FREEZE2, L1C_LRU_FREEZE3)
188 .word L1DISTBL(L1C_LRU_FREEZE3, L1C_LRU_FREEZE0)
189 .word L1DISTBL(L1C_LRU_FREEZE3, L1C_LRU_FREEZE1)
190 .word L1DISTBL(L1C_LRU_FREEZE3, L1C_LRU_FREEZE2)
191 .word L1DISTBL(L1C_LRU_FREEZE3, L1C_LRU_FREEZE3)
196 /* *********************************************************************
197 * SB1250_L1CACHE_INIT()
199 * Initialize the L1 Cache tags to be "invalid"
209 ********************************************************************* */
212 LEAF(sb1250_l1cache_init)
215 * Test to see if we're running on a pre-production part with
216 * a defective L1 cache. We store information in the SCD
217 * SYSTEM_REVISION register that identifies what is
222 * First, check the part number
225 li t0,PHYS_TO_K1(A_SCD_SYSTEM_REVISION)
227 ld t1,0(t0) /* get SYSTEM_REVISION */
229 dsrl t1,t1,S_SYS_PART
230 andi t1,t1,(M_SYS_PART >> S_SYS_PART)
232 beq t1,0x1250,sb1250_l1cache_check_rev /* Go if real 1250 */
233 beq t1,0x1150,sb1250_l1cache_check_rev /* or 1250 in uni-cpu mode */
234 b sb1250_l1cache_init_good /* otherwise not a 1250, no WID check */
237 * Now, check the revision. Anything earlier than step A3
238 * does not need this check. Pass 3 does not need this check also.
240 * Exception: Step A6 parts return 0x04 in their revision field.
241 * These parts can can be verified as A6 by having a nonzero WID.
244 sb1250_l1cache_check_rev:
245 ld t1,0(t0) /* get the SYSTEM_REVISION again */
246 dsrl t1,t1,S_SYS_REVISION
247 andi t1,t1,(M_SYS_REVISION >> S_SYS_REVISION)
248 beq t1,0x04,sb1250_l1cache_check_wid
249 blt t1,0x05,sb1250_l1cache_init_good
250 bge t1,0x20,sb1250_l1cache_init_good
253 * Okay, we really need to check the WID now. If the WID is
254 * not programmed at all, assume the part is good.
255 * (yes, this includes the wafer/lot bits)
258 sb1250_l1cache_check_wid:
259 ld t1,0(t0) /* Get the WID bits back */
260 dsrl t1,t1,S_SYS_WID /* wafer ID to bits 0..31 */
261 li t2,(M_SYS_WID >> S_SYS_WID)
264 WID_UNCONVOLUTE(t1,t2,t3,t4)
266 beq t1,zero,sb1250_l1cache_init_good
269 * Get the bin number from the WID. This tells us many things.
270 * For the L1 cache we need to know which ways to use,
271 * and this is determined by what we put in the tag registers.
274 dmtc0 zero,C0_TAGLO /* assume all is good. */
276 dmtc0 zero,C0_TAGLO,2
277 dmtc0 zero,C0_TAGHI,2
279 andi t0,t1,M_WID_BIN /* bin # into T0 */
280 li t2,1 /* make a bitmask */
281 sll t0,t2,t0 /* put '1' in correct place */
284 * t0 now contains a single bit set corresponding to the bin number
285 * that this chip belongs to.
286 * for example, if it is in bin 4, then the value is 1<<4
290 * Check for the case of a fully operational cache.
293 IF_BIN(t0,M_WID_BIN_FID,sb1250_l1cache_init_good)
296 * Now compute an index into the table using the WID bits and
297 * the "3/4" value from the bin number.
300 li t1,PHYS_TO_K1(A_SCD_SYSTEM_REVISION)
301 ld t1,0(t1) /* get SYSTEM_REVISION */
302 dsrl t1,t1,S_SYS_WID /* get WID bits */
304 WID_UNCONVOLUTE(t1,t2,t3,t4)
306 IF_CPU1(sb1250_l1init_cpu1)
308 li t2,PHYS_TO_K1(A_SCD_SYSTEM_CFG)
311 and t2,t3 /* T2 nonzero if UNICPU1 */
312 bne t2,zero,sb1250_l1init_cpu1
324 dsrl t1,t1,t2 /* move CPU way bits into posn */
325 andi t1,t1,(M_WID_CPUX_L1I|M_WID_CPUX_L1D) /* keep only way bits */
328 IF_BIN(t0,M_WID_BIN_3ID,1f)
329 ori t1,t1,0x10 /* 1/4 bit set */
333 * Okay, now t1 is the index into the table.
334 * Look up the I and D way disable values from the table and store
335 * them in the TAGHI and TAGHI,2 registers.
337 sll t1,3 /* make 64-bit offset */
340 LOADREL(t2,sb1250_l1cache_disabletable)
343 add t2,t2,t1 /* t2 points at our table entry */
345 lw t1,0(t2) /* DCache disable mask */
347 lw t1,4(t2) /* ICache disable mask */
351 * Go ahead and initialize the cache now, using the
352 * values programmed into the TAGHI registers.
354 * T0 is _still_ our bitmask from the bin register. We will
361 li t3,L1CACHE_LINESIZE*8 /* only 8 indicies now */
363 li t3,L1CACHE_IDXHIGH
367 1: cache L1CACHEOP(L1C_I,L1C_OP_IDXSTORETAG),0(t2)
368 addu t2,L1CACHE_LINESIZE
373 1: cache L1CACHEOP(L1C_D,L1C_OP_IDXSTORETAG),0(t2)
374 addu t2,L1CACHE_LINESIZE
379 * Set the defeature register if we're doing the 1/4 case.
380 * If we're here, at least _something_ is wrong.
383 IF_BIN(t0,M_WID_BIN_3ID,2f)
386 * In the 1/4 case, we'll always freeze the D cache.
387 * We might not freeze the I cache, though.
390 li t2,(1<<10) /* Freeze D */
391 mfc0 t1,$23,2 /* start with current value */
393 IF_BIN(t0,M_WID_BIN_FI,1f) /* If I cache is ok, no freeze */
395 or t2,t2,t3 /* also freeze I */
397 or t1,t1,t2 /* Merge in new bits */
399 mtc0 t1,$23,2 /* Write back to defeature register */
404 * Done, if you can believe it!
409 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
412 * This part of the routine handles a fully operational L1
416 sb1250_l1cache_init_good:
423 li t3,L1CACHE_LINESIZE*8 /* only 8 indicies now */
425 li t3,L1CACHE_IDXHIGH
430 1: cache L1CACHEOP(L1C_I,L1C_OP_IDXSTORETAG),0(t2)
431 addu t2,L1CACHE_LINESIZE
434 dmtc0 zero,C0_TAGLO,2
435 dmtc0 zero,C0_TAGHI,2
440 1: cache L1CACHEOP(L1C_D,L1C_OP_IDXSTORETAG),0(t2)
441 addu t2,L1CACHE_LINESIZE
446 END(sb1250_l1cache_init)
451 LEAF(sb1250_reset_defeature)
454 * Test to see if we're running on a pre-production part with
455 * a defective L1 cache. We store information in the SCD
456 * SYSTEM_REVISION register that identifies what is
461 * First, check the part number
464 li t0,PHYS_TO_K1(A_SCD_SYSTEM_REVISION)
465 ld t1,0(t0) /* get SYSTEM_REVISION */
467 dsrl t1,t1,S_SYS_PART
468 andi t1,t1,(M_SYS_PART >> S_SYS_PART)
470 beq t1,0x1250,1f /* Go if real 1250 */
471 beq t1,0x1150,1f /* or 1250 in uni-cpu mode */
472 b sb1250_no_defeature /* otherwise not a 1250, no WID check */
475 * Now, check the revision. Anything earlier than step A3
476 * does not need this check.
478 * Exception: Step A6 parts return 0x04 in their revision field.
479 * These parts can can be verified as A6 by having a nonzero WID.
482 1: ld t1,0(t0) /* get the SYSTEM_REVISION again */
483 dsrl t1,t1,S_SYS_REVISION
484 andi t1,t1,(M_SYS_REVISION >> S_SYS_REVISION)
486 blt t1,0x05,sb1250_no_defeature
489 * Okay, we really need to check the WID now. If the WID is
490 * not programmed at all, assume the part is good.
491 * (yes, this includes the wafer/lot bits)
494 1: ld t1,0(t0) /* Get the WID bits back */
495 dsrl t1,t1,S_SYS_WID /* wafer ID to bits 0..31 */
496 li t2,(M_SYS_WID >> S_SYS_WID)
499 WID_UNCONVOLUTE(t1,t2,t3,t4)
501 beq t1,zero,sb1250_no_defeature
504 * Get the bin number from the WID. This tells us many things.
505 * For the L1 cache we need to know which ways to use,
506 * and this is determined by what we put in the tag registers.
509 andi t0,t1,M_WID_BIN /* bin # into T0 */
510 li t2,1 /* make a bitmask */
511 sll t0,t2,t0 /* put '1' in correct place */
514 * Set the defeature register if we're doing the 1/4 case.
515 * If we're here, at least _something_ is wrong.
516 * The 3/4 and full cache cases don't need defeaturing.
519 IF_BIN(t0,(M_WID_BIN_3ID | M_WID_BIN_FID),sb1250_no_defeature)
522 * In the 1/4 case, we'll always freeze the D cache.
523 * We might not freeze the I cache, though.
526 li t2,(1<<10) /* Freeze D */
527 mfc0 t1,$23,2 /* start with current value */
529 IF_BIN(t0,M_WID_BIN_FI,1f) /* If I cache is ok, no freeze */
531 or t2,t2,t3 /* also freeze I */
533 or t1,t1,t2 /* Merge in new bits */
535 mtc0 t1,$23,2 /* Write back to defeature register */
542 END(sb1250_reset_defeature)
547 /* *********************************************************************
548 * SB1250_L1CACHE_INVAL_I()
550 * Invalidate the L1 ICache
560 ********************************************************************* */
563 LEAF(sb1250_l1cache_inval_i)
567 li t3,L1CACHE_IDXHIGH
571 1: cache L1CACHEOP(L1C_I,L1C_OP_IDXINVAL),0(t2)
572 addu t2,L1CACHE_LINESIZE
577 END(sb1250_l1cache_inval_i)
580 /* *********************************************************************
581 * SB1250_L1CACHE_FLUSH_D()
583 * Flush the entire L1 DCache (write dirty lines back to memory)
593 ********************************************************************* */
596 LEAF(sb1250_l1cache_flush_d)
599 li t3,L1CACHE_IDXHIGH
604 1: cache L1CACHEOP(L1C_D,L1C_OP_IDXINVAL),0(t2)
605 addu t2,L1CACHE_LINESIZE
609 sync /* pass1 issue. */
613 END(sb1250_l1cache_flush_d)
616 /* *********************************************************************
618 ********************************************************************* */