#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
#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)
#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
LEAF(size_i_cache)
.set noreorder
mfc0 a0, CP0_CONFIG, 1
move t0, a0
srl a0, a0, IS_SHIFT
and a0, a0, IS_MASK
li v0, 0x40
sllv v0, v0, a0
move a0, t0
srl a0, a0, IL_SHIFT
and a0, a0, IL_MASK
beqz a0, no_i_cache
nop
addi a0, a0, 1
li v1, 1
sll v1, v1, a0
sll v0, v0, a0
move a0, t0
srl a0, a0, IA_SHIFT
and a0, a0, IA_MASK
addi a0, a0, 0x1
multu v0, a0
mflo v0
b 1f
nop
no_i_cache:
move v0, zero
move v1, zero
1:
jr ra
nop
.set reorder
END(size_i_cache)
LEAF(size_d_cache)
.set noreorder
mfc0 a0, CP0_CONFIG, 1
move t0, a0
srl a0, a0, DS_SHIFT
and a0, a0, DS_MASK
li v0, 0x40
sllv v0, v0, a0
move a0, t0
srl a0, a0, DL_SHIFT
and a0, a0, DL_MASK
beqz a0, no_d_cache
nop
addi a0, a0, 1
li v1, 1
sll v1, v1, a0
sll v0, v0, a0
move a0, t0
srl a0, a0, DA_SHIFT
and a0, a0, DA_MASK
addi a0, a0, 0x1
multu v0, a0
mflo v0
b 1f
nop
no_d_cache:
move v0, zero
move v1, zero
1:
jr ra
nop
.set reorder
END(size_d_cache)
.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
.globl l1_init
.ent l1_init
.set noreorder
l1_init:
move t8, ra
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
jal enable_ID
nop
jal size_i_cache
nop
la k0, 1f
lui k1, 0x2000
or k0, k1, k0
jr k0
nop
1:
mfc0 t0, CP0_CONFIG
and t0, t0, ~CP0_CONFIG_K0_MASK
or t0, t0, 3
mtc0 t0, CP0_CONFIG
li a0, KSEG0
cacheop(a0, v0, v1, Index_Store_Tag_I)
la k0, 1f
lui k1, 0x2000
or k0, k1, k0
xor k0, k1, k0
jr k0
nop
1:
jal size_d_cache
nop
li a0, KSEG0
cacheop(a0, v0, v1, Index_Store_Tag_D)
jr t8
nop
.end l1_init
.set reorder
LEAF(set_other_config)
.set noreorder
mfc0 t0, CP0_CACHEERR, 0
li t1, 0x4
or t0, t1
mtc0 t0, CP0_CACHEERR, 0
mfc0 t0, CP0_CACHEERR, 1
li t1, 0x4
or t0, t1
mtc0 t0, CP0_CACHEERR, 1
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)
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
li t1, BRCM_BrPRED_BHT_ENABLE
sll t1, CP0_BRCM_MODE_BrPRED_SHIFT
or t0, t0, t1
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)
LEAF(set_luc)
.set noreorder
mfc0 t0, CP0_BRCM_MODE
li t1, ~(CP0_BRCM_MODE_Luc_MASK)
and t0, t0, t1
ori t0, t0, CP0_BRCM_MODE_Luc_MASK
mtc0 t0, CP0_BRCM_MODE
jr ra
nop
.set reorder
END(set_luc)
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)
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)
LEAF(set_zephyr)
.set noreorder
li t0, 0x5a455048
.word 0x4088b00f
.word 0x4008b008
li t1, 0x09008000
or t0, t0, t1
.word 0x4088b008
sync
li t0, 0x0
.word 0x4088b00f
jr ra
nop
.set reorder
END(set_zephyr)
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)
.globl core_init
.ent core_init
.set noreorder
core_init:
move t8, ra
bal set_zephyr
nop
li a0, 1
bal set_llmb
nop
bal set_branch_pred
nop
bal set_luc
nop
bal set_cwf_tse
nop
li a0, 0
bal set_clock_ratio
nop
bal set_other_config
nop
move ra, t8
jr ra
nop
.set reorder
.end core_init
#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
.globl bmips_5xxx_init
.ent bmips_5xxx_init
.set noreorder
bmips_5xxx_init:
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