blob: 7c1837b8f747039315c5205eab9ffa0fae5f1f37 [file] [log] [blame]
/****************************************************************************//**
* @file startup_M2351.S
* @version V1.00
* @brief CMSIS Device Startup File
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
.syntax unified
.arch armv8 - m.base
.section .stack
.align 3
#ifndef Stack_Size
.equ Stack_Size, 0x00000800
#endif
.global __StackTop
.global __StackLimit
__StackLimit:
.space Stack_Size
.size __StackLimit, . - __StackLimit
__StackTop:
.size __StackTop, . - __StackTop
.section .heap
.align 3
#ifndef Heap_Size
.equ Heap_Size, 0x00000100
#endif
.global __HeapBase
.global __HeapLimit
__HeapBase:
.if Heap_Size
.space Heap_Size
.endif
.size __HeapBase, . - __HeapBase
__HeapLimit:
.size __HeapLimit, . - __HeapLimit
.section .vectors
.align 2
.global __Vectors
__Vectors:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* NMI Handler */
.long HardFault_Handler /* Hard Fault Handler */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long SVC_Handler /* SVCall Handler */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long PendSV_Handler /* PendSV Handler */
.long SysTick_Handler /* SysTick Handler */
/* External interrupts */
.long BOD_IRQHandler /* 0 */
.long IRC_IRQHandler /* 1 */
.long PWRWU_IRQHandler /* 2 */
.long SRAM_IRQHandler /* 3 */
.long CLKFAIL_IRQHandler /* 4 */
.long Default_Handler /* 5 */
.long RTC_IRQHandler /* 6 */
.long TAMPER_IRQHandler /* 7 */
.long WDT_IRQHandler /* 8 */
.long WWDT_IRQHandler /* 9 */
.long EINT0_IRQHandler /* 10 */
.long EINT1_IRQHandler /* 11 */
.long EINT2_IRQHandler /* 12 */
.long EINT3_IRQHandler /* 13 */
.long EINT4_IRQHandler /* 14 */
.long EINT5_IRQHandler /* 15 */
.long GPA_IRQHandler /* 16 */
.long GPB_IRQHandler /* 17 */
.long GPC_IRQHandler /* 18 */
.long GPD_IRQHandler /* 19 */
.long GPE_IRQHandler /* 20 */
.long GPF_IRQHandler /* 21 */
.long QSPI0_IRQHandler /* 22 */
.long SPI0_IRQHandler /* 23 */
.long BRAKE0_IRQHandler /* 24 */
.long EPWM0_P0_IRQHandler /* 25 */
.long EPWM0_P1_IRQHandler /* 26 */
.long EPWM0_P2_IRQHandler /* 27 */
.long BRAKE1_IRQHandler /* 28 */
.long EPWM1_P0_IRQHandler /* 29 */
.long EPWM1_P1_IRQHandler /* 30 */
.long EPWM1_P2_IRQHandler /* 31 */
.long TMR0_IRQHandler /* 32 */
.long TMR1_IRQHandler /* 33 */
.long TMR2_IRQHandler /* 34 */
.long TMR3_IRQHandler /* 35 */
.long UART0_IRQHandler /* 36 */
.long UART1_IRQHandler /* 37 */
.long I2C0_IRQHandler /* 38 */
.long I2C1_IRQHandler /* 39 */
.long PDMA0_IRQHandler /* 40 */
.long DAC_IRQHandler /* 41 */
.long EADC0_IRQHandler /* 42 */
.long EADC1_IRQHandler /* 43 */
.long ACMP01_IRQHandler /* 44 */
.long Default_Handler /* 45 */
.long EADC2_IRQHandler /* 46 */
.long EADC3_IRQHandler /* 47 */
.long UART2_IRQHandler /* 48 */
.long UART3_IRQHandler /* 49 */
.long Default_Handler /* 50 */
.long SPI1_IRQHandler /* 51 */
.long SPI2_IRQHandler /* 52 */
.long USBD_IRQHandler /* 53 */
.long USBH_IRQHandler /* 54 */
.long USBOTG_IRQHandler /* 55 */
.long CAN0_IRQHandler /* 56 */
.long Default_Handler /* 57 */
.long SC0_IRQHandler /* 58 */
.long SC1_IRQHandler /* 59 */
.long SC2_IRQHandler /* 60 */
.long Default_Handler /* 61 */
.long SPI3_IRQHandler /* 62 */
.long Default_Handler /* 63 */
.long SDH0_IRQHandler /* 64 */
.long Default_Handler /* 65 */
.long Default_Handler /* 66 */
.long Default_Handler /* 67 */
.long I2S0_IRQHandler /* 68 */
.long Default_Handler /* 69 */
.long OPA0_IRQHandler /* 70 */
.long CRPT_IRQHandler /* 71 */
.long GPG_IRQHandler /* 72 */
.long EINT6_IRQHandler /* 73 */
.long UART4_IRQHandler /* 74 */
.long UART5_IRQHandler /* 75 */
.long USCI0_IRQHandler /* 76 */
.long USCI1_IRQHandler /* 77 */
.long BPWM0_IRQHandler /* 78 */
.long BPWM1_IRQHandler /* 79 */
.long Default_Handler /* 80 */
.long Default_Handler /* 81 */
.long I2C2_IRQHandler /* 82 */
.long Default_Handler /* 83 */
.long QEI0_IRQHandler /* 84 */
.long QEI1_IRQHandler /* 85 */
.long ECAP0_IRQHandler /* 86 */
.long ECAP1_IRQHandler /* 87 */
.long GPH_IRQHandler /* 88 */
.long EINT7_IRQHandler /* 89 */
.long Default_Handler /* 90 */
.long Default_Handler /* 91 */
.long Default_Handler /* 92 */
.long Default_Handler /* 93 */
.long Default_Handler /* 94 */
.long Default_Handler /* 95 */
.long Default_Handler /* 96 */
.long Default_Handler /* 97 */
.long PDMA1_IRQHandler /* 98 */
.long SCU_IRQHandler /* 99 */
.long Default_Handler /* 100 */
.long TRNG_IRQHandler /* 101 */
.size __Vectors, . - __Vectors
.text
.thumb
.thumb_func
.align 2
.global Reset_Handler
.type Reset_Handler, % function
Reset_Handler:
/* 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
blt .L_loop0_0_done
ldr r0, [r1, r3]
str r0, [r2, r3]
b .L_loop0_0
.L_loop0_0_done:
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__
subs r3, r2
ble .L_loop1_done
.L_loop1:
subs r3, #4
ldr r0, [r1, r3]
str r0, [r2, r3]
bgt .L_loop1
.L_loop1_done:
#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
blt .L_loop2_0_done
str r0, [r1, r2]
b .L_loop2_0
.L_loop2_0_done:
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
subs r2, r1
ble .L_loop3_done
.L_loop3:
subs r2, #4
str r0, [r1, r2]
bgt .L_loop3
.L_loop3_done:
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
#ifndef __NO_SYSTEM_INIT
bl SystemInit
#endif
#ifndef __START
#define __START _start
#endif
bl __START
.pool
.size Reset_Handler, . - Reset_Handler
.align 1
.thumb_func
.weak Default_Handler
.type Default_Handler, % function
Default_Handler:
b .
.size Default_Handler, . - Default_Handler
/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.weak \handler_name
.set \handler_name, Default_Handler
.endm
def_irq_handler NMI_Handler
def_irq_handler HardFault_Handler
def_irq_handler SVC_Handler
def_irq_handler PendSV_Handler
def_irq_handler SysTick_Handler
def_irq_handler BOD_IRQHandler
def_irq_handler IRC_IRQHandler
def_irq_handler PWRWU_IRQHandler
def_irq_handler SRAM_IRQHandler
def_irq_handler CLKFAIL_IRQHandler
def_irq_handler RTC_IRQHandler
def_irq_handler TAMPER_IRQHandler
def_irq_handler WDT_IRQHandler
def_irq_handler WWDT_IRQHandler
def_irq_handler EINT0_IRQHandler
def_irq_handler EINT1_IRQHandler
def_irq_handler EINT2_IRQHandler
def_irq_handler EINT3_IRQHandler
def_irq_handler EINT4_IRQHandler
def_irq_handler EINT5_IRQHandler
def_irq_handler GPA_IRQHandler
def_irq_handler GPB_IRQHandler
def_irq_handler GPC_IRQHandler
def_irq_handler GPD_IRQHandler
def_irq_handler GPE_IRQHandler
def_irq_handler GPF_IRQHandler
def_irq_handler QSPI0_IRQHandler
def_irq_handler SPI0_IRQHandler
def_irq_handler BRAKE0_IRQHandler
def_irq_handler EPWM0_P0_IRQHandler
def_irq_handler EPWM0_P1_IRQHandler
def_irq_handler EPWM0_P2_IRQHandler
def_irq_handler BRAKE1_IRQHandler
def_irq_handler EPWM1_P0_IRQHandler
def_irq_handler EPWM1_P1_IRQHandler
def_irq_handler EPWM1_P2_IRQHandler
def_irq_handler TMR0_IRQHandler
def_irq_handler TMR1_IRQHandler
def_irq_handler TMR2_IRQHandler
def_irq_handler TMR3_IRQHandler
def_irq_handler UART0_IRQHandler
def_irq_handler UART1_IRQHandler
def_irq_handler I2C0_IRQHandler
def_irq_handler I2C1_IRQHandler
def_irq_handler PDMA0_IRQHandler
def_irq_handler DAC_IRQHandler
def_irq_handler EADC0_IRQHandler
def_irq_handler EADC1_IRQHandler
def_irq_handler ACMP01_IRQHandler
def_irq_handler EADC2_IRQHandler
def_irq_handler EADC3_IRQHandler
def_irq_handler UART2_IRQHandler
def_irq_handler UART3_IRQHandler
def_irq_handler SPI1_IRQHandler
def_irq_handler SPI2_IRQHandler
def_irq_handler USBD_IRQHandler
def_irq_handler USBH_IRQHandler
def_irq_handler USBOTG_IRQHandler
def_irq_handler CAN0_IRQHandler
def_irq_handler SC0_IRQHandler
def_irq_handler SC1_IRQHandler
def_irq_handler SC2_IRQHandler
def_irq_handler SPI3_IRQHandler
def_irq_handler SDH0_IRQHandler
def_irq_handler I2S0_IRQHandler
def_irq_handler OPA0_IRQHandler
def_irq_handler CRPT_IRQHandler
def_irq_handler GPG_IRQHandler
def_irq_handler EINT6_IRQHandler
def_irq_handler UART4_IRQHandler
def_irq_handler UART5_IRQHandler
def_irq_handler USCI0_IRQHandler
def_irq_handler USCI1_IRQHandler
def_irq_handler BPWM0_IRQHandler
def_irq_handler BPWM1_IRQHandler
def_irq_handler I2C2_IRQHandler
def_irq_handler QEI0_IRQHandler
def_irq_handler QEI1_IRQHandler
def_irq_handler ECAP0_IRQHandler
def_irq_handler ECAP1_IRQHandler
def_irq_handler GPH_IRQHandler
def_irq_handler EINT7_IRQHandler
def_irq_handler PDMA1_IRQHandler
def_irq_handler SCU_IRQHandler
def_irq_handler TRNG_IRQHandler
/* ;int32_t SH_DoCommand(int32_t n32In_R0, int32_t n32In_R1, int32_t *pn32Out_R0) */
.align 2
.thumb_func
.type SH_DoCommand, % function
SH_DoCommand:
BKPT 0xAB /* ; Wait ICE or HardFault */
LDR R3, = SH_Return
MOV R4, lr
BLX R3 /* ; Call SH_Return. The return value is in R0 */
BX R4 /* ; Return value = R0 */
.size SH_DoCommand, . - SH_DoCommand
.align 2
.thumb_func
.global __PC
.type __PC, % function
__PC:
MOV r0, lr
BLX lr
.size __PC, . - __PC
.end