linux/arch/mips/kernel/bmips_5xxx_init.S
<<
>>
Prefs
   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