# C Startup for EPIPHANY # Copyright (c) 2011, Adapteva, Inc. # All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of Adapteva nor the names of its contributors may be # used to endorse or promote products derived from this software without # specific prior written permission. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. .section IVT,"a",@progbits ; .global _start; .type _start, %function; _start: .balign 4 ; b .normal_start .balign 4 ; 0x4 b .sw_exception_v .balign 4 ; 0x8 b .page_miss_v; .balign 4 ; 0xc b .timer0_expired_v .balign 4 ; 0x10 b .timer1_expired_v .balign 4 ; 0x14 b .message_v .balign 4 ; 0x18 b .dma0_v .balign 4 ; 0x1c b .dma1_v .balign 4 ; 0x20 b .wand_v .balign 4 ; 0x24 b .soft_v .size _start, .-_start .section RESERVED_CRT0,"a",@progbits ; .global .normal_start; .balign 4 .type .normal_start, %function .normal_start: mov r3,%low(_external_start) movt r3,%high(_external_start) jalr r3 .size .normal_start, .-.normal_start .section .text; .org 0x0000 ; Relative to start of text section .global _external_start .type _external_start, %function _external_start: .align 4 ;; Initialise the stack pointer and frame pointer. Hopefully __stack ;; is somewhere meaningful. mov sp,%low(___stack) movt sp,%high(___stack) mov fp,sp ;; Zero the data space mov r0,%low(___bss_start) movt r0,%high(___bss_start) mov r1,%low(_end) movt r1,%high(_end) mov r2,#0 mov r3,#0 .L0_init_: strd r2,[r0],+#1 sub r5,r1,r0 bne .L0_init_ ;; Setup destructors to be called from exit if main never returns #if 0 mov r0,%low(fini) movt r0,%high(fini) mov r2,%low(_atexit) movt r2,%high(_atexit) jalr r2 #else ; calling atexit drags in malloc, so instead poke the function ; address directly into the reent structure mov r2,%low(__impure_ptr) movt r2,%high(__impure_ptr) ldr r2,[r2] mov r1,%low(fini) movt r1,%high(fini) #ifdef __STRUCT_ALIGN_64__ #error add r2,r2,need_to_find_out; &_GLOBAL_REENT->atexit0 str r2, [r2,-1];??or -2?; _GLOBAL_REENT->atexit mov r0, 1 str r0, [r2,1] ; _GLOBAL_REENT->atexit0._ind str r1, [r2,2] ; _GLOBAL_REENT->atexit0._fns[0] #else /* !__STRUCT_ALIGN_64__ */ add r0,r2,0x14c ; &_GLOBAL_REENT->atexit0 str r0, [r0,-1] ; _GLOBAL_REENT->atexit mov r0, 1 strd r0, [r2,0x2a] ; _GLOBAL_REENT->atexit0._ind #endif /* !__STRUCT_ALIGN_64__ */ #endif /* !0 */ ;; Call global and static constructors mov r2,%low(init) movt r2,%high(init) jalr r2 ;;return from reset ISR mov R0,%low(RDS) movt R0,%high(RDS) movts iret,r0 rti RDS: ;; Initialise argc, argv and envp to empty and call main mov r0,#0 mov r1,#0 mov r2,#0 mov r3,%low(_main) movt r3,%high(_main) jalr r3 ;;bl _main ;; Call exit mov r3,%low(_exit) movt r3,%high(_exit) jalr r3 ;;bl _exit ;; Should never reach here idle .size _external_start, .-_external_start