416 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			416 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| // **********************************************************************
 | |
| // *                    SEGGER Microcontroller GmbH                     *
 | |
| // *                        The Embedded Experts                        *
 | |
| // **********************************************************************
 | |
| // *                                                                    *
 | |
| // *            (c) 2014 - 2018 SEGGER Microcontroller GmbH             *
 | |
| // *            (c) 2001 - 2018 Rowley Associates Limited               *
 | |
| // *                                                                    *
 | |
| // *           www.segger.com     Support: support@segger.com           *
 | |
| // *                                                                    *
 | |
| // **********************************************************************
 | |
| // *                                                                    *
 | |
| // * 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.    *
 | |
| // *                                                                    *
 | |
| // * - Neither the name of SEGGER Microcontroller GmbH                  *
 | |
| // *   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 SEGGER Microcontroller GmbH 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.                                                            *
 | |
| // *                                                                    *
 | |
| // **********************************************************************
 | |
| //
 | |
| //
 | |
| //                           Preprocessor Definitions
 | |
| //                           ------------------------
 | |
| // APP_ENTRY_POINT
 | |
| //
 | |
| //   Defines the application entry point function, if undefined this setting
 | |
| //   defaults to "main".
 | |
| //
 | |
| // INITIALIZE_STACK
 | |
| //
 | |
| //   If defined, the contents of the stack will be initialized to a the
 | |
| //   value 0xCC.
 | |
| //
 | |
| // INITIALIZE_SECONDARY_SECTIONS
 | |
| //
 | |
| //   If defined, the .data2, .text2, .rodata2 and .bss2 sections will be initialized.
 | |
| //
 | |
| // INITIALIZE_TCM_SECTIONS
 | |
| //
 | |
| //   If defined, the .data_tcm, .text_tcm, .rodata_tcm and .bss_tcm sections 
 | |
| //   will be initialized.
 | |
| //
 | |
| // INITIALIZE_USER_SECTIONS
 | |
| //
 | |
| //   If defined, the function InitializeUserMemorySections will be called prior
 | |
| //   to entering main in order to allow the user to initialize any user defined
 | |
| //   memory sections.
 | |
| //
 | |
| // FULL_LIBRARY
 | |
| //
 | |
| //  If defined then 
 | |
| //    - argc, argv are setup by the debug_getargs.
 | |
| //    - the exit symbol is defined and executes on return from main.
 | |
| //    - the exit symbol calls destructors, atexit functions and then debug_exit.
 | |
| //  
 | |
| //  If not defined then
 | |
| //    - argc and argv are zero.
 | |
| //    - the exit symbol is defined, executes on return from main and loops
 | |
| //
 | |
| 
 | |
| #ifndef APP_ENTRY_POINT
 | |
| #define APP_ENTRY_POINT main
 | |
| #endif
 | |
| 
 | |
| #ifndef ARGSSPACE
 | |
| #define ARGSSPACE 128
 | |
| #endif
 | |
|   .syntax unified
 | |
| 
 | |
|   .global _start
 | |
|   .extern APP_ENTRY_POINT
 | |
|   .global exit
 | |
|   .weak exit
 | |
| 
 | |
| #ifdef INITIALIZE_USER_SECTIONS
 | |
|   .extern InitializeUserMemorySections
 | |
| #endif
 | |
| 
 | |
|   .section .init, "ax"
 | |
|   .code 16
 | |
|   .balign 2
 | |
|   .thumb_func
 | |
| 
 | |
| _start:
 | |
|   /* Set up main stack if size > 0 */
 | |
|   ldr r1, =__stack_end__
 | |
|   ldr r0, =__stack_start__
 | |
|   subs r2, r1, r0
 | |
|   beq 1f
 | |
| #ifdef __ARM_EABI__
 | |
|   movs r2, #0x7
 | |
|   bics r1, r2
 | |
| #endif
 | |
|   mov sp, r1
 | |
| #ifdef INITIALIZE_STACK
 | |
|   movs r2, #0xCC
 | |
|   ldr r0, =__stack_start__
 | |
|   bl memory_set
 | |
| #endif
 | |
| 1:
 | |
| 
 | |
|   /* Set up process stack if size > 0 */
 | |
|   ldr r1, =__stack_process_end__
 | |
|   ldr r0, =__stack_process_start__
 | |
|   subs r2, r1, r0
 | |
|   beq 1f
 | |
| #ifdef __ARM_EABI__
 | |
|   movs r2, #0x7
 | |
|   bics r1, r2
 | |
| #endif
 | |
|   msr psp, r1
 | |
|   movs r2, #2
 | |
|   msr control, r2
 | |
| #ifdef INITIALIZE_STACK
 | |
|   movs r2, #0xCC
 | |
|   bl memory_set
 | |
| #endif
 | |
| 1:
 | |
| 
 | |
|   /* Copy initialized memory sections into RAM (if necessary). */
 | |
|   ldr r0, =__data_load_start__
 | |
|   ldr r1, =__data_start__
 | |
|   ldr r2, =__data_end__
 | |
|   bl memory_copy
 | |
|   ldr r0, =__text_load_start__
 | |
|   ldr r1, =__text_start__
 | |
|   ldr r2, =__text_end__
 | |
|   bl memory_copy
 | |
|   ldr r0, =__fast_load_start__
 | |
|   ldr r1, =__fast_start__
 | |
|   ldr r2, =__fast_end__
 | |
|   bl memory_copy
 | |
|   ldr r0, =__ctors_load_start__
 | |
|   ldr r1, =__ctors_start__
 | |
|   ldr r2, =__ctors_end__
 | |
|   bl memory_copy
 | |
|   ldr r0, =__dtors_load_start__
 | |
|   ldr r1, =__dtors_start__
 | |
|   ldr r2, =__dtors_end__
 | |
|   bl memory_copy
 | |
|   ldr r0, =__rodata_load_start__
 | |
|   ldr r1, =__rodata_start__
 | |
|   ldr r2, =__rodata_end__
 | |
|   bl memory_copy
 | |
|   ldr r0, =__tdata_load_start__
 | |
|   ldr r1, =__tdata_start__
 | |
|   ldr r2, =__tdata_end__
 | |
|   bl memory_copy
 | |
| #ifdef INITIALIZE_SECONDARY_SECTIONS
 | |
|   ldr r0, =__data2_load_start__
 | |
|   ldr r1, =__data2_start__
 | |
|   ldr r2, =__data2_end__
 | |
|   bl memory_copy
 | |
|   ldr r0, =__text2_load_start__
 | |
|   ldr r1, =__text2_start__
 | |
|   ldr r2, =__text2_end__
 | |
|   bl memory_copy
 | |
|   ldr r0, =__rodata2_load_start__
 | |
|   ldr r1, =__rodata2_start__
 | |
|   ldr r2, =__rodata2_end__
 | |
|   bl memory_copy
 | |
| #endif /* #ifdef INITIALIZE_SECONDARY_SECTIONS */
 | |
| #ifdef INITIALIZE_TCM_SECTIONS
 | |
|   ldr r0, =__data_tcm_load_start__
 | |
|   ldr r1, =__data_tcm_start__
 | |
|   ldr r2, =__data_tcm_end__
 | |
|   bl memory_copy
 | |
|   ldr r0, =__text_tcm_load_start__
 | |
|   ldr r1, =__text_tcm_start__
 | |
|   ldr r2, =__text_tcm_end__
 | |
|   bl memory_copy
 | |
|   ldr r0, =__rodata_tcm_load_start__
 | |
|   ldr r1, =__rodata_tcm_start__
 | |
|   ldr r2, =__rodata_tcm_end__
 | |
|   bl memory_copy
 | |
| #endif /* #ifdef INITIALIZE_TCM_SECTIONS */
 | |
| 
 | |
|   /* Zero the bss. */
 | |
|   ldr r0, =__bss_start__
 | |
|   ldr r1, =__bss_end__
 | |
|   movs r2, #0
 | |
|   bl memory_set
 | |
|   ldr r0, =__tbss_start__
 | |
|   ldr r1, =__tbss_end__
 | |
|   movs r2, #0
 | |
|   bl memory_set
 | |
| #ifdef INITIALIZE_SECONDARY_SECTIONS
 | |
|   ldr r0, =__bss2_start__
 | |
|   ldr r1, =__bss2_end__
 | |
|   mov r2, #0
 | |
|   bl memory_set
 | |
| #endif /* #ifdef INITIALIZE_SECONDARY_SECTIONS */
 | |
| #ifdef INITIALIZE_TCM_SECTIONS
 | |
|   ldr r0, =__bss_tcm_start__
 | |
|   ldr r1, =__bss_tcm_end__
 | |
|   mov r2, #0
 | |
|   bl memory_set
 | |
| #endif /* #ifdef INITIALIZE_TCM_SECTIONS */
 | |
| 
 | |
|   /* Initialize the heap */
 | |
|   ldr r0, = __heap_start__
 | |
|   ldr r1, = __heap_end__
 | |
|   subs r1, r1, r0
 | |
|   cmp r1, #8
 | |
|   blt 1f
 | |
|   movs r2, #0
 | |
|   str r2, [r0]
 | |
|   adds r0, r0, #4
 | |
|   str r1, [r0]
 | |
| 1:
 | |
| 
 | |
| #ifdef INITIALIZE_USER_SECTIONS
 | |
|   ldr r2, =InitializeUserMemorySections
 | |
|   blx r2
 | |
| #endif
 | |
| 
 | |
|   /* Call constructors */
 | |
|   ldr r0, =__ctors_start__
 | |
|   ldr r1, =__ctors_end__
 | |
| ctor_loop:
 | |
|   cmp r0, r1
 | |
|   beq ctor_end
 | |
|   ldr r2, [r0]
 | |
|   adds r0, #4
 | |
|   push {r0-r1}  
 | |
|   blx r2
 | |
|   pop {r0-r1}
 | |
|   b ctor_loop
 | |
| ctor_end:
 | |
| 
 | |
|   /* Setup initial call frame */
 | |
|   movs r0, #0
 | |
|   mov lr, r0
 | |
|   mov r12, sp
 | |
| 
 | |
|   .type start, function
 | |
| start:
 | |
|   /* Jump to application entry point */
 | |
| #ifdef FULL_LIBRARY
 | |
|   movs r0, #ARGSSPACE
 | |
|   ldr r1, =args
 | |
|   ldr r2, =debug_getargs  
 | |
|   blx r2
 | |
|   ldr r1, =args
 | |
| #else
 | |
|   movs r0, #0
 | |
|   movs r1, #0
 | |
| #endif
 | |
|   ldr r2, =APP_ENTRY_POINT
 | |
|   blx r2
 | |
| 
 | |
|   .thumb_func
 | |
| exit:
 | |
| #ifdef FULL_LIBRARY  
 | |
|   mov r5, r0 // save the exit parameter/return result
 | |
| 
 | |
|   /* Call destructors */
 | |
|   ldr r0, =__dtors_start__
 | |
|   ldr r1, =__dtors_end__
 | |
| dtor_loop:
 | |
|   cmp r0, r1
 | |
|   beq dtor_end
 | |
|   ldr r2, [r0]
 | |
|   add r0, #4
 | |
|   push {r0-r1}
 | |
|   blx r2
 | |
|   pop {r0-r1}
 | |
|   b dtor_loop
 | |
| dtor_end:
 | |
| 
 | |
|   /* Call atexit functions */
 | |
|   ldr r2, =_execute_at_exit_fns  
 | |
|   blx r2
 | |
| 
 | |
|   /* Call debug_exit with return result/exit parameter */
 | |
|   mov r0, r5
 | |
|   ldr r2, =debug_exit  
 | |
|   blx r2
 | |
| #endif
 | |
| 
 | |
|   /* Returned from application entry point, loop forever. */
 | |
| exit_loop:
 | |
|   b exit_loop
 | |
| 
 | |
|   .thumb_func
 | |
| memory_copy:
 | |
|   cmp r0, r1
 | |
|   beq 2f
 | |
|   subs r2, r2, r1
 | |
|   beq 2f
 | |
| 1:
 | |
|   ldrb r3, [r0]
 | |
|   adds r0, r0, #1
 | |
|   strb r3, [r1]
 | |
|   adds r1, r1, #1
 | |
|   subs r2, r2, #1
 | |
|   bne 1b
 | |
| 2:
 | |
|   bx lr
 | |
| 
 | |
|   .thumb_func
 | |
| memory_set:
 | |
|   cmp r0, r1
 | |
|   beq 1f
 | |
|   strb r2, [r0]
 | |
|   adds r0, r0, #1
 | |
|   b memory_set
 | |
| 1:
 | |
|   bx lr
 | |
| 
 | |
|   // default C/C++ library helpers
 | |
| 
 | |
| .macro HELPER helper_name
 | |
|   .section .text.\helper_name, "ax", %progbits
 | |
|   .balign 2
 | |
|   .global \helper_name
 | |
|   .weak \helper_name  
 | |
| \helper_name:
 | |
|   .thumb_func
 | |
| .endm
 | |
| 
 | |
| .macro JUMPTO name
 | |
| #if defined(__thumb__) && !defined(__thumb2__)
 | |
|   mov r12, r0
 | |
|   ldr r0, =\name
 | |
|   push {r0}
 | |
|   mov r0, r12
 | |
|   pop {pc}
 | |
| #else
 | |
|   b \name
 | |
| #endif
 | |
| .endm
 | |
| 
 | |
| HELPER __aeabi_read_tp
 | |
|   ldr r0, =__tbss_start__-8
 | |
|   bx lr
 | |
| HELPER abort
 | |
|   b .
 | |
| HELPER __assert
 | |
|   b .
 | |
| HELPER __aeabi_assert
 | |
|   b .
 | |
| HELPER __sync_synchronize
 | |
|   bx lr
 | |
| HELPER __getchar
 | |
|   JUMPTO debug_getchar
 | |
| HELPER __putchar
 | |
|   JUMPTO debug_putchar
 | |
| HELPER __open
 | |
|   JUMPTO debug_fopen
 | |
| HELPER __close
 | |
|   JUMPTO debug_fclose
 | |
| HELPER __write   
 | |
|   mov r3, r0
 | |
|   mov r0, r1
 | |
|   movs r1, #1  
 | |
|   JUMPTO debug_fwrite
 | |
| HELPER __read  
 | |
|   mov r3, r0
 | |
|   mov r0, r1
 | |
|   movs r1, #1 
 | |
|   JUMPTO debug_fread
 | |
| HELPER __seek
 | |
|   push {r4, lr}
 | |
|   mov r4, r0
 | |
|   bl debug_fseek
 | |
|   cmp r0, #0
 | |
|   bne 1f
 | |
|   mov r0, r4
 | |
|   bl debug_ftell
 | |
|   pop {r4, pc}
 | |
| 1:
 | |
|   ldr r0, =-1
 | |
|   pop {r4, pc}
 | |
|   // char __user_locale_name_buffer[];
 | |
|   .section .bss.__user_locale_name_buffer, "aw", %nobits
 | |
|   .global __user_locale_name_buffer
 | |
|   .weak __user_locale_name_buffer
 | |
|   __user_locale_name_buffer:
 | |
|   .word 0x0
 | |
| 
 | |
| #ifdef FULL_LIBRARY
 | |
|   .bss
 | |
| args:
 | |
|   .space ARGSSPACE
 | |
| #endif
 | |
| 
 | |
|   /* Setup attibutes of stack and heap sections so they don't take up room in the elf file */
 | |
|   .section .stack, "wa", %nobits
 | |
|   .section .stack_process, "wa", %nobits
 | |
|   .section .heap, "wa", %nobits
 | |
| 
 | 
