1/* File: startup_ARMCM0plus.S
2 * Purpose: startup file for Cortex-M0+ devices. Should use with
3 *   GCC for ARM Embedded Processors
4 * Version: V2.01
5 * Date: 12 June 2014
6 *
7 */
8/* Copyright (c) 2011 - 2014 ARM LIMITED
9
10   All rights reserved.
11   Redistribution and use in source and binary forms, with or without
12   modification, are permitted provided that the following conditions are met:
13   - Redistributions of source code must retain the above copyright
14     notice, this list of conditions and the following disclaimer.
15   - Redistributions in binary form must reproduce the above copyright
16     notice, this list of conditions and the following disclaimer in the
17     documentation and/or other materials provided with the distribution.
18   - Neither the name of ARM nor the names of its contributors may be used
19     to endorse or promote products derived from this software without
20     specific prior written permission.
21   *
22   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
26   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32   POSSIBILITY OF SUCH DAMAGE.
33   ---------------------------------------------------------------------------*/
34
35
36	.syntax	unified
37	.arch	armv6-m
38
39	.section .stack
40	.align	3
41#ifdef __STACK_SIZE
42	.equ	Stack_Size, __STACK_SIZE
43#else
44	.equ	Stack_Size, 0x00000400
45#endif
46	.globl	__StackTop
47	.globl	__StackLimit
48__StackLimit:
49	.space	Stack_Size
50	.size	__StackLimit, . - __StackLimit
51__StackTop:
52	.size	__StackTop, . - __StackTop
53
54	.section .heap
55	.align	3
56#ifdef __HEAP_SIZE
57	.equ	Heap_Size, __HEAP_SIZE
58#else
59	.equ	Heap_Size, 0x00000C00
60#endif
61	.globl	__HeapBase
62	.globl	__HeapLimit
63__HeapBase:
64	.if	Heap_Size
65	.space	Heap_Size
66	.endif
67	.size	__HeapBase, . - __HeapBase
68__HeapLimit:
69	.size	__HeapLimit, . - __HeapLimit
70
71	.section .vectors
72	.align 2
73	.globl	__Vectors
74__Vectors:
75	.long	__StackTop            /* Top of Stack */
76	.long	Reset_Handler         /* Reset Handler */
77	.long	NMI_Handler           /* NMI Handler */
78	.long	HardFault_Handler     /* Hard Fault Handler */
79	.long	0                     /* Reserved */
80	.long	0                     /* Reserved */
81	.long	0                     /* Reserved */
82	.long	0                     /* Reserved */
83	.long	0                     /* Reserved */
84	.long	0                     /* Reserved */
85	.long	0                     /* Reserved */
86	.long	SVC_Handler           /* SVCall Handler */
87	.long	0                     /* Reserved */
88	.long	0                     /* Reserved */
89	.long	PendSV_Handler        /* PendSV Handler */
90	.long	SysTick_Handler       /* SysTick Handler */
91
92	/* External interrupts */
93	.long	WDT_IRQHandler        /*  0:  Watchdog Timer            */
94	.long	RTC_IRQHandler        /*  1:  Real Time Clock           */
95	.long	TIM0_IRQHandler       /*  2:  Timer0 / Timer1           */
96	.long	TIM2_IRQHandler       /*  3:  Timer2 / Timer3           */
97	.long	MCIA_IRQHandler       /*  4:  MCIa                      */
98	.long	MCIB_IRQHandler       /*  5:  MCIb                      */
99	.long	UART0_IRQHandler      /*  6:  UART0 - DUT FPGA          */
100	.long	UART1_IRQHandler      /*  7:  UART1 - DUT FPGA          */
101	.long	UART2_IRQHandler      /*  8:  UART2 - DUT FPGA          */
102	.long	UART4_IRQHandler      /*  9:  UART4 - not connected     */
103	.long	AACI_IRQHandler       /* 10: AACI / AC97                */
104	.long	CLCD_IRQHandler       /* 11: CLCD Combined Interrupt    */
105	.long	ENET_IRQHandler       /* 12: Ethernet                   */
106	.long	USBDC_IRQHandler      /* 13: USB Device                 */
107	.long	USBHC_IRQHandler      /* 14: USB Host Controller        */
108	.long	CHLCD_IRQHandler      /* 15: Character LCD              */
109	.long	FLEXRAY_IRQHandler    /* 16: Flexray                    */
110	.long	CAN_IRQHandler        /* 17: CAN                        */
111	.long	LIN_IRQHandler        /* 18: LIN                        */
112	.long	I2C_IRQHandler        /* 19: I2C ADC/DAC                */
113	.long	0                     /* 20: Reserved                   */
114	.long	0                     /* 21: Reserved                   */
115	.long	0                     /* 22: Reserved                   */
116	.long	0                     /* 23: Reserved                   */
117	.long	0                     /* 24: Reserved                   */
118	.long	0                     /* 25: Reserved                   */
119	.long	0                     /* 26: Reserved                   */
120	.long	0                     /* 27: Reserved                   */
121	.long	CPU_CLCD_IRQHandler   /* 28: Reserved - CPU FPGA CLCD   */
122	.long	0                     /* 29: Reserved - CPU FPGA        */
123	.long	UART3_IRQHandler      /* 30: UART3    - CPU FPGA        */
124	.long	SPI_IRQHandler        /* 31: SPI Touchscreen - CPU FPGA */
125
126	.size	__Vectors, . - __Vectors
127
128	.text
129	.thumb
130	.thumb_func
131	.align	1
132	.globl	Reset_Handler
133	.type	Reset_Handler, %function
134Reset_Handler:
135/*  Firstly it copies data from read only memory to RAM. There are two schemes
136 *  to copy. One can copy more than one sections. Another can only copy
137 *  one section.  The former scheme needs more instructions and read-only
138 *  data to implement than the latter.
139 *  Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes.  */
140
141#ifdef __STARTUP_COPY_MULTIPLE
142/*  Multiple sections scheme.
143 *
144 *  Between symbol address __copy_table_start__ and __copy_table_end__,
145 *  there are array of triplets, each of which specify:
146 *    offset 0: LMA of start of a section to copy from
147 *    offset 4: VMA of start of a section to copy to
148 *    offset 8: size of the section to copy. Must be multiply of 4
149 *
150 *  All addresses must be aligned to 4 bytes boundary.
151 */
152	ldr	r4, =__copy_table_start__
153	ldr	r5, =__copy_table_end__
154
155.L_loop0:
156	cmp	r4, r5
157	bge	.L_loop0_done
158	ldr	r1, [r4]
159	ldr	r2, [r4, #4]
160	ldr	r3, [r4, #8]
161
162.L_loop0_0:
163	subs	r3, #4
164	blt	.L_loop0_0_done
165	ldr	r0, [r1, r3]
166	str	r0, [r2, r3]
167	b	.L_loop0_0
168
169.L_loop0_0_done:
170	adds	r4, #12
171	b	.L_loop0
172
173.L_loop0_done:
174#else
175/*  Single section scheme.
176 *
177 *  The ranges of copy from/to are specified by following symbols
178 *    __etext: LMA of start of the section to copy from. Usually end of text
179 *    __data_start__: VMA of start of the section to copy to
180 *    __data_end__: VMA of end of the section to copy to
181 *
182 *  All addresses must be aligned to 4 bytes boundary.
183 */
184	ldr	r1, =__etext
185	ldr	r2, =__data_start__
186	ldr	r3, =__data_end__
187
188	subs	r3, r2
189	ble	.L_loop1_done
190
191.L_loop1:
192	subs	r3, #4
193	ldr	r0, [r1,r3]
194	str	r0, [r2,r3]
195	bgt	.L_loop1
196
197.L_loop1_done:
198#endif /*__STARTUP_COPY_MULTIPLE */
199
200/*  This part of work usually is done in C library startup code. Otherwise,
201 *  define this macro to enable it in this startup.
202 *
203 *  There are two schemes too. One can clear multiple BSS sections. Another
204 *  can only clear one section. The former is more size expensive than the
205 *  latter.
206 *
207 *  Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
208 *  Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
209 */
210#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
211/*  Multiple sections scheme.
212 *
213 *  Between symbol address __copy_table_start__ and __copy_table_end__,
214 *  there are array of tuples specifying:
215 *    offset 0: Start of a BSS section
216 *    offset 4: Size of this BSS section. Must be multiply of 4
217 */
218	ldr	r3, =__zero_table_start__
219	ldr	r4, =__zero_table_end__
220
221.L_loop2:
222	cmp	r3, r4
223	bge	.L_loop2_done
224	ldr	r1, [r3]
225	ldr	r2, [r3, #4]
226	movs	r0, 0
227
228.L_loop2_0:
229	subs	r2, #4
230	blt	.L_loop2_0_done
231	str	r0, [r1, r2]
232	b	.L_loop2_0
233.L_loop2_0_done:
234
235	adds	r3, #8
236	b	.L_loop2
237.L_loop2_done:
238#elif defined (__STARTUP_CLEAR_BSS)
239/*  Single BSS section scheme.
240 *
241 *  The BSS section is specified by following symbols
242 *    __bss_start__: start of the BSS section.
243 *    __bss_end__: end of the BSS section.
244 *
245 *  Both addresses must be aligned to 4 bytes boundary.
246 */
247	ldr	r1, =__bss_start__
248	ldr	r2, =__bss_end__
249
250	movs	r0, 0
251
252	subs	r2, r1
253	ble	.L_loop3_done
254
255.L_loop3:
256	subs	r2, #4
257	str	r0, [r1, r2]
258	bgt	.L_loop3
259.L_loop3_done:
260#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
261
262#ifndef __NO_SYSTEM_INIT
263	bl	SystemInit
264#endif
265
266#ifndef __START
267#define __START _start
268#endif
269	bl	__START
270
271	.pool
272	.size	Reset_Handler, . - Reset_Handler
273
274	.align	1
275	.thumb_func
276	.weak	Default_Handler
277	.type	Default_Handler, %function
278Default_Handler:
279	b	.
280	.size	Default_Handler, . - Default_Handler
281
282/*    Macro to define default handlers. Default handler
283 *    will be weak symbol and just dead loops. They can be
284 *    overwritten by other handlers */
285	.macro	def_irq_handler	handler_name
286	.weak	\handler_name
287	.set	\handler_name, Default_Handler
288	.endm
289
290	def_irq_handler	NMI_Handler
291	def_irq_handler	HardFault_Handler
292	def_irq_handler	SVC_Handler
293	def_irq_handler	PendSV_Handler
294	def_irq_handler	SysTick_Handler
295
296	def_irq_handler	WDT_IRQHandler
297	def_irq_handler	RTC_IRQHandler
298	def_irq_handler	TIM0_IRQHandler
299	def_irq_handler	TIM2_IRQHandler
300	def_irq_handler	MCIA_IRQHandler
301	def_irq_handler	MCIB_IRQHandler
302	def_irq_handler	UART0_IRQHandler
303	def_irq_handler	UART1_IRQHandler
304	def_irq_handler	UART2_IRQHandler
305	def_irq_handler	UART3_IRQHandler
306	def_irq_handler	UART4_IRQHandler
307	def_irq_handler	AACI_IRQHandler
308	def_irq_handler	CLCD_IRQHandler
309	def_irq_handler	ENET_IRQHandler
310	def_irq_handler	USBDC_IRQHandler
311	def_irq_handler	USBHC_IRQHandler
312	def_irq_handler	CHLCD_IRQHandler
313	def_irq_handler	FLEXRAY_IRQHandler
314	def_irq_handler	CAN_IRQHandler
315	def_irq_handler	LIN_IRQHandler
316	def_irq_handler	I2C_IRQHandler
317	def_irq_handler	CPU_CLCD_IRQHandler
318	def_irq_handler	SPI_IRQHandler
319
320	.end
321