blob: 7f00930913ec2d8101178b841d466f81e6cb1661 [file] [log] [blame]
/*
* Copyright (C) 2010 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#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/brcmstb/brcmstb.h>
.macro CLR_FPR a b c d
mtc1 $0, $\a
mtc1 $0, $\b
mtc1 $0, $\c
mtc1 $0, $\d
.endm
.macro BARRIER
.set mips32
ssnop
ssnop
ssnop
.set mips0
.endm
/***********************************************************************
* NMI vector
* This entire function gets copied to 8000_0000.
***********************************************************************/
__CPUINIT
NESTED(brcm_reset_nmi_vec, PT_SIZE, sp)
.set push
.set noat
.align 4
#ifdef CONFIG_SMP
/* if the NMI bit is clear, assume this is a TP1 reset instead */
li k1, (1 << 19)
mfc0 k0, CP0_STATUS
and k0, k1
beqz k0, brcmstb_tp1_entry
#endif /* CONFIG_SMP */
SAVE_ALL
move a0, sp
/* clear EXL, ERL, BEV so that TLB refills still work */
/* Also enable coprocessor 0, clear ST0_IE and
* set KSU to 0 (kernel privilege level) */
mfc0 k0, CP0_STATUS
li k1, ST0_CU0 | ST0_BEV | ST0_KSU | ST0_ERL | ST0_EXL | ST0_IE
or k0, k1
li k1, ST0_BEV | ST0_KSU | ST0_ERL | ST0_EXL | ST0_IE
xor k0, k1
mtc0 k0, CP0_STATUS
BARRIER
/* call the NMI handler function (probably doesn't return) */
la k0, brcm_nmi_handler
lw k1, 0(k0)
jalr k1
RESTORE_ALL
.set mips3
eret
/***********************************************************************
* TP1 reset vector (used for the initial boot only)
* This is still part of brcm_reset_nmi_vec().
***********************************************************************/
#ifdef CONFIG_SMP
brcmstb_tp1_entry:
/* set up CP0 STATUS; enable FPU */
li k0, 0x30000000
mtc0 k0, CP0_STATUS
BARRIER
/* set local CP0 CONFIG to make kseg0 cacheable, write-back */
mfc0 k0, CP0_CONFIG
ori k0, 0x07
xori k0, 0x04
mtc0 k0, CP0_CONFIG
/* initialize FPU registers */
CLR_FPR f0 f1 f2 f3
CLR_FPR f4 f5 f6 f7
CLR_FPR f8 f9 f10 f11
CLR_FPR f12 f13 f14 f15
CLR_FPR f16 f17 f18 f19
CLR_FPR f20 f21 f22 f23
CLR_FPR f24 f25 f26 f27
CLR_FPR f28 f29 f30 f31
#if defined(CONFIG_BMIPS4380)
/* initialize TP1's local I-cache */
li k0, 0x80000000
li k1, 0x80008000
mtc0 zero, $28
mtc0 zero, $28, 1
BARRIER
1: cache Index_Store_Tag_I, 0(k0)
addiu k0, 64
bne k0, k1, 1b
#elif defined(CONFIG_BMIPS5000)
/* set exception vector base */
la k0, ebase
lw k0, 0(k0)
mtc0 k0, $15, 1
BARRIER
#endif
/* jump back to kseg0 in case we need to remap the kseg1 area */
la k0, 1f
jr k0
1:
la k0, brcmstb_enable_xks01
jalr k0
/* use temporary stack to set up upper memory TLB */
li sp, BRCM_WARM_RESTART_VEC
la k0, brcm_upper_tlb_setup
jalr k0
/* switch to permanent stack and continue booting */
.global brcmstb_tp1_reentry
brcmstb_tp1_reentry:
la k0, brcmstb_smp_boot_sp
lw sp, 0(k0)
la k0, brcmstb_smp_boot_gp
lw gp, 0(k0)
la k0, start_secondary
jr k0
#endif /* CONFIG_SMP */
.align 4
.global brcm_reset_nmi_vec_end
brcm_reset_nmi_vec_end:
END(brcm_reset_nmi_vec)
.set pop
.previous
/***********************************************************************
* TP1 warm restart vector (used for second and subsequent boots).
* Also used for passive standby recovery (PM).
* This entire function gets copied to (BRCM_WARM_RESTART_VEC)
***********************************************************************/
LEAF(brcm_tp1_int_vec)
.align 4
mfc0 k0, CP0_STATUS
ori k0, 0x01
xori k0, 0x01
mtc0 k0, CP0_STATUS
eret
.align 4
.global brcm_tp1_int_vec_end
brcm_tp1_int_vec_end:
END(brcm_tp1_int_vec)
/***********************************************************************
* XKS01 support
***********************************************************************/
LEAF(brcmstb_enable_xks01)
#if defined(CONFIG_BRCM_UPPER_768MB)
/*
* Enable XKS01 1024MB kseg0
*
* Memory map is documented in <asm/mach-brcmstb/spaces.h>
*/
#if defined(CONFIG_BMIPS4380)
mfc0 t0, $22, 3
li t1, 0x1ff0
li t2, (1 << 12) | (1 << 9)
or t0, t1
xor t0, t1
or t0, t2
mtc0 t0, $22, 3
BARRIER
#elif defined(CONFIG_BMIPS5000)
mfc0 t0, $22, 5
li t1, 0x01ff
li t2, (1 << 8) | (1 << 5)
or t0, t1
xor t0, t1
or t0, t2
mtc0 t0, $22, 5
BARRIER
#else
#error Missing XKS01 setup
#endif
#endif /* defined(CONFIG_BRCM_UPPER_768MB) */
jr ra
END(brcmstb_enable_xks01)