locore.S revision 203114
1178172Simp/*	$OpenBSD: locore.S,v 1.18 1998/09/15 10:58:53 pefo Exp $	*/
2178172Simp/*-
3178172Simp * Copyright (c) 1992, 1993
4178172Simp *	The Regents of the University of California.  All rights reserved.
5178172Simp *
6178172Simp * This code is derived from software contributed to Berkeley by
7178172Simp * Digital Equipment Corporation and Ralph Campbell.
8178172Simp *
9178172Simp * Redistribution and use in source and binary forms, with or without
10178172Simp * modification, are permitted provided that the following conditions
11178172Simp * are met:
12178172Simp * 1. Redistributions of source code must retain the above copyright
13178172Simp *    notice, this list of conditions and the following disclaimer.
14178172Simp * 2. Redistributions in binary form must reproduce the above copyright
15178172Simp *    notice, this list of conditions and the following disclaimer in the
16178172Simp *    documentation and/or other materials provided with the distribution.
17178172Simp * 4. Neither the name of the University nor the names of its contributors
18178172Simp *    may be used to endorse or promote products derived from this software
19178172Simp *    without specific prior written permission.
20178172Simp *
21178172Simp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22178172Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23178172Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24178172Simp * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25178172Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26178172Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27178172Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28178172Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29178172Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30178172Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31178172Simp * SUCH DAMAGE.
32178172Simp *
33178172Simp * Copyright (C) 1989 Digital Equipment Corporation.
34178172Simp * Permission to use, copy, modify, and distribute this software and
35178172Simp * its documentation for any purpose and without fee is hereby granted,
36178172Simp * provided that the above copyright notice appears in all copies.
37178172Simp * Digital Equipment Corporation makes no representations about the
38178172Simp * suitability of this software for any purpose.  It is provided "as is"
39178172Simp * without express or implied warranty.
40178172Simp *
41178172Simp * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/loMem.s,
42178172Simp *	v 1.1 89/07/11 17:55:04 nelson Exp  SPRITE (DECWRL)
43178172Simp * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsm.s,
44178172Simp *	v 9.2 90/01/29 18:00:39 shirriff Exp  SPRITE (DECWRL)
45178172Simp * from: Header: /sprite/src/kernel/vm/ds3100.md/vmPmaxAsm.s,
46178172Simp *	v 1.1 89/07/10 14:27:41 nelson Exp  SPRITE (DECWRL)
47178172Simp *
48178172Simp *	from: @(#)locore.s	8.5 (Berkeley) 1/4/94
49178172Simp *	JNPR: locore.S,v 1.6.2.1 2007/08/29 12:24:49 girish
50178172Simp * $FreeBSD: head/sys/mips/mips/locore.S 203114 2010-01-28 14:03:06Z rrs $
51178172Simp */
52178172Simp
53178172Simp/*
54178172Simp * FREEBSD_DEVELOPERS_FIXME
55178172Simp * The start routine below was written for a multi-core CPU
56178172Simp * with each core being hyperthreaded. This serves as an example
57178172Simp * for a complex CPU architecture. For a different CPU complex
58178172Simp * please make necessary changes to read CPU-ID etc.
59178172Simp * A clean solution would be to have a different locore file for
60178172Simp * each CPU type.
61178172Simp */
62178172Simp
63178172Simp/*
64178172Simp *	Contains code that is the first executed at boot time plus
65178172Simp *	assembly language support routines.
66178172Simp */
67178172Simp
68178172Simp#include <machine/asm.h>
69178172Simp#include <machine/cpu.h>
70178172Simp#include <machine/cpuregs.h>
71178172Simp#include <machine/regnum.h>
72178172Simp
73178172Simp#include "assym.s"
74178172Simp
75178172Simp	.data
76178172Simp#ifdef YAMON
77178172SimpGLOBAL(fenvp)
78178172Simp	.space 4			# Assumes mips32?  Is that OK?
79178172Simp#endif
80178172SimpGLOBAL(stackspace)
81178172Simp	.space NBPG /* Smaller than it should be since it's temp. */
82178172Simp	.align 8
83178172SimpGLOBAL(topstack)
84178172Simp
85178172Simp
86178172Simp	.set noreorder
87178172Simp
88178172Simp	.text
89178172Simp
90178172SimpGLOBAL(btext)
91178172SimpASM_ENTRY(_start)
92178172SimpVECTOR(_locore, unknown)
93178172Simp	/* UNSAFE TO USE a0..a3, since some bootloaders pass that to us */
94178172Simp	mtc0	zero, COP_0_CAUSE_REG	# Clear soft interrupts
95178172Simp
96178172Simp#if defined(TARGET_OCTEON)
97178172Simp	/*
98178172Simp	 * t1: Bits to set explicitly:
99178172Simp	 *	Enable FPU
100178172Simp	 */
101178172Simp
102178172Simp	/* Set these bits */
103178172Simp        li	t1, (MIPS_SR_COP_2_BIT | MIPS_SR_COP_0_BIT | MIPS_SR_PX | MIPS_SR_KX | MIPS_SR_UX | MIPS_SR_SX | MIPS_SR_BEV)
104178172Simp
105178172Simp	/* Reset these bits */
106178172Simp        li	t0, ~(MIPS_SR_DE | MIPS_SR_SOFT_RESET | MIPS_SR_ERL | MIPS_SR_EXL | MIPS_SR_INT_IE)
107203114Srrs#elif defined (CPU_XLR)
108203114Srrs	/* Set these bits */
109203114Srrs        li	t1, (MIPS_SR_COP_2_BIT | MIPS_SR_COP_0_BIT | MIPS_SR_KX)
110203114Srrs
111203114Srrs	/* Reset these bits */
112203114Srrs        li	t0, ~(MIPS_SR_BEV | MIPS_SR_SOFT_RESET | MIPS_SR_INT_IE)
113178172Simp#else
114178172Simp	/*
115178172Simp	 * t0: Bits to preserve if set:
116178172Simp	 * 	Soft reset
117178172Simp	 *	Boot exception vectors (firmware-provided)
118178172Simp	 */
119178172Simp	li	t0, (MIPS_SR_BEV | MIPS_SR_SOFT_RESET)
120178172Simp	/*
121178172Simp	 * t1: Bits to set explicitly:
122178172Simp	 *	Enable FPU
123178172Simp	 */
124178172Simp	li	t1, MIPS_SR_COP_1_BIT
125178172Simp#endif
126178172Simp	/*
127178172Simp	 * Read coprocessor 0 status register, clear bits not
128178172Simp	 * preserved (namely, clearing interrupt bits), and set
129178172Simp	 * bits we want to explicitly set.
130178172Simp	 */
131178172Simp	mfc0	t2, COP_0_STATUS_REG
132178172Simp	and	t2, t0
133178172Simp	or	t2, t1
134178172Simp	mtc0	t2, COP_0_STATUS_REG
135178172Simp	COP0_SYNC
136178172Simp	/* Make sure KSEG0 is cached */
137178172Simp	li	t0, CFG_K0_CACHED
138178172Simp	mtc0	t0, MIPS_COP_0_CONFIG
139178172Simp	COP0_SYNC
140178172Simp
141178172Simp	/* Read and store the PrID FPU ID for CPU identification, if any. */
142178172Simp	mfc0	t2, COP_0_STATUS_REG
143178172Simp	mfc0	t0, MIPS_COP_0_PRID
144202046Simp#ifdef CPU_HAVEFPU
145178172Simp	and	t2, MIPS_SR_COP_1_BIT
146178172Simp	beqz	t2, 1f
147178172Simp	move	t1, zero
148178172Simp	cfc1	t1, MIPS_FPU_ID
149178172Simp1:
150178172Simp#else
151178172Simp	/*
152178172Simp	 * This platform has no FPU, and attempting to detect one
153178172Simp	 * using the official method causes an exception.
154178172Simp	 */
155178172Simp	move	t1, zero
156178172Simp#endif
157178172Simp	sw	t0, _C_LABEL(cpu_id)
158178172Simp	sw	t1, _C_LABEL(fpu_id)
159178172Simp
160178172Simp/*
161178172Simp * Initialize stack and call machine startup.
162178172Simp */
163202046Simp	PTR_LA	sp, _C_LABEL(topstack) - START_FRAME
164202046Simp	PTR_LA	gp, _C_LABEL(_gp)
165178172Simp	sw	zero, START_FRAME - 4(sp)  # Zero out old ra for debugger
166178172Simp
167178172Simp	/*xxximp
168178172Simp	 * now that we pass a0...a3 to the platform_init routine, do we need
169178172Simp	 * to stash this stuff here?
170178172Simp	 */
171178172Simp#ifdef YAMON
172178172Simp	/* Save YAMON boot environment pointer */
173178172Simp	sw	a2, _C_LABEL(fenvp)
174178172Simp#endif
175178172Simp
176178172Simp	/*
177178172Simp	 * The following needs to be done differently for each platform and
178178172Simp	 * there needs to be a good way to plug this in.
179178172Simp	 */
180178172Simp#if defined(SMP) && defined(CPU_XLR)
181178172Simp/*
182178172Simp * Block all the slave CPUs
183178172Simp */
184202046Simp	/* XXX a0, a1, a2 shouldn't be used here */
185178172Simp	/*
186178172Simp	 * Read the cpu id from the cp0 config register
187178172Simp	 * cpuid[9:4], thrid[3: 0]
188178172Simp	 */
189178172Simp	mfc0	a0, COP_0_CONFIG, 7
190178172Simp	srl	a1, a0, 4
191178172Simp	andi	a1, a1, 0x3f
192178172Simp	andi	a0, a0, 0xf
193178172Simp
194178172Simp	/* calculate linear cpuid */
195178172Simp	sll     t0, a1, 2
196178172Simp	addu    a2, t0, a0
197178172Simp/* Initially, disable all hardware threads on each core except thread0 */
198178172Simp	li	t1, VCPU_ID_0
199178172Simp	li	t2, XLR_THREAD_ENABLE_IND
200178172Simp	mtcr	t1, t2
201178172Simp#endif
202178172Simp
203178172Simp
204178172Simp#if defined(TARGET_OCTEON) /* Maybe this is mips32/64 generic? */
205178172Simp	.set push
206178172Simp	.set mips32r2
207178172Simp	rdhwr	t0, $0
208178172Simp	.set pop
209178172Simp#else
210178172Simp	move	t0, zero
211178172Simp#endif
212178172Simp
213178172Simp	/* Stage the secondary cpu start until later */
214178172Simp	bne	t0, zero, start_secondary
215178172Simp	nop
216178172Simp
217178172Simp#ifdef SMP
218202046Simp	PTR_LA	t0, _C_LABEL(__pcpu)
219178172Simp	SET_CPU_PCPU(t0)
220178172Simp	/* If not master cpu, jump... */
221178172Simp/*XXX this assumes the above #if 0'd code runs */
222178172Simp	bne    a2, zero, start_secondary
223178172Simp	nop
224178172Simp#endif
225178172Simp
226178172Simp	/* Call the platform-specific startup code. */
227178172Simp	jal	_C_LABEL(platform_start)
228178172Simp	sw	zero, START_FRAME - 8(sp)	# Zero out old fp for debugger
229178172Simp
230202046Simp	PTR_LA	sp, _C_LABEL(thread0)
231178172Simp	lw      a0, TD_PCB(sp)
232178172Simp	li	t0, ~7
233178172Simp	and	a0, a0, t0
234178172Simp	subu    sp, a0, START_FRAME
235178172Simp
236178172Simp	jal	_C_LABEL(mi_startup)		# mi_startup(frame)
237178172Simp	sw	zero, START_FRAME - 8(sp)	# Zero out old fp for debugger
238178172Simp
239178172Simp	PANIC("Startup failed!")
240178172Simp
241178172Simp#ifdef SMP
242178172Simpstart_secondary:
243178172Simp	move	a0, a1
244178172Simp2:
245178172Simp	addiu	t0, PCPU_SIZE
246178172Simp	subu	a1, 1
247178172Simp	bne	a1, zero, 2b
248178172Simp	nop
249178172Simp	SET_CPU_PCPU(t0)
250178172Simpsmp_wait:
251178172Simp	lw	sp, PC_BOOT_STACK(t0)
252178172Simp	beqz	sp, smp_wait
253178172Simp	nop
254178172Simp	jal	_C_LABEL(smp_init_secondary)
255178172Simp	nop
256178172Simp#else
257178172Simpstart_secondary:
258178172Simp	b	start_secondary
259178172Simp	nop
260178172Simp#endif
261178172Simp
262178172SimpVECTOR_END(_locore)
263