1/* ********************************************************************* 2 * SB1250 Board Support Package 3 * 4 * L1 Cache initialization File: sb1250_l1cache.S 5 * 6 * This module contains code to initialize the L1 cache. 7 * 8 * Note: all the routines in this module rely on registers only, 9 * since DRAM may not be active yet. 10 * 11 * Author: Mitch Lichtenberg (mpl@broadcom.com) 12 * 13 ********************************************************************* 14 * 15 * Copyright 2000,2001,2002,2003 16 * Broadcom Corporation. All rights reserved. 17 * 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. 24 * 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. 28 * 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. 34 * 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 ********************************************************************* */ 49 50#include "sbmips.h" 51#include "mipsmacros.h" 52#include "sb1250_defs.h" 53#include "sb1250_regs.h" 54#include "sb1250_scd.h" 55#include "sb1250_wid.h" 56 57/* 58 * This lets us override the WID by poking values into our PromICE 59 */ 60#ifdef _MAGICWID_ 61#undef A_SCD_SYSTEM_REVISION 62#define A_SCD_SYSTEM_REVISION 0x1FC00508 63#endif 64 65 .text 66 67 .set mips64 68 69 70/* ********************************************************************* 71 * Macros 72 ********************************************************************* */ 73 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) 78 79#define L1CACHEOP(cachename,op) ((cachename) | ((op) << 2)) 80 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 86#define L1C_OP_FILL 5 87#define L1C_OP_HITWRITEBACK 6 88#define L1C_OP_FETCHLOCK 7 89 90#define L1C_I 0 91#define L1C_D 1 92 93/* 94 * CP0 C0_TAGHI values for cache freezing/way elimination 95 */ 96 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] */ 101 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 */ 106 107/* 108 * Macro to test bin numbers 109 */ 110 111#define HAZARD ssnop ; ssnop ; ssnop ; ssnop ; ssnop ; ssnop ; ssnop 112 113#define IF_BIN(binreg,binmask,label) \ 114 .set noat ; \ 115 andi AT,binreg,binmask ; \ 116 bne AT,zero,label ; \ 117 .set at 118 119#define IF_CPU1(label) \ 120 .set noat ; \ 121 mfc0 AT,C0_PRID ; \ 122 srl AT,AT,25 ; \ 123 andi AT,AT,7 ; \ 124 bne AT,zero,label ; \ 125 .set at 126 127/* ********************************************************************* 128 * SB1250_L1CACHE_DISABLETABLE 129 * 130 * This table maps the bits in the diagnostic result 131 * register (part of WID) to which ways we want to enable/remove 132 * from the L1. 133 * 134 * The format of the table is: 135 * 136 * X DD II 137 * 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) 140 * 141 * and 142 * 143 * DD is the way number for the DCache 144 * II is the way number for the ICache 145 * 146 * there are 32 64-bit entries in this table. 147 ********************************************************************* */ 148 149#define L1DISTBL(d,i) (d),(i) 150 151sb1250_l1cache_disabletable: 152 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) 157 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) 162 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) 167 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) 172 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) 177 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) 182 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) 187 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) 192 193 194 195 196/* ********************************************************************* 197 * SB1250_L1CACHE_INIT() 198 * 199 * Initialize the L1 Cache tags to be "invalid" 200 * 201 * Input parameters: 202 * nothing 203 * 204 * Return value: 205 * nothing 206 * 207 * Registers used: 208 * t0,t1,t2,t3 209 ********************************************************************* */ 210 211 212LEAF(sb1250_l1cache_init) 213 214 /* 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 218 * going on. 219 */ 220 221 /* 222 * First, check the part number 223 */ 224 225 li t0,PHYS_TO_K1(A_SCD_SYSTEM_REVISION) 226 227 ld t1,0(t0) /* get SYSTEM_REVISION */ 228 229 dsrl t1,t1,S_SYS_PART 230 andi t1,t1,(M_SYS_PART >> S_SYS_PART) 231 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 */ 235 236 /* 237 * Now, check the revision. Anything earlier than step A3 238 * does not need this check. Pass 3 does not need this check also. 239 * 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. 242 */ 243 244sb1250_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 251 252 /* 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) 256 */ 257 258sb1250_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) 262 and t1,t1,t2 263 264 WID_UNCONVOLUTE(t1,t2,t3,t4) 265 266 beq t1,zero,sb1250_l1cache_init_good 267 268 /* 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. 272 */ 273 274 dmtc0 zero,C0_TAGLO /* assume all is good. */ 275 dmtc0 zero,C0_TAGHI 276 dmtc0 zero,C0_TAGLO,2 277 dmtc0 zero,C0_TAGHI,2 278 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 */ 282 283 /* 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 287 */ 288 289 /* 290 * Check for the case of a fully operational cache. 291 */ 292 293 IF_BIN(t0,M_WID_BIN_FID,sb1250_l1cache_init_good) 294 295 /* 296 * Now compute an index into the table using the WID bits and 297 * the "3/4" value from the bin number. 298 */ 299 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 */ 303 304 WID_UNCONVOLUTE(t1,t2,t3,t4) 305 306 IF_CPU1(sb1250_l1init_cpu1) 307 308 li t2,PHYS_TO_K1(A_SCD_SYSTEM_CFG) 309 ld t2,0(t2) 310 dli t3,M_SYS_UNICPU1 311 and t2,t3 /* T2 nonzero if UNICPU1 */ 312 bne t2,zero,sb1250_l1init_cpu1 313 314 315sb1250_l1init_cpu0: 316 li t2,S_WID_CPU0 317 b sb1250_l1init_cont 318 319sb1250_l1init_cpu1: 320 li t2,S_WID_CPU1 321 322 323sb1250_l1init_cont: 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 */ 326 327 328 IF_BIN(t0,M_WID_BIN_3ID,1f) 329 ori t1,t1,0x10 /* 1/4 bit set */ 3301: 331 332 /* 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. 336 */ 337 sll t1,3 /* make 64-bit offset */ 338 339 move t3,ra 340 LOADREL(t2,sb1250_l1cache_disabletable) 341 or t2,K1BASE 342 move ra,t3 343 add t2,t2,t1 /* t2 points at our table entry */ 344 345 lw t1,0(t2) /* DCache disable mask */ 346 dmtc0 t1,C0_TAGHI,2 347 lw t1,4(t2) /* ICache disable mask */ 348 dmtc0 t1,C0_TAGHI 349 350 /* 351 * Go ahead and initialize the cache now, using the 352 * values programmed into the TAGHI registers. 353 * 354 * T0 is _still_ our bitmask from the bin register. We will 355 * need that later. 356 */ 357 358 359 li t2,K1BASE 360#ifdef _FASTINIT_ 361 li t3,L1CACHE_LINESIZE*8 /* only 8 indicies now */ 362#else 363 li t3,L1CACHE_IDXHIGH 364#endif 365 366 add t1,t2,t3 3671: cache L1CACHEOP(L1C_I,L1C_OP_IDXSTORETAG),0(t2) 368 addu t2,L1CACHE_LINESIZE 369 bne t1,t2,1b 370 371 li t2,K1BASE 372 add t1,t2,t3 3731: cache L1CACHEOP(L1C_D,L1C_OP_IDXSTORETAG),0(t2) 374 addu t2,L1CACHE_LINESIZE 375 bne t1,t2,1b 376 377 378 /* 379 * Set the defeature register if we're doing the 1/4 case. 380 * If we're here, at least _something_ is wrong. 381 */ 382 383 IF_BIN(t0,M_WID_BIN_3ID,2f) 384 385 /* 386 * In the 1/4 case, we'll always freeze the D cache. 387 * We might not freeze the I cache, though. 388 */ 389 390 li t2,(1<<10) /* Freeze D */ 391 mfc0 t1,$23,2 /* start with current value */ 392 393 IF_BIN(t0,M_WID_BIN_FI,1f) /* If I cache is ok, no freeze */ 394 li t3,(1<<28) 395 or t2,t2,t3 /* also freeze I */ 3961: 397 or t1,t1,t2 /* Merge in new bits */ 398 HAZARD 399 mtc0 t1,$23,2 /* Write back to defeature register */ 400 HAZARD 401 4022: 403 /* 404 * Done, if you can believe it! 405 */ 406 407 j ra 408 409/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 410 411 /* 412 * This part of the routine handles a fully operational L1 413 * cache. 414 */ 415 416sb1250_l1cache_init_good: 417 418 dmtc0 zero,C0_TAGLO 419 dmtc0 zero,C0_TAGHI 420 421 li t2,K1BASE 422#ifdef _FASTINIT_ 423 li t3,L1CACHE_LINESIZE*8 /* only 8 indicies now */ 424#else 425 li t3,L1CACHE_IDXHIGH 426#endif 427 428 add t0,t2,t3 429 .align 4 4301: cache L1CACHEOP(L1C_I,L1C_OP_IDXSTORETAG),0(t2) 431 addu t2,L1CACHE_LINESIZE 432 bne t0,t2,1b 433 434 dmtc0 zero,C0_TAGLO,2 435 dmtc0 zero,C0_TAGHI,2 436 437 li t2,K1BASE 438 add t0,t2,t3 439 .align 4 4401: cache L1CACHEOP(L1C_D,L1C_OP_IDXSTORETAG),0(t2) 441 addu t2,L1CACHE_LINESIZE 442 bne t0,t2,1b 443 444 j ra 445 446END(sb1250_l1cache_init) 447 448 449#if CFG_VAPI 450 451LEAF(sb1250_reset_defeature) 452 453 /* 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 457 * going on. 458 */ 459 460 /* 461 * First, check the part number 462 */ 463 464 li t0,PHYS_TO_K1(A_SCD_SYSTEM_REVISION) 465 ld t1,0(t0) /* get SYSTEM_REVISION */ 466 467 dsrl t1,t1,S_SYS_PART 468 andi t1,t1,(M_SYS_PART >> S_SYS_PART) 469 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 */ 473 474 /* 475 * Now, check the revision. Anything earlier than step A3 476 * does not need this check. 477 * 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. 480 */ 481 4821: 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) 485 beq t1,0x04,1f 486 blt t1,0x05,sb1250_no_defeature 487 488 /* 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) 492 */ 493 4941: 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) 497 and t1,t1,t2 498 499 WID_UNCONVOLUTE(t1,t2,t3,t4) 500 501 beq t1,zero,sb1250_no_defeature 502 503 /* 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. 507 */ 508 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 */ 512 513 /* 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. 517 */ 518 519 IF_BIN(t0,(M_WID_BIN_3ID | M_WID_BIN_FID),sb1250_no_defeature) 520 521 /* 522 * In the 1/4 case, we'll always freeze the D cache. 523 * We might not freeze the I cache, though. 524 */ 525 526 li t2,(1<<10) /* Freeze D */ 527 mfc0 t1,$23,2 /* start with current value */ 528 529 IF_BIN(t0,M_WID_BIN_FI,1f) /* If I cache is ok, no freeze */ 530 li t3,(1<<28) 531 or t2,t2,t3 /* also freeze I */ 5321: 533 or t1,t1,t2 /* Merge in new bits */ 534 HAZARD 535 mtc0 t1,$23,2 /* Write back to defeature register */ 536 HAZARD 537 538sb1250_no_defeature: 539 540 j ra 541 542END(sb1250_reset_defeature) 543 544#endif 545 546 547/* ********************************************************************* 548 * SB1250_L1CACHE_INVAL_I() 549 * 550 * Invalidate the L1 ICache 551 * 552 * Input parameters: 553 * nothing 554 * 555 * Return value: 556 * nothing 557 * 558 * Registers used: 559 * t0,t1,t2,t3 560 ********************************************************************* */ 561 562 563LEAF(sb1250_l1cache_inval_i) 564 565 566 li t2,K1BASE 567 li t3,L1CACHE_IDXHIGH 568 569 add t0,t2,t3 570 .align 4 5711: cache L1CACHEOP(L1C_I,L1C_OP_IDXINVAL),0(t2) 572 addu t2,L1CACHE_LINESIZE 573 bne t0,t2,1b 574 575 j ra 576 577END(sb1250_l1cache_inval_i) 578 579 580/* ********************************************************************* 581 * SB1250_L1CACHE_FLUSH_D() 582 * 583 * Flush the entire L1 DCache (write dirty lines back to memory) 584 * 585 * Input parameters: 586 * nothing 587 * 588 * Return value: 589 * nothing 590 * 591 * Registers used: 592 * t0,t1,t2,t3 593 ********************************************************************* */ 594 595 596LEAF(sb1250_l1cache_flush_d) 597 598 li t2,K1BASE 599 li t3,L1CACHE_IDXHIGH 600 601 li t2,K1BASE 602 add t0,t2,t3 603 .align 4 6041: cache L1CACHEOP(L1C_D,L1C_OP_IDXINVAL),0(t2) 605 addu t2,L1CACHE_LINESIZE 606 bne t0,t2,1b 607 608 sync 609 sync /* pass1 issue. */ 610 611 j ra 612 613END(sb1250_l1cache_flush_d) 614 615 616/* ********************************************************************* 617 * End 618 ********************************************************************* */ 619 620