2 // For the Xtensa simulator target, this code sets up the C calling context
3 // and calls main() (via __clibrary_start).
4 // Control arrives here at _start from the reset vector or from crt0-app.S.
6 // Copyright (c) 1998-2010 Tensilica Inc.
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
16 // The above copyright notice and this permission notice shall be included
17 // in all copies or substantial portions of the Software.
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 #include <xtensa/simboard.h>
28 #include <xtensa/simcall.h>
29 #include <xtensa/coreasm.h>
30 #include "xtos-internal.h"
37 // __clibrary_init from C library (eg. newlib or uclibc)
38 // exit from C library
39 // main from user application
40 // __stack from linker script (see LSP Ref Manual)
42 .type __clibrary_init, @function
47 // Macros to abstract away ABI differences
49 #if __XTENSA_CALL0_ABI__
51 # define ARG1 a2 /* 1st outgoing call argument */
52 # define ARG2 a3 /* 2nd outgoing call argument */
53 # define ARG3 a4 /* 3rd outgoing call argument */
54 # define ARG4 a5 /* 4th outgoing call argument */
55 # define ARG5 a6 /* 5th outgoing call argument */
58 # define ARG1 a6 /* 1st outgoing call argument */
59 # define ARG2 a7 /* 2nd outgoing call argument */
60 # define ARG3 a8 /* 3rd outgoing call argument */
61 # define ARG4 a9 /* 4th outgoing call argument */
62 # define ARG5 a10 /* 5th outgoing call argument */
66 .weak _start_envp // allow overriding
68 _start_envp: .word 0 // empty environ
76 // _start is typically NOT at the beginning of the text segment --
77 // it is always called from either the reset vector or other code
78 // that does equivalent initialization (such as crt0-app.S).
80 // Assumptions on entry to _start:
81 // - low (level-one) and medium priority interrupts are disabled
82 // via PS.INTLEVEL and/or INTENABLE (PS.INTLEVEL is expected to
83 // be zeroed, to potentially enable them, before calling main)
84 // - C calling context not initialized:
85 // - PS not initialized
86 // - SP not initialized
87 // - the following are initialized:
88 // - LITBASE, cache attributes, WindowBase, WindowStart,
89 // CPENABLE, FP's FCR and FSR, EXCSAVE[n]
91 // Keep a0 zero. It is used to initialize a few things.
92 // It is also the return address, where zero indicates
93 // that the frame used by _start is the bottommost frame.
95 movi a0, 0 // keep this register zero.
97 #if XTOS_RESET_UNNEEDED
98 #include "reset-unneeded.S"
102 // Initialize the stack pointer.
103 // See the "ABI and Software Conventions" chapter in the
104 // Xtensa ISA Reference manual for details.
106 // NOTE: Because the _start routine does not use any memory in its
107 // stack frame, and because all of its CALL instructions use a
108 // window size of 4, the stack frame for _start can be empty.
111 // reserve stack space for
113 // - argument strings
114 movi a2, SYS_iss_argv_size
115 simcall // returns size of argv[] + its strings in a2
117 // The stack only needs 16-byte alignment.
118 // However, here we round up the argv size further to 128 byte multiples
119 // so that in most cases, variations in argv[0]'s path do not result in
120 // different stack allocation. Otherwise, such variations can impact
121 // execution timing (eg. due to cache effects etc) for the same code and data.
122 // If we have a PIF, it's more likely the extra required space is okay.
127 // Keep stack 16-byte aligned.
132 // No need to use MOVSP because we have no caller (we're the
133 // base caller); in fact it's better not to use MOVSP in this
134 // context, to avoid unnecessary ALLOCA exceptions and copying
135 // from undefined memory:
142 * Now that sp (a1) is set, we can set PS as per the application
143 * (user vector mode, enable interrupts, enable window exceptions if applicable).
145 #if XCHAL_HAVE_EXCEPTIONS
146 # ifdef __XTENSA_CALL0_ABI__
147 movi a3, PS_UM // PS.WOE = 0, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0
149 movi a3, PS_UM|PS_WOE // PS.WOE = 1, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0
156 /* The new ISS simcall only appeared after RB-2007.2: */
157 #if !XCHAL_HAVE_BOOTLOADER && (XCHAL_HW_MAX_VERSION > XTENSA_HWVERSION_RB_2007_2) /* pre-LX2 cores only */
159 * Clear the BSS (uninitialized data) segments.
160 * This code supports multiple zeroed sections (*.bss).
161 * For speed, we clear memory using an ISS simcall
162 * (see crt1-boards.S for more generic BSS clearing code).
164 movi a6, _bss_table_start
165 movi a7, _bss_table_end
169 l32i a3, a6, 0 // arg1 = fill start address
170 movi a4, 0 // arg2 = fill pattern
171 l32i a5, a6, 4 // get end address
172 addi a6, a6, 8 // next bss table entry
173 sub a5, a5, a3 // arg3 = fill size in bytes
174 simcall // memset(a3,a4,a5)
175 bltu a6, a7, .Lbssloop // loop until end of bss table
181 * Call __clibrary_init to initialize the C library:
183 * void __clibrary_init(int argc, char ** argv, char ** environ,
184 * void(*init_func)(void), void(*fini_func)(void));
187 // Get argv with the arguments from the ISS
188 mov a3, sp // tell simcall where to write argv[]
189 movi a2, SYS_iss_set_argv
190 simcall // write argv[] array at a3
192 movi a2, SYS_iss_argc
193 simcall // put argc in a2
196 // Alternative smaller code for Xtensa TX.
197 // Many starting with simulation assume a full C env, so NOT DONE FOR NOW.
199 //#if XCHAL_HAVE_HALT
201 // // Assume minimalist environment for memory-constrained TX cores.
202 // // No C library or board initialization, and no call to exit().
203 // // However, in the interest of software regressions, for now we
204 // // still pass parameters to main (but not the rarely used envp).
206 // //mov ARG1, a2 // argc already in a2.
207 // mov ARG2, sp // argv
215 #if __XTENSA_CALL0_ABI__
216 mov a12, a2 // save argc (a2 is ARG1)
221 movi ARG3, _start_envp // envp
222 movi ARG4, _init // _init
223 movi ARG5, _fini // _fini
226 // Call: int main(int argc, char ** argv, char ** environ);
227 #if __XTENSA_CALL0_ABI__
228 mov ARG1, a12 // argc
233 movi ARG3, _start_envp // envp = [0]
235 // The return value is the same register as the first outgoing argument.
236 CALL exit // exit with main's return value
237 // Does not return here.
239 .size _start, . - _start
244 // comment-start: "// "
245 // comment-start-skip: "// *"