1/***************************************************************************//**
2 * @file
3 * @brief startup file for Silicon Labs EFM32HG devices.
4 *        For use with GCC for ARM Embedded Processors
5 *******************************************************************************
6 * # License
7 *
8 * The licensor of this software is Silicon Laboratories Inc. Your use of this
9 * software is governed by the terms of Silicon Labs Master Software License
10 * Agreement (MSLA) available at
11 * www.silabs.com/about-us/legal/master-software-license-agreement. This
12 * software is Third Party Software licensed by Silicon Labs from a third party
13 * and is governed by the sections of the MSLA applicable to Third Party
14 * Software and the additional terms set forth below.
15 *
16 ******************************************************************************/
17/*
18 * Copyright (c) 2009-2016 ARM Limited. All rights reserved.
19 *
20 * SPDX-License-Identifier: Apache-2.0
21 *
22 * Licensed under the Apache License, Version 2.0 (the License); you may
23 * not use this file except in compliance with the License.
24 * You may obtain a copy of the License at
25 *
26 * www.apache.org/licenses/LICENSE-2.0
27 *
28 * Unless required by applicable law or agreed to in writing, software
29 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
30 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 * See the License for the specific language governing permissions and
32 * limitations under the License.
33 */
34
35    .syntax     unified
36    .arch       armv6-m
37
38    .section    .stack
39    .align      3
40#ifdef __STACK_SIZE
41    .equ        Stack_Size, __STACK_SIZE
42#else
43    .equ        Stack_Size, 0x00000400
44#endif
45    .globl      __StackTop
46    .globl      __StackLimit
47__StackLimit:
48    .space      Stack_Size
49    .size       __StackLimit, . - __StackLimit
50__StackTop:
51    .size       __StackTop, . - __StackTop
52
53    .section    .heap
54    .align      3
55#ifdef __HEAP_SIZE
56    .equ        Heap_Size, __HEAP_SIZE
57#else
58    .equ        Heap_Size, 0x00000400
59#endif
60    .globl      __HeapBase
61    .globl      __HeapLimit
62__HeapBase:
63    .if Heap_Size
64    .space      Heap_Size
65    .endif
66    .size       __HeapBase, . - __HeapBase
67__HeapLimit:
68    .size       __HeapLimit, . - __HeapLimit
69
70    .section    .vectors
71    .align      2
72    .globl      __Vectors
73__Vectors:
74    .long       __StackTop                 /* Top of Stack */
75    .long       Reset_Handler              /* Reset Handler */
76    .long       NMI_Handler                /* NMI Handler */
77    .long       HardFault_Handler          /* Hard Fault Handler */
78    .long       Default_Handler            /* Reserved */
79    .long       Default_Handler            /* Reserved */
80    .long       Default_Handler            /* Reserved */
81    .long       Default_Handler            /* Reserved */
82    .long       Default_Handler            /* Reserved */
83    .long       Default_Handler            /* Reserved */
84    .long       Default_Handler            /* Reserved */
85    .long       SVC_Handler                /* SVCall Handler */
86    .long       Default_Handler            /* Reserved */
87    .long       sl_app_properties          /* Application properties */
88    .long       PendSV_Handler             /* PendSV Handler */
89    .long       SysTick_Handler            /* SysTick Handler */
90
91    /* External interrupts */
92
93    .long       DMA_IRQHandler             /* 0 - DMA */
94    .long       GPIO_EVEN_IRQHandler       /* 1 - GPIO_EVEN */
95    .long       TIMER0_IRQHandler          /* 2 - TIMER0 */
96    .long       ACMP0_IRQHandler           /* 3 - ACMP0 */
97    .long       ADC0_IRQHandler            /* 4 - ADC0 */
98    .long       I2C0_IRQHandler            /* 5 - I2C0 */
99    .long       GPIO_ODD_IRQHandler        /* 6 - GPIO_ODD */
100    .long       TIMER1_IRQHandler          /* 7 - TIMER1 */
101    .long       USART1_RX_IRQHandler       /* 8 - USART1_RX */
102    .long       USART1_TX_IRQHandler       /* 9 - USART1_TX */
103    .long       LEUART0_IRQHandler         /* 10 - LEUART0 */
104    .long       PCNT0_IRQHandler           /* 11 - PCNT0 */
105    .long       RTC_IRQHandler             /* 12 - RTC */
106    .long       CMU_IRQHandler             /* 13 - CMU */
107    .long       VCMP_IRQHandler            /* 14 - VCMP */
108    .long       MSC_IRQHandler             /* 15 - MSC */
109    .long       AES_IRQHandler             /* 16 - AES */
110    .long       USART0_RX_IRQHandler       /* 17 - USART0_RX */
111    .long       USART0_TX_IRQHandler       /* 18 - USART0_TX */
112    .long       USB_IRQHandler             /* 19 - USB */
113    .long       TIMER2_IRQHandler          /* 20 - TIMER2 */
114
115
116    .size       __Vectors, . - __Vectors
117
118    .text
119    .thumb
120    .thumb_func
121    .align      2
122    .globl      Reset_Handler
123    .type       Reset_Handler, %function
124Reset_Handler:
125#ifndef __NO_SYSTEM_INIT
126    ldr     r0, =SystemInit
127    blx     r0
128#endif
129
130/*  Firstly it copies data from read only memory to RAM. There are two schemes
131 *  to copy. One can copy more than one sections. Another can only copy
132 *  one section.  The former scheme needs more instructions and read-only
133 *  data to implement than the latter.
134 *  Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes.
135 */
136
137#ifdef __STARTUP_COPY_MULTIPLE
138/*  Multiple sections scheme.
139 *
140 *  Between symbol address __copy_table_start__ and __copy_table_end__,
141 *  there are array of triplets, each of which specify:
142 *    offset 0: LMA of start of a section to copy from
143 *    offset 4: VMA of start of a section to copy to
144 *    offset 8: size of the section to copy. Must be multiply of 4
145 *
146 *  All addresses must be aligned to 4 bytes boundary.
147 */
148    ldr     r4, =__copy_table_start__
149    ldr     r5, =__copy_table_end__
150
151.L_loop0:
152    cmp     r4, r5
153    bge     .L_loop0_done
154    ldr     r1, [r4]
155    ldr     r2, [r4, #4]
156    ldr     r3, [r4, #8]
157
158.L_loop0_0:
159    subs    r3, #4
160    blt     .L_loop0_0_done
161    ldr     r0, [r1, r3]
162    str     r0, [r2, r3]
163    b       .L_loop0_0
164
165.L_loop0_0_done:
166    adds    r4, #12
167    b       .L_loop0
168
169.L_loop0_done:
170#else
171/*  Single section scheme.
172 *
173 *  The ranges of copy from/to are specified by following symbols
174 *    __etext: LMA of start of the section to copy from. Usually end of text
175 *    __data_start__: VMA of start of the section to copy to
176 *    __data_end__: VMA of end of the section to copy to
177 *
178 *  All addresses must be aligned to 4 bytes boundary.
179 */
180    ldr     r1, =__etext
181    ldr     r2, =__data_start__
182    ldr     r3, =__data_end__
183
184    subs    r3, r2
185    ble     .L_loop1_done
186
187.L_loop1:
188    subs    r3, #4
189    ldr     r0, [r1,r3]
190    str     r0, [r2,r3]
191    bgt     .L_loop1
192
193.L_loop1_done:
194#endif /* __STARTUP_COPY_MULTIPLE */
195
196/*  This part of work usually is done in C library startup code. Otherwise,
197 *  define this macro to enable it in this startup.
198 *
199 *  There are two schemes too. One can clear multiple BSS sections. Another
200 *  can only clear one section. The former is more size expensive than the
201 *  latter.
202 *
203 *  Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
204 *  Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
205 */
206#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
207/*  Multiple sections scheme.
208 *
209 *  Between symbol address __zero_table_start__ and __zero_table_end__,
210 *  there are array of tuples specifying:
211 *    offset 0: Start of a BSS section
212 *    offset 4: Size of this BSS section. Must be multiply of 4
213 */
214    ldr     r3, =__zero_table_start__
215    ldr     r4, =__zero_table_end__
216
217.L_loop2:
218    cmp     r3, r4
219    bge     .L_loop2_done
220    ldr     r1, [r3]
221    ldr     r2, [r3, #4]
222    movs    r0, 0
223
224.L_loop2_0:
225    subs    r2, #4
226    blt     .L_loop2_0_done
227    str     r0, [r1, r2]
228    b       .L_loop2_0
229.L_loop2_0_done:
230
231    adds    r3, #8
232    b       .L_loop2
233.L_loop2_done:
234#elif defined (__STARTUP_CLEAR_BSS)
235/*  Single BSS section scheme.
236 *
237 *  The BSS section is specified by following symbols
238 *    __bss_start__: start of the BSS section.
239 *    __bss_end__: end of the BSS section.
240 *
241 *  Both addresses must be aligned to 4 bytes boundary.
242 */
243    ldr     r1, =__bss_start__
244    ldr     r2, =__bss_end__
245
246    movs    r0, 0
247    subs    r2, r1
248    ble     .L_loop3_done
249
250.L_loop3:
251    subs    r2, #4
252    str     r0, [r1, r2]
253    bgt     .L_loop3
254.L_loop3_done:
255#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
256
257#ifndef __START
258#define __START _start
259#endif
260    bl      __START
261
262    .pool
263    .size   Reset_Handler, . - Reset_Handler
264
265    .align  1
266    .thumb_func
267    .weak   Default_Handler
268    .type   Default_Handler, %function
269    .weak   sl_app_properties
270    .type   sl_app_properties, %common
271Default_Handler:
272sl_app_properties: /* Provide a dummy value for the sl_app_properties symbol. */
273    b       .
274    .size   Default_Handler, . - Default_Handler
275
276/*    Macro to define default handlers. Default handler
277 *    will be weak symbol and just dead loops. They can be
278 *    overwritten by other handlers.
279 */
280    .macro  def_irq_handler	handler_name
281    .weak   \handler_name
282    .set    \handler_name, Default_Handler
283    .endm
284
285    def_irq_handler     NMI_Handler
286    def_irq_handler     HardFault_Handler
287    def_irq_handler     SVC_Handler
288    def_irq_handler     PendSV_Handler
289    def_irq_handler     SysTick_Handler
290
291    def_irq_handler     DMA_IRQHandler
292    def_irq_handler     GPIO_EVEN_IRQHandler
293    def_irq_handler     TIMER0_IRQHandler
294    def_irq_handler     ACMP0_IRQHandler
295    def_irq_handler     ADC0_IRQHandler
296    def_irq_handler     I2C0_IRQHandler
297    def_irq_handler     GPIO_ODD_IRQHandler
298    def_irq_handler     TIMER1_IRQHandler
299    def_irq_handler     USART1_RX_IRQHandler
300    def_irq_handler     USART1_TX_IRQHandler
301    def_irq_handler     LEUART0_IRQHandler
302    def_irq_handler     PCNT0_IRQHandler
303    def_irq_handler     RTC_IRQHandler
304    def_irq_handler     CMU_IRQHandler
305    def_irq_handler     VCMP_IRQHandler
306    def_irq_handler     MSC_IRQHandler
307    def_irq_handler     AES_IRQHandler
308    def_irq_handler     USART0_RX_IRQHandler
309    def_irq_handler     USART0_TX_IRQHandler
310    def_irq_handler     USB_IRQHandler
311    def_irq_handler     TIMER2_IRQHandler
312
313
314    .end
315