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