Setting up repository
[linux-libre-firmware.git] / ath9k_htc / sboot / magpie_1_1 / sboot / athos / src / xtos / crt1-sim.S
1 // crt1-sim.S
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.
5
6 // Copyright (c) 1998-2010 Tensilica Inc.
7 //
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:
15 //
16 // The above copyright notice and this permission notice shall be included
17 // in all copies or substantial portions of the Software.
18 //
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.
26
27 #include <xtensa/simboard.h>
28 #include <xtensa/simcall.h>
29 #include <xtensa/coreasm.h>
30 #include "xtos-internal.h"
31
32
33 // Exports
34 .global _start
35
36 // Imports
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)
41
42 .type   __clibrary_init, @function
43 .type   main, @function
44 .type   exit, @function
45
46
47 // Macros to abstract away ABI differences
48
49 #if __XTENSA_CALL0_ABI__
50 # define CALL   call0
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 */
56 #else
57 # define CALL   call4
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 */
63 #endif
64
65                 .data
66                 .weak   _start_envp     // allow overriding
67                 .align  4
68 _start_envp:    .word   0               // empty environ
69
70
71
72         .text
73         .align 4
74
75 _start:
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).
79         //
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]
90
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.
94         //
95         movi    a0, 0           // keep this register zero.
96
97 #if XTOS_RESET_UNNEEDED
98 #include "reset-unneeded.S"
99 #endif
100
101
102         // Initialize the stack pointer.
103         // See the "ABI and Software Conventions" chapter in the
104         // Xtensa ISA Reference manual for details.
105
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.
109         movi    sp, __stack
110
111         // reserve stack space for
112         //    - argv array
113         //    - argument strings
114         movi    a2, SYS_iss_argv_size
115         simcall         // returns size of argv[] + its strings in a2
116 #if XCHAL_HAVE_PIF
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.
123         addi    a2, a2, 127
124         srli    a2, a2, 7
125         slli    a2, a2, 7
126 #else
127         // Keep stack 16-byte aligned.
128         addi    a2, a2, 15
129         srli    a2, a2, 4
130         slli    a2, a2, 4
131 #endif
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:
136         //   sub     a3, sp, a2
137         //   movsp   sp, a3
138         sub     sp, sp, a2
139
140
141         /*
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).
144          */
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
148 # else  
149         movi    a3, PS_UM|PS_WOE        // PS.WOE = 1, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0
150 # endif
151         wsr     a3, PS
152         rsync
153 #endif
154
155
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 */
158         /*
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).
163          */
164         movi    a6, _bss_table_start
165         movi    a7, _bss_table_end
166         bgeu    a6, a7, .Lnobss
167 .Lbssloop:
168         movi    a2, SYS_memset
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
176 .Lnobss:
177 #endif
178
179
180         /* 
181          *  Call __clibrary_init to initialize the C library:
182          *
183          *  void __clibrary_init(int argc, char ** argv, char ** environ, 
184          *              void(*init_func)(void), void(*fini_func)(void));
185          */     
186
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
191
192         movi    a2, SYS_iss_argc
193         simcall                 // put argc in a2       
194
195
196 //      Alternative smaller code for Xtensa TX.
197 //      Many starting with simulation assume a full C env, so NOT DONE FOR NOW.
198 //
199 //#if XCHAL_HAVE_HALT
200 //
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).
205 //
206 //      //mov   ARG1, a2                // argc already in a2.
207 //      mov     ARG2, sp                // argv
208 //      CALL    main
209 //      halt
210 //
211 //#else /* !HALT */
212 //      ...
213
214
215 #if __XTENSA_CALL0_ABI__
216         mov     a12, a2                 // save argc (a2 is ARG1)
217 #else
218         mov     ARG1, a2                // argc
219 #endif
220         mov     ARG2, sp                // argv
221         movi    ARG3, _start_envp       // envp
222         movi    ARG4, _init             // _init
223         movi    ARG5, _fini             // _fini
224         CALL    __clibrary_init
225
226         //  Call:   int main(int argc, char ** argv, char ** environ);
227 #if __XTENSA_CALL0_ABI__
228         mov     ARG1, a12               // argc
229 #else
230         mov     ARG1, a2                // argc
231 #endif
232         mov     ARG2, sp                // argv
233         movi    ARG3, _start_envp       // envp = [0]
234         CALL    main
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.
238
239         .size   _start, . - _start
240
241 \f
242 // Local Variables:
243 // mode:fundamental
244 // comment-start: "// "
245 // comment-start-skip: "// *"
246 // End: