| [444] | 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 | ##      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 | 
|---|
 | 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_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 | 
|---|