#include <linux/init.h>
#include <asm/addrspace.h>
#include <asm/asm.h>
#include <asm/asm-offsets.h>
#include <asm/asmmacro.h>
#include <asm/cacheops.h>
#include <asm/eva.h>
#include <asm/mipsregs.h>
#include <asm/mipsmtregs.h>
#include <asm/pm.h>
#include <asm/smp-cps.h>
#define GCR_CPC_BASE_OFS 0x0088
#define GCR_CL_COHERENCE_OFS 0x2008
#define GCR_CL_ID_OFS 0x2028
#define CM3_GCR_Cx_ID_CLUSTER_SHF 8
#define CM3_GCR_Cx_ID_CLUSTER_MSK (0xff << 8)
#define CM3_GCR_Cx_ID_CORENUM_SHF 0
#define CM3_GCR_Cx_ID_CORENUM_MSK (0xff << 0)
#define CPC_CL_VC_STOP_OFS 0x2020
#define CPC_CL_VC_RUN_OFS 0x2028
.extern mips_cm_base
.set noreorder
#ifdef CONFIG_64BIT
# define STATUS_BITDEPS ST0_KX
#else
# define STATUS_BITDEPS 0
#endif
#ifdef CONFIG_MIPS_CPS_NS16550
#define DUMP_EXCEP(name) \
PTR_LA a0, 8f; \
jal mips_cps_bev_dump; \
nop; \
TEXT(name)
#else
#define DUMP_EXCEP(name)
#endif
.macro has_mt dest, nomt
mfc0 \dest, CP0_CONFIG, 1
bgez \dest, \nomt
mfc0 \dest, CP0_CONFIG, 2
bgez \dest, \nomt
mfc0 \dest, CP0_CONFIG, 3
andi \dest, \dest, MIPS_CONF3_MT
beqz \dest, \nomt
nop
.endm
.macro has_vp dest, nomt
mfc0 \dest, CP0_CONFIG, 1
bgez \dest, \nomt
mfc0 \dest, CP0_CONFIG, 2
bgez \dest, \nomt
mfc0 \dest, CP0_CONFIG, 3
bgez \dest, \nomt
mfc0 \dest, CP0_CONFIG, 4
bgez \dest, \nomt
mfc0 \dest, CP0_CONFIG, 5
andi \dest, \dest, MIPS_CONF5_VP
beqz \dest, \nomt
nop
.endm
LEAF(mips_cps_core_boot)
move s0, a0
move s1, a1
#if MIPS_ISA_REV > 0
lw s7, GCR_CL_COHERENCE_OFS(s1)
bnez s7, 1f
nop
jal mips_cps_cache_init
nop
li t0, 0xff
sw t0, GCR_CL_COHERENCE_OFS(s1)
ehb
#endif
1: mfc0 t0, CP0_CONFIG
ori t0, 0x7
xori t0, 0x7
or t0, t0, s0
mtc0 t0, CP0_CONFIG
ehb
PTR_LA t0, 1f
jr t0
nop
1: eva_init
jal mips_cps_get_bootcfg
nop
bnez s7, 1f
nop
jal mips_cps_core_init
nop
move a1, t9
jal mips_cps_boot_vpes
move a0, v0
1: PTR_L t1, VPEBOOTCFG_PC(v1)
PTR_L gp, VPEBOOTCFG_GP(v1)
PTR_L sp, VPEBOOTCFG_SP(v1)
jr t1
nop
END(mips_cps_core_boot)
__INIT
LEAF(excep_tlbfill)
DUMP_EXCEP("TLB Fill")
b .
nop
END(excep_tlbfill)
LEAF(excep_xtlbfill)
DUMP_EXCEP("XTLB Fill")
b .
nop
END(excep_xtlbfill)
LEAF(excep_cache)
DUMP_EXCEP("Cache")
b .
nop
END(excep_cache)
LEAF(excep_genex)
DUMP_EXCEP("General")
b .
nop
END(excep_genex)
LEAF(excep_intex)
DUMP_EXCEP("Interrupt")
b .
nop
END(excep_intex)
LEAF(excep_ejtag)
PTR_LA k0, ejtag_debug_handler
jr k0
nop
END(excep_ejtag)
__FINIT
LEAF(mips_cps_core_init)
#ifdef CONFIG_MIPS_MT_SMP
has_mt t0, 3f
.set push
.set MIPS_ISA_LEVEL_RAW
.set mt
dmt
dvpe
PTR_LA t1, 1f
jr.hb t1
nop
1: mfc0 t0, CP0_MVPCONTROL
ori t0, t0, MVPCONTROL_VPC
mtc0 t0, CP0_MVPCONTROL
mfc0 t0, CP0_MVPCONF0
srl t0, t0, MVPCONF0_PVPE_SHIFT
andi t0, t0, (MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT)
addiu ta3, t0, 1
beqz t0, 2f
nop
li ta1, 1
1:
mtc0 ta1, CP0_VPECONTROL
ehb
mttc0 ta1, CP0_TCBIND
li t0, VPECONF0_MVP
sll t1, ta1, VPECONF0_XTC_SHIFT
or t0, t0, t1
mttc0 t0, CP0_VPECONF0
mttc0 zero, CP0_TCSTATUS
li t0, TCHALT_H
mttc0 t0, CP0_TCHALT
addiu ta1, ta1, 1
slt t0, ta1, ta3
bnez t0, 1b
nop
2: mfc0 t0, CP0_MVPCONTROL
xori t0, t0, MVPCONTROL_VPC
mtc0 t0, CP0_MVPCONTROL
3: .set pop
#endif
jr ra
nop
END(mips_cps_core_init)
LEAF(mips_cps_get_bootcfg)
PTR_LA v0, mips_cps_cluster_bootcfg
PTR_L v0, 0(v0)
lw t0, GCR_CL_ID_OFS(s1)
#ifdef CONFIG_CPU_MIPSR6
ext t1, t0, CM3_GCR_Cx_ID_CLUSTER_SHF, 8
li t2, CLUSTERBOOTCFG_SIZE
mul t1, t1, t2
PTR_ADDU \
v0, v0, t1
#endif
PTR_L v0, CLUSTERBOOTCFG_CORECONFIG(v0)
andi t0, t0, CM3_GCR_Cx_ID_CORENUM_MSK
li t1, COREBOOTCFG_SIZE
mul t0, t0, t1
PTR_ADDU v0, v0, t0
li t9, 0
#if defined(CONFIG_CPU_MIPSR6)
has_vp ta2, 1f
mfc0 t9, CP0_GLOBALNUMBER
andi t9, t9, MIPS_GLOBALNUMBER_VP
#elif defined(CONFIG_MIPS_MT_SMP)
has_mt ta2, 1f
mfc0 t1, CP0_MVPCONF0
srl t1, t1, MVPCONF0_PVPE_SHIFT
andi t1, t1, MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT
addiu t1, t1, 1
clz t1, t1
li t2, 31
subu t1, t2, t1
li t2, 1
sll t1, t2, t1
addiu t1, t1, -1
mfc0 t9, $15, 1
and t9, t9, t1
#endif
1:
li t1, VPEBOOTCFG_SIZE
mul v1, t9, t1
PTR_L ta3, COREBOOTCFG_VPECONFIG(v0)
PTR_ADDU v1, v1, ta3
jr ra
nop
END(mips_cps_get_bootcfg)
LEAF(mips_cps_boot_vpes)
lw ta2, COREBOOTCFG_VPEMASK(a0)
PTR_L ta3, COREBOOTCFG_VPECONFIG(a0)
#if defined(CONFIG_CPU_MIPSR6)
has_vp t0, 5f
PTR_LA t1, mips_gcr_base
PTR_L t1, 0(t1)
PTR_L t1, GCR_CPC_BASE_OFS(t1)
PTR_LI t2, ~0x7fff
and t1, t1, t2
PTR_LI t2, UNCAC_BASE
PTR_ADD t1, t1, t2
PTR_S ta2, CPC_CL_VC_RUN_OFS(t1)
not ta2
PTR_S ta2, CPC_CL_VC_STOP_OFS(t1)
ehb
#elif defined(CONFIG_MIPS_MT)
has_mt t0, 5f
.set push
.set MIPS_ISA_LEVEL_RAW
.set mt
dvpe
.set pop
PTR_LA t1, 1f
jr.hb t1
nop
1: mfc0 t1, CP0_MVPCONTROL
ori t1, t1, MVPCONTROL_VPC
mtc0 t1, CP0_MVPCONTROL
ehb
move t8, ta2
li ta1, 0
1: andi t0, ta2, 1
beqz t0, 2f
nop
mfc0 t0, CP0_VPECONTROL
ori t0, t0, VPECONTROL_TARGTC
xori t0, t0, VPECONTROL_TARGTC
or t0, t0, ta1
mtc0 t0, CP0_VPECONTROL
ehb
.set push
.set MIPS_ISA_LEVEL_RAW
.set mt
mftc0 t0, CP0_TCHALT
beqz t0, 2f
nop
li t0, VPEBOOTCFG_SIZE
mul t0, t0, ta1
PTR_ADDU t0, t0, ta3
lw t1, VPEBOOTCFG_PC(t0)
mttc0 t1, CP0_TCRESTART
lw t1, VPEBOOTCFG_SP(t0)
mttgpr t1, sp
lw t1, VPEBOOTCFG_GP(t0)
mttgpr t1, gp
mfc0 t0, CP0_CONFIG
mttc0 t0, CP0_CONFIG
mfc0 t0, CP0_CONFIG, 3
and t0, t0, MIPS_CONF3_SC
beqz t0, 3f
nop
mfc0 t0, CP0_SEGCTL0
mttc0 t0, CP0_SEGCTL0
mfc0 t0, CP0_SEGCTL1
mttc0 t0, CP0_SEGCTL1
mfc0 t0, CP0_SEGCTL2
mttc0 t0, CP0_SEGCTL2
3:
mttc0 zero, CP0_CAUSE
mttc0 zero, CP0_STATUS
mftc0 t0, CP0_TCSTATUS
li t1, ~TCSTATUS_IXMT
and t0, t0, t1
ori t0, t0, TCSTATUS_A
mttc0 t0, CP0_TCSTATUS
mttc0 zero, CP0_TCHALT
mftc0 t0, CP0_VPECONF0
ori t0, t0, VPECONF0_VPA
mttc0 t0, CP0_VPECONF0
2: srl ta2, ta2, 1
addiu ta1, ta1, 1
bnez ta2, 1b
nop
mfc0 t1, CP0_MVPCONTROL
xori t1, t1, MVPCONTROL_VPC
mtc0 t1, CP0_MVPCONTROL
ehb
evpe
.set pop
li t0, 1
sll t0, t0, a1
and t0, t0, t8
bnez t0, 2f
nop
li t0, TCHALT_H
mtc0 t0, CP0_TCHALT
PTR_LA t0, 1f
1: jr.hb t0
nop
2:
#endif
5: jr ra
nop
END(mips_cps_boot_vpes)
#if MIPS_ISA_REV > 0
LEAF(mips_cps_cache_init)
mtc0 zero, CP0_TAGLO, 0
mtc0 zero, CP0_TAGHI, 0
mtc0 zero, CP0_TAGLO, 2
mtc0 zero, CP0_TAGHI, 2
ehb
mfc0 v0, CP0_CONFIG, 1
_EXT t0, v0, MIPS_CONF1_IL_SHF, MIPS_CONF1_IL_SZ
beqz t0, icache_done
li t1, 2
sllv t0, t1, t0
_EXT t1, v0, MIPS_CONF1_IS_SHF, MIPS_CONF1_IS_SZ
xori t2, t1, 0x7
beqz t2, 1f
li t3, 32
addiu t1, t1, 1
sllv t1, t3, t1
1:
_EXT t2, v0, MIPS_CONF1_IA_SHF, MIPS_CONF1_IA_SZ
addiu t2, t2, 1
mul t1, t1, t0
mul t1, t1, t2
li a0, CKSEG0
PTR_ADD a1, a0, t1
1: cache Index_Store_Tag_I, 0(a0)
PTR_ADD a0, a0, t0
bne a0, a1, 1b
nop
icache_done:
_EXT t0, v0, MIPS_CONF1_DL_SHF, MIPS_CONF1_DL_SZ
beqz t0, dcache_done
li t1, 2
sllv t0, t1, t0
_EXT t1, v0, MIPS_CONF1_DS_SHF, MIPS_CONF1_DS_SZ
xori t2, t1, 0x7
beqz t2, 1f
li t3, 32
addiu t1, t1, 1
sllv t1, t3, t1
1:
_EXT t2, v0, MIPS_CONF1_DA_SHF, MIPS_CONF1_DA_SZ
addiu t2, t2, 1
mul t1, t1, t0
mul t1, t1, t2
li a0, CKSEG0
PTR_ADDU a1, a0, t1
PTR_SUBU a1, a1, t0
1: cache Index_Store_Tag_D, 0(a0)
bne a0, a1, 1b
PTR_ADD a0, a0, t0
dcache_done:
jr ra
nop
END(mips_cps_cache_init)
#endif
#if defined(CONFIG_MIPS_CPS_PM) && defined(CONFIG_CPU_PM)
.macro psstate dest
.set push
.set noat
lw $1, TI_CPU(gp)
sll $1, $1, LONGLOG
PTR_LA \dest, __per_cpu_offset
PTR_ADDU $1, $1, \dest
lw $1, 0($1)
PTR_LA \dest, cps_cpu_state
PTR_ADDU \dest, \dest, $1
.set pop
.endm
LEAF(mips_cps_pm_save)
SUSPEND_SAVE_REGS
psstate t1
SUSPEND_SAVE_STATIC
jr v0
nop
END(mips_cps_pm_save)
LEAF(mips_cps_pm_restore)
psstate t1
RESUME_RESTORE_STATIC
RESUME_RESTORE_REGS_RETURN
END(mips_cps_pm_restore)
#endif