197 lines
4.9 KiB
ArmAsm
197 lines
4.9 KiB
ArmAsm
|
/***************************************************************************
|
||
|
*
|
||
|
* Copyright 2015-2019 BES.
|
||
|
* All rights reserved. All unpublished rights reserved.
|
||
|
*
|
||
|
* No part of this work may be used or reproduced in any form or by any
|
||
|
* means, or stored in a database or retrieval system, without prior written
|
||
|
* permission of BES.
|
||
|
*
|
||
|
* Use of this work is governed by a license granted by BES.
|
||
|
* This work contains confidential and proprietary information of
|
||
|
* BES. which is protected by copyright, trade secret,
|
||
|
* trademark and other intellectual property rights.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
#ifndef __ARM_ARCH_ISA_ARM
|
||
|
|
||
|
#if defined(NOSTD) || defined(__ARMCC_VERSION)
|
||
|
#define __STARTUP_CLEAR_BSS
|
||
|
#endif
|
||
|
|
||
|
#ifdef __ARMCC_VERSION
|
||
|
#include "link_sym_armclang.h"
|
||
|
#endif
|
||
|
|
||
|
.syntax unified
|
||
|
|
||
|
.section .boot_loader, "ax", %progbits
|
||
|
.thumb
|
||
|
.thumb_func
|
||
|
.align 2
|
||
|
.globl Boot_Loader
|
||
|
.type Boot_Loader, %function
|
||
|
Boot_Loader:
|
||
|
|
||
|
#ifdef __ARM_ARCH_8M_MAIN__
|
||
|
ldr r0, =__StackLimit
|
||
|
msr msplim, r0
|
||
|
#endif
|
||
|
|
||
|
#if defined(CHIP_BEST2001) && defined(LARGE_RAM)
|
||
|
ldr r3, =0x4000008c
|
||
|
ldr r0, [r3]
|
||
|
bic.w r0, r0, #0x03f80000
|
||
|
orr.w r0, r0, #0x00f80000 /*0x1f<<19*/
|
||
|
str r0, [r3]
|
||
|
#endif
|
||
|
|
||
|
ldr r3, =__StackTop
|
||
|
msr msp, r3
|
||
|
|
||
|
bl NVIC_InitVectors
|
||
|
|
||
|
#ifndef __NO_BOOT_INIT
|
||
|
bl BootInit
|
||
|
#endif
|
||
|
|
||
|
#ifdef USER_SECURE_BOOT
|
||
|
bl user_secure_boot_init
|
||
|
#endif
|
||
|
|
||
|
/* Firstly it copies data from read only memory to RAM. There are two schemes
|
||
|
* to copy. One can copy more than one sections. Another can only copy
|
||
|
* one section. The former scheme needs more instructions and read-only
|
||
|
* data to implement than the latter.
|
||
|
* Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */
|
||
|
|
||
|
#ifdef __STARTUP_COPY_MULTIPLE
|
||
|
/* Multiple sections scheme.
|
||
|
*
|
||
|
* Between symbol address __copy_table_start__ and __copy_table_end__,
|
||
|
* there are array of triplets, each of which specify:
|
||
|
* offset 0: LMA of start of a section to copy from
|
||
|
* offset 4: VMA of start of a section to copy to
|
||
|
* offset 8: size of the section to copy. Must be multiply of 4
|
||
|
*
|
||
|
* All addresses must be aligned to 4 bytes boundary.
|
||
|
*/
|
||
|
ldr r4, =__copy_table_start__
|
||
|
ldr r5, =__copy_table_end__
|
||
|
|
||
|
.L_loop0:
|
||
|
cmp r4, r5
|
||
|
bge .L_loop0_done
|
||
|
ldr r1, [r4]
|
||
|
ldr r2, [r4, #4]
|
||
|
ldr r3, [r4, #8]
|
||
|
|
||
|
.L_loop0_0:
|
||
|
subs r3, #4
|
||
|
ittt ge
|
||
|
ldrge r0, [r1, r3]
|
||
|
strge r0, [r2, r3]
|
||
|
bge .L_loop0_0
|
||
|
|
||
|
adds r4, #12
|
||
|
b .L_loop0
|
||
|
|
||
|
.L_loop0_done:
|
||
|
#else
|
||
|
/* Single section scheme.
|
||
|
*
|
||
|
* The ranges of copy from/to are specified by following symbols
|
||
|
* __etext: LMA of start of the section to copy from. Usually end of text
|
||
|
* __data_start__: VMA of start of the section to copy to
|
||
|
* __data_end__: VMA of end of the section to copy to
|
||
|
*
|
||
|
* All addresses must be aligned to 4 bytes boundary.
|
||
|
*/
|
||
|
ldr r1, =__etext
|
||
|
ldr r2, =__data_start__
|
||
|
ldr r3, =__data_end__
|
||
|
|
||
|
.L_loop1:
|
||
|
cmp r2, r3
|
||
|
ittt lt
|
||
|
ldrlt r0, [r1], #4
|
||
|
strlt r0, [r2], #4
|
||
|
blt .L_loop1
|
||
|
#endif /*__STARTUP_COPY_MULTIPLE */
|
||
|
|
||
|
/* This part of work usually is done in C library startup code. Otherwise,
|
||
|
* define this macro to enable it in this startup.
|
||
|
*
|
||
|
* There are two schemes too. One can clear multiple BSS sections. Another
|
||
|
* can only clear one section. The former is more size expensive than the
|
||
|
* latter.
|
||
|
*
|
||
|
* Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
|
||
|
* Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
|
||
|
*/
|
||
|
#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
|
||
|
/* Multiple sections scheme.
|
||
|
*
|
||
|
* Between symbol address __copy_table_start__ and __copy_table_end__,
|
||
|
* there are array of tuples specifying:
|
||
|
* offset 0: Start of a BSS section
|
||
|
* offset 4: Size of this BSS section. Must be multiply of 4
|
||
|
*/
|
||
|
ldr r3, =__zero_table_start__
|
||
|
ldr r4, =__zero_table_end__
|
||
|
|
||
|
.L_loop2:
|
||
|
cmp r3, r4
|
||
|
bge .L_loop2_done
|
||
|
ldr r1, [r3]
|
||
|
ldr r2, [r3, #4]
|
||
|
movs r0, 0
|
||
|
|
||
|
.L_loop2_0:
|
||
|
subs r2, #4
|
||
|
itt ge
|
||
|
strge r0, [r1, r2]
|
||
|
bge .L_loop2_0
|
||
|
|
||
|
adds r3, #8
|
||
|
b .L_loop2
|
||
|
.L_loop2_done:
|
||
|
#elif defined (__STARTUP_CLEAR_BSS)
|
||
|
/* Single BSS section scheme.
|
||
|
*
|
||
|
* The BSS section is specified by following symbols
|
||
|
* __bss_start__: start of the BSS section.
|
||
|
* __bss_end__: end of the BSS section.
|
||
|
*
|
||
|
* Both addresses must be aligned to 4 bytes boundary.
|
||
|
*/
|
||
|
ldr r1, =__bss_start__
|
||
|
ldr r2, =__bss_end__
|
||
|
|
||
|
movs r0, 0
|
||
|
.L_loop3:
|
||
|
cmp r1, r2
|
||
|
itt lt
|
||
|
strlt r0, [r1], #4
|
||
|
blt .L_loop3
|
||
|
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
|
||
|
|
||
|
#ifndef __NO_SYSTEM_INIT
|
||
|
bl SystemInit
|
||
|
#endif
|
||
|
|
||
|
#if defined(__ARMCC_VERSION) && !defined(NOSTD)
|
||
|
bl __rt_entry
|
||
|
#else
|
||
|
bl _start
|
||
|
#endif
|
||
|
|
||
|
.pool
|
||
|
.size Boot_Loader, . - Boot_Loader
|
||
|
|
||
|
.end
|
||
|
|
||
|
#endif
|
||
|
|