source: trunk/libs/newlib/src/libgloss/nds32/crt1.S @ 564

Last change on this file since 564 was 444, checked in by satin@…, 7 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 6.1 KB
Line 
1/*
2Copyright (c) 2013-2014 Andes Technology Corporation.
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7
8    Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10
11    Redistributions in binary form must reproduce the above copyright
12    notice, this list of conditions and the following disclaimer in the
13    documentation and/or other materials provided with the distribution.
14
15    The name of the company may not be used to endorse or promote
16    products derived from this software without specific prior written
17    permission.
18
19THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22DISCLAIMED.  IN NO EVENT SHALL RED HAT INCORPORATED BE LIABLE FOR ANY
23DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*/
30
31##==============================================================================
32##
33##      crt1.S
34##
35##      nds32 startup code
36##
37##==============================================================================
38
39#include "syscall_extra.h"
40
41##------------------------------------------------------------------------------
42## Vector table setup
43##------------------------------------------------------------------------------
44        .section        .nds32_init, "ax"
45        j       _start
46
47##------------------------------------------------------------------------------
48## Startup code implementation
49##------------------------------------------------------------------------------
50        .section        .text
51        .weak   _SDA_BASE_
52        .weak   _ITB_BASE_
53        .weak   _arg_init
54        .weak   __pre_c_init
55        .weak   __post_c_init
56        .weak   _call_exit
57        .global _start
58        .type   _start, @function
59        .align  2
60_start:
61        /* The initialization sequence really does matter !!!
62           The global pointer must be
63           initialized precedence over all others.  */
64
65.L_init_gp:
66        /* Initialization for global pointer.  The symbol _SDA_BASE_ is
67           determined by Linker.  SDA stands for Small Data Access.  */
68        la      $gp, _SDA_BASE_
69
70#if __NDS32_EXT_EX9__
71.L_init_itb:
72        /* Initialization for Instruction Table Base (ITB).
73           The symbol _ITB_BASE_ is determined by Linker.
74           Set $ITB only if MSC_CFG.EIT (cr4.b'24) is set.  */
75        mfsr    $r0, $MSC_CFG
76        srli    $r0, $r0, 24
77        andi    $r0, $r0, 0x1
78        beqz    $r0, 1f         /* Fall through ?  */
79        la      $r0, _ITB_BASE_
80        mtusr   $r0, $ITB
811:
82#endif
83
84.L_init_sp:
85        /* Initialization for stack pointer.  The symbol _stack is defined
86           in linker script.  Make sure $sp is 8-byte aligned.  */
87        la      $sp, _stack
88#if __NDS32_ISA_V3__
89        bitci   $sp, $sp, #7
90#else
91        movi    $r0, #-8                /* Set $r0 as 0xFFFFFFF8.  */
92        and     $sp, $sp, $r0
93#endif
94
95#if __NDS32_EXT_FPU_SP__ || __NDS32_EXT_FPU_DP__
96.L_init_fpu:
97        /* Initialize FPU
98           Set FUCOP_CTL.CP0EN (fucpr.b'0).  */
99        mfsr    $r0, $FUCOP_CTL
100        ori     $r0, $r0, 0x1
101        mtsr    $r0, $FUCOP_CTL
102        dsb
103        /* According to [bugzilla #9425], set flush-to-zero mode.
104           That is, set $FPCSR.DNZ(b'12) = 1.  */
105        FMFCSR  $r0
106        ori     $r0, $r0, 0x1000
107        FMTCSR  $r0
108        dsb
109#endif
110
111.L_pre_c_init:
112        ! call __pre_c_init if provided
113        ! sample __pre_c_init is in BSP
114        la      $r15, __pre_c_init      ! load address of __pre_c_init
115        beqz    $r15, .L_zero_out_bss   ! check existence of __pre_c_init
116        jral    $r15                    ! pre-c-runtime initialization
117
118.L_zero_out_bss:
119        /* Zero out the bss section.
120           Equivalence C code for follow part:
121           if (_end == _edata) goto .L_call_main
122           unsinged int *ptr = _edata;
123           while (ptr != _end)
124             *ptr++ = 0
125           $r0 = ptr/_edata
126           $r1 = _end
127           $r2 = 0
128         */
129        la      $r0, _edata
130        la      $r1, _end
131        movi    $r2, #0
132        beq     $r0, $r1, .L_cpp_init   /* Branch if no bss.  */
133.Lword_clear:
134        swi.bi  $r2, [$r0], #4
135        bne     $r0, $r1, .Lword_clear
136
137.L_cpp_init:
138        /* Call '_init' to invoke constructors.  */
139        jal     _init
140        /* Register '_fini' into atexit() to invoke destructors when
141           exit() has been reached.  */
142        la      $r0, _fini
143        jal     atexit
144
145.L_post_c_init:
146        ! call __post_c_init if provided
147        ! no sample __post_c_init is provided
148        la      $r15, __post_c_init     ! load address of __post_c_init
149        beqz    $r15, .L_arg_init       ! check existence of __post_c_init
150        jral    $r15                    ! post-c-runtime initialization
151
152.L_arg_init:
153        ! argc/argv initialization if necessary
154        la      $r7, _arg_init          ! get address of _arg_init
155        beqz    $r7, .L_clean_reg       ! if there isn't _arg_init, go main
156        addi    $sp, $sp, -512          ! allocate space for command line
157                                        ! and arguments
158        move    $r6, $sp                ! r6 = buffer addr of cmd line
159        move    $r0, $r6                ! r0 = buffer addr of cmd line
160        syscall SYS_getcmdline          ! get cmd line
161        move    $r0, $r6                ! r0 = buffer addr of cmd line
162        addi    $r1, $r6, 256           ! r1 = argv
163        jral    $r7                     ! init argc/argv
164        addi    $r1, $r6, 256           ! r1 = argv
165        b       .L_call_main
166
167.L_clean_reg:
168        /* Prepare argc/argv/env for main function.
169           Since there is no operating system so far,
170           we set $r0, $r1, and $r2 to be zero.
171           Note: $r2 already set to zero in .L_zero_out_bss: code fragment.  */
172        movi    $r0, 0
173        movi    $r1, 0
174        movi    $r2, 0
175
176.L_call_main:
177        /* Call 'main'.  */
178        bal     main
179
180        /* Call _call_exit.  */
181        ! call _call_exit if necessary; default implementation is in crtexit.c
182        la      $r15, _call_exit                ! load address of _call_exit
183        beqz    $r15, .L_terminate_program      ! no _call_exit? go exit
184        jral    $r15                            ! _call_exit will never return
185
186.L_terminate_program:
187        /* There are two ways to terminate program:
188            1. User "syscall 0x1" directly.
189            2. Call exit. The  return value $r0 from main() is
190              implicitly passed as argument.
191
192            Currently, we use option 2 as a solution to follow C99 5.1.2.2.3,
193            but aware that general exit() will do some cleanup procedures
194            which may result in large-memory-footprints.  */
195
196        bal     exit
197
198.L_forever_loop:
199        /* Should never return here.  */
200        b       .L_forever_loop
201
202        .size   _start, .-_start
Note: See TracBrowser for help on using the repository browser.