mpreset.S revision 256281
166458Sdfr/*-
266458Sdfr * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights
366458Sdfr * reserved.
466458Sdfr *
566458Sdfr * Redistribution and use in source and binary forms, with or without
666458Sdfr * modification, are permitted provided that the following conditions are
766458Sdfr * met:
866458Sdfr *
966458Sdfr * 1. Redistributions of source code must retain the above copyright
1066458Sdfr *    notice, this list of conditions and the following disclaimer.
1166458Sdfr * 2. Redistributions in binary form must reproduce the above copyright
1266458Sdfr *    notice, this list of conditions and the following disclaimer in
1366458Sdfr *    the documentation and/or other materials provided with the
1466458Sdfr *    distribution.
1566458Sdfr *
1666458Sdfr * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND
1766458Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1866458Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1966458Sdfr * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE
2066458Sdfr * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2166458Sdfr * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2266458Sdfr * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2366458Sdfr * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2466458Sdfr * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2566458Sdfr * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2666458Sdfr * THE POSSIBILITY OF SUCH DAMAGE.
2766458Sdfr *
2866458Sdfr * NETLOGIC_BSD
2966458Sdfr * $FreeBSD: stable/10/sys/mips/nlm/mpreset.S 233535 2012-03-27 07:51:42Z jchandra $
3066458Sdfr */
3166458Sdfr
3266458Sdfr#include <machine/asm.h>
3366458Sdfr#include <machine/cpu.h>
3466458Sdfr#include <machine/cpuregs.h>
3566458Sdfr#include <mips/nlm/hal/iomap.h>
3666458Sdfr#include <mips/nlm/hal/sys.h>
3766458Sdfr#include <mips/nlm/hal/cpucontrol.h>
3866458Sdfr
3966458Sdfr#define SYS_REG_KSEG1(node, reg)	(0xa0000000 + XLP_DEFAULT_IO_BASE + \
4066458Sdfr		XLP_IO_SYS_OFFSET(node)  + XLP_IO_PCI_HDRSZ + (reg) * 4)
4166458Sdfr#include "assym.s"
42235941Sbz
4366458Sdfr	.text
4466458Sdfr	.set	noat
4566458Sdfr	.set	noreorder
4666458Sdfr	.set	mips64
4766458Sdfr
4866458Sdfr#define	MFCR(rt,rs)	.word	((0x1c<<26)|((rs)<<21)|((rt)<<16)|(0x18))
49143063Sjoerg#define	MTCR(rt,rs)	.word	((0x1c<<26)|((rs)<<21)|((rt)<<16)|(0x19))
5066458Sdfr/*
5166458Sdfr * We need to do this to really flush the dcache before splitting it
5266458Sdfr */
5366458Sdfr.macro flush_l1_dcache
5466458Sdfr	.set	push
5566458Sdfr	.set	noreorder
5666458Sdfr	li	$8, LSU_DEBUG_DATA0 /* use register number to handle */
5766458Sdfr	li	$9, LSU_DEBUG_ADDR  /* different ABIs */
5866458Sdfr	li	t2, 0		/* index */
5966458Sdfr	li	t3, 0x1000	/* loop count, 512 sets * 8 whatever? */
6066458Sdfr1:
6166458Sdfr	sll	v0, t2, 5
6266458Sdfr	MTCR(0, 8)
6366458Sdfr	ori	v1, v0, 0x3	/* way0 | write_enable | write_active */
6466458Sdfr	MTCR(3, 9)
6566458Sdfr2:
6666458Sdfr	MFCR(3, 9)
6766458Sdfr	andi	v1, 0x1		/* wait for write_active == 0 */
6866458Sdfr	bnez	v1, 2b
69235941Sbz	nop
7066458Sdfr	MTCR(0, 8)
7166458Sdfr	ori	v1, v0, 0x7	/* way1 | write_enable | write_active */
72235941Sbz	MTCR(3, 9)
7366458Sdfr3:
74235941Sbz	MFCR(3, 9)
7566458Sdfr	andi	v1, 0x1		/* wait for write_active == 0 */
7666458Sdfr	bnez	v1, 3b
7766458Sdfr	nop
7866458Sdfr	addi	t2, 1
7966458Sdfr	bne	t3, t2, 1b
8066458Sdfr	nop
81	.set pop
82.endm
83
84VECTOR(XLPResetEntry, unknown)
85	mfc0	t0, MIPS_COP_0_STATUS
86	li	t1, 0x80000
87	and	t1, t0, t1
88	bnez	t1, nmi_handler
89	nop
90
91#ifdef SMP
92	/* Reset entry for secordary cores */
93	mfc0	t0, MIPS_COP_0_PRID, 1
94	srl	t0, t0, 2		/* discard thread id */
95	andi	t0, t0, 0x7		/* core id */
96	li	t1, 1
97	sll	t0, t1, t0
98	nor     t0, t0, zero		/* mask with core id bit clear */
99
100	/* clear CPU non-coherent bit */
101	li	t2, SYS_REG_KSEG1(0, SYS_CPU_NONCOHERENT_MODE)
102	lw	t1, 0(t2)
103	and	t1, t1, t0
104	sw	t1, 0(t2)
105	lw	t1, 0(t2)	/* read-back ensures operation complete */
106	sync
107
108	dla	t2, mpentry
109	jr	t2
110	nop
111#endif
112	nop
113	/* NOT REACHED */
114VECTOR_END(XLPResetEntry)
115
116
117	/* Not yet */
118nmi_handler:
119	nop
120	nop
121	j	nmi_handler
122
123#ifdef SMP
124	/*
125	 * Enable other threads in the core, called from thread 0
126	 * of the core
127 	 */
128LEAF(xlp_enable_threads)
129	/*
130	 * Save and restore callee saved registers of all ABIs
131	 * Enabling threads trashes the registers
132	 */
133	dmtc0	sp, $4, 2	/* SP saved in UserLocal */
134	ori	sp, sp, 0x7
135	xori	sp, sp, 0x7	/* align 64 bit */
136	addiu	sp, sp, -128
137	mfc0	t1, MIPS_COP_0_STATUS
138	sd	s0, 0(sp)
139	sd	s1, 8(sp)
140	sd	s2, 16(sp)
141	sd	s3, 24(sp)
142	sd	s4, 32(sp)
143	sd	s5, 40(sp)
144	sd	s6, 48(sp)
145	sd	s7, 56(sp)
146	sd	s8, 64(sp)
147	sd	t1, 72(sp)
148	sd	gp, 80(sp)
149	sd	ra, 88(sp)
150
151	flush_l1_dcache
152
153	/* Use register number to work in o32 and n32 */
154	li	$9, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE)
155	move	$8, a0
156	sync
157	MTCR(8, 9)
158	mfc0	t0, MIPS_COP_0_PRID, 1
159	andi	t0, 0x3
160	beqz	t0, 2f
161	nop
162	dla	t1, mpentry	/* child thread, go to hardware init */
163	jr	t1
164	nop
165
166
1672: 	/*
168	 * Parent hardware thread, restore registers, return
169	 */
170#if 1
171	/*
172	 * A0 Errata - Write MMU_SETUP after changing thread mode register.
173	 */
174	li	$9, 0x400
175	li	$8, 0
176	MTCR(8, 9)
177	sll	zero,3		/* ehb */
178#endif
179	dmfc0	t0, $4, 2	/* SP saved in UserLocal */
180	ori	sp, t0, 0x7
181	xori	sp, sp, 0x7	/* align 64 bit */
182	addiu	sp, sp, -128
183	ld	s0, 0(sp)
184	ld	s1, 8(sp)
185	ld	s2, 16(sp)
186	ld	s3, 24(sp)
187	ld	s4, 32(sp)
188	ld	s5, 40(sp)
189	ld	s6, 48(sp)
190	ld	s7, 56(sp)
191	ld	s8, 64(sp)
192	ld	t1, 72(sp)
193	ld	gp, 80(sp)
194	ld	ra, 88(sp)
195	mfc0	t1, MIPS_COP_0_STATUS
196
197	move	sp, t0		/* Restore the real SP */
198	jr.hb	ra
199	nop
200END(xlp_enable_threads)
201#endif
202