| 1 | /* | 
|---|
| 2 | Copyright (c) 2013-2014 Andes Technology Corporation. | 
|---|
| 3 | All rights reserved. | 
|---|
| 4 |  | 
|---|
| 5 | Redistribution and use in source and binary forms, with or without | 
|---|
| 6 | modification, 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 |  | 
|---|
| 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 
|---|
| 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
|---|
| 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
|---|
| 22 | DISCLAIMED.  IN NO EVENT SHALL RED HAT INCORPORATED BE LIABLE FOR ANY | 
|---|
| 23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 
|---|
| 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 
|---|
| 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 
|---|
| 26 | ON 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 | 
|---|
| 28 | SOFTWARE, 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 | 
|---|
| 81 | 1: | 
|---|
| 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 | 
|---|