source: trunk/libs/newlib/src/libgloss/nds32/crt0.S @ 678

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

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

File size: 5.9 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##      crt0.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_post_c_init
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_post_c_init        /* Branch if no bss.  */
133.Lword_clear:
134        swi.bi  $r2, [$r0], #4
135        bne     $r0, $r1, .Lword_clear
136
137.L_post_c_init:
138        ! call __post_c_init if provided
139        ! no sample __post_c_init is provided
140        la      $r15, __post_c_init     ! load address of __post_c_init
141        beqz    $r15, .L_arg_init       ! check existence of __post_c_init
142        jral    $r15                    ! post-c-runtime initialization
143
144.L_arg_init:
145        ! argc/argv initialization if necessary
146        la      $r7, _arg_init          ! get address of _arg_init
147        beqz    $r7, .L_clean_reg       ! if there isn't _arg_init, go main
148        addi    $sp, $sp, -512          ! allocate space for command line
149                                        ! and arguments
150        move    $r6, $sp                ! r6 = buffer addr of cmd line
151        move    $r0, $r6                ! r0 = buffer addr of cmd line
152        syscall SYS_getcmdline          ! get cmd line
153        move    $r0, $r6                ! r0 = buffer addr of cmd line
154        addi    $r1, $r6, 256           ! r1 = argv
155        jral    $r7                     ! init argc/argv
156        addi    $r1, $r6, 256           ! r1 = argv
157        b       .L_call_main
158
159.L_clean_reg:
160        /* Prepare argc/argv/env for main function.
161           Since there is no operating system so far,
162           we set $r0, $r1, and $r2 to be zero.
163           Note: $r2 already set to zero in .L_zero_out_bss: code fragment.  */
164        movi    $r0, 0
165        movi    $r1, 0
166        movi    $r2, 0
167
168.L_call_main:
169        /* Call 'main'.  */
170        bal     main
171
172        /* Call _call_exit.  */
173        ! call _call_exit if necessary; default implementation is in crtexit.c
174        la      $r15, _call_exit                ! load address of _call_exit
175        beqz    $r15, .L_terminate_program      ! no _call_exit? go exit
176        jral    $r15                            ! _call_exit will never return
177
178.L_terminate_program:
179        /* There are two ways to terminate program:
180            1. User "syscall 0x1" directly.
181            2. Call exit. The  return value $r0 from main() is
182              implicitly passed as argument.
183
184            Currently, we use option 2 as a solution to follow C99 5.1.2.2.3,
185            but aware that general exit() will do some cleanup procedures
186            which may result in large-memory-footprints.  */
187        bal     exit
188
189.L_forever_loop:
190        /* Should never return here.  */
191        b       .L_forever_loop
192
193        .size   _start, .-_start
Note: See TracBrowser for help on using the repository browser.