Initial cut of the open ath9k htc firmware.
[open-ath9k-htc-firmware.git] / target_firmware / magpie_fw_dev / build / magpie_1_1 / sboot / athos / src / xtos / crt1-boards.S
1 // crt1-boards.S
2 //
3 // For most hardware / boards, this code sets up the C calling context
4 // (setting up stack, PS, and clearing BSS) and jumps to __clibrary_start
5 // which sets up the C library, calls constructors and registers destructors,
6 // and calls main().
7 //
8 // Control arrives here at _start from the reset vector or from crt0-app.S.
9
10 // Copyright (c) 1998-2010 Tensilica Inc.
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
31 #include <xtensa/coreasm.h>
32 #include "xtos-internal.h"
33
34
35 // Exports
36 .global _start
37
38 // Imports
39 //   __clibrary_init            from C library (eg. newlib or uclibc)
40 //   exit                       from C library
41 //   main                       from user application
42 //   board_init                 board-specific (uart/mingloss/tinygloss.c)
43 //   xthal_dcache_all_writeback from HAL library
44 //   __stack                    from linker script (see LSP Ref Manual)
45 //   _bss_table_start           from linker script (see LSP Ref Manual)
46 //   _bss_table_end             from linker script (see LSP Ref Manual)
47
48 .type   main, @function
49
50 // Macros to abstract away ABI differences
51
52 #if __XTENSA_CALL0_ABI__
53 # define CALL   call0
54 # define ARG1   a2      /* 1st outgoing call argument */
55 # define ARG2   a3      /* 2nd outgoing call argument */
56 # define ARG3   a4      /* 3rd outgoing call argument */
57 # define ARG4   a5      /* 4th outgoing call argument */
58 # define ARG5   a6      /* 5th outgoing call argument */
59 #else
60 # define CALL   call4
61 # define ARG1   a6      /* 1st outgoing call argument */
62 # define ARG2   a7      /* 2nd outgoing call argument */
63 # define ARG3   a8      /* 3rd outgoing call argument */
64 # define ARG4   a9      /* 4th outgoing call argument */
65 # define ARG5   a10     /* 5th outgoing call argument */
66 #endif
67
68
69 /**************************************************************************/
70
71         .text
72         .align 4
73 _start:
74         //  _start is typically NOT at the beginning of the text segment --
75         //  it is always called from either the reset vector or other code
76         //  that does equivalent initialization (such as crt0-app.S).
77         //
78         //  Assumptions on entry to _start:
79         //      - low (level-one) and medium priority interrupts are disabled
80         //        via PS.INTLEVEL and/or INTENABLE (PS.INTLEVEL is expected to
81         //        be zeroed, to potentially enable them, before calling main)
82         //      - C calling context not initialized:
83         //        - PS not initialized
84         //        - SP not initialized
85         //      - the following are initialized:
86         //        - LITBASE, cache attributes, WindowBase, WindowStart,
87         //          CPENABLE, FP's FCR and FSR, EXCSAVE[n]
88
89         // Keep a0 zero.  It is used to initialize a few things.
90         // It is also the return address, where zero indicates
91         // that the frame used by _start is the bottommost frame.
92         //
93 #if !XCHAL_HAVE_HALT || !XCHAL_HAVE_BOOTLOADER          // not needed for Xtensa TX
94         movi    a0, 0           // keep this register zero.
95 #endif
96
97 #if XTOS_RESET_UNNEEDED && !XCHAL_HAVE_HALT
98 #include "reset-unneeded.S"
99 #endif
100
101         // Initialize the stack pointer.
102         // See the "ABI and Software Conventions" chapter in the
103         // Xtensa ISA Reference manual for details.
104
105         // NOTE: Because the _start routine does not use any memory in its
106         // stack frame, and because all of its CALL instructions use a
107         // window size of 4 (or zero), the stack frame for _start can be empty.
108
109         movi    sp, __stack
110
111         /*
112          *  Now that sp (a1) is set, we can set PS as per the application
113          *  (user vector mode, enable interrupts, enable window exceptions if applicable).
114          */
115 #if XCHAL_HAVE_EXCEPTIONS
116 # ifdef __XTENSA_CALL0_ABI__
117         movi    a3, PS_UM               // PS.WOE = 0, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0
118 # else  
119         movi    a3, PS_UM|PS_WOE        // PS.WOE = 1, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0
120 # endif
121         wsr     a3, PS
122         rsync
123 #endif
124
125
126 #if !XCHAL_HAVE_BOOTLOADER      /* boot loader takes care of zeroing BSS */
127         /*
128          *  Clear the BSS (uninitialized data) segments.
129          *  This code supports multiple zeroed sections (*.bss).
130          *
131          *  Register allocation:
132          *      a0 = 0
133          *      a6 = pointer to start of table, and through table
134          *      a7 = pointer to end of table
135          *      a8 = start address of bytes to be zeroed
136          *      a9 = end address of bytes to be zeroed
137          *      a10 = length of bytes to be zeroed
138          */
139         movi    a6, _bss_table_start
140         movi    a7, _bss_table_end
141         bgeu    a6, a7, .L3zte
142
143 .L0zte: l32i    a8, a6, 0       // get start address, assumed multiple of 4
144         l32i    a9, a6, 4       // get end address, assumed multiple of 4
145         addi    a6, a6, 8       // next entry
146         sub     a10, a9, a8     // a10 = length, assumed a multiple of 4
147         bbci.l  a10, 2, .L1zte
148         s32i    a0, a8, 0       // clear 4 bytes to make length multiple of 8
149         addi    a8, a8, 4
150 .L1zte: bbci.l  a10, 3, .L2zte
151         s32i    a0, a8, 0       // clear 8 bytes to make length multiple of 16
152         s32i    a0, a8, 4
153         addi    a8, a8, 8
154 .L2zte: srli    a10, a10, 4     // length is now multiple of 16, divide by 16
155         floopnez        a10, clearzte
156         s32i    a0, a8,  0      // clear 16 bytes at a time...
157         s32i    a0, a8,  4
158         s32i    a0, a8,  8
159         s32i    a0, a8, 12
160         addi    a8, a8, 16
161         floopend        a10, clearzte
162
163         bltu    a6, a7, .L0zte  // loop until end of table of *.bss sections
164 .L3zte:
165 #endif
166
167
168         //  We can now call C code, the C calling environment has been initialized.
169         //
170         //  From this point on, we use ABI-specific macros to refer to registers a0 .. a15
171         //  (ARG#).
172
173
174 #if XCHAL_HAVE_HALT
175
176         //  Assume minimalist environment for memory-constrained TX cores.
177         //  No C library or board initialization, no parameters passed to main
178         //  (assume declared as "void main(void)") and no call to exit().
179
180         CALL    main
181         halt
182
183 #else /* !HALT */
184
185         .type   board_init, @function
186         .type   __clibrary_init, @function
187         .type   exit, @function
188
189
190         //  Initialize the board (eg. the UART on the XT2000).
191         CALL    board_init
192
193         /* 
194          *  Call __clibrary_init to initialize the C library:
195          *
196          *  void __clibrary_init(int argc, char ** argv, char ** environ, 
197          *              void(*init_func)(void), void(*fini_func)(void));
198          */     
199
200         //  Pass an empty argv array, with an empty string as the program name.
201
202         movi    ARG1, _start_argc       // argc address
203         movi    ARG2, _start_argv       // argv = ["", 0]
204         movi    ARG3, _start_envp       // envp = [0]
205         movi    ARG4, _init             // function that calls constructors
206         movi    ARG5, _fini             // function that calls destructors
207         l32i    ARG1, ARG1, 0           // argc = 1
208         CALL    __clibrary_init
209
210         //  Call:   int main(int argc, char ** argv, char ** environ);
211         movi    ARG1, _start_argc       // argc address
212         movi    ARG2, _start_argv       // argv = ["", 0]
213         movi    ARG3, _start_envp       // envp = [0]
214         l32i    ARG1, ARG1, 0           // argc = 1
215         CALL    main
216         //  The return value is the same register as the first outgoing argument.
217         CALL    exit                    // exit with main's return value
218         // Does not return here.
219
220         .data
221         //  Mark argc/argv/envp parameters as weak so that an external
222         //  object file can override them.
223         .weak   _start_argc, _start_argv, _start_envp
224         .align  4
225 _start_argv:
226         .word   _start_null     // empty program name
227 _start_null:
228 _start_envp:
229         .word   0               // end of argv array, empty string, empty environ
230 _start_argc:
231         .word   1               // one argument (program name)
232         .text
233
234 #endif /* !HALT */
235
236         .size   _start, . - _start
237