1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * SDRAM init module File: sbmemc.S 5 * 6 * BCM5836 Sonics SiliconBackplane MEMC core initialization 7 * 8 ********************************************************************* 9 * 10 * Copyright 2002,2003,2004 11 * Broadcom Corporation. All rights reserved. 12 * 13 * This software is furnished under license and may be used and 14 * copied only in accordance with the following terms and 15 * conditions. Subject to these conditions, you may download, 16 * copy, install, use, modify and distribute modified or unmodified 17 * copies of this software in source and/or binary form. No title 18 * or ownership is transferred hereby. 19 * 20 * 1) Any source code used, modified or distributed must reproduce 21 * and retain this copyright notice and list of conditions 22 * as they appear in the source file. 23 * 24 * 2) No right is granted to use any trade name, trademark, or 25 * logo of Broadcom Corporation. The "Broadcom Corporation" 26 * name may not be used to endorse or promote products derived 27 * from this software without the prior written permission of 28 * Broadcom Corporation. 29 * 30 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 31 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 32 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 33 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 34 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 35 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 36 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 38 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 39 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 40 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 41 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 42 * THE POSSIBILITY OF SUCH DAMAGE. 43 ********************************************************************* */ 44 45#include "sbmips32.h" 46#include "bsp_config.h" 47#include "sb_bp.h" 48#include "sbmemc.h" 49 50/* 51 * LEAF - declare leaf routine 52 */ 53#undef LEAF 54#define LEAF(symbol) \ 55 .globl symbol; \ 56 .align 2; \ 57 .type symbol,@function; \ 58 .ent symbol,0; \ 59symbol: .frame sp,0,ra 60 61/* 62 * END - mark end of function 63 */ 64#undef END 65#define END(function) \ 66 .end function; \ 67 .size function,.-function 68 69 70LEAF(board_draminfo) 71 /* 72 * XXX - in the future, v0 could return the address of the 73 * PROM SDRAM table. 74 */ 75 76 move v0,zero # auto configure 77 j ra 78END(board_draminfo) 79 80 81/* 82 * Register usage within this file: 83 * 84 * top ncdlsearch test_mem Xdr_do_init sb_core_reset 85 * v0: retval retval 86 * v1: corerev - - corerev - 87 * a0: coreptr coreptr - coreptr coreptr 88 * a1: x x x sdr/ddr flag 89 * a2: x 90 * a3: x 91 * t0: - - config 92 * t1: - - mode 93 * t2: - wr/strm off wr/strm 94 * t3: - rd/strd rd/strd 95 * t4: - g/clkd g/clkd 96 * t5: x 97 * t6: retaddr - - - 98 * t7: - - retaddr - 99 * s0: pass_count - - 100 * s1: wrsum/clkdsum - - 101 * s2: rdsum/pass_countmax - - 102 * s3: gsum/strmmax - - 103 * s4: wrlim/stdmmax - - 104 * s5: rdlim/clkdmax - - 105 * s6: glim/clkdlim - - 106 * s7: dll - - 107 * t8: - - x tmp 108 * t9: - - x retaddr 109 * k0: trace trace trace - - 110 * k1: trace trace trace - - 111 * gp: 112 * sp: 113 * s8: - step - - 114 * ra: 115 */ 116 117LEAF(board_draminit) 118 .set noreorder 119 120 /* Save return address */ 121 move t6,ra 122 123 /* Scan for a MEMC controller (a0) */ 124 li a0,PHYS_TO_K1(SB_ENUM_BASE) 1251: lw v1,R_SBIDHIGH(a0) 126 and a1,v1,M_SBID_CR 127 srl a1,a1,S_SBID_CR 128 beq a1,K_CR_MEMC,read_nvram 129 nop 130 addu a0,SB_CORE_SIZE 131 bne a1,(M_SBID_CR >> S_SBID_CR),1b # XXX No bus error? 132 nop 133 134 /* No MEMC controller */ 135 jr t6 136 li v0, 0 137 138read_nvram: 139 /* Isolate corerev in v1 */ 140 and v1,v1,M_SBID_RV 141#ifdef BCM5365 142 li v1,1 # chip mis-id, per HNBU 143#endif 144 145#if 0 /* XXX Force defaults */ 146 /* Find NVRAM (a2) */ 147 li t0,PHYS_TO_K1(SB_ENUM_BASE) # Is it a chipcommon core? 148 lw t1,R_SBIDHIGH(t0) 149 and t1,t1,M_SBID_CR 150 srl t1,t1,S_SBID_CR 151 bne t1,K_CR_CHIP_COMMON,notcc 152 nop 153 /* If it is a chipcommon core, use the 32MB window */ 154 li t2,(CC_FLASH_BASE - NVRAM_SPACE) 155 li t4,CC_FLASH_MAX 156 b find_nvram 157 nop 158 159notcc: 160 /* else use the 4MB window */ 161 li t2,(FLASH_BASE - NVRAM_SPACE) 162 li t4,FLASH_MAX 163 164find_nvram: 165 li t3,FLASH_MIN 166 li t0, NVRAM_MAGIC 167 1681: 169 add a2,t2,t3 170 lw t1, 0(a2) 171 beq t0,t1,read_parms 172 nop 173 174 sll t3,t3,1 175 ble t3,t4,1b 176 nop 177 178 /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ 179 li a2,(FLASH_BASE + 0x1000) 180 lw t1,0(a2) 181 beq t0,t1,read_parms 182 nop 183 184 li a2,(FLASH_BASE + 0x400) 185 lw t1,0(a2) 186 beq t0,t1,read_parms 187 nop 188#endif /* XXX */ 189 190 b init # No NVRAM 191 li a2, 0 192 193read_parms: 194 /* Get SDRAM parameters (t0, t1, t2) from NVRAM (a2) */ 195 lw t0, 8(a2) # SDRAM init 196 srl t0, 16 197 lw t2, 12(a2) 198 andi t1, t2, 0xffff # SDRAM config 199 srl t2, 16 # SDRAM refresh 200 lw t3,16(a2) # SDRAM ncdl 201 202init: 203memc_init: 204 bnez a2,1f # Already have the parms in t0, t1, t2, t3 205 nop 206 207 /* No nvram parms: get configured values (sbmemc.h) */ 208 209#ifdef MEMSDR 210 li t0,MEMC_SDR_INIT 211 li t1,MEMC_SDR_MODE 212 li t3,MEMC_SDR_NCDL # If rev0, 2: 213 bne v1,1,1f 214 nop 215 li t3,MEMC_SDR1_NCDL # rev1: 2161: 217#else 218 li t0,MEMC_DDR_INIT 219 li t1,MEMC_DDR_MODE 220 li t3,MEMC_DDR_NCDL # If rev0, 2: 221 bne v1,1,1f 222 nop 223 li t3,MEMC_DDR1_NCDL # rev1: 2241: 225#endif 226 andi a3,t0,MEMC_CONFIG_DDR # Low bit of init selects ddr or sdr 227 beqz a3,memc_sdr_init 228 nop 229 230 231/* 232 * Routines for initializing DDR SDRAM 233 */ 234 235memc_ddr_init: 236 beqz t3,ddr_find_ncdl # Do we have ncdl values? (0s) 237 nop 238 li t4,-1 # or ffs 239 bne t3,t4,break_ddr_ncdl 240 nop 241 242ddr_find_ncdl: 243 244/* Register usage */ 245#define pass_count s0 246#define wrsum s1 247#define rdsum s2 248#define gsum s3 249#define wrlim s4 250#define rdlim s5 251#define glim s6 252#define dll s7 253#define step s8 254#define wr t2 255#define rd t3 256#define g t4 257 258 /* Initialize counter & accumulators */ 259 move pass_count,zero 260 move wrsum,zero 261 move rdsum,zero 262 move gsum,zero 263 264 /* Initialize with default values */ 265 li wr,5 266 li rd,5 267 bal ddr_do_init 268 li g,10 269 270 /* Read dll value */ 271 lw dll,MEMC_NCDLCTL(a0) 272 andi dll,dll,0xfe 273 srl dll,dll,1 274 beqz dll,szmem # If zero, leave the default values 275 nop 276 277 move wrlim,dll # dll value is lim for wr, rd and g 278 move rdlim,dll 279 move glim,dll 280 281 addi step,dll,15 # step = (dll + 16 - 1) / 16 282 srl step,step,4 283 284 sub wr,zero,dll # Negate dll as initial value 285 move rd,wr 286 move g,wr 287 288 /* Inner loop: call ddr_do_init to re-initialize and the test mem */ 289loop: 290 bal ddr_do_init 291 nop 292 293 bal test_mem 294 nop 295 296 beqz v0,nextg 297 nop 298 299 /* Memory is ok */ 300 301 addi pass_count,1 302 add wrsum,wrsum,wr 303 add rdsum,rdsum,rd 304 add gsum,gsum,g 305 306 bne wr,dll,1f 307 nop 308 sll wrlim,dll,1 3091: 310 bne rd,dll,2f 311 nop 312 sll rdlim,dll,1 3132: 314 bne g,dll,nextg 315 nop 316 sll glim,dll,1 317 318nextg: 319 add g,g,step 320 ble g,glim,loop 321 nop 322 sub g,zero,dll 323 move glim,dll 324 325 /* nextrd: */ 326 add rd,rd,step 327 ble rd,rdlim,loop 328 nop 329 sub rd,zero,dll 330 move rdlim,dll 331 332 /* nextwr: */ 333 add wr,wr,step 334 ble wr,wrlim,loop 335 nop 336 337 /* All done, calculate average values and program them */ 338 339 beqz pass_count,1f 340 nop 341 342 div zero,wrsum,pass_count 343 mflo wr 344 345 div zero,rdsum,pass_count 346 mflo rd 347 348 div zero,gsum,pass_count 349 mflo g 350 351 b ddr_got_ncdl 352 nop 353 354 /* No passing values, panic! (use defaults) */ 3551: 356#ifdef MEMSDR 357 li t3,MEMC_SDR_NCDL # If rev0, 2: 358 bne v1,1,2f 359 nop 360 li t3,MEMC_SDR1_NCDL # rev1: 361#else 362 li t3,MEMC_DDR_NCDL # If rev0, 2: 363 bne v1,1,2f 364 nop 365 li t3,MEMC_DDR1_NCDL # rev1: 366#endif 3672: 368 369break_ddr_ncdl: 370 andi t4,t3,0xff # t4: g 371 srl t2,t3,16 # t2: wr 372 andi t2,t2,0xff 373 srl t3,t3,8 # t3: rd 374 andi t3,t3,0xff 375 376ddr_got_ncdl: 377 bal ddr_do_init 378 nop 379 380 b szmem 381 nop 382 383 384 /* Do an init of the memc core for ddr 385 * a0: memc core pointer 386 * t0: memc config value 387 * t1: memc mode value 388 * t2: memc wr ncdl value 389 * t3: memc rd ncdl value 390 * t4: memc g ncdl value 391 * 392 * Uses a1, t7, t8, t9 (here and by calling sb_core_reset) 393 */ 394ddr_do_init: 395 396 /* Save return address */ 397 move t7,ra 398 399 bal sb_core_reset 400 li a1,0 401 402 li a1,MEMC_CONFIG_INIT 403 or a1,a1,t0 404 sw a1,MEMC_CONFIG(a0) 405 406 li a1,MEMC_DRAMTIM25_INIT # Assume CAS latency of 2.5 407 andi t8,t1,0xf0 # Find out the CAS latency 408 bne t8,0x20,1f 409 nop 410 li a1,MEMC_DRAMTIM2_INIT # CAS latency is 2 4111: 412 sw a1,MEMC_DRAMTIM(a0) 413 414 andi t8,t3,0xff 415 sll a1,t8,8 # Replicate rd ncdl 4 times 416 or a1,a1,t8 417 sll t8,a1,16 418 or t8,t8,a1 419 li a1,MEMC_RDNCDLCOR_INIT 420 or a1,a1,t8 421 sw a1,MEMC_RDNCDLCOR(a0) 422 423 li a1,MEMC_WRNCDLCOR_INIT # If rev0, 2: 424 bne v1,1,1f 425 nop 426 li a1,MEMC_1_WRNCDLCOR_INIT # rev1 4271: 428 andi t8,t2,0xff 429 or a1,a1,t8 430 sw a1,MEMC_WRNCDLCOR(a0) 431 432 li a1,MEMC_DQSGATENCDL_INIT 433 andi t8,t4,0xff 434 or a1,a1,t8 435 sw a1,MEMC_DQSGATENCDL(a0) 436 437 li a1,MEMC_MISCDLYCTL_INIT # If rev0, 2: 438 bne v1,1,2f 439 nop 440 li a1,MEMC_1_MISCDLYCTL_INIT # rev1 4412: 442 sw a1,MEMC_MISCDLYCTL(a0) 443 444 li a1,MEMC_NCDLCTL_INIT 445 sw a1,MEMC_NCDLCTL(a0) 446 447 li a1,MEMC_CONTROL_INIT0 448 sw a1,MEMC_CONTROL(a0) 449 450 li a1,MEMC_CONTROL_INIT1 451 sw a1,MEMC_CONTROL(a0) 452 453 li a1,MEMC_MODEBUF_INIT0 454 sw a1,MEMC_MODEBUF(a0) 455 456 li a1,MEMC_CONTROL_INIT2 457 sw a1,MEMC_CONTROL(a0) 458 459 li a1,MEMC_MODEBUF_INIT1 460 or a1,a1,t1 461 sw a1,MEMC_MODEBUF(a0) 462 463 li a1,MEMC_CONTROL_INIT3 464 sw a1,MEMC_CONTROL(a0) 465 466 li a1,MEMC_CONTROL_INIT4 467 sw a1,MEMC_CONTROL(a0) 468 469 li a1,MEMC_CONTROL_INIT5 470 sw a1,MEMC_CONTROL(a0) 471 lw a1,MEMC_CONTROL(a0) 472 lw a1,MEMC_CONTROL(a0) 473 lw a1,MEMC_CONTROL(a0) 474 475 li a1,MEMC_CONTROL_INIT5 476 sw a1,MEMC_CONTROL(a0) 477 lw a1,MEMC_CONTROL(a0) 478 lw a1,MEMC_CONTROL(a0) 479 lw a1,MEMC_CONTROL(a0) 480 481 li a1,MEMC_REFRESH_INIT 482 sw a1,MEMC_REFRESH(a0) 483 484 li a1,MEMC_MODEBUF_INIT2 485 or a1,a1,t1 486 sw a1,MEMC_MODEBUF(a0) 487 488 li a1,MEMC_CONTROL_INIT6 489 sw a1,MEMC_CONTROL(a0) 490 491 li a1,MEMC_CONTROL_INIT7 492 sw a1,MEMC_CONTROL(a0) 493 494 /* Wait for SDRAM controller to refresh. 495 * We want 8uS delay. (Assumes >= 160ns per iteration) 496 */ 497 li t8,50 4981: lw a1,R_SBIDLOW(a0) 499 lw a1,R_SBIDHIGH(a0) 500 501 bnez t8,1b 502 subu t8,1 503 504 jr t7 505 nop 506 507 508/* 509 * Routines for initializing SDR SDRAM 510 */ 511 512memc_sdr_init: 513 beqz t3,sdr_find_ncdl # Do we have ncdl values? 514 nop 515 516 li t4,-1 517 bne t3,t4,break_sdr_ncdl 518 nop 519 520sdr_find_ncdl: 521 522/* Register usage */ 523#define pass_count s0 524#define clkdsum s1 525#define pass_countmax s2 526#define strmmax s3 527#define strdmax s4 528#define clkdmax s5 529#define clkdlim s6 530#define strm t2 531#define strd t3 532#define clkd t4 533 534#define STRMLIM 4 535#define STRDLIM 16 536#define CLKDLIM 128 537#define CLKDLIM_IC 256 538 539 /* Initialize counter & saved values */ 540 move pass_countmax,zero 541 move strmmax,zero 542 move strdmax,zero 543 li clkdlim,CLKDLIM 544 545 and strm,t0,0x2000 # Test for internal clock (Using strm as a temp) 546 beqz strm,strmloop 547 nop 548 549 li clkdlim,CLKDLIM_IC 550 551 move strm,zero # strm loop 552strmloop: 553 move strd,zero 554strdloop: 555 move pass_count,zero 556 move clkdsum,zero 557 move clkd,zero 558 559 /* Inner loop: call sdr_do_init to re-initialize and the test mem */ 560clkdloop: 561 bal sdr_do_init 562 nop 563 564 bal test_mem 565 nop 566 567 beqz v0,failclkd 568 nop 569 570 /* Memory is ok */ 571 572 addi pass_count,1 573 add clkdsum,clkdsum,clkd 574 b nextclkd 575 nop 576 577failclkd: 578 bnez pass_count,clkdout # End of passing range, leave clkd loop 579 nop 580 581nextclkd: 582 addi clkd,clkd,1 583 blt clkd,clkdlim,clkdloop 584 nop 585 586clkdout: 587 /* If no passing values, skip to next strm */ 588 beqz pass_count,nextstrm 589 nop 590 591 /* If this is a new max, Save the values */ 592 ble pass_count,pass_countmax,nextstrd 593 nop 594 595 move pass_countmax,pass_count 596 div zero,clkdsum,pass_count 597 mflo clkdmax 598 move strdmax,strd 599 move strmmax,strm 600 601nextstrd: 602 addi strd,strd,1 603 blt strd,STRDLIM,strdloop 604 nop 605 606nextstrm: 607 addi strm,strm,1 608 blt strm,STRMLIM,strmloop 609 nop 610 611 /* All done, program the new ncdl values */ 612 613 beqz pass_countmax,1f 614 nop 615 616 move clkd,clkdmax 617 move strd,strdmax 618 move strm,strmmax 619 b sdr_got_ncdl 620 nop 621 622 /* No passing values, panic! (use defaults) */ 6231: 624#ifdef MEMSDR 625 li t3,MEMC_SDR_NCDL # If rev0, 2: 626 bne v1,1,2f 627 nop 628 li t3,MEMC_SDR1_NCDL # rev1: 629#else 630 li t3,MEMC_DDR_NCDL # If rev0, 2: 631 bne v1,1,2f 632 nop 633 li t3,MEMC_DDR1_NCDL # rev1: 634#endif 6352: 636 637break_sdr_ncdl: 638 andi t4,t3,0xff # t4: cd 639 srl t2,t3,16 # t2: sm 640 andi t2,t2,3 # sm is 2 bits only 641 srl t3,t3,8 # t3: sd 642 andi t3,t3,0xf # sd is 4 bits 643 644sdr_got_ncdl: 645 bal sdr_do_init 646 nop 647 648 b szmem 649 nop 650 651 652 /* Do an init of the memc core for sdr 653 * a0: memc core pointer 654 * t0: memc config value 655 * t1: memc mode value 656 * t2: memc strobe mode ncdl value 657 * t3: memc strobe delay ncdl value 658 * t4: memc clock delay ncdl value 659 * 660 * Uses a1, t7, t8, t9 (here and by calling sb_core_reset) 661 */ 662sdr_do_init: 663 664 /* Save return address */ 665 move t7,ra 666 667 bal sb_core_reset 668 li a1,0x40 669 670 /* Initialize SDRAM */ 671 li a1,MEMC_SD_CONFIG_INIT 672 or a1,a1,t0 673 sw a1,MEMC_CONFIG(a0) 674 675 li a1,MEMC_SD_DRAMTIM3_INIT # Assume CAS latency of 3 676 andi t8,t1,0xf0 # Find out the CAS latency 677 bne t8,0x20,1f 678 nop 679 li a1,MEMC_SD_DRAMTIM2_INIT # CAS latency is 2 6801: 681 sw a1,MEMC_DRAMTIM(a0) 682 683 andi t8,t4,0xff 684 ble t8,MEMC_CD_THRESHOLD,1f # if (cd <= 128) rd = cd 685 nop 686 687 li t8,MEMC_CD_THRESHOLD # else rd = 128 688 6891: # t8 is now rd 690 sll a1,t8,8 # .. replicate it 4 times 691 or a1,a1,t8 692 sll t8,a1,16 693 or t8,t8,a1 694 li a1,MEMC_SD_RDNCDLCOR_INIT 695 or a1,a1,t8 696 sw a1,MEMC_RDNCDLCOR(a0) 697 698 li a1,MEMC_SD1_WRNCDLCOR_INIT # rev1 699 beq v1,1,1f 700 nop 701 li a1,MEMC_SD_WRNCDLCOR_INIT # rev0, 2 7021: 703 li t8,0 704 ble t4,MEMC_CD_THRESHOLD,2f # if (cd <= 128) wr = 0 705 nop 706 707 andi t8,t4,0xff # else wr = cd - 128 708 sub t8,t8,MEMC_CD_THRESHOLD 709 andi t8,t8,0xff 710 7112: # t8 is now wr, a0 is extra bits 712 or a1,a1,t8 713 sw a1,MEMC_WRNCDLCOR(a0) 714 715 andi t8,t2,3 716 sll a1,t8,28 717 andi t8,t3,0xf 718 sll t8,t8,24 719 or t8,t8,a1 720 li a1,MEMC_SD_MISCDLYCTL_INIT 721 bne v1,1,3f # If rev0, 2: 722 nop 723 li a1,MEMC_SD1_MISCDLYCTL_INIT # rev1: 7243: 725 or a1,a1,t8 726 sw a1,MEMC_MISCDLYCTL(a0) 727 728 li a1,MEMC_SD_CONTROL_INIT0 729 sw a1,MEMC_CONTROL(a0) 730 731 li a1,MEMC_SD_CONTROL_INIT1 732 sw a1,MEMC_CONTROL(a0) 733 734 li a1,MEMC_SD_CONTROL_INIT2 735 sw a1,MEMC_CONTROL(a0) 736 lw a1,MEMC_CONTROL(a0) 737 lw a1,MEMC_CONTROL(a0) 738 lw a1,MEMC_CONTROL(a0) 739 740 li a1,MEMC_SD_CONTROL_INIT2 741 sw a1,MEMC_CONTROL(a0) 742 lw a1,MEMC_CONTROL(a0) 743 lw a1,MEMC_CONTROL(a0) 744 lw a1,MEMC_CONTROL(a0) 745 746 li a1,MEMC_SD_CONTROL_INIT2 747 sw a1,MEMC_CONTROL(a0) 748 lw a1,MEMC_CONTROL(a0) 749 lw a1,MEMC_CONTROL(a0) 750 lw a1,MEMC_CONTROL(a0) 751 752 li a1,MEMC_SD_REFRESH_INIT 753 sw a1,MEMC_REFRESH(a0) 754 755 li a1,MEMC_SD_MODEBUF_INIT 756 or a1,a1,t1 757 sw a1,MEMC_MODEBUF(a0) 758 759 li a1,MEMC_SD_CONTROL_INIT3 760 sw a1,MEMC_CONTROL(a0) 761 762 li a1,MEMC_SD_CONTROL_INIT4 763 sw a1,MEMC_CONTROL(a0) 764 765 li t8,50 7661: lw a1,R_SBIDLOW(a0) 767 lw a1,R_SBIDHIGH(a0) 768 bnez t8,1b 769 subu t8,1 770 771 jr t7 772 nop 773 774 775 776/* 777 * Common exit code and subroutines shared by SDR and DDR initialization. 778 */ 779 780 /* Determine memory size and return 781 * 782 * Somewhat simplistic, assumes size is a power of 2 and looks 783 * for aliases of location 0. 784 */ 785szmem: 786 li t0,PHYS_TO_K1(0) 787 li t2,0xaa55beef 788 sw t2,0(t0) 789 li v0,4 /* Assume minimum of 4MB */ 790 7911: 792 sll t0,v0,20 793 or t0,PHYS_TO_K1(0) 794 lw t1,0(t0) 795 beq t1,t2,done 796 nop 797 798 sll v0,v0,1 799 bne v0,128,1b /* Fully populated at 128MB, no alias */ 800 nop 801 802done: 803 jr t6 804 nop 805 806 807 /* 808 * Test memory 809 * 810 * Uses arg in t2(wr/sd), t3(rd/sm) and t4(g/clkd) 811 * Returns success (1) or failure (0) in v0 812 * Uses a1, a2, a3 & t5 813 */ 814test_mem: 815 /* Use t4 to generate a semi-random address in the second KB */ 816 li a1,0xa0000000 817 addi a2,t4,255 818 sll a2,a2,2 819 add a1,a1,a2 820 821 /* First set: 0 & its negation */ 822 li a2,0 823 sw a2,0(a1) 824 not a3,a2 825 sw a3,4(a1) 826 nop 827 lw t5,0(a1) 828 bne a2,t5,bad_mem 829 nop 830 lw t5,4(a1) 831 bne a3,t5,bad_mem 832 nop 833 834 /* Second set: 0xaaaaaaaa & its negation */ 835 li a2,0xaaaaaaaa 836 sw a2,0(a1) 837 not a3,a2 838 sw a3,4(a1) 839 nop 840 lw t5,0(a1) 841 bne a2,t5,bad_mem 842 nop 843 lw t5,4(a1) 844 bne a3,t5,bad_mem 845 nop 846 847 /* Third set: 0x12345678 & its negation */ 848 li a2,0x12345678 849 sw a2,0(a1) 850 not a3,a2 851 sw a3,4(a1) 852 nop 853 lw t5,0(a1) 854 bne a2,t5,bad_mem 855 nop 856 lw t5,4(a1) 857 bne a3,t5,bad_mem 858 nop 859 860 /* Fourth set: the ncdl & its negation */ 861 sll a2,t2,8 862 or a2,t3 863 sll a2,a2,8 864 or a2,t4 865 sw a2,0(a1) 866 not a3,a2 867 sw a3,4(a1) 868 nop 869 lw t5,0(a1) 870 bne a2,t5,bad_mem 871 nop 872 lw t5,4(a1) 873 bne a3,t5,bad_mem 874 nop 875 876 /* Fifth set: the CPU count register & its negation */ 877 mfc0 a2,$9 878 sw a2,0(a1) 879 not a3,a2 880 sw a3,4(a1) 881 nop 882 lw t5,0(a1) 883 bne a2,t5,bad_mem 884 nop 885 lw t5,4(a1) 886 bne a3,t5,bad_mem 887 nop 888 889 jr ra 890 li v0,1 891 892bad_mem: 893 jr ra 894 li v0,0 895 896 897 /* Special sb_core_reset that makes sure the first time 898 * clock is enabled, address line 6 is in the state specified 899 * by a1. 900 * 901 * a0: Core pointer 902 * a1: 0x40 if a6 needs to be 1, 0 otherwise 903 * uses t8, t9 904 */ 905 906 .align 6 907 908sb_core_reset: 909 910 /* Save return address */ 911 move t9,ra 912 913 /* run uncached */ 914 bal kseg1_switch 915 nop 916 917 /* Figure out our address */ 918 bal h0 919 nop 920h0: add t8,ra,24 # This is (h1 - h0) 921 andi t8,t8,0x40 922 bne t8,a1,alt_core_reset 923 nop 924 925 /* Set reset while enabling the clock */ 926 li t8,(M_SBTS_FC | M_SBTS_CE | M_SBTS_RS) # 2 instructions 927h1: sw t8,R_SBTMSTATELOW(a0) 928 b cont 929 nop 930 931 /* Now pad to 0x40: We want (h2 - h1) == 0x40 and there 932 * are 5 instructions in between them. 933 */ 934 .space (0x40 - 20) 935 936alt_core_reset: 937 /* Set reset while enabling the clock */ 938 li t8,(M_SBTS_FC | M_SBTS_CE | M_SBTS_RS) # 2 instructions 939h2: sw t8,R_SBTMSTATELOW(a0) 940 941cont: 942 /* Read back and delay */ 943 lw t8, R_SBTMSTATELOW(a0) 944 lw t8, R_SBTMSTATELOW(a0) 945 lw t8, R_SBTMSTATELOW(a0) 946 947 /* Clear reset */ 948 li t8, (M_SBTS_FC | M_SBTS_CE) 949 sw t8, R_SBTMSTATELOW(a0) 950 951 /* Read back and delay */ 952 lw t8, R_SBTMSTATELOW(a0) 953 lw t8, R_SBTMSTATELOW(a0) 954 lw t8, R_SBTMSTATELOW(a0) 955 956 /* Leave clock enabled */ 957 li t8, M_SBTS_CE 958 sw t8, R_SBTMSTATELOW(a0) 959 960 /* Read back and delay */ 961 lw t8, R_SBTMSTATELOW(a0) 962 lw t8, R_SBTMSTATELOW(a0) 963 lw t8, R_SBTMSTATELOW(a0) 964 965 jr t9 966 nop 967 968 969kseg1_switch: 970 and ra, ra, 0x1fffffff 971 or ra, ra, PHYS_TO_K1(0) 972 jr ra 973 nop 974 975 .set reorder 976 END(board_draminit) 977