source: rtems/bsps/arm/shared/start/start.S @ e0caabe

5
Last change on this file since e0caabe was e0caabe, checked in by Sebastian Huber <sebastian.huber@…>, on 11/20/18 at 12:09:53

bsps/arm: Avoid short range branch in start.S

  • Property mode set to 100644
File size: 8.8 KB
RevLine 
[8dcfc0a]1/**
2 * @file
3 *
4 * @brief Boot and system start code.
5 */
6
7/*
[511dc4b]8 * Copyright (c) 2008, 2018 embedded brains GmbH.  All rights reserved.
[8dcfc0a]9 *
[4c622e5]10 *  embedded brains GmbH
[04bd261]11 *  Dornierstr. 4
[4c622e5]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>
[04bd261]22#include <rtems/score/percpu.h>
[511dc4b]23
[091705c]24#include <bspopts.h>
[4c622e5]25#include <bsp/irq.h>
[5812df8f]26
[4c622e5]27        /* Global symbols */
28        .globl  _start
29        .globl  bsp_start_vector_table_begin
30        .globl  bsp_start_vector_table_end
31        .globl  bsp_start_vector_table_size
32        .globl  bsp_vector_table_size
[8dcfc0a]33
[4c622e5]34        .section        ".bsp_start_text", "ax"
[8dcfc0a]35
[4c622e5]36#if defined(ARM_MULTILIB_ARCH_V4)
[091705c]37
[511dc4b]38#ifdef BSP_START_IN_HYP_SUPPORT
39        .globl  bsp_start_hyp_vector_table_begin
40#endif
41
[4c622e5]42        .arm
[9647f7fe]43
44/*
45 * This is the exception vector table and the pointers to the default
46 * exceptions handlers.
47 */
48
[4c622e5]49bsp_start_vector_table_begin:
[9647f7fe]50
[faafc229]51        ldr     pc, .Lhandler_addr_reset
52        ldr     pc, .Lhandler_addr_undef
53        ldr     pc, .Lhandler_addr_swi
54        ldr     pc, .Lhandler_addr_prefetch
55        ldr     pc, .Lhandler_addr_abort
[9647f7fe]56
57        /* Program signature checked by boot loader */
58        .word   0xb8a06f58
59
[faafc229]60        ldr     pc, .Lhandler_addr_irq
61        ldr     pc, .Lhandler_addr_fiq
[9647f7fe]62
[faafc229]63.Lhandler_addr_reset:
[9647f7fe]64
[091705c]65#ifdef BSP_START_RESET_VECTOR
66        .word   BSP_START_RESET_VECTOR
67#else
[a3579d3b]68        .word   _start
[091705c]69#endif
[9647f7fe]70
[faafc229]71.Lhandler_addr_undef:
[9647f7fe]72
[13cf952]73        .word   _ARMV4_Exception_undef_default
[9647f7fe]74
[faafc229]75.Lhandler_addr_swi:
[9647f7fe]76
[13cf952]77        .word   _ARMV4_Exception_swi_default
[9647f7fe]78
[faafc229]79.Lhandler_addr_prefetch:
[9647f7fe]80
[a44917e]81        .word   _ARMV4_Exception_pref_abort_default
[9647f7fe]82
[faafc229]83.Lhandler_addr_abort:
[9647f7fe]84
[a44917e]85        .word   _ARMV4_Exception_data_abort_default
[9647f7fe]86
[faafc229]87.Lhandler_addr_reserved:
[9647f7fe]88
[13cf952]89        .word   _ARMV4_Exception_reserved_default
[9647f7fe]90
[faafc229]91.Lhandler_addr_irq:
[9647f7fe]92
[3a7f588]93        .word   _ARMV4_Exception_interrupt
[9647f7fe]94
[faafc229]95.Lhandler_addr_fiq:
[9647f7fe]96
[13cf952]97        .word   _ARMV4_Exception_fiq_default
[9647f7fe]98
[4c622e5]99bsp_start_vector_table_end:
100
[5812df8f]101#ifdef BSP_START_IN_HYP_SUPPORT
102bsp_start_hyp_vector_table_begin:
[faafc229]103        ldr     pc, .Lhandler_addr_hyp_reset
104        ldr     pc, .Lhandler_addr_hyp_undef
105        ldr     pc, .Lhandler_addr_hyp_swi
106        ldr     pc, .Lhandler_addr_hyp_prefetch
107        ldr     pc, .Lhandler_addr_hyp_abort
108        ldr     pc, .Lhandler_addr_hyp_hyp
109        ldr     pc, .Lhandler_addr_hyp_irq
110        ldr     pc, .Lhandler_addr_hyp_fiq
111
112.Lhandler_addr_hyp_reset:
[5812df8f]113        .word   _ARMV4_Exception_reserved_default
114
[faafc229]115.Lhandler_addr_hyp_undef:
[5812df8f]116        .word   _ARMV4_Exception_reserved_default
117
[faafc229]118.Lhandler_addr_hyp_swi:
[5812df8f]119        .word   _ARMV4_Exception_reserved_default
120
[faafc229]121.Lhandler_addr_hyp_prefetch:
[5812df8f]122        .word   _ARMV4_Exception_reserved_default
123
[faafc229]124.Lhandler_addr_hyp_abort:
[5812df8f]125        .word   _ARMV4_Exception_reserved_default
126
[faafc229]127.Lhandler_addr_hyp_hyp:
[5812df8f]128        .word   _ARMV4_Exception_reserved_default
129
[faafc229]130.Lhandler_addr_hyp_irq:
[5812df8f]131        .word   _ARMV4_Exception_reserved_default
132
[faafc229]133.Lhandler_addr_hyp_fiq:
[5812df8f]134        .word   _ARMV4_Exception_reserved_default
135#endif
136
[8dcfc0a]137/* Start entry */
138
[a3579d3b]139_start:
[8dcfc0a]140
[091705c]141        /*
142         * We do not save the context since we do not return to the boot
[5812df8f]143         * loader but preserve r1 and r2 to allow access to bootloader parameters
[091705c]144         */
[5812df8f]145#ifndef BSP_START_NEEDS_REGISTER_INITIALIZATION
146        mov     r5, r1          /* machine type number or ~0 for DT boot */
147        mov     r6, r2          /* physical address of ATAGs or DTB */
148#else /* BSP_START_NEEDS_REGISTER_INITIALIZATION */
[991fdb33]149        bl bsp_start_init_registers_core
150#endif
151
[8e6a407a]152#ifdef RTEMS_SMP
153        /* Read MPIDR and get current processor index */
154        mrc     p15, 0, r7, c0, c0, 5
155        and     r7, #0xff
156#endif
157
[f6115d7c]158#ifdef BSP_START_COPY_FDT_FROM_U_BOOT
[8e6a407a]159#ifdef RTEMS_SMP
160        cmp     r7, #0
161        bne     1f
162#endif
[f6115d7c]163        mov     r0, r6
[8e6a407a]164        bl      bsp_fdt_copy
1651:
[f6115d7c]166#endif
167
[db42c079]168#ifdef RTEMS_SMP
[04bd261]169        /*
170         * Get current per-CPU control and store it in PL1 only Thread ID
171         * Register (TPIDRPRW).
172         */
173        ldr     r1, =_Per_CPU_Information
[8e6a407a]174        add     r1, r1, r7, asl #PER_CPU_CONTROL_SIZE_LOG2
[04bd261]175        mcr     p15, 0, r1, c13, c0, 4
[db42c079]176
177#endif
178
[511dc4b]179        /* Calculate interrupt stack area end for current processor */
[ff081aee]180        ldr     r1, =_ISR_Stack_size
[511dc4b]181#ifdef RTEMS_SMP
182        add     r7, #1
183        mul     r1, r1, r7
184#endif
[ff081aee]185        ldr     r2, =_ISR_Stack_area_begin
[511dc4b]186        add     r7, r1, r2
187
188        /* Save original CPSR value */
189        mrs     r4, cpsr
190
[5812df8f]191#ifdef BSP_START_IN_HYP_SUPPORT
192        orr     r0, r4, #(ARM_PSR_I | ARM_PSR_F)
193        msr     cpsr, r4
194
195        and     r0, r4, #ARM_PSR_M_MASK
196        cmp     r0, #ARM_PSR_M_HYP
[faafc229]197        bne     .L_skip_hyp_svc_switch
[5812df8f]198
[511dc4b]199        /* Boot loader starts kernel in HYP mode, switch to SVC necessary */
200        ldr     r1, =bsp_stack_hyp_size
201        mov     sp, r7
202        sub     r7, r7, r1
[5812df8f]203        bl      bsp_start_arm_drop_hyp_mode
204
[faafc229]205.L_skip_hyp_svc_switch:
[5812df8f]206#endif
[091705c]207        /* Initialize stack pointer registers for the various modes */
[8dcfc0a]208
[091705c]209        /* Enter FIQ mode and set up the FIQ stack pointer */
[39c8fdb]210        mov     r0, #(ARM_PSR_M_FIQ | ARM_PSR_I | ARM_PSR_F)
[8dcfc0a]211        msr     cpsr, r0
[511dc4b]212        ldr     r1, =bsp_stack_fiq_size
213        mov     sp, r7
214        sub     r7, r7, r1
[8dcfc0a]215
[991fdb33]216#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
217        bl bsp_start_init_registers_banked_fiq
218#endif
219
[091705c]220        /* Enter ABT mode and set up the ABT stack pointer */
[39c8fdb]221        mov     r0, #(ARM_PSR_M_ABT | ARM_PSR_I | ARM_PSR_F)
[8dcfc0a]222        msr     cpsr, r0
[511dc4b]223        ldr     r1, =bsp_stack_abt_size
224        mov     sp, r7
225        sub     r7, r7, r1
[8dcfc0a]226
[39c8fdb]227        /* Enter UND mode and set up the UND stack pointer */
228        mov     r0, #(ARM_PSR_M_UND | ARM_PSR_I | ARM_PSR_F)
[8dcfc0a]229        msr     cpsr, r0
[511dc4b]230        ldr     r1, =bsp_stack_und_size
231        mov     sp, r7
232        sub     r7, r7, r1
233
234        /* Enter IRQ mode and set up the IRQ stack pointer */
235        mov     r0, #(ARM_PSR_M_IRQ | ARM_PSR_I | ARM_PSR_F)
236        msr     cpsr, r0
237        mov     sp, r7
[8dcfc0a]238
[511dc4b]239        /*
240         * Enter SVC mode and set up the SVC stack pointer, reuse IRQ stack
241         * (interrupts are disabled).
242         */
[39c8fdb]243        mov     r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F)
[8dcfc0a]244        msr     cpsr, r0
[511dc4b]245        mov     sp, r7
[8dcfc0a]246
[091705c]247        /* Stay in SVC mode */
[8dcfc0a]248
[dc9aaf7]249#ifdef ARM_MULTILIB_VFP
[b43c2e8]250#ifdef ARM_MULTILIB_HAS_CPACR
[cfd8d7a]251        /* Read CPACR */
252        mrc p15, 0, r0, c1, c0, 2
253
254        /* Enable CP10 and CP11 */
255        orr r0, r0, #(1 << 20)
256        orr r0, r0, #(1 << 22)
257
[dc9aaf7]258        /*
259         * Clear ASEDIS and D32DIS.  Writes to D32DIS are ignored for VFP-D16.
260         */
[cfd8d7a]261        bic r0, r0, #(3 << 30)
262
263        /* Write CPACR */
264        mcr p15, 0, r0, c1, c0, 2
265        isb
[b43c2e8]266#endif
[cfd8d7a]267
268        /* Enable FPU */
269        mov r0, #(1 << 30)
270        vmsr FPEXC, r0
[991fdb33]271
272#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
273        bl bsp_start_init_registers_vfp
274#endif
275
[dc9aaf7]276#endif /* ARM_MULTILIB_VFP */
[cfd8d7a]277
[091705c]278        /*
[e0caabe]279         * Invoke the start hook 0.
[091705c]280         *
[7a6f8d0]281         * The previous code and parts of the start hook 0 may run with an
[e0caabe]282         * address offset.  After the return from start hook 0 it is assumed
[7a6f8d0]283         * that the code can run at its intended position.  Thus the link
[e0caabe]284         * register will be loaded with the absolute address and the branch
285         * link instruction cannot be used.  In THUMB mode the branch
286         * instruction as a very limited address range of 2KiB.  Use a bx to
287         * the start hook 0 address instead corrected by the address offset.
[091705c]288         */
289
[faafc229]290        ldr     lr, =.Lstart_hook_0_done
[e0caabe]291        mov     r0, pc
292        ldr     r1, =.Lget_absolute_pc
293.Lget_absolute_pc:
294        sub     r1, r0
295        ldr     r7, =bsp_start_hook_0
296        add     r7, r1
[7a6f8d0]297
[511dc4b]298        mov     r0, r4          /* original CPSR value */
[5812df8f]299        mov     r1, r5          /* machine type number or ~0 for DT boot */
300        mov     r2, r6          /* physical address of ATAGs or DTB */
301
[e0caabe]302        bx      r7
[8dcfc0a]303
[faafc229]304.Lstart_hook_0_done:
[091705c]305
306        /*
[8dcfc0a]307         * Initialize the exception vectors.  This includes the exceptions
308         * vectors and the pointers to the default exception handlers.
[091705c]309         */
[8dcfc0a]310
[5812df8f]311        stmdb   sp!, {r4, r5, r6}
312
[c5d8d2dc]313        ldr     r0, =bsp_vector_table_begin
[4c622e5]314        adr     r1, bsp_start_vector_table_begin
[9ce65803]315        cmp     r0, r1
[faafc229]316        beq     .Lvector_table_copy_done
[8dcfc0a]317        ldmia   r1!, {r2-r9}
318        stmia   r0!, {r2-r9}
319        ldmia   r1!, {r2-r9}
320        stmia   r0!, {r2-r9}
321
[faafc229]322.Lvector_table_copy_done:
[9ce65803]323
[5812df8f]324        ldmia   sp!, {r0, r1, r2}
325
326        SWITCH_FROM_ARM_TO_THUMB        r3
[7a6f8d0]327
[091705c]328        /* Branch to start hook 1 */
[8dcfc0a]329        bl      bsp_start_hook_1
330
[091705c]331        /* Branch to boot card */
[7ae2775]332        mov     r0, #0
[8dcfc0a]333        bl      boot_card
334
[4c622e5]335#elif defined(ARM_MULTILIB_ARCH_V7M)
[091705c]336
[8ae37323]337#include <rtems/score/armv7m.h>
338
[4c622e5]339        .syntax unified
[091705c]340
[4c622e5]341        .thumb
[091705c]342
[4c622e5]343bsp_start_vector_table_begin:
[091705c]344
[ff081aee]345        .word   _ISR_Stack_area_end
[4c622e5]346        .word   _start /* Reset */
[04f399d]347        .word   _ARMV7M_Exception_default /* NMI */
348        .word   _ARMV7M_Exception_default /* Hard Fault */
349        .word   _ARMV7M_Exception_default /* MPU Fault */
350        .word   _ARMV7M_Exception_default /* Bus Fault */
351        .word   _ARMV7M_Exception_default /* Usage Fault */
352        .word   _ARMV7M_Exception_default /* Reserved */
353        .word   _ARMV7M_Exception_default /* Reserved */
354        .word   _ARMV7M_Exception_default /* Reserved */
355        .word   _ARMV7M_Exception_default /* Reserved */
356        .word   _ARMV7M_Exception_default /* SVC */
357        .word   _ARMV7M_Exception_default /* Debug Monitor */
358        .word   _ARMV7M_Exception_default /* Reserved */
359        .word   _ARMV7M_Exception_default /* PendSV */
360        .word   _ARMV7M_Exception_default /* SysTick */
[4c622e5]361        .rept   BSP_INTERRUPT_VECTOR_MAX + 1
[04f399d]362        .word   _ARMV7M_Exception_default /* IRQ */
[4c622e5]363        .endr
[091705c]364
[4c622e5]365bsp_start_vector_table_end:
[091705c]366
[4c622e5]367        .thumb_func
[091705c]368
[4c622e5]369_start:
[091705c]370
[991fdb33]371#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
372        bl bsp_start_init_registers_core
373#endif
374
[8ae37323]375#ifdef ARM_MULTILIB_VFP
[b43c2e8]376#ifdef ARM_MULTILIB_HAS_CPACR
[8ae37323]377        /*
378         * Enable CP10 and CP11 coprocessors for privileged and user mode in
379         * CPACR (bits 20-23).  Ensure that write to register completes.
380         */
381        ldr     r0, =ARMV7M_CPACR
382        ldr     r1, [r0]
383        orr     r1, r1, #(0xf << 20)
384        str     r1, [r0]
385        dsb
386        isb
[b43c2e8]387#endif
[991fdb33]388
389#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
390        bl bsp_start_init_registers_vfp
[8ae37323]391#endif
392
[991fdb33]393#endif /* ARM_MULTILIB_VFP */
394
[ff081aee]395        ldr     sp, =_ISR_Stack_area_end
[faafc229]396        ldr     lr, =.Lstart_hook_0_done + 1
[4c622e5]397        b       bsp_start_hook_0
398
[faafc229]399.Lstart_hook_0_done:
[4c622e5]400
401        bl      bsp_start_hook_1
402        movs    r0, #0
403        bl      boot_card
404
405#endif /* defined(ARM_MULTILIB_ARCH_V7M) */
406
407        .set    bsp_start_vector_table_size, bsp_start_vector_table_end - bsp_start_vector_table_begin
408        .set    bsp_vector_table_size, bsp_start_vector_table_size
Note: See TracBrowser for help on using the repository browser.