[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 | ## 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 |
---|