123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754 |
- /*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2011-2012 by Broadcom Corporation
- *
- * Init for bmips 5000.
- * Used to init second core in dual core 5000's.
- */
- #include <linux/init.h>
- #include <asm/asm.h>
- #include <asm/asmmacro.h>
- #include <asm/cacheops.h>
- #include <asm/regdef.h>
- #include <asm/mipsregs.h>
- #include <asm/stackframe.h>
- #include <asm/addrspace.h>
- #include <asm/hazards.h>
- #include <asm/bmips.h>
- #ifdef CONFIG_CPU_BMIPS5000
- #define cacheop(kva, size, linesize, op) \
- .set noreorder ; \
- addu t1, kva, size ; \
- subu t2, linesize, 1 ; \
- not t2 ; \
- and t0, kva, t2 ; \
- addiu t1, t1, -1 ; \
- and t1, t2 ; \
- 9: cache op, 0(t0) ; \
- bne t0, t1, 9b ; \
- addu t0, linesize ; \
- .set reorder ;
- #define IS_SHIFT 22
- #define IL_SHIFT 19
- #define IA_SHIFT 16
- #define DS_SHIFT 13
- #define DL_SHIFT 10
- #define DA_SHIFT 7
- #define IS_MASK 7
- #define IL_MASK 7
- #define IA_MASK 7
- #define DS_MASK 7
- #define DL_MASK 7
- #define DA_MASK 7
- #define ICE_MASK 0x80000000
- #define DCE_MASK 0x40000000
- #define CP0_BRCM_CONFIG0 $22, 0
- #define CP0_BRCM_MODE $22, 1
- #define CP0_CONFIG_K0_MASK 7
- #define CP0_ICACHE_TAG_LO $28
- #define CP0_ICACHE_DATA_LO $28, 1
- #define CP0_DCACHE_TAG_LO $28, 2
- #define CP0_D_SEC_CACHE_DATA_LO $28, 3
- #define CP0_ICACHE_TAG_HI $29
- #define CP0_ICACHE_DATA_HI $29, 1
- #define CP0_DCACHE_TAG_HI $29, 2
- #define CP0_BRCM_MODE_Luc_MASK (1 << 11)
- #define CP0_BRCM_CONFIG0_CWF_MASK (1 << 20)
- #define CP0_BRCM_CONFIG0_TSE_MASK (1 << 19)
- #define CP0_BRCM_MODE_SET_MASK (1 << 7)
- #define CP0_BRCM_MODE_ClkRATIO_MASK (7 << 4)
- #define CP0_BRCM_MODE_BrPRED_MASK (3 << 24)
- #define CP0_BRCM_MODE_BrPRED_SHIFT 24
- #define CP0_BRCM_MODE_BrHIST_MASK (0x1f << 20)
- #define CP0_BRCM_MODE_BrHIST_SHIFT 20
- /* ZSC L2 Cache Register Access Register Definitions */
- #define BRCM_ZSC_ALL_REGS_SELECT 0x7 << 24
- #define BRCM_ZSC_CONFIG_REG 0 << 3
- #define BRCM_ZSC_REQ_BUFFER_REG 2 << 3
- #define BRCM_ZSC_RBUS_ADDR_MAPPING_REG0 4 << 3
- #define BRCM_ZSC_RBUS_ADDR_MAPPING_REG1 6 << 3
- #define BRCM_ZSC_RBUS_ADDR_MAPPING_REG2 8 << 3
- #define BRCM_ZSC_SCB0_ADDR_MAPPING_REG0 0xa << 3
- #define BRCM_ZSC_SCB0_ADDR_MAPPING_REG1 0xc << 3
- #define BRCM_ZSC_SCB1_ADDR_MAPPING_REG0 0xe << 3
- #define BRCM_ZSC_SCB1_ADDR_MAPPING_REG1 0x10 << 3
- #define BRCM_ZSC_CONFIG_LMB1En 1 << (15)
- #define BRCM_ZSC_CONFIG_LMB0En 1 << (14)
- /* branch predition values */
- #define BRCM_BrPRED_ALL_TAKEN (0x0)
- #define BRCM_BrPRED_ALL_NOT_TAKEN (0x1)
- #define BRCM_BrPRED_BHT_ENABLE (0x2)
- #define BRCM_BrPRED_PREDICT_BACKWARD (0x3)
- .align 2
- /*
- * Function: size_i_cache
- * Arguments: None
- * Returns: v0 = i cache size, v1 = I cache line size
- * Description: compute the I-cache size and I-cache line size
- * Trashes: v0, v1, a0, t0
- *
- * pseudo code:
- *
- */
- LEAF(size_i_cache)
- .set noreorder
- mfc0 a0, CP0_CONFIG, 1
- move t0, a0
- /*
- * Determine sets per way: IS
- *
- * This field contains the number of sets (i.e., indices) per way of
- * the instruction cache:
- * i) 0x0: 64, ii) 0x1: 128, iii) 0x2: 256, iv) 0x3: 512, v) 0x4: 1k
- * vi) 0x5 - 0x7: Reserved.
- */
- srl a0, a0, IS_SHIFT
- and a0, a0, IS_MASK
- /* sets per way = (64<<IS) */
- li v0, 0x40
- sllv v0, v0, a0
- /*
- * Determine line size
- *
- * This field contains the line size of the instruction cache:
- * i) 0x0: No I-cache present, i) 0x3: 16 bytes, ii) 0x4: 32 bytes, iii)
- * 0x5: 64 bytes, iv) the rest: Reserved.
- */
- move a0, t0
- srl a0, a0, IL_SHIFT
- and a0, a0, IL_MASK
- beqz a0, no_i_cache
- nop
- /* line size = 2 ^ (IL+1) */
- addi a0, a0, 1
- li v1, 1
- sll v1, v1, a0
- /* v0 now have sets per way, multiply it by line size now
- * that will give the set size
- */
- sll v0, v0, a0
- /*
- * Determine set associativity
- *
- * This field contains the set associativity of the instruction cache.
- * i) 0x0: Direct mapped, ii) 0x1: 2-way, iii) 0x2: 3-way, iv) 0x3:
- * 4-way, v) 0x4 - 0x7: Reserved.
- */
- move a0, t0
- srl a0, a0, IA_SHIFT
- and a0, a0, IA_MASK
- addi a0, a0, 0x1
- /* v0 has the set size, multiply it by
- * set associativiy, to get the cache size
- */
- multu v0, a0 /*multu is interlocked, so no need to insert nops */
- mflo v0
- b 1f
- nop
- no_i_cache:
- move v0, zero
- move v1, zero
- 1:
- jr ra
- nop
- .set reorder
- END(size_i_cache)
- /*
- * Function: size_d_cache
- * Arguments: None
- * Returns: v0 = d cache size, v1 = d cache line size
- * Description: compute the D-cache size and D-cache line size.
- * Trashes: v0, v1, a0, t0
- *
- */
- LEAF(size_d_cache)
- .set noreorder
- mfc0 a0, CP0_CONFIG, 1
- move t0, a0
- /*
- * Determine sets per way: IS
- *
- * This field contains the number of sets (i.e., indices) per way of
- * the instruction cache:
- * i) 0x0: 64, ii) 0x1: 128, iii) 0x2: 256, iv) 0x3: 512, v) 0x4: 1k
- * vi) 0x5 - 0x7: Reserved.
- */
- srl a0, a0, DS_SHIFT
- and a0, a0, DS_MASK
- /* sets per way = (64<<IS) */
- li v0, 0x40
- sllv v0, v0, a0
- /*
- * Determine line size
- *
- * This field contains the line size of the instruction cache:
- * i) 0x0: No I-cache present, i) 0x3: 16 bytes, ii) 0x4: 32 bytes, iii)
- * 0x5: 64 bytes, iv) the rest: Reserved.
- */
- move a0, t0
- srl a0, a0, DL_SHIFT
- and a0, a0, DL_MASK
- beqz a0, no_d_cache
- nop
- /* line size = 2 ^ (IL+1) */
- addi a0, a0, 1
- li v1, 1
- sll v1, v1, a0
- /* v0 now have sets per way, multiply it by line size now
- * that will give the set size
- */
- sll v0, v0, a0
- /* determine set associativity
- *
- * This field contains the set associativity of the instruction cache.
- * i) 0x0: Direct mapped, ii) 0x1: 2-way, iii) 0x2: 3-way, iv) 0x3:
- * 4-way, v) 0x4 - 0x7: Reserved.
- */
- move a0, t0
- srl a0, a0, DA_SHIFT
- and a0, a0, DA_MASK
- addi a0, a0, 0x1
- /* v0 has the set size, multiply it by
- * set associativiy, to get the cache size
- */
- multu v0, a0 /*multu is interlocked, so no need to insert nops */
- mflo v0
- b 1f
- nop
- no_d_cache:
- move v0, zero
- move v1, zero
- 1:
- jr ra
- nop
- .set reorder
- END(size_d_cache)
- /*
- * Function: enable_ID
- * Arguments: None
- * Returns: None
- * Description: Enable I and D caches, initialize I and D-caches, also set
- * hardware delay for d-cache (TP0).
- * Trashes: t0
- *
- */
- .global enable_ID
- .ent enable_ID
- .set noreorder
- enable_ID:
- mfc0 t0, CP0_BRCM_CONFIG0
- or t0, t0, (ICE_MASK | DCE_MASK)
- mtc0 t0, CP0_BRCM_CONFIG0
- jr ra
- nop
- .end enable_ID
- .set reorder
- /*
- * Function: l1_init
- * Arguments: None
- * Returns: None
- * Description: Enable I and D caches, and initialize I and D-caches
- * Trashes: a0, v0, v1, t0, t1, t2, t8
- *
- */
- .globl l1_init
- .ent l1_init
- .set noreorder
- l1_init:
- /* save return address */
- move t8, ra
- /* initialize I and D cache Data and Tag registers. */
- mtc0 zero, CP0_ICACHE_TAG_LO
- mtc0 zero, CP0_ICACHE_TAG_HI
- mtc0 zero, CP0_ICACHE_DATA_LO
- mtc0 zero, CP0_ICACHE_DATA_HI
- mtc0 zero, CP0_DCACHE_TAG_LO
- mtc0 zero, CP0_DCACHE_TAG_HI
- /* Enable Caches before Clearing. If the caches are disabled
- * then the cache operations to clear the cache will be ignored
- */
- jal enable_ID
- nop
- jal size_i_cache /* v0 = i-cache size, v1 = i-cache line size */
- nop
- /* run uncached in kseg 1 */
- la k0, 1f
- lui k1, 0x2000
- or k0, k1, k0
- jr k0
- nop
- 1:
- /*
- * set K0 cache mode
- */
- mfc0 t0, CP0_CONFIG
- and t0, t0, ~CP0_CONFIG_K0_MASK
- or t0, t0, 3 /* Write Back mode */
- mtc0 t0, CP0_CONFIG
- /*
- * Initialize instruction cache.
- */
- li a0, KSEG0
- cacheop(a0, v0, v1, Index_Store_Tag_I)
- /*
- * Now we can run from I-$, kseg 0
- */
- la k0, 1f
- lui k1, 0x2000
- or k0, k1, k0
- xor k0, k1, k0
- jr k0
- nop
- 1:
- /*
- * Initialize data cache.
- */
- jal size_d_cache /* v0 = d-cache size, v1 = d-cache line size */
- nop
- li a0, KSEG0
- cacheop(a0, v0, v1, Index_Store_Tag_D)
- jr t8
- nop
- .end l1_init
- .set reorder
- /*
- * Function: set_other_config
- * Arguments: none
- * Returns: None
- * Description: initialize other remainder configuration to defaults.
- * Trashes: t0, t1
- *
- * pseudo code:
- *
- */
- LEAF(set_other_config)
- .set noreorder
- /* enable Bus error for I-fetch */
- mfc0 t0, CP0_CACHEERR, 0
- li t1, 0x4
- or t0, t1
- mtc0 t0, CP0_CACHEERR, 0
- /* enable Bus error for Load */
- mfc0 t0, CP0_CACHEERR, 1
- li t1, 0x4
- or t0, t1
- mtc0 t0, CP0_CACHEERR, 1
- /* enable Bus Error for Store */
- mfc0 t0, CP0_CACHEERR, 2
- li t1, 0x4
- or t0, t1
- mtc0 t0, CP0_CACHEERR, 2
- jr ra
- nop
- .set reorder
- END(set_other_config)
- /*
- * Function: set_branch_pred
- * Arguments: none
- * Returns: None
- * Description:
- * Trashes: t0, t1
- *
- * pseudo code:
- *
- */
- LEAF(set_branch_pred)
- .set noreorder
- mfc0 t0, CP0_BRCM_MODE
- li t1, ~(CP0_BRCM_MODE_BrPRED_MASK | CP0_BRCM_MODE_BrHIST_MASK )
- and t0, t0, t1
- /* enable Branch prediction */
- li t1, BRCM_BrPRED_BHT_ENABLE
- sll t1, CP0_BRCM_MODE_BrPRED_SHIFT
- or t0, t0, t1
- /* set history count to 8 */
- li t1, 8
- sll t1, CP0_BRCM_MODE_BrHIST_SHIFT
- or t0, t0, t1
- mtc0 t0, CP0_BRCM_MODE
- jr ra
- nop
- .set reorder
- END(set_branch_pred)
- /*
- * Function: set_luc
- * Arguments: set link uncached.
- * Returns: None
- * Description:
- * Trashes: t0, t1
- *
- */
- LEAF(set_luc)
- .set noreorder
- mfc0 t0, CP0_BRCM_MODE
- li t1, ~(CP0_BRCM_MODE_Luc_MASK)
- and t0, t0, t1
- /* set Luc */
- ori t0, t0, CP0_BRCM_MODE_Luc_MASK
- mtc0 t0, CP0_BRCM_MODE
- jr ra
- nop
- .set reorder
- END(set_luc)
- /*
- * Function: set_cwf_tse
- * Arguments: set CWF and TSE bits
- * Returns: None
- * Description:
- * Trashes: t0, t1
- *
- */
- LEAF(set_cwf_tse)
- .set noreorder
- mfc0 t0, CP0_BRCM_CONFIG0
- li t1, (CP0_BRCM_CONFIG0_CWF_MASK | CP0_BRCM_CONFIG0_TSE_MASK)
- or t0, t0, t1
- mtc0 t0, CP0_BRCM_CONFIG0
- jr ra
- nop
- .set reorder
- END(set_cwf_tse)
- /*
- * Function: set_clock_ratio
- * Arguments: set clock ratio specified by a0
- * Returns: None
- * Description:
- * Trashes: v0, v1, a0, a1
- *
- * pseudo code:
- *
- */
- LEAF(set_clock_ratio)
- .set noreorder
- mfc0 t0, CP0_BRCM_MODE
- li t1, ~(CP0_BRCM_MODE_SET_MASK | CP0_BRCM_MODE_ClkRATIO_MASK)
- and t0, t0, t1
- li t1, CP0_BRCM_MODE_SET_MASK
- or t0, t0, t1
- or t0, t0, a0
- mtc0 t0, CP0_BRCM_MODE
- jr ra
- nop
- .set reorder
- END(set_clock_ratio)
- /*
- * Function: set_zephyr
- * Arguments: None
- * Returns: None
- * Description: Set any zephyr bits
- * Trashes: t0 & t1
- *
- */
- LEAF(set_zephyr)
- .set noreorder
- /* enable read/write of CP0 #22 sel. 8 */
- li t0, 0x5a455048
- .word 0x4088b00f /* mtc0 t0, $22, 15 */
- .word 0x4008b008 /* mfc0 t0, $22, 8 */
- li t1, 0x09008000 /* turn off pref, jtb */
- or t0, t0, t1
- .word 0x4088b008 /* mtc0 t0, $22, 8 */
- sync
- /* disable read/write of CP0 #22 sel 8 */
- li t0, 0x0
- .word 0x4088b00f /* mtc0 t0, $22, 15 */
- jr ra
- nop
- .set reorder
- END(set_zephyr)
- /*
- * Function: set_llmb
- * Arguments: a0=0 disable llmb, a0=1 enables llmb
- * Returns: None
- * Description:
- * Trashes: t0, t1, t2
- *
- * pseudo code:
- *
- */
- LEAF(set_llmb)
- .set noreorder
- li t2, 0x90000000 | BRCM_ZSC_ALL_REGS_SELECT | BRCM_ZSC_CONFIG_REG
- sync
- cache 0x7, 0x0(t2)
- sync
- mfc0 t0, CP0_D_SEC_CACHE_DATA_LO
- li t1, ~(BRCM_ZSC_CONFIG_LMB1En | BRCM_ZSC_CONFIG_LMB0En)
- and t0, t0, t1
- beqz a0, svlmb
- nop
- enable_lmb:
- li t1, (BRCM_ZSC_CONFIG_LMB1En | BRCM_ZSC_CONFIG_LMB0En)
- or t0, t0, t1
- svlmb:
- mtc0 t0, CP0_D_SEC_CACHE_DATA_LO
- sync
- cache 0xb, 0x0(t2)
- sync
- jr ra
- nop
- .set reorder
- END(set_llmb)
- /*
- * Function: core_init
- * Arguments: none
- * Returns: None
- * Description: initialize core related configuration
- * Trashes: v0,v1,a0,a1,t8
- *
- * pseudo code:
- *
- */
- .globl core_init
- .ent core_init
- .set noreorder
- core_init:
- move t8, ra
- /* set Zephyr bits. */
- bal set_zephyr
- nop
- #if ENABLE_FPU==1
- /* initialize the Floating point unit (both TPs) */
- bal init_fpu
- nop
- #endif
- /* set low latency memory bus */
- li a0, 1
- bal set_llmb
- nop
- /* set branch prediction (TP0 only) */
- bal set_branch_pred
- nop
- /* set link uncached */
- bal set_luc
- nop
- /* set CWF and TSE */
- bal set_cwf_tse
- nop
- /*
- *set clock ratio by setting 1 to 'set'
- * and 0 to ClkRatio, (TP0 only)
- */
- li a0, 0
- bal set_clock_ratio
- nop
- /* set other configuration to defaults */
- bal set_other_config
- nop
- move ra, t8
- jr ra
- nop
- .set reorder
- .end core_init
- /*
- * Function: clear_jump_target_buffer
- * Arguments: None
- * Returns: None
- * Description:
- * Trashes: t0, t1, t2
- *
- */
- #define RESET_CALL_RETURN_STACK_THIS_THREAD (0x06<<16)
- #define RESET_JUMP_TARGET_BUFFER_THIS_THREAD (0x04<<16)
- #define JTB_CS_CNTL_MASK (0xFF<<16)
- .globl clear_jump_target_buffer
- .ent clear_jump_target_buffer
- .set noreorder
- clear_jump_target_buffer:
- mfc0 t0, $22, 2
- nop
- nop
- li t1, ~JTB_CS_CNTL_MASK
- and t0, t0, t1
- li t2, RESET_CALL_RETURN_STACK_THIS_THREAD
- or t0, t0, t2
- mtc0 t0, $22, 2
- nop
- nop
- and t0, t0, t1
- li t2, RESET_JUMP_TARGET_BUFFER_THIS_THREAD
- or t0, t0, t2
- mtc0 t0, $22, 2
- nop
- nop
- jr ra
- nop
- .end clear_jump_target_buffer
- .set reorder
- /*
- * Function: bmips_cache_init
- * Arguments: None
- * Returns: None
- * Description: Enable I and D caches, and initialize I and D-caches
- * Trashes: v0, v1, t0, t1, t2, t5, t7, t8
- *
- */
- .globl bmips_5xxx_init
- .ent bmips_5xxx_init
- .set noreorder
- bmips_5xxx_init:
- /* save return address and A0 */
- move t7, ra
- move t5, a0
- jal l1_init
- nop
- jal core_init
- nop
- jal clear_jump_target_buffer
- nop
- mtc0 zero, CP0_CAUSE
- move a0, t5
- jr t7
- nop
- .end bmips_5xxx_init
- .set reorder
- #endif
|