/*
* 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, 9 b ; \
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 0 x80000000
#define DCE_MASK 0 x40000000
#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 (0 x1f << 20 )
#define CP0_BRCM_MODE_BrHIST_SHIFT 20
/* ZSC L2 Cache Register Access Register Definitions */
#define BRCM_ZSC_ALL_REGS_SELECT 0 x7 << 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 0 xa << 3
#define BRCM_ZSC_SCB0_ADDR_MAPPING_REG1 0 xc << 3
#define BRCM_ZSC_SCB1_ADDR_MAPPING_REG0 0 xe << 3
#define BRCM_ZSC_SCB1_ADDR_MAPPING_REG1 0 x10 << 3
#define BRCM_ZSC_CONFIG_LMB1En 1 << (15 )
#define BRCM_ZSC_CONFIG_LMB0En 1 << (14 )
/* branch predition values */
#define BRCM_BrPRED_ALL_TAKEN (0 x0)
#define BRCM_BrPRED_ALL_NOT_TAKEN (0 x1)
#define BRCM_BrPRED_BHT_ENABLE (0 x2)
#define BRCM_BrPRED_PREDICT_BACKWARD (0 x3)
.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 ) 0 x0 : 64 , ii ) 0 x1 : 128 , iii ) 0 x2 : 256 , iv ) 0 x3 : 512 , v ) 0 x4 : 1 k
* vi ) 0 x5 - 0 x7 : Reserved .
*/
srl a0, a0, IS_SHIFT
and a0, a0, IS_MASK
/* sets per way = (64<<IS) */
li v0, 0 x40
sllv v0, v0, a0
/*
* Determine line size
*
* This field contains the line size of the instruction cache :
* i ) 0 x0 : No I - cache present , i ) 0 x3 : 16 bytes , ii ) 0 x4 : 32 bytes , iii )
* 0 x5 : 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 ) 0 x0 : Direct mapped , ii ) 0 x1 : 2 - way , iii ) 0 x2 : 3 - way , iv ) 0 x3 :
* 4 - way , v ) 0 x4 - 0 x7 : Reserved .
*/
move a0, t0
srl a0, a0, IA_SHIFT
and a0, a0, IA_MASK
addi a0, a0, 0 x1
/* 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 1 f
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 ) 0 x0 : 64 , ii ) 0 x1 : 128 , iii ) 0 x2 : 256 , iv ) 0 x3 : 512 , v ) 0 x4 : 1 k
* vi ) 0 x5 - 0 x7 : Reserved .
*/
srl a0, a0, DS_SHIFT
and a0, a0, DS_MASK
/* sets per way = (64<<IS) */
li v0, 0 x40
sllv v0, v0, a0
/*
* Determine line size
*
* This field contains the line size of the instruction cache :
* i ) 0 x0 : No I - cache present , i ) 0 x3 : 16 bytes , ii ) 0 x4 : 32 bytes , iii )
* 0 x5 : 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 ) 0 x0 : Direct mapped , ii ) 0 x1 : 2 - way , iii ) 0 x2 : 3 - way , iv ) 0 x3 :
* 4 - way , v ) 0 x4 - 0 x7 : Reserved .
*/
move a0, t0
srl a0, a0, DA_SHIFT
and a0, a0, DA_MASK
addi a0, a0, 0 x1
/* 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 1 f
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, 1 f
lui k1, 0 x2000
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, 1 f
lui k1, 0 x2000
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, 0 x4
or t0, t1
mtc0 t0, CP0_CACHEERR, 0
/* enable Bus error for Load */
mfc0 t0, CP0_CACHEERR, 1
li t1, 0 x4
or t0, t1
mtc0 t0, CP0_CACHEERR, 1
/* enable Bus Error for Store */
mfc0 t0, CP0_CACHEERR, 2
li t1, 0 x4
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, 0 x5a455048
.word 0 x4088b00f /* mtc0 t0, $22, 15 */
.word 0 x4008b008 /* mfc0 t0, $22, 8 */
li t1, 0 x09008000 /* turn off pref, jtb */
or t0, t0, t1
.word 0 x4088b008 /* mtc0 t0, $22, 8 */
sync
/* disable read/write of CP0 #22 sel 8 */
li t0, 0 x0
.word 0 x4088b00f /* 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, 0 x90000000 | BRCM_ZSC_ALL_REGS_SELECT | BRCM_ZSC_CONFIG_REG
sync
cache 0 x7, 0 x0(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 0 xb, 0 x0(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
/* 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 (0 x06<<16 )
#define RESET_JUMP_TARGET_BUFFER_THIS_THREAD (0 x04<<16 )
#define JTB_CS_CNTL_MASK (0 xFF<<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
Messung V0.5 in Prozent C=92 H=100 G=95
¤ Dauer der Verarbeitung: 0.18 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland