1 2 /* 3 * This file is subject to the terms and conditions of the GNU General Public 4 * License. See the file "COPYING" in the main directory of this archive 5 * for more details. 6 * 7 * Copyright (C) 2011-2012 by Broadcom Corporation 8 * 9 * Init for bmips 5000. 10 * Used to init second core in dual core 5000's. 11 */ 12 13 #include <linux/init.h> 14 15 #include <asm/asm.h> 16 #include <asm/asmmacro.h> 17 #include <asm/cacheops.h> 18 #include <asm/regdef.h> 19 #include <asm/mipsregs.h> 20 #include <asm/stackframe.h> 21 #include <asm/addrspace.h> 22 #include <asm/hazards.h> 23 #include <asm/bmips.h> 24 25 #ifdef CONFIG_CPU_BMIPS5000 26 27 28 #define cacheop(kva, size, linesize, op) \ 29 .set noreorder ; \ 30 addu t1, kva, size ; \ 31 subu t2, linesize, 1 ; \ 32 not t2 ; \ 33 and t0, kva, t2 ; \ 34 addiu t1, t1, -1 ; \ 35 and t1, t2 ; \ 36 9: cache op, 0(t0) ; \ 37 bne t0, t1, 9b ; \ 38 addu t0, linesize ; \ 39 .set reorder ; 40 41 42 43 #define IS_SHIFT 22 44 #define IL_SHIFT 19 45 #define IA_SHIFT 16 46 #define DS_SHIFT 13 47 #define DL_SHIFT 10 48 #define DA_SHIFT 7 49 #define IS_MASK 7 50 #define IL_MASK 7 51 #define IA_MASK 7 52 #define DS_MASK 7 53 #define DL_MASK 7 54 #define DA_MASK 7 55 #define ICE_MASK 0x80000000 56 #define DCE_MASK 0x40000000 57 58 #define CP0_BRCM_CONFIG0 $22, 0 59 #define CP0_BRCM_MODE $22, 1 60 #define CP0_CONFIG_K0_MASK 7 61 62 #define CP0_ICACHE_TAG_LO $28 63 #define CP0_ICACHE_DATA_LO $28, 1 64 #define CP0_DCACHE_TAG_LO $28, 2 65 #define CP0_D_SEC_CACHE_DATA_LO $28, 3 66 #define CP0_ICACHE_TAG_HI $29 67 #define CP0_ICACHE_DATA_HI $29, 1 68 #define CP0_DCACHE_TAG_HI $29, 2 69 70 #define CP0_BRCM_MODE_Luc_MASK (1 << 11) 71 #define CP0_BRCM_CONFIG0_CWF_MASK (1 << 20) 72 #define CP0_BRCM_CONFIG0_TSE_MASK (1 << 19) 73 #define CP0_BRCM_MODE_SET_MASK (1 << 7) 74 #define CP0_BRCM_MODE_ClkRATIO_MASK (7 << 4) 75 #define CP0_BRCM_MODE_BrPRED_MASK (3 << 24) 76 #define CP0_BRCM_MODE_BrPRED_SHIFT 24 77 #define CP0_BRCM_MODE_BrHIST_MASK (0x1f << 20) 78 #define CP0_BRCM_MODE_BrHIST_SHIFT 20 79 80 /* ZSC L2 Cache Register Access Register Definitions */ 81 #define BRCM_ZSC_ALL_REGS_SELECT 0x7 << 24 82 83 #define BRCM_ZSC_CONFIG_REG 0 << 3 84 #define BRCM_ZSC_REQ_BUFFER_REG 2 << 3 85 #define BRCM_ZSC_RBUS_ADDR_MAPPING_REG0 4 << 3 86 #define BRCM_ZSC_RBUS_ADDR_MAPPING_REG1 6 << 3 87 #define BRCM_ZSC_RBUS_ADDR_MAPPING_REG2 8 << 3 88 89 #define BRCM_ZSC_SCB0_ADDR_MAPPING_REG0 0xa << 3 90 #define BRCM_ZSC_SCB0_ADDR_MAPPING_REG1 0xc << 3 91 92 #define BRCM_ZSC_SCB1_ADDR_MAPPING_REG0 0xe << 3 93 #define BRCM_ZSC_SCB1_ADDR_MAPPING_REG1 0x10 << 3 94 95 #define BRCM_ZSC_CONFIG_LMB1En 1 << (15) 96 #define BRCM_ZSC_CONFIG_LMB0En 1 << (14) 97 98 /* branch predition values */ 99 100 #define BRCM_BrPRED_ALL_TAKEN (0x0) 101 #define BRCM_BrPRED_ALL_NOT_TAKEN (0x1) 102 #define BRCM_BrPRED_BHT_ENABLE (0x2) 103 #define BRCM_BrPRED_PREDICT_BACKWARD (0x3) 104 105 106 107 .align 2 108 /* 109 * Function: size_i_cache 110 * Arguments: None 111 * Returns: v0 = i cache size, v1 = I cache line size 112 * Description: compute the I-cache size and I-cache line size 113 * Trashes: v0, v1, a0, t0 114 * 115 * pseudo code: 116 * 117 */ 118 119 LEAF(size_i_cache) 120 .set noreorder 121 122 mfc0 a0, CP0_CONFIG, 1 123 move t0, a0 124 125 /* 126 * Determine sets per way: IS 127 * 128 * This field contains the number of sets (i.e., indices) per way of 129 * the instruction cache: 130 * i) 0x0: 64, ii) 0x1: 128, iii) 0x2: 256, iv) 0x3: 512, v) 0x4: 1k 131 * vi) 0x5 - 0x7: Reserved. 132 */ 133 134 srl a0, a0, IS_SHIFT 135 and a0, a0, IS_MASK 136 137 /* sets per way = (64<<IS) */ 138 139 li v0, 0x40 140 sllv v0, v0, a0 141 142 /* 143 * Determine line size 144 * 145 * This field contains the line size of the instruction cache: 146 * i) 0x0: No I-cache present, i) 0x3: 16 bytes, ii) 0x4: 32 bytes, iii) 147 * 0x5: 64 bytes, iv) the rest: Reserved. 148 */ 149 150 move a0, t0 151 152 srl a0, a0, IL_SHIFT 153 and a0, a0, IL_MASK 154 155 beqz a0, no_i_cache 156 nop 157 158 /* line size = 2 ^ (IL+1) */ 159 160 addi a0, a0, 1 161 li v1, 1 162 sll v1, v1, a0 163 164 /* v0 now have sets per way, multiply it by line size now 165 * that will give the set size 166 */ 167 168 sll v0, v0, a0 169 170 /* 171 * Determine set associativity 172 * 173 * This field contains the set associativity of the instruction cache. 174 * i) 0x0: Direct mapped, ii) 0x1: 2-way, iii) 0x2: 3-way, iv) 0x3: 175 * 4-way, v) 0x4 - 0x7: Reserved. 176 */ 177 178 move a0, t0 179 180 srl a0, a0, IA_SHIFT 181 and a0, a0, IA_MASK 182 addi a0, a0, 0x1 183 184 /* v0 has the set size, multiply it by 185 * set associativiy, to get the cache size 186 */ 187 188 multu v0, a0 /*multu is interlocked, so no need to insert nops */ 189 mflo v0 190 b 1f 191 nop 192 193 no_i_cache: 194 move v0, zero 195 move v1, zero 196 1: 197 jr ra 198 nop 199 .set reorder 200 201 END(size_i_cache) 202 203 /* 204 * Function: size_d_cache 205 * Arguments: None 206 * Returns: v0 = d cache size, v1 = d cache line size 207 * Description: compute the D-cache size and D-cache line size. 208 * Trashes: v0, v1, a0, t0 209 * 210 */ 211 212 LEAF(size_d_cache) 213 .set noreorder 214 215 mfc0 a0, CP0_CONFIG, 1 216 move t0, a0 217 218 /* 219 * Determine sets per way: IS 220 * 221 * This field contains the number of sets (i.e., indices) per way of 222 * the instruction cache: 223 * i) 0x0: 64, ii) 0x1: 128, iii) 0x2: 256, iv) 0x3: 512, v) 0x4: 1k 224 * vi) 0x5 - 0x7: Reserved. 225 */ 226 227 srl a0, a0, DS_SHIFT 228 and a0, a0, DS_MASK 229 230 /* sets per way = (64<<IS) */ 231 232 li v0, 0x40 233 sllv v0, v0, a0 234 235 /* 236 * Determine line size 237 * 238 * This field contains the line size of the instruction cache: 239 * i) 0x0: No I-cache present, i) 0x3: 16 bytes, ii) 0x4: 32 bytes, iii) 240 * 0x5: 64 bytes, iv) the rest: Reserved. 241 */ 242 move a0, t0 243 244 srl a0, a0, DL_SHIFT 245 and a0, a0, DL_MASK 246 247 beqz a0, no_d_cache 248 nop 249 250 /* line size = 2 ^ (IL+1) */ 251 252 addi a0, a0, 1 253 li v1, 1 254 sll v1, v1, a0 255 256 /* v0 now have sets per way, multiply it by line size now 257 * that will give the set size 258 */ 259 260 sll v0, v0, a0 261 262 /* determine set associativity 263 * 264 * This field contains the set associativity of the instruction cache. 265 * i) 0x0: Direct mapped, ii) 0x1: 2-way, iii) 0x2: 3-way, iv) 0x3: 266 * 4-way, v) 0x4 - 0x7: Reserved. 267 */ 268 269 move a0, t0 270 271 srl a0, a0, DA_SHIFT 272 and a0, a0, DA_MASK 273 addi a0, a0, 0x1 274 275 /* v0 has the set size, multiply it by 276 * set associativiy, to get the cache size 277 */ 278 279 multu v0, a0 /*multu is interlocked, so no need to insert nops */ 280 mflo v0 281 282 b 1f 283 nop 284 285 no_d_cache: 286 move v0, zero 287 move v1, zero 288 1: 289 jr ra 290 nop 291 .set reorder 292 293 END(size_d_cache) 294 295 296 /* 297 * Function: enable_ID 298 * Arguments: None 299 * Returns: None 300 * Description: Enable I and D caches, initialize I and D-caches, also set 301 * hardware delay for d-cache (TP0). 302 * Trashes: t0 303 * 304 */ 305 .global enable_ID 306 .ent enable_ID 307 .set noreorder 308 enable_ID: 309 mfc0 t0, CP0_BRCM_CONFIG0 310 or t0, t0, (ICE_MASK | DCE_MASK) 311 mtc0 t0, CP0_BRCM_CONFIG0 312 jr ra 313 nop 314 315 .end enable_ID 316 .set reorder 317 318 319 /* 320 * Function: l1_init 321 * Arguments: None 322 * Returns: None 323 * Description: Enable I and D caches, and initialize I and D-caches 324 * Trashes: a0, v0, v1, t0, t1, t2, t8 325 * 326 */ 327 .globl l1_init 328 .ent l1_init 329 .set noreorder 330 l1_init: 331 332 /* save return address */ 333 move t8, ra 334 335 336 /* initialize I and D cache Data and Tag registers. */ 337 mtc0 zero, CP0_ICACHE_TAG_LO 338 mtc0 zero, CP0_ICACHE_TAG_HI 339 mtc0 zero, CP0_ICACHE_DATA_LO 340 mtc0 zero, CP0_ICACHE_DATA_HI 341 mtc0 zero, CP0_DCACHE_TAG_LO 342 mtc0 zero, CP0_DCACHE_TAG_HI 343 344 /* Enable Caches before Clearing. If the caches are disabled 345 * then the cache operations to clear the cache will be ignored 346 */ 347 348 jal enable_ID 349 nop 350 351 jal size_i_cache /* v0 = i-cache size, v1 = i-cache line size */ 352 nop 353 354 /* run uncached in kseg 1 */ 355 la k0, 1f 356 lui k1, 0x2000 357 or k0, k1, k0 358 jr k0 359 nop 360 1: 361 362 /* 363 * set K0 cache mode 364 */ 365 366 mfc0 t0, CP0_CONFIG 367 and t0, t0, ~CP0_CONFIG_K0_MASK 368 or t0, t0, 3 /* Write Back mode */ 369 mtc0 t0, CP0_CONFIG 370 371 /* 372 * Initialize instruction cache. 373 */ 374 375 li a0, KSEG0 376 cacheop(a0, v0, v1, Index_Store_Tag_I) 377 378 /* 379 * Now we can run from I-$, kseg 0 380 */ 381 la k0, 1f 382 lui k1, 0x2000 383 or k0, k1, k0 384 xor k0, k1, k0 385 jr k0 386 nop 387 1: 388 /* 389 * Initialize data cache. 390 */ 391 392 jal size_d_cache /* v0 = d-cache size, v1 = d-cache line size */ 393 nop 394 395 396 li a0, KSEG0 397 cacheop(a0, v0, v1, Index_Store_Tag_D) 398 399 jr t8 400 nop 401 402 .end l1_init 403 .set reorder 404 405 406 /* 407 * Function: set_other_config 408 * Arguments: none 409 * Returns: None 410 * Description: initialize other remainder configuration to defaults. 411 * Trashes: t0, t1 412 * 413 * pseudo code: 414 * 415 */ 416 LEAF(set_other_config) 417 .set noreorder 418 419 /* enable Bus error for I-fetch */ 420 mfc0 t0, CP0_CACHEERR, 0 421 li t1, 0x4 422 or t0, t1 423 mtc0 t0, CP0_CACHEERR, 0 424 425 /* enable Bus error for Load */ 426 mfc0 t0, CP0_CACHEERR, 1 427 li t1, 0x4 428 or t0, t1 429 mtc0 t0, CP0_CACHEERR, 1 430 431 /* enable Bus Error for Store */ 432 mfc0 t0, CP0_CACHEERR, 2 433 li t1, 0x4 434 or t0, t1 435 mtc0 t0, CP0_CACHEERR, 2 436 437 jr ra 438 nop 439 .set reorder 440 END(set_other_config) 441 442 /* 443 * Function: set_branch_pred 444 * Arguments: none 445 * Returns: None 446 * Description: 447 * Trashes: t0, t1 448 * 449 * pseudo code: 450 * 451 */ 452 453 LEAF(set_branch_pred) 454 .set noreorder 455 mfc0 t0, CP0_BRCM_MODE 456 li t1, ~(CP0_BRCM_MODE_BrPRED_MASK | CP0_BRCM_MODE_BrHIST_MASK ) 457 and t0, t0, t1 458 459 /* enable Branch prediction */ 460 li t1, BRCM_BrPRED_BHT_ENABLE 461 sll t1, CP0_BRCM_MODE_BrPRED_SHIFT 462 or t0, t0, t1 463 464 /* set history count to 8 */ 465 li t1, 8 466 sll t1, CP0_BRCM_MODE_BrHIST_SHIFT 467 or t0, t0, t1 468 469 mtc0 t0, CP0_BRCM_MODE 470 jr ra 471 nop 472 .set reorder 473 END(set_branch_pred) 474 475 476 /* 477 * Function: set_luc 478 * Arguments: set link uncached. 479 * Returns: None 480 * Description: 481 * Trashes: t0, t1 482 * 483 */ 484 LEAF(set_luc) 485 .set noreorder 486 mfc0 t0, CP0_BRCM_MODE 487 li t1, ~(CP0_BRCM_MODE_Luc_MASK) 488 and t0, t0, t1 489 490 /* set Luc */ 491 ori t0, t0, CP0_BRCM_MODE_Luc_MASK 492 493 mtc0 t0, CP0_BRCM_MODE 494 jr ra 495 nop 496 .set reorder 497 END(set_luc) 498 499 /* 500 * Function: set_cwf_tse 501 * Arguments: set CWF and TSE bits 502 * Returns: None 503 * Description: 504 * Trashes: t0, t1 505 * 506 */ 507 LEAF(set_cwf_tse) 508 .set noreorder 509 mfc0 t0, CP0_BRCM_CONFIG0 510 li t1, (CP0_BRCM_CONFIG0_CWF_MASK | CP0_BRCM_CONFIG0_TSE_MASK) 511 or t0, t0, t1 512 513 mtc0 t0, CP0_BRCM_CONFIG0 514 jr ra 515 nop 516 .set reorder 517 END(set_cwf_tse) 518 519 /* 520 * Function: set_clock_ratio 521 * Arguments: set clock ratio specified by a0 522 * Returns: None 523 * Description: 524 * Trashes: v0, v1, a0, a1 525 * 526 * pseudo code: 527 * 528 */ 529 LEAF(set_clock_ratio) 530 .set noreorder 531 532 mfc0 t0, CP0_BRCM_MODE 533 li t1, ~(CP0_BRCM_MODE_SET_MASK | CP0_BRCM_MODE_ClkRATIO_MASK) 534 and t0, t0, t1 535 li t1, CP0_BRCM_MODE_SET_MASK 536 or t0, t0, t1 537 or t0, t0, a0 538 mtc0 t0, CP0_BRCM_MODE 539 jr ra 540 nop 541 .set reorder 542 END(set_clock_ratio) 543 /* 544 * Function: set_zephyr 545 * Arguments: None 546 * Returns: None 547 * Description: Set any zephyr bits 548 * Trashes: t0 & t1 549 * 550 */ 551 LEAF(set_zephyr) 552 .set noreorder 553 554 /* enable read/write of CP0 #22 sel. 8 */ 555 li t0, 0x5a455048 556 .word 0x4088b00f /* mtc0 t0, $22, 15 */ 557 558 .word 0x4008b008 /* mfc0 t0, $22, 8 */ 559 li t1, 0x09008000 /* turn off pref, jtb */ 560 or t0, t0, t1 561 .word 0x4088b008 /* mtc0 t0, $22, 8 */ 562 sync 563 564 /* disable read/write of CP0 #22 sel 8 */ 565 li t0, 0x0 566 .word 0x4088b00f /* mtc0 t0, $22, 15 */ 567 568 569 jr ra 570 nop 571 .set reorder 572 573 END(set_zephyr) 574 575 576 /* 577 * Function: set_llmb 578 * Arguments: a0=0 disable llmb, a0=1 enables llmb 579 * Returns: None 580 * Description: 581 * Trashes: t0, t1, t2 582 * 583 * pseudo code: 584 * 585 */ 586 LEAF(set_llmb) 587 .set noreorder 588 589 li t2, 0x90000000 | BRCM_ZSC_ALL_REGS_SELECT | BRCM_ZSC_CONFIG_REG 590 sync 591 cache 0x7, 0x0(t2) 592 sync 593 mfc0 t0, CP0_D_SEC_CACHE_DATA_LO 594 li t1, ~(BRCM_ZSC_CONFIG_LMB1En | BRCM_ZSC_CONFIG_LMB0En) 595 and t0, t0, t1 596 597 beqz a0, svlmb 598 nop 599 600 enable_lmb: 601 li t1, (BRCM_ZSC_CONFIG_LMB1En | BRCM_ZSC_CONFIG_LMB0En) 602 or t0, t0, t1 603 604 svlmb: 605 mtc0 t0, CP0_D_SEC_CACHE_DATA_LO 606 sync 607 cache 0xb, 0x0(t2) 608 sync 609 610 jr ra 611 nop 612 .set reorder 613 614 END(set_llmb) 615 /* 616 * Function: core_init 617 * Arguments: none 618 * Returns: None 619 * Description: initialize core related configuration 620 * Trashes: v0,v1,a0,a1,t8 621 * 622 * pseudo code: 623 * 624 */ 625 .globl core_init 626 .ent core_init 627 .set noreorder 628 core_init: 629 move t8, ra 630 631 /* set Zephyr bits. */ 632 bal set_zephyr 633 nop 634 635 /* set low latency memory bus */ 636 li a0, 1 637 bal set_llmb 638 nop 639 640 /* set branch prediction (TP0 only) */ 641 bal set_branch_pred 642 nop 643 644 /* set link uncached */ 645 bal set_luc 646 nop 647 648 /* set CWF and TSE */ 649 bal set_cwf_tse 650 nop 651 652 /* 653 *set clock ratio by setting 1 to 'set' 654 * and 0 to ClkRatio, (TP0 only) 655 */ 656 li a0, 0 657 bal set_clock_ratio 658 nop 659 660 /* set other configuration to defaults */ 661 bal set_other_config 662 nop 663 664 move ra, t8 665 jr ra 666 nop 667 668 .set reorder 669 .end core_init 670 671 /* 672 * Function: clear_jump_target_buffer 673 * Arguments: None 674 * Returns: None 675 * Description: 676 * Trashes: t0, t1, t2 677 * 678 */ 679 #define RESET_CALL_RETURN_STACK_THIS_THREAD (0x06<<16) 680 #define RESET_JUMP_TARGET_BUFFER_THIS_THREAD (0x04<<16) 681 #define JTB_CS_CNTL_MASK (0xFF<<16) 682 683 .globl clear_jump_target_buffer 684 .ent clear_jump_target_buffer 685 .set noreorder 686 clear_jump_target_buffer: 687 688 mfc0 t0, $22, 2 689 nop 690 nop 691 692 li t1, ~JTB_CS_CNTL_MASK 693 and t0, t0, t1 694 li t2, RESET_CALL_RETURN_STACK_THIS_THREAD 695 or t0, t0, t2 696 mtc0 t0, $22, 2 697 nop 698 nop 699 700 and t0, t0, t1 701 li t2, RESET_JUMP_TARGET_BUFFER_THIS_THREAD 702 or t0, t0, t2 703 mtc0 t0, $22, 2 704 nop 705 nop 706 jr ra 707 nop 708 709 .end clear_jump_target_buffer 710 .set reorder 711 /* 712 * Function: bmips_cache_init 713 * Arguments: None 714 * Returns: None 715 * Description: Enable I and D caches, and initialize I and D-caches 716 * Trashes: v0, v1, t0, t1, t2, t5, t7, t8 717 * 718 */ 719 .globl bmips_5xxx_init 720 .ent bmips_5xxx_init 721 .set noreorder 722 bmips_5xxx_init: 723 724 /* save return address and A0 */ 725 move t7, ra 726 move t5, a0 727 728 jal l1_init 729 nop 730 731 jal core_init 732 nop 733 734 jal clear_jump_target_buffer 735 nop 736 737 mtc0 zero, CP0_CAUSE 738 739 move a0, t5 740 jr t7 741 nop 742 743 .end bmips_5xxx_init 744 .set reorder 745 746 747 #endif
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.