1/* 2 Copyright (c) 2015, Synopsys, Inc. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are met: 6 7 1) Redistributions of source code must retain the above copyright notice, 8 this list of conditions and the following disclaimer. 9 10 2) Redistributions in binary form must reproduce the above copyright notice, 11 this list of conditions and the following disclaimer in the documentation 12 and/or other materials provided with the distribution. 13 14 3) Neither the name of the Synopsys, Inc., nor the names of its contributors 15 may be used to endorse or promote products derived from this software 16 without specific prior written permission. 17 18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 POSSIBILITY OF SUCH DAMAGE. 29*/ 30 31/* 32 The startup code for the ARC family of processors does the following before 33 transferring control to user defined main label: 34 1. Set sp to __stack_top (link time variable) 35 2. Set fp to zero 36 3. Zero out the bss section (for uninitialized globals) 37 After returning from main, the processor is halted and the pipeline is 38 flushed out. 39 40 We expect argc in r0 and argv in r1. These are saved in r13 / r14 during 41 the initialization code. 42*/ 43 44 .file "crt0.S" 45 .extern main 46 47#if defined (__EM__) || defined (__HS__) 48 .section .ivt, "a", @progbits 49 50; handler's name, type, number,name, offset in IVT (hex/dec) 51.word __start ; exception 0 program entry point 0x0 0 52.word memory_error ; exception 1 memory_error 0x4 4 53.word instruction_error ; exception 2 instruction_error 0x8 8 54.word EV_MachineCheck ; exception 3 EV_MachineCheck 0xC 12 55.word EV_TLBMissI ; exception 4 EV_TLBMissI 0x10 16 56.word EV_TLBMissD ; exception 5 EV_TLBMissD 0x14 20 57.word EV_ProtV ; exception 6 EV_ProtV 0x18 24 58.word EV_PrivilegeV ; exception 7 EV_PrivilegeV 0x1C 28 59.word EV_SWI ; exception 8 EV_SWI 0x20 32 60.word EV_Trap ; exception 9 EV_Trap 0x24 36 61.word EV_Extension ; exception 10 EV_Extension 0x28 40 62.word EV_DivZero ; exception 11 EV_DivZero 0x2C 44 63.word EV_DCError ; exception 12 EV_DCError 0x30 48 64.word EV_Malignedr ; exception 13 EV_Maligned 0x34 52 65.word _exit_halt ; exception 14 unused 0x38 56 66.word _exit_halt ; exception 15 unused 0x3C 60 67.word IRQ_Timer0 ; IRQ 16 Timer 0 0x40 64 68.word IRQ_Timer1 ; IRQ 17 Timer 1 0x44 68 69.word IRQ_18 ; IRQ 18 0x48 72 70.word IRQ_19 ; IRQ 19 0x4C 76 71.word IRQ_20 ; IRQ 20 0x50 80 72 73 74 .section .text.__startup, "ax", @progbits 75#else 76 .text 77#endif 78 79 .global __start 80 .type __start, @function 81 82#ifdef __ARC601__ 83; Startup code for the ARC601 processor 84__start: 85 mov gp, @__SDATA_BEGIN__ 86 mov sp, @__stack_top ; Point to top of stack 87 mov r5, 0 ; Zero value 88 mov_s r2, @__sbss_start ; r2 = start of the bss section 89 sub r3, @_end, r2 ; r3 = size of the bss section in bytes 90 91 asr_s r3, r3 92 asr_s r3, r3 ; r3 = size of bss in words 93 94.Lbss_loop: 95 cmp r3, 0xff ; Check for max lp_count 96 mov.le lp_count, r3 97 mov.gt lp_count, 0xff 98 lpnz 2f ; Loop to zero bss 99 st.ab r5,[r2, 4] ; Write word of zeros 100 nop 1012: 102 sub.f r3, r3, 0xff ; Decrement word count 103 jp .Lbss_loop 104 105#else /* __ARC601__ */ 106 107; Startup code for the ARC600, ARC700 and ARCv2 processors 108; NOTE: The following restrictions apply on zero overhead loops (other 109; restrictions are not pertinent to this code) 110; - loop end should be 4 instruction words away from the lp_count setting 111; instruction 112; - loop body should have at least two instruction words 113__start: 114#if defined (__HS__) 115 ; Allow unaligned accesses. 116 lr r2, [0xA] 117 bset r2, r2, 19 118 flag r2 119#endif 120 mov gp, @__SDATA_BEGIN__ 121 mov_s r2, @__sbss_start ; r2 = start of the bss section 122 sub r3, @_end, r2 ; r3 = size of the bss section in bytes 123 ; set up the loop counter register to the size (in words) of the bss section 124 asr.f lp_count, r3, 2 125#if defined (__ARC600__) 126 ; loop to zero out the bss. Enter loop only if lp_count != 0 127 lpnz @.Lend_zbss 128 add r3, pcl, 20 129 sr r3, [2] ; LP_END 130 ; initialize stack pointer, and this instruction has 2 words 131 mov sp, @__stack_top 132 mov_s r3, 0 133 st.ab r3, [r2, 4] ; zero out the word 134.Lend_zbss: 135#else 136 mov sp, @__stack_top ; initialize stack pointer 137 mov_s r3,0 138 ; loop to zero out the bss. Enter loop only if lp_count != 0 139 lpnz @.Lend_zbss 140 st.ab r3,[r2, 4] ; zero out the word 141 nop 142.Lend_zbss: 143#endif 144 145#endif /* !__ARC601__ */ 146 147; Some targets use the .init and .fini sections to create constructors and 148; destructors, and for these targets we need to call the _init function and 149; arrange for _fini to be called at program exit. 150 mov_s r13, r0 151 mov_s r14, r1 152 ; calling atexit drags in malloc, so instead poke the function 153 ; address directly into the reent structure 154 ld r1, [gp, @_impure_ptr@sda] 155 mov_s r0, @_fini 156 add r1, r1, 0x14c ; &_GLOBAL_REENT->atexit0 157 st r1, [r1, -4] ; _GLOBAL_REENT->atexit 158 st_s r0, [r1, 8] ; _GLOBAL_REENT->atexit0._fns[0] 159 mov_s r0, 1 160 st_s r0, [r1, 4] ; _GLOBAL_REENT->atexit0._ind 161; branch to _init 162#if defined (__EM__) || defined (__HS__) 163 jl @_init 164#else 165 bl @_init 166#endif 167 mov_s r0, r13 168 mov_s r1, r14 169; branch to main 170#if defined (__EM__) || defined (__HS__) 171 mov fp,0 ; initialize frame pointer 172 jl @main 173#else 174 bl.d @main 175 mov fp, 0 ; initialize frame pointer 176#endif 177 ; r0 contains exit code 178 j @exit 179 180#if defined (__EM__) || defined (__HS__) 181; ARCv2 default interrupt routines, defined as weak symbols. 182; Default implementation halts the core. To conserve code size those symbols 183; share a single implementation, however as a downside debugger and 184; disassembler will not be able to distinguish one from another. 185.weak memory_error 186.weak instruction_error 187.weak EV_MachineCheck 188.weak EV_TLBMissI 189.weak EV_TLBMissD 190.weak EV_ProtV 191.weak EV_PrivilegeV 192.weak EV_SWI 193.weak EV_Trap 194.weak EV_Extension 195.weak EV_DivZero 196.weak EV_DCError 197.weak EV_Malignedr 198.weak IRQ_Timer0 199.weak IRQ_Timer1 200.weak IRQ_18 201.weak IRQ_19 202.weak IRQ_20 203 204.balign 4 205memory_error : 206instruction_error : 207EV_MachineCheck : 208EV_TLBMissI : 209EV_TLBMissD : 210EV_ProtV : 211EV_PrivilegeV : 212EV_SWI : 213EV_Trap : 214EV_Extension : 215EV_DivZero : 216EV_DCError : 217EV_Malignedr : 218IRQ_Timer0 : 219IRQ_Timer1 : 220IRQ_18 : 221IRQ_19 : 222IRQ_20 : 223.Lloop_halt: 224 flag 0x01 225 nop 226 b .Lloop_halt 227 nop 228#endif 229 230 .section .text._exit_halt,"ax",@progbits 231 .global _exit_halt 232 .type _exit_halt, @function 233 234_exit_halt: 235 ; r0 contains exit code 236 flag 0x01 237 nop 238 nop ; ARCompact requires 3 nops after flag 1 239 nop 240 b @_exit_halt 241 nop 242