1224110Sjchandra/*-
2224110Sjchandra * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights
3224110Sjchandra * reserved.
4224110Sjchandra *
5224110Sjchandra * Redistribution and use in source and binary forms, with or without
6224110Sjchandra * modification, are permitted provided that the following conditions are
7224110Sjchandra * met:
8224110Sjchandra *
9224110Sjchandra * 1. Redistributions of source code must retain the above copyright
10224110Sjchandra *    notice, this list of conditions and the following disclaimer.
11224110Sjchandra * 2. Redistributions in binary form must reproduce the above copyright
12224110Sjchandra *    notice, this list of conditions and the following disclaimer in
13224110Sjchandra *    the documentation and/or other materials provided with the
14224110Sjchandra *    distribution.
15224110Sjchandra *
16224110Sjchandra * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND
17224110Sjchandra * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18224110Sjchandra * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19224110Sjchandra * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE
20224110Sjchandra * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21224110Sjchandra * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22224110Sjchandra * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23224110Sjchandra * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24224110Sjchandra * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25224110Sjchandra * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26224110Sjchandra * THE POSSIBILITY OF SUCH DAMAGE.
27224110Sjchandra *
28225394Sjchandra * NETLOGIC_BSD
29224110Sjchandra * $FreeBSD: releng/10.3/sys/mips/nlm/mpreset.S 233535 2012-03-27 07:51:42Z jchandra $
30225394Sjchandra */
31224110Sjchandra
32224110Sjchandra#include <machine/asm.h>
33224110Sjchandra#include <machine/cpu.h>
34224110Sjchandra#include <machine/cpuregs.h>
35224110Sjchandra#include <mips/nlm/hal/iomap.h>
36224110Sjchandra#include <mips/nlm/hal/sys.h>
37224110Sjchandra#include <mips/nlm/hal/cpucontrol.h>
38224110Sjchandra
39225394Sjchandra#define SYS_REG_KSEG1(node, reg)	(0xa0000000 + XLP_DEFAULT_IO_BASE + \
40225394Sjchandra		XLP_IO_SYS_OFFSET(node)  + XLP_IO_PCI_HDRSZ + (reg) * 4)
41224110Sjchandra#include "assym.s"
42224110Sjchandra
43224110Sjchandra	.text
44224110Sjchandra	.set	noat
45224110Sjchandra	.set	noreorder
46224110Sjchandra	.set	mips64
47224110Sjchandra
48227799Sjchandra#define	MFCR(rt,rs)	.word	((0x1c<<26)|((rs)<<21)|((rt)<<16)|(0x18))
49227799Sjchandra#define	MTCR(rt,rs)	.word	((0x1c<<26)|((rs)<<21)|((rt)<<16)|(0x19))
50227799Sjchandra/*
51227799Sjchandra * We need to do this to really flush the dcache before splitting it
52227799Sjchandra */
53227799Sjchandra.macro flush_l1_dcache
54227799Sjchandra	.set	push
55227799Sjchandra	.set	noreorder
56227799Sjchandra	li	$8, LSU_DEBUG_DATA0 /* use register number to handle */
57227799Sjchandra	li	$9, LSU_DEBUG_ADDR  /* different ABIs */
58233535Sjchandra	li	t2, 0		/* index */
59233535Sjchandra	li	t3, 0x1000	/* loop count, 512 sets * 8 whatever? */
60227799Sjchandra1:
61227799Sjchandra	sll	v0, t2, 5
62227799Sjchandra	MTCR(0, 8)
63233535Sjchandra	ori	v1, v0, 0x3	/* way0 | write_enable | write_active */
64227799Sjchandra	MTCR(3, 9)
65227799Sjchandra2:
66227799Sjchandra	MFCR(3, 9)
67233535Sjchandra	andi	v1, 0x1		/* wait for write_active == 0 */
68227799Sjchandra	bnez	v1, 2b
69227799Sjchandra	nop
70227799Sjchandra	MTCR(0, 8)
71233535Sjchandra	ori	v1, v0, 0x7	/* way1 | write_enable | write_active */
72227799Sjchandra	MTCR(3, 9)
73227799Sjchandra3:
74227799Sjchandra	MFCR(3, 9)
75233535Sjchandra	andi	v1, 0x1		/* wait for write_active == 0 */
76227799Sjchandra	bnez	v1, 3b
77227799Sjchandra	nop
78227799Sjchandra	addi	t2, 1
79227799Sjchandra	bne	t3, t2, 1b
80227799Sjchandra	nop
81227799Sjchandra	.set pop
82227799Sjchandra.endm
83227799Sjchandra
84224110SjchandraVECTOR(XLPResetEntry, unknown)
85224110Sjchandra	mfc0	t0, MIPS_COP_0_STATUS
86224110Sjchandra	li	t1, 0x80000
87224110Sjchandra	and	t1, t0, t1
88224110Sjchandra	bnez	t1, nmi_handler
89224110Sjchandra	nop
90224110Sjchandra
91224110Sjchandra#ifdef SMP
92224110Sjchandra	/* Reset entry for secordary cores */
93224110Sjchandra	mfc0	t0, MIPS_COP_0_PRID, 1
94224110Sjchandra	srl	t0, t0, 2		/* discard thread id */
95224110Sjchandra	andi	t0, t0, 0x7		/* core id */
96224110Sjchandra	li	t1, 1
97224110Sjchandra	sll	t0, t1, t0
98224110Sjchandra	nor     t0, t0, zero		/* mask with core id bit clear */
99224110Sjchandra
100224110Sjchandra	/* clear CPU non-coherent bit */
101225394Sjchandra	li	t2, SYS_REG_KSEG1(0, SYS_CPU_NONCOHERENT_MODE)
102224110Sjchandra	lw	t1, 0(t2)
103224110Sjchandra	and	t1, t1, t0
104224110Sjchandra	sw	t1, 0(t2)
105224110Sjchandra	lw	t1, 0(t2)	/* read-back ensures operation complete */
106224110Sjchandra	sync
107224110Sjchandra
108224110Sjchandra	dla	t2, mpentry
109224110Sjchandra	jr	t2
110224110Sjchandra	nop
111224110Sjchandra#endif
112224110Sjchandra	nop
113224110Sjchandra	/* NOT REACHED */
114224110SjchandraVECTOR_END(XLPResetEntry)
115224110Sjchandra
116224110Sjchandra
117224110Sjchandra	/* Not yet */
118224110Sjchandranmi_handler:
119224110Sjchandra	nop
120224110Sjchandra	nop
121224110Sjchandra	j	nmi_handler
122224110Sjchandra
123224110Sjchandra#ifdef SMP
124224110Sjchandra	/*
125224110Sjchandra	 * Enable other threads in the core, called from thread 0
126224110Sjchandra	 * of the core
127224110Sjchandra 	 */
128224110SjchandraLEAF(xlp_enable_threads)
129224110Sjchandra	/*
130224110Sjchandra	 * Save and restore callee saved registers of all ABIs
131224110Sjchandra	 * Enabling threads trashes the registers
132224110Sjchandra	 */
133224110Sjchandra	dmtc0	sp, $4, 2	/* SP saved in UserLocal */
134224110Sjchandra	ori	sp, sp, 0x7
135224110Sjchandra	xori	sp, sp, 0x7	/* align 64 bit */
136224110Sjchandra	addiu	sp, sp, -128
137224110Sjchandra	mfc0	t1, MIPS_COP_0_STATUS
138224110Sjchandra	sd	s0, 0(sp)
139224110Sjchandra	sd	s1, 8(sp)
140224110Sjchandra	sd	s2, 16(sp)
141224110Sjchandra	sd	s3, 24(sp)
142224110Sjchandra	sd	s4, 32(sp)
143224110Sjchandra	sd	s5, 40(sp)
144224110Sjchandra	sd	s6, 48(sp)
145224110Sjchandra	sd	s7, 56(sp)
146224110Sjchandra	sd	s8, 64(sp)
147224110Sjchandra	sd	t1, 72(sp)
148224110Sjchandra	sd	gp, 80(sp)
149224110Sjchandra	sd	ra, 88(sp)
150227799Sjchandra
151227799Sjchandra	flush_l1_dcache
152227799Sjchandra
153224110Sjchandra	/* Use register number to work in o32 and n32 */
154225394Sjchandra	li	$9, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE)
155224110Sjchandra	move	$8, a0
156224110Sjchandra	sync
157227799Sjchandra	MTCR(8, 9)
158224110Sjchandra	mfc0	t0, MIPS_COP_0_PRID, 1
159224110Sjchandra	andi	t0, 0x3
160224110Sjchandra	beqz	t0, 2f
161224110Sjchandra	nop
162224110Sjchandra	dla	t1, mpentry	/* child thread, go to hardware init */
163224110Sjchandra	jr	t1
164224110Sjchandra	nop
165224110Sjchandra
166224110Sjchandra
167224110Sjchandra2: 	/*
168224110Sjchandra	 * Parent hardware thread, restore registers, return
169224110Sjchandra	 */
170224110Sjchandra#if 1
171224110Sjchandra	/*
172224110Sjchandra	 * A0 Errata - Write MMU_SETUP after changing thread mode register.
173224110Sjchandra	 */
174224110Sjchandra	li	$9, 0x400
175224110Sjchandra	li	$8, 0
176227799Sjchandra	MTCR(8, 9)
177227799Sjchandra	sll	zero,3		/* ehb */
178224110Sjchandra#endif
179224110Sjchandra	dmfc0	t0, $4, 2	/* SP saved in UserLocal */
180224110Sjchandra	ori	sp, t0, 0x7
181224110Sjchandra	xori	sp, sp, 0x7	/* align 64 bit */
182224110Sjchandra	addiu	sp, sp, -128
183224110Sjchandra	ld	s0, 0(sp)
184224110Sjchandra	ld	s1, 8(sp)
185224110Sjchandra	ld	s2, 16(sp)
186224110Sjchandra	ld	s3, 24(sp)
187224110Sjchandra	ld	s4, 32(sp)
188224110Sjchandra	ld	s5, 40(sp)
189224110Sjchandra	ld	s6, 48(sp)
190224110Sjchandra	ld	s7, 56(sp)
191224110Sjchandra	ld	s8, 64(sp)
192224110Sjchandra	ld	t1, 72(sp)
193224110Sjchandra	ld	gp, 80(sp)
194224110Sjchandra	ld	ra, 88(sp)
195224110Sjchandra	mfc0	t1, MIPS_COP_0_STATUS
196224110Sjchandra
197224110Sjchandra	move	sp, t0		/* Restore the real SP */
198233535Sjchandra	jr.hb	ra
199224110Sjchandra	nop
200224110SjchandraEND(xlp_enable_threads)
201224110Sjchandra#endif
202