]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/mips/mips/locore.S
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / mips / mips / locore.S
1 /*      $OpenBSD: locore.S,v 1.18 1998/09/15 10:58:53 pefo Exp $        */
2 /*-
3  * Copyright (c) 1992, 1993
4  *      The Regents of the University of California.  All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * Digital Equipment Corporation and Ralph Campbell.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Copyright (C) 1989 Digital Equipment Corporation.
34  * Permission to use, copy, modify, and distribute this software and
35  * its documentation for any purpose and without fee is hereby granted,
36  * provided that the above copyright notice appears in all copies.
37  * Digital Equipment Corporation makes no representations about the
38  * suitability of this software for any purpose.  It is provided "as is"
39  * without express or implied warranty.
40  *
41  * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/loMem.s,
42  *      v 1.1 89/07/11 17:55:04 nelson Exp  SPRITE (DECWRL)
43  * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsm.s,
44  *      v 9.2 90/01/29 18:00:39 shirriff Exp  SPRITE (DECWRL)
45  * from: Header: /sprite/src/kernel/vm/ds3100.md/vmPmaxAsm.s,
46  *      v 1.1 89/07/10 14:27:41 nelson Exp  SPRITE (DECWRL)
47  *
48  *      from: @(#)locore.s      8.5 (Berkeley) 1/4/94
49  *      JNPR: locore.S,v 1.6.2.1 2007/08/29 12:24:49 girish
50  * $FreeBSD$
51  */
52
53 /*
54  * FREEBSD_DEVELOPERS_FIXME
55  * The start routine below was written for a multi-core CPU
56  * with each core being hyperthreaded. This serves as an example
57  * for a complex CPU architecture. For a different CPU complex
58  * please make necessary changes to read CPU-ID etc.
59  * A clean solution would be to have a different locore file for
60  * each CPU type.
61  */
62
63 /*
64  *      Contains code that is the first executed at boot time plus
65  *      assembly language support routines.
66  */
67
68 #include <machine/asm.h>
69 #include <machine/cpu.h>
70 #include <machine/cpuregs.h>
71 #include <machine/regnum.h>
72
73 #include "assym.s"
74
75         .data
76 #ifdef YAMON
77 GLOBAL(fenvp)
78         .space 4                        # Assumes mips32?  Is that OK?
79 #endif
80 #ifdef CFE                      /* Assumes MIPS32, bad? */
81 GLOBAL(cfe_handle)
82         .space 4
83 GLOBAL(cfe_vector)
84         .space 4
85 #endif
86 #if defined(TARGET_OCTEON)
87 GLOBAL(app_descriptor_addr)
88         .space 8
89 #endif
90 GLOBAL(stackspace)
91         .space NBPG /* Smaller than it should be since it's temp. */
92         .align 8
93 GLOBAL(topstack)
94
95         
96         .set noreorder
97         
98         .text
99
100 GLOBAL(btext)
101 ASM_ENTRY(_start)
102 VECTOR(_locore, unknown)
103         /* UNSAFE TO USE a0..a3, since some bootloaders pass that to us */
104         mtc0    zero, COP_0_CAUSE_REG   # Clear soft interrupts
105         
106 #if defined(TARGET_OCTEON)
107         /*
108          * t1: Bits to set explicitly:
109          *      Enable FPU
110          */
111
112         /* Set these bits */
113         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)
114
115         /* Reset these bits */
116         li      t0, ~(MIPS_SR_DE | MIPS_SR_SOFT_RESET | MIPS_SR_ERL | MIPS_SR_EXL | MIPS_SR_INT_IE)
117 #else
118         /*
119          * t0: Bits to preserve if set:
120          *      Soft reset
121          *      Boot exception vectors (firmware-provided)
122          */
123         li      t0, (MIPS_SR_BEV | MIPS_SR_SOFT_RESET)
124         /*
125          * t1: Bits to set explicitly:
126          *      Enable FPU
127          */
128         li      t1, MIPS_SR_COP_1_BIT
129 #endif
130         /*
131          * Read coprocessor 0 status register, clear bits not
132          * preserved (namely, clearing interrupt bits), and set
133          * bits we want to explicitly set.
134          */
135         mfc0    t2, COP_0_STATUS_REG
136         and     t2, t0
137         or      t2, t1
138         mtc0    t2, COP_0_STATUS_REG
139         COP0_SYNC
140         /* Make sure KSEG0 is cached */
141         li      t0, CFG_K0_CACHED
142         mtc0    t0, MIPS_COP_0_CONFIG
143         COP0_SYNC
144
145         /* Read and store the PrID FPU ID for CPU identification, if any. */
146         mfc0    t2, COP_0_STATUS_REG
147         mfc0    t0, MIPS_COP_0_PRID
148 #ifndef CPU_NOFPU
149         and     t2, MIPS_SR_COP_1_BIT
150         beqz    t2, 1f
151         move    t1, zero
152         cfc1    t1, MIPS_FPU_ID
153 1:
154 #else
155         /*
156          * This platform has no FPU, and attempting to detect one
157          * using the official method causes an exception.
158          */
159         move    t1, zero
160 #endif
161         sw      t0, _C_LABEL(cpu_id)
162         sw      t1, _C_LABEL(fpu_id)
163
164 /*
165  * Initialize stack and call machine startup.
166  */
167         la      sp, _C_LABEL(topstack) - START_FRAME
168         la      gp, _C_LABEL(_gp)
169         sw      zero, START_FRAME - 4(sp)  # Zero out old ra for debugger
170
171         /*xxximp
172          * now that we pass a0...a3 to the platform_init routine, do we need
173          * to stash this stuff here?
174          */
175 #ifdef YAMON
176         /* Save YAMON boot environment pointer */
177         sw      a2, _C_LABEL(fenvp)
178 #endif
179 #ifdef CFE
180         /*
181         * Save the CFE context passed to us by the loader.
182         */
183         li      t1, 0x43464531
184         bne     a3, t1, no_cfe          /* Check for "CFE1" signature */
185         sw      a0, _C_LABEL(cfe_handle)/* Firmware data segment */
186         sw      a2, _C_LABEL(cfe_vector)/* Firmware entry vector */
187 no_cfe:
188 #endif
189 #if defined(TARGET_OCTEON)
190         la      a0, app_descriptor_addr
191         sw      a3, 0(a0)               /* Store app descriptor ptr */
192 #endif
193
194         /*
195          * The following needs to be done differently for each platform and
196          * there needs to be a good way to plug this in.
197          */
198 #if defined(SMP) && defined(CPU_XLR)
199 /*
200  * Block all the slave CPUs
201  */
202         /*
203          * Read the cpu id from the cp0 config register
204          * cpuid[9:4], thrid[3: 0]
205          */
206         mfc0    a0, COP_0_CONFIG, 7
207         srl     a1, a0, 4
208         andi    a1, a1, 0x3f
209         andi    a0, a0, 0xf
210
211         /* calculate linear cpuid */
212         sll     t0, a1, 2
213         addu    a2, t0, a0
214 /* Initially, disable all hardware threads on each core except thread0 */
215         li      t1, VCPU_ID_0
216         li      t2, XLR_THREAD_ENABLE_IND
217         mtcr    t1, t2
218 #endif
219
220
221 #if defined(TARGET_OCTEON) /* Maybe this is mips32/64 generic? */
222         .set push
223         .set mips32r2
224         rdhwr   t0, $0
225         .set pop
226 #else
227         move    t0, zero
228 #endif
229
230         /* Stage the secondary cpu start until later */
231         bne     t0, zero, start_secondary
232         nop
233
234 #ifdef SMP
235         la      t0, _C_LABEL(__pcpu)
236         SET_CPU_PCPU(t0)
237         /* If not master cpu, jump... */
238 /*XXX this assumes the above #if 0'd code runs */
239         bne    a2, zero, start_secondary
240         nop
241 #endif
242
243         /* Call the platform-specific startup code. */
244         jal     _C_LABEL(platform_start)
245         sw      zero, START_FRAME - 8(sp)       # Zero out old fp for debugger
246
247         la      sp, _C_LABEL(thread0)
248         lw      a0, TD_PCB(sp)
249         li      t0, ~7
250         and     a0, a0, t0
251         subu    sp, a0, START_FRAME
252
253         jal     _C_LABEL(mi_startup)            # mi_startup(frame)
254         sw      zero, START_FRAME - 8(sp)       # Zero out old fp for debugger
255
256         PANIC("Startup failed!")
257
258 #ifdef SMP
259 start_secondary:
260         move    a0, a1
261 2:
262         addiu   t0, PCPU_SIZE
263         subu    a1, 1
264         bne     a1, zero, 2b
265         nop
266         SET_CPU_PCPU(t0)
267 smp_wait:
268         lw      sp, PC_BOOT_STACK(t0)
269         beqz    sp, smp_wait
270         nop
271         jal     _C_LABEL(smp_init_secondary)
272         nop
273 #else
274 start_secondary:
275         b       start_secondary
276         nop
277 #endif
278
279 VECTOR_END(_locore)