[8dcfc0a] | 1 | /** |
---|
| 2 | * @file |
---|
| 3 | * |
---|
| 4 | * @brief Boot and system start code. |
---|
| 5 | */ |
---|
| 6 | |
---|
| 7 | /* |
---|
[3a7f588] | 8 | * Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved. |
---|
[8dcfc0a] | 9 | * |
---|
[4c622e5] | 10 | * embedded brains GmbH |
---|
| 11 | * Obere Lagerstr. 30 |
---|
| 12 | * 82178 Puchheim |
---|
| 13 | * Germany |
---|
| 14 | * <rtems@embedded-brains.de> |
---|
| 15 | * |
---|
| 16 | * The license and distribution terms for this file may be |
---|
| 17 | * found in the file LICENSE in this distribution or at |
---|
[c499856] | 18 | * http://www.rtems.org/license/LICENSE. |
---|
[8dcfc0a] | 19 | */ |
---|
[091705c] | 20 | |
---|
| 21 | #include <rtems/asm.h> |
---|
[c193baad] | 22 | #include <rtems/system.h> |
---|
[39c8fdb] | 23 | #include <rtems/score/cpu.h> |
---|
[c193baad] | 24 | |
---|
[091705c] | 25 | #include <bspopts.h> |
---|
[4c622e5] | 26 | #include <bsp/irq.h> |
---|
[8dcfc0a] | 27 | #include <bsp/linker-symbols.h> |
---|
| 28 | |
---|
[4c622e5] | 29 | /* External symbols */ |
---|
| 30 | .extern bsp_reset |
---|
| 31 | .extern boot_card |
---|
| 32 | .extern bsp_start_hook_0 |
---|
| 33 | .extern bsp_start_hook_1 |
---|
[db42c079] | 34 | .extern bsp_stack_irq_end |
---|
| 35 | .extern bsp_stack_fiq_end |
---|
| 36 | .extern bsp_stack_abt_end |
---|
| 37 | .extern bsp_stack_und_end |
---|
| 38 | .extern bsp_stack_svc_end |
---|
| 39 | #ifdef RTEMS_SMP |
---|
| 40 | .extern bsp_stack_all_size |
---|
| 41 | #endif |
---|
[13cf952] | 42 | .extern _ARMV4_Exception_undef_default |
---|
| 43 | .extern _ARMV4_Exception_swi_default |
---|
| 44 | .extern _ARMV4_Exception_data_abort_default |
---|
| 45 | .extern _ARMV4_Exception_pref_abort_default |
---|
| 46 | .extern _ARMV4_Exception_reserved_default |
---|
[3a7f588] | 47 | .extern _ARMV4_Exception_interrupt |
---|
[13cf952] | 48 | .extern _ARMV4_Exception_fiq_default |
---|
[04f399d] | 49 | .extern _ARMV7M_Exception_default |
---|
[8dcfc0a] | 50 | |
---|
[4c622e5] | 51 | /* Global symbols */ |
---|
| 52 | .globl _start |
---|
| 53 | .globl bsp_start_vector_table_begin |
---|
| 54 | .globl bsp_start_vector_table_end |
---|
| 55 | .globl bsp_start_vector_table_size |
---|
| 56 | .globl bsp_vector_table_size |
---|
[8dcfc0a] | 57 | |
---|
[4c622e5] | 58 | .section ".bsp_start_text", "ax" |
---|
[8dcfc0a] | 59 | |
---|
[4c622e5] | 60 | #if defined(ARM_MULTILIB_ARCH_V4) |
---|
[091705c] | 61 | |
---|
[4c622e5] | 62 | .arm |
---|
[9647f7fe] | 63 | |
---|
| 64 | /* |
---|
| 65 | * This is the exception vector table and the pointers to the default |
---|
| 66 | * exceptions handlers. |
---|
| 67 | */ |
---|
| 68 | |
---|
[4c622e5] | 69 | bsp_start_vector_table_begin: |
---|
[9647f7fe] | 70 | |
---|
| 71 | ldr pc, handler_addr_reset |
---|
| 72 | ldr pc, handler_addr_undef |
---|
| 73 | ldr pc, handler_addr_swi |
---|
| 74 | ldr pc, handler_addr_prefetch |
---|
| 75 | ldr pc, handler_addr_abort |
---|
| 76 | |
---|
| 77 | /* Program signature checked by boot loader */ |
---|
| 78 | .word 0xb8a06f58 |
---|
| 79 | |
---|
| 80 | ldr pc, handler_addr_irq |
---|
| 81 | ldr pc, handler_addr_fiq |
---|
| 82 | |
---|
| 83 | handler_addr_reset: |
---|
| 84 | |
---|
[091705c] | 85 | #ifdef BSP_START_RESET_VECTOR |
---|
| 86 | .word BSP_START_RESET_VECTOR |
---|
| 87 | #else |
---|
[a3579d3b] | 88 | .word _start |
---|
[091705c] | 89 | #endif |
---|
[9647f7fe] | 90 | |
---|
| 91 | handler_addr_undef: |
---|
| 92 | |
---|
[13cf952] | 93 | .word _ARMV4_Exception_undef_default |
---|
[9647f7fe] | 94 | |
---|
| 95 | handler_addr_swi: |
---|
| 96 | |
---|
[13cf952] | 97 | .word _ARMV4_Exception_swi_default |
---|
[9647f7fe] | 98 | |
---|
| 99 | handler_addr_prefetch: |
---|
| 100 | |
---|
[a44917e] | 101 | .word _ARMV4_Exception_pref_abort_default |
---|
[9647f7fe] | 102 | |
---|
| 103 | handler_addr_abort: |
---|
| 104 | |
---|
[a44917e] | 105 | .word _ARMV4_Exception_data_abort_default |
---|
[9647f7fe] | 106 | |
---|
| 107 | handler_addr_reserved: |
---|
| 108 | |
---|
[13cf952] | 109 | .word _ARMV4_Exception_reserved_default |
---|
[9647f7fe] | 110 | |
---|
| 111 | handler_addr_irq: |
---|
| 112 | |
---|
[3a7f588] | 113 | .word _ARMV4_Exception_interrupt |
---|
[9647f7fe] | 114 | |
---|
| 115 | handler_addr_fiq: |
---|
| 116 | |
---|
[13cf952] | 117 | .word _ARMV4_Exception_fiq_default |
---|
[9647f7fe] | 118 | |
---|
[4c622e5] | 119 | bsp_start_vector_table_end: |
---|
| 120 | |
---|
[8dcfc0a] | 121 | /* Start entry */ |
---|
| 122 | |
---|
[a3579d3b] | 123 | _start: |
---|
[8dcfc0a] | 124 | |
---|
[091705c] | 125 | /* |
---|
| 126 | * We do not save the context since we do not return to the boot |
---|
| 127 | * loader. |
---|
| 128 | */ |
---|
[8dcfc0a] | 129 | |
---|
[db42c079] | 130 | #ifdef RTEMS_SMP |
---|
| 131 | /* Read MPIDR */ |
---|
| 132 | mrc p15, 0, r0, c0, c0, 5 |
---|
| 133 | |
---|
| 134 | /* Calculate stack offset */ |
---|
| 135 | and r0, #0xff |
---|
| 136 | ldr r1, =bsp_stack_all_size |
---|
| 137 | mul r1, r0 |
---|
| 138 | #endif |
---|
| 139 | |
---|
[091705c] | 140 | /* |
---|
| 141 | * Set SVC mode, disable interrupts and enable ARM instructions. |
---|
| 142 | */ |
---|
[39c8fdb] | 143 | mov r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F) |
---|
[8dcfc0a] | 144 | msr cpsr, r0 |
---|
| 145 | |
---|
[091705c] | 146 | /* Initialize stack pointer registers for the various modes */ |
---|
[8dcfc0a] | 147 | |
---|
[091705c] | 148 | /* Enter IRQ mode and set up the IRQ stack pointer */ |
---|
[39c8fdb] | 149 | mov r0, #(ARM_PSR_M_IRQ | ARM_PSR_I | ARM_PSR_F) |
---|
[8dcfc0a] | 150 | msr cpsr, r0 |
---|
[7ae2775] | 151 | ldr sp, =bsp_stack_irq_end |
---|
[db42c079] | 152 | #ifdef RTEMS_SMP |
---|
| 153 | add sp, r1 |
---|
| 154 | #endif |
---|
[8dcfc0a] | 155 | |
---|
[091705c] | 156 | /* Enter FIQ mode and set up the FIQ stack pointer */ |
---|
[39c8fdb] | 157 | mov r0, #(ARM_PSR_M_FIQ | ARM_PSR_I | ARM_PSR_F) |
---|
[8dcfc0a] | 158 | msr cpsr, r0 |
---|
[7ae2775] | 159 | ldr sp, =bsp_stack_fiq_end |
---|
[db42c079] | 160 | #ifdef RTEMS_SMP |
---|
| 161 | add sp, r1 |
---|
| 162 | #endif |
---|
[8dcfc0a] | 163 | |
---|
[091705c] | 164 | /* Enter ABT mode and set up the ABT stack pointer */ |
---|
[39c8fdb] | 165 | mov r0, #(ARM_PSR_M_ABT | ARM_PSR_I | ARM_PSR_F) |
---|
[8dcfc0a] | 166 | msr cpsr, r0 |
---|
[7ae2775] | 167 | ldr sp, =bsp_stack_abt_end |
---|
[db42c079] | 168 | #ifdef RTEMS_SMP |
---|
| 169 | add sp, r1 |
---|
| 170 | #endif |
---|
[8dcfc0a] | 171 | |
---|
[39c8fdb] | 172 | /* Enter UND mode and set up the UND stack pointer */ |
---|
| 173 | mov r0, #(ARM_PSR_M_UND | ARM_PSR_I | ARM_PSR_F) |
---|
[8dcfc0a] | 174 | msr cpsr, r0 |
---|
[39c8fdb] | 175 | ldr sp, =bsp_stack_und_end |
---|
[db42c079] | 176 | #ifdef RTEMS_SMP |
---|
| 177 | add sp, r1 |
---|
| 178 | #endif |
---|
[8dcfc0a] | 179 | |
---|
[091705c] | 180 | /* Enter SVC mode and set up the SVC stack pointer */ |
---|
[39c8fdb] | 181 | mov r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F) |
---|
[8dcfc0a] | 182 | msr cpsr, r0 |
---|
[7ae2775] | 183 | ldr sp, =bsp_stack_svc_end |
---|
[db42c079] | 184 | #ifdef RTEMS_SMP |
---|
| 185 | add sp, r1 |
---|
| 186 | #endif |
---|
[8dcfc0a] | 187 | |
---|
[091705c] | 188 | /* Stay in SVC mode */ |
---|
[8dcfc0a] | 189 | |
---|
[dc9aaf7] | 190 | #ifdef ARM_MULTILIB_VFP |
---|
[cfd8d7a] | 191 | /* Read CPACR */ |
---|
| 192 | mrc p15, 0, r0, c1, c0, 2 |
---|
| 193 | |
---|
| 194 | /* Enable CP10 and CP11 */ |
---|
| 195 | orr r0, r0, #(1 << 20) |
---|
| 196 | orr r0, r0, #(1 << 22) |
---|
| 197 | |
---|
[dc9aaf7] | 198 | /* |
---|
| 199 | * Clear ASEDIS and D32DIS. Writes to D32DIS are ignored for VFP-D16. |
---|
| 200 | */ |
---|
[cfd8d7a] | 201 | bic r0, r0, #(3 << 30) |
---|
| 202 | |
---|
| 203 | /* Write CPACR */ |
---|
| 204 | mcr p15, 0, r0, c1, c0, 2 |
---|
| 205 | isb |
---|
| 206 | |
---|
| 207 | /* Enable FPU */ |
---|
| 208 | mov r0, #(1 << 30) |
---|
| 209 | vmsr FPEXC, r0 |
---|
[dc9aaf7] | 210 | #endif /* ARM_MULTILIB_VFP */ |
---|
[cfd8d7a] | 211 | |
---|
[091705c] | 212 | /* |
---|
| 213 | * Branch to start hook 0. |
---|
| 214 | * |
---|
[7a6f8d0] | 215 | * The previous code and parts of the start hook 0 may run with an |
---|
| 216 | * address offset. This implies that only branches relative to the |
---|
| 217 | * program counter are allowed. After the start hook 0 it is assumed |
---|
| 218 | * that the code can run at its intended position. Thus the link |
---|
| 219 | * register will be loaded with the absolute address. In THUMB mode |
---|
| 220 | * the start hook 0 must be within a 2kByte range due to the branch |
---|
| 221 | * instruction limitation. |
---|
[091705c] | 222 | */ |
---|
| 223 | |
---|
| 224 | ldr lr, =bsp_start_hook_0_done |
---|
[7a6f8d0] | 225 | #ifdef __thumb__ |
---|
| 226 | orr lr, #1 |
---|
| 227 | #endif |
---|
| 228 | |
---|
| 229 | SWITCH_FROM_ARM_TO_THUMB r0 |
---|
| 230 | |
---|
[091705c] | 231 | b bsp_start_hook_0 |
---|
[8dcfc0a] | 232 | |
---|
[091705c] | 233 | bsp_start_hook_0_done: |
---|
| 234 | |
---|
[7a6f8d0] | 235 | SWITCH_FROM_THUMB_TO_ARM |
---|
| 236 | |
---|
[091705c] | 237 | /* |
---|
[8dcfc0a] | 238 | * Initialize the exception vectors. This includes the exceptions |
---|
| 239 | * vectors and the pointers to the default exception handlers. |
---|
[091705c] | 240 | */ |
---|
[8dcfc0a] | 241 | |
---|
[c5d8d2dc] | 242 | ldr r0, =bsp_vector_table_begin |
---|
[4c622e5] | 243 | adr r1, bsp_start_vector_table_begin |
---|
[9ce65803] | 244 | cmp r0, r1 |
---|
| 245 | beq bsp_vector_table_copy_done |
---|
[8dcfc0a] | 246 | ldmia r1!, {r2-r9} |
---|
| 247 | stmia r0!, {r2-r9} |
---|
| 248 | ldmia r1!, {r2-r9} |
---|
| 249 | stmia r0!, {r2-r9} |
---|
| 250 | |
---|
[9ce65803] | 251 | bsp_vector_table_copy_done: |
---|
| 252 | |
---|
[7a6f8d0] | 253 | SWITCH_FROM_ARM_TO_THUMB r0 |
---|
| 254 | |
---|
[091705c] | 255 | /* Branch to start hook 1 */ |
---|
[8dcfc0a] | 256 | bl bsp_start_hook_1 |
---|
| 257 | |
---|
[091705c] | 258 | /* Branch to boot card */ |
---|
[7ae2775] | 259 | mov r0, #0 |
---|
[8dcfc0a] | 260 | bl boot_card |
---|
| 261 | |
---|
[305234f7] | 262 | twiddle: |
---|
| 263 | |
---|
[091705c] | 264 | /* Branch to reset function */ |
---|
[8dcfc0a] | 265 | bl bsp_reset |
---|
[39c8fdb] | 266 | |
---|
[305234f7] | 267 | b twiddle |
---|
[8dcfc0a] | 268 | |
---|
[4c622e5] | 269 | #elif defined(ARM_MULTILIB_ARCH_V7M) |
---|
[091705c] | 270 | |
---|
[8ae37323] | 271 | #include <rtems/score/armv7m.h> |
---|
| 272 | |
---|
[4c622e5] | 273 | .syntax unified |
---|
[091705c] | 274 | |
---|
[4c622e5] | 275 | .extern bsp_stack_main_end |
---|
[091705c] | 276 | |
---|
[4c622e5] | 277 | .thumb |
---|
[091705c] | 278 | |
---|
[4c622e5] | 279 | bsp_start_vector_table_begin: |
---|
[091705c] | 280 | |
---|
[4c622e5] | 281 | .word bsp_stack_main_end |
---|
| 282 | .word _start /* Reset */ |
---|
[04f399d] | 283 | .word _ARMV7M_Exception_default /* NMI */ |
---|
| 284 | .word _ARMV7M_Exception_default /* Hard Fault */ |
---|
| 285 | .word _ARMV7M_Exception_default /* MPU Fault */ |
---|
| 286 | .word _ARMV7M_Exception_default /* Bus Fault */ |
---|
| 287 | .word _ARMV7M_Exception_default /* Usage Fault */ |
---|
| 288 | .word _ARMV7M_Exception_default /* Reserved */ |
---|
| 289 | .word _ARMV7M_Exception_default /* Reserved */ |
---|
| 290 | .word _ARMV7M_Exception_default /* Reserved */ |
---|
| 291 | .word _ARMV7M_Exception_default /* Reserved */ |
---|
| 292 | .word _ARMV7M_Exception_default /* SVC */ |
---|
| 293 | .word _ARMV7M_Exception_default /* Debug Monitor */ |
---|
| 294 | .word _ARMV7M_Exception_default /* Reserved */ |
---|
| 295 | .word _ARMV7M_Exception_default /* PendSV */ |
---|
| 296 | .word _ARMV7M_Exception_default /* SysTick */ |
---|
[4c622e5] | 297 | .rept BSP_INTERRUPT_VECTOR_MAX + 1 |
---|
[04f399d] | 298 | .word _ARMV7M_Exception_default /* IRQ */ |
---|
[4c622e5] | 299 | .endr |
---|
[091705c] | 300 | |
---|
[4c622e5] | 301 | bsp_start_vector_table_end: |
---|
[091705c] | 302 | |
---|
[4c622e5] | 303 | .thumb_func |
---|
[091705c] | 304 | |
---|
[4c622e5] | 305 | _start: |
---|
[091705c] | 306 | |
---|
[8ae37323] | 307 | #ifdef ARM_MULTILIB_VFP |
---|
| 308 | /* |
---|
| 309 | * Enable CP10 and CP11 coprocessors for privileged and user mode in |
---|
| 310 | * CPACR (bits 20-23). Ensure that write to register completes. |
---|
| 311 | */ |
---|
| 312 | ldr r0, =ARMV7M_CPACR |
---|
| 313 | ldr r1, [r0] |
---|
| 314 | orr r1, r1, #(0xf << 20) |
---|
| 315 | str r1, [r0] |
---|
| 316 | dsb |
---|
| 317 | isb |
---|
| 318 | #endif |
---|
| 319 | |
---|
[4c622e5] | 320 | ldr sp, =bsp_stack_main_end |
---|
| 321 | ldr lr, =bsp_start_hook_0_done + 1 |
---|
| 322 | b bsp_start_hook_0 |
---|
| 323 | |
---|
| 324 | bsp_start_hook_0_done: |
---|
| 325 | |
---|
| 326 | bl bsp_start_hook_1 |
---|
| 327 | movs r0, #0 |
---|
| 328 | bl boot_card |
---|
| 329 | |
---|
| 330 | twiddle: |
---|
| 331 | |
---|
| 332 | bl bsp_reset |
---|
| 333 | b twiddle |
---|
| 334 | |
---|
| 335 | #endif /* defined(ARM_MULTILIB_ARCH_V7M) */ |
---|
| 336 | |
---|
| 337 | .set bsp_start_vector_table_size, bsp_start_vector_table_end - bsp_start_vector_table_begin |
---|
| 338 | .set bsp_vector_table_size, bsp_start_vector_table_size |
---|