]>
Commit | Line | Data |
---|---|---|
49703eb3 JJ |
1 | /* |
2 | * crt0_cfe.S -- Runtime startup for MIPS targets running CFE. | |
3 | * | |
4 | * Copyright 2003 | |
5 | * Broadcom Corporation. All rights reserved. | |
6 | * | |
7 | * This software is furnished under license and may be used and copied only | |
8 | * in accordance with the following terms and conditions. Subject to these | |
9 | * conditions, you may download, copy, install, use, modify and distribute | |
10 | * modified or unmodified copies of this software in source and/or binary | |
11 | * form. No title or ownership is transferred hereby. | |
12 | * | |
13 | * 1) Any source code used, modified or distributed must reproduce and | |
14 | * retain this copyright notice and list of conditions as they appear in | |
15 | * the source file. | |
16 | * | |
17 | * 2) No right is granted to use any trade name, trademark, or logo of | |
18 | * Broadcom Corporation. The "Broadcom Corporation" name may not be | |
19 | * used to endorse or promote products derived from this software | |
20 | * without the prior written permission of Broadcom Corporation. | |
21 | * | |
22 | * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED | |
23 | * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF | |
24 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR | |
25 | * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE | |
26 | * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE | |
27 | * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
28 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | |
30 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
31 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | |
32 | * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
33 | */ | |
34 | ||
35 | /* | |
36 | * Derived from crt0_cygmon.S: | |
37 | * | |
38 | * Copyright (c) 1995, 1996, 1997, 2000 Red Hat, Inc. | |
39 | * | |
40 | * The authors hereby grant permission to use, copy, modify, distribute, | |
41 | * and license this software and its documentation for any purpose, provided | |
42 | * that existing copyright notices are retained in all copies and that this | |
43 | * notice is included verbatim in any distributions. No written agreement, | |
44 | * license, or royalty fee is required for any of the authorized uses. | |
45 | * Modifications to this software may be copyrighted by their authors | |
46 | * and need not follow the licensing terms described here, provided that | |
47 | * the new terms are clearly indicated on the first page of each file where | |
48 | * they apply. | |
49 | */ | |
50 | ||
51 | /* | |
52 | * This file does minimal runtime startup for code running under | |
53 | * CFE firmware. | |
54 | * | |
55 | * It does minimal hardware initialization. In particular | |
56 | * it sets Status:FR to match the requested floating point | |
57 | * mode. | |
58 | * | |
59 | * It is meant to be linked with the other files provided by libcfe.a, | |
60 | * and calls routines in those files. | |
61 | */ | |
62 | ||
63 | #ifdef __mips16 | |
64 | /* This file contains 32 bit assembly code. */ | |
65 | .set nomips16 | |
66 | #endif | |
67 | #ifdef __mips_embedded_pic | |
68 | # error -membedded-pic is not supported. | |
69 | #endif | |
70 | ||
71 | #include "regs.S" | |
72 | ||
73 | /* | |
74 | * Set up some room for a stack. We just grab a chunk of memory. | |
75 | */ | |
76 | #define STARTUP_STACK_SIZE (1 * 1024) | |
77 | ||
78 | .comm _lstack, STARTUP_STACK_SIZE | |
79 | ||
80 | .text | |
81 | .align 4 | |
82 | ||
83 | /* | |
84 | * Without the following nop, GDB thinks _start is a data variable. | |
85 | * This is probably a bug in GDB in handling a symbol that is at the | |
86 | * start of the .text section. | |
87 | */ | |
88 | nop | |
89 | ||
90 | ||
91 | /* | |
92 | * On entry, the following values have been passed in registers | |
93 | * by the firmware: | |
94 | * | |
95 | * a0: firmware handle | |
96 | * a1: zero (unused) | |
97 | * a2: firmware callback entrypoint | |
98 | * a3: CFE entrypoint seal (unused) | |
99 | * | |
100 | * They must be preserved until the CFE entrypoint and handle | |
101 | * are passed to __libcfe_init(). | |
102 | */ | |
103 | ||
104 | .globl _start | |
105 | .ent _start | |
106 | _start: | |
107 | .set noreorder | |
108 | /* Set the global data pointer, defined in the linker script. */ | |
109 | la gp, _gp | |
110 | ||
111 | #ifndef __mips_soft_float | |
112 | /* If compiled for hard float, set the FPU mode based on the | |
113 | compilation flags. Note that this assumes that enough code | |
114 | will run after the mtc0 to clear any hazards. */ | |
115 | mfc0 t0, C0_SR | |
116 | or t0, t0, (SR_CU1 | SR_FR) | |
117 | #if (__mips_fpr == 32) | |
118 | xor t0, t0, SR_FR /* If 32-bit FP mode, clear FR. */ | |
119 | #endif | |
120 | mtc0 t0, C0_SR | |
121 | #endif | |
122 | .end _start | |
123 | ||
124 | /* | |
125 | * zero out the bss section. | |
126 | */ | |
127 | .globl _zerobss | |
128 | .ent _zerobss | |
129 | _zerobss: | |
130 | /* These variables are defined in the linker script. */ | |
131 | la v0, _fbss | |
132 | la v1, _end | |
133 | ||
134 | 3: | |
135 | sw zero, 0(v0) | |
136 | bltu v0, v1, 3b | |
137 | addiu v0, v0, 4 /* Delay slot. */ | |
138 | .end _zerobss | |
139 | ||
140 | /* | |
141 | * Setup a small stack so we can run some C code, and do | |
142 | * the library initialization. (32 bytes are saved for | |
143 | * the argument registers' stack slots.) | |
144 | */ | |
145 | .globl _stackinit | |
146 | .ent _stackinit | |
147 | _stackinit: | |
148 | la t0, _lstack | |
149 | addiu sp, t0, (STARTUP_STACK_SIZE - 32) | |
150 | jal __libcfe_init | |
151 | nop | |
152 | ||
153 | /* | |
154 | * Setup the stack pointer -- | |
155 | * __libcfe_init() returns the value to be used as the top of | |
156 | * the program's stack. | |
157 | * | |
158 | * We subtract 32 bytes for the 4 argument registers, in case | |
159 | * main() wants to write them back to the stack. The caller | |
160 | * allocates stack space for parameters in the old MIPS ABIs. | |
161 | * We must do this even though we aren't passing arguments, | |
162 | * because main might be declared to have them.) | |
163 | * | |
164 | * We subtract 32 more bytes for the argv/envp setup for the | |
165 | * call to main(). | |
166 | */ | |
167 | subu v0, v0, 64 | |
168 | move sp, v0 | |
169 | ||
170 | .end _stackinit | |
171 | ||
172 | /* | |
173 | * initialize target specific stuff. Only execute these | |
174 | * functions it they exist. | |
175 | */ | |
176 | .globl hardware_init_hook .text | |
177 | .globl software_init_hook .text | |
178 | .type _fini,@function | |
179 | .type _init,@function | |
180 | .globl atexit .text | |
181 | .globl exit .text | |
182 | .globl _crt0init | |
183 | .ent _crt0init | |
184 | _crt0init: | |
185 | la t9, hardware_init_hook # init the hardware if needed | |
186 | beq t9, zero, 6f | |
187 | nop | |
188 | jal t9 | |
189 | nop | |
190 | 6: | |
191 | la t9, software_init_hook # init the software if needed | |
192 | beq t9, zero, 7f | |
193 | nop | |
194 | jal t9 | |
195 | nop | |
196 | 7: | |
197 | la a0, _fini | |
198 | jal atexit | |
199 | nop | |
200 | ||
201 | #ifdef GCRT0 | |
202 | .globl _ftext | |
203 | .globl _extext | |
204 | la a0, _ftext | |
205 | la a1, _etext | |
206 | jal monstartup | |
207 | nop | |
208 | #endif | |
209 | ||
210 | jal _init # run global constructors | |
211 | nop | |
212 | ||
213 | addiu a1,sp,32 # argv = sp + 32 | |
214 | addiu a2,sp,40 # envp = sp + 40 | |
215 | #if __mips64 | |
216 | sd zero,(a1) # argv[argc] = 0 | |
217 | sd zero,(a2) # envp[0] = 0 | |
218 | #else | |
219 | sw zero,(a1) | |
220 | sw zero,(a2) | |
221 | #endif | |
222 | ||
223 | jal main # call the program start function | |
224 | move a0,zero # set argc to 0; delay slot. | |
225 | ||
226 | # fall through to the "exit" routine | |
227 | jal exit # call libc exit to run the G++ | |
228 | # destructors | |
229 | move a0, v0 # pass through the exit code | |
230 | .end _crt0init | |
231 | ||
232 | /* | |
233 | * _exit -- Exit from the application. This is provided in this file because | |
234 | * program exit should shut down profiling (if GCRT0 is defined), | |
235 | * and only this file is compiled with GCRT0 defined. | |
236 | */ | |
237 | .globl _exit | |
238 | .ent _exit | |
239 | _exit: | |
240 | 7: | |
241 | move s0, a0 /* Save in case we loop. */ | |
242 | ||
243 | #ifdef GCRT0 | |
244 | jal _mcleanup | |
245 | nop | |
246 | #endif | |
247 | ||
248 | la t0, hardware_exit_hook | |
249 | beq t0,zero,1f | |
250 | nop | |
251 | jal t0 | |
252 | nop | |
253 | ||
254 | 1: | |
255 | /* Call into the library to do the heavy lifting. */ | |
256 | jal __libcfe_exit | |
257 | move a0, s0 /* Delay slot. */ | |
258 | ||
259 | b 7b /* Loop back just in case. */ | |
260 | nop | |
261 | .end _exit | |
262 | ||
263 | /* EOF crt0_cfe.S */ |