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 ; \ 369: 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 119LEAF(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 193no_i_cache: 194 move v0, zero 195 move v1, zero 1961: 197 jr ra 198 nop 199 .set reorder 200 201END(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 212LEAF(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 285no_d_cache: 286 move v0, zero 287 move v1, zero 2881: 289 jr ra 290 nop 291 .set reorder 292 293END(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 308enable_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 330l1_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 3601: 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 3871: 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 */ 416LEAF(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 440END(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 453LEAF(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 473END(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 */ 484LEAF(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 497END(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 */ 507LEAF(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 517END(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 */ 529LEAF(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 542END(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 */ 551LEAF(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 573END(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 */ 586LEAF(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 600enable_lmb: 601 li t1, (BRCM_ZSC_CONFIG_LMB1En | BRCM_ZSC_CONFIG_LMB0En) 602 or t0, t0, t1 603 604svlmb: 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 614END(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 628core_init: 629 move t8, ra 630 631 /* set Zephyr bits. */ 632 bal set_zephyr 633 nop 634 635#if ENABLE_FPU==1 636 /* initialize the Floating point unit (both TPs) */ 637 bal init_fpu 638 nop 639#endif 640 641 /* set low latency memory bus */ 642 li a0, 1 643 bal set_llmb 644 nop 645 646 /* set branch prediction (TP0 only) */ 647 bal set_branch_pred 648 nop 649 650 /* set link uncached */ 651 bal set_luc 652 nop 653 654 /* set CWF and TSE */ 655 bal set_cwf_tse 656 nop 657 658 /* 659 *set clock ratio by setting 1 to 'set' 660 * and 0 to ClkRatio, (TP0 only) 661 */ 662 li a0, 0 663 bal set_clock_ratio 664 nop 665 666 /* set other configuration to defaults */ 667 bal set_other_config 668 nop 669 670 move ra, t8 671 jr ra 672 nop 673 674 .set reorder 675 .end core_init 676 677/* 678 * Function: clear_jump_target_buffer 679 * Arguments: None 680 * Returns: None 681 * Description: 682 * Trashes: t0, t1, t2 683 * 684 */ 685#define RESET_CALL_RETURN_STACK_THIS_THREAD (0x06<<16) 686#define RESET_JUMP_TARGET_BUFFER_THIS_THREAD (0x04<<16) 687#define JTB_CS_CNTL_MASK (0xFF<<16) 688 689 .globl clear_jump_target_buffer 690 .ent clear_jump_target_buffer 691 .set noreorder 692clear_jump_target_buffer: 693 694 mfc0 t0, $22, 2 695 nop 696 nop 697 698 li t1, ~JTB_CS_CNTL_MASK 699 and t0, t0, t1 700 li t2, RESET_CALL_RETURN_STACK_THIS_THREAD 701 or t0, t0, t2 702 mtc0 t0, $22, 2 703 nop 704 nop 705 706 and t0, t0, t1 707 li t2, RESET_JUMP_TARGET_BUFFER_THIS_THREAD 708 or t0, t0, t2 709 mtc0 t0, $22, 2 710 nop 711 nop 712 jr ra 713 nop 714 715 .end clear_jump_target_buffer 716 .set reorder 717/* 718 * Function: bmips_cache_init 719 * Arguments: None 720 * Returns: None 721 * Description: Enable I and D caches, and initialize I and D-caches 722 * Trashes: v0, v1, t0, t1, t2, t5, t7, t8 723 * 724 */ 725 .globl bmips_5xxx_init 726 .ent bmips_5xxx_init 727 .set noreorder 728bmips_5xxx_init: 729 730 /* save return address and A0 */ 731 move t7, ra 732 move t5, a0 733 734 jal l1_init 735 nop 736 737 jal core_init 738 nop 739 740 jal clear_jump_target_buffer 741 nop 742 743 mtc0 zero, CP0_CAUSE 744 745 move a0, t5 746 jr t7 747 nop 748 749 .end bmips_5xxx_init 750 .set reorder 751 752 753#endif 754