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 194