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

Last change on this file since e0caabe was e0caabe, checked in by Sebastian Huber <sebastian.huber@…>, on Nov 20, 2018 at 12:09:53 PM

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

  • Property mode set to 100644
File size: 8.8 KB
Line 
1/**
2 * @file
3 *
4 * @brief Boot and system start code.
5 */
6
7/*
8 * Copyright (c) 2008, 2018 embedded brains GmbH.  All rights reserved.
9 *
10 *  embedded brains GmbH
11 *  Dornierstr. 4
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
18 * http://www.rtems.org/license/LICENSE.
19 */
20
21#include <rtems/asm.h>
22#include <rtems/score/percpu.h>
23
24#include <bspopts.h>
25#include <bsp/irq.h>
26
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
33
34        .section        ".bsp_start_text", "ax"
35
36#if defined(ARM_MULTILIB_ARCH_V4)
37
38#ifdef BSP_START_IN_HYP_SUPPORT
39        .globl  bsp_start_hyp_vector_table_begin
40#endif
41
42        .arm
43
44/*
45 * This is the exception vector table and the pointers to the default
46 * exceptions handlers.
47 */
48
49bsp_start_vector_table_begin:
50
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
56
57        /* Program signature checked by boot loader */
58        .word   0xb8a06f58
59
60        ldr     pc, .Lhandler_addr_irq
61        ldr     pc, .Lhandler_addr_fiq
62
63.Lhandler_addr_reset:
64
65#ifdef BSP_START_RESET_VECTOR
66        .word   BSP_START_RESET_VECTOR
67#else
68        .word   _start
69#endif
70
71.Lhandler_addr_undef:
72
73        .word   _ARMV4_Exception_undef_default
74
75.Lhandler_addr_swi:
76
77        .word   _ARMV4_Exception_swi_default
78
79.Lhandler_addr_prefetch:
80
81        .word   _ARMV4_Exception_pref_abort_default
82
83.Lhandler_addr_abort:
84
85        .word   _ARMV4_Exception_data_abort_default
86
87.Lhandler_addr_reserved:
88
89        .word   _ARMV4_Exception_reserved_default
90
91.Lhandler_addr_irq:
92
93        .word   _ARMV4_Exception_interrupt
94
95.Lhandler_addr_fiq:
96
97        .word   _ARMV4_Exception_fiq_default
98
99bsp_start_vector_table_end:
100
101#ifdef BSP_START_IN_HYP_SUPPORT
102bsp_start_hyp_vector_table_begin:
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:
113        .word   _ARMV4_Exception_reserved_default
114
115.Lhandler_addr_hyp_undef:
116        .word   _ARMV4_Exception_reserved_default
117
118.Lhandler_addr_hyp_swi:
119        .word   _ARMV4_Exception_reserved_default
120
121.Lhandler_addr_hyp_prefetch:
122        .word   _ARMV4_Exception_reserved_default
123
124.Lhandler_addr_hyp_abort:
125        .word   _ARMV4_Exception_reserved_default
126
127.Lhandler_addr_hyp_hyp:
128        .word   _ARMV4_Exception_reserved_default
129
130.Lhandler_addr_hyp_irq:
131        .word   _ARMV4_Exception_reserved_default
132
133.Lhandler_addr_hyp_fiq:
134        .word   _ARMV4_Exception_reserved_default
135#endif
136
137/* Start entry */
138
139_start:
140
141        /*
142         * We do not save the context since we do not return to the boot
143         * loader but preserve r1 and r2 to allow access to bootloader parameters
144         */
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 */
149        bl bsp_start_init_registers_core
150#endif
151
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
158#ifdef BSP_START_COPY_FDT_FROM_U_BOOT
159#ifdef RTEMS_SMP
160        cmp     r7, #0
161        bne     1f
162#endif
163        mov     r0, r6
164        bl      bsp_fdt_copy
1651:
166#endif
167
168#ifdef RTEMS_SMP
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
174        add     r1, r1, r7, asl #PER_CPU_CONTROL_SIZE_LOG2
175        mcr     p15, 0, r1, c13, c0, 4
176
177#endif
178
179        /* Calculate interrupt stack area end for current processor */
180        ldr     r1, =_ISR_Stack_size
181#ifdef RTEMS_SMP
182        add     r7, #1
183        mul     r1, r1, r7
184#endif
185        ldr     r2, =_ISR_Stack_area_begin
186        add     r7, r1, r2
187
188        /* Save original CPSR value */
189        mrs     r4, cpsr
190
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
197        bne     .L_skip_hyp_svc_switch
198
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
203        bl      bsp_start_arm_drop_hyp_mode
204
205.L_skip_hyp_svc_switch:
206#endif
207        /* Initialize stack pointer registers for the various modes */
208
209        /* Enter FIQ mode and set up the FIQ stack pointer */
210        mov     r0, #(ARM_PSR_M_FIQ | ARM_PSR_I | ARM_PSR_F)
211        msr     cpsr, r0
212        ldr     r1, =bsp_stack_fiq_size
213        mov     sp, r7
214        sub     r7, r7, r1
215
216#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
217        bl bsp_start_init_registers_banked_fiq
218#endif
219
220        /* Enter ABT mode and set up the ABT stack pointer */
221        mov     r0, #(ARM_PSR_M_ABT | ARM_PSR_I | ARM_PSR_F)
222        msr     cpsr, r0
223        ldr     r1, =bsp_stack_abt_size
224        mov     sp, r7
225        sub     r7, r7, r1
226
227        /* Enter UND mode and set up the UND stack pointer */
228        mov     r0, #(ARM_PSR_M_UND | ARM_PSR_I | ARM_PSR_F)
229        msr     cpsr, r0
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
238
239        /*
240         * Enter SVC mode and set up the SVC stack pointer, reuse IRQ stack
241         * (interrupts are disabled).
242         */
243        mov     r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F)
244        msr     cpsr, r0
245        mov     sp, r7
246
247        /* Stay in SVC mode */
248
249#ifdef ARM_MULTILIB_VFP
250#ifdef ARM_MULTILIB_HAS_CPACR
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
258        /*
259         * Clear ASEDIS and D32DIS.  Writes to D32DIS are ignored for VFP-D16.
260         */
261        bic r0, r0, #(3 << 30)
262
263        /* Write CPACR */
264        mcr p15, 0, r0, c1, c0, 2
265        isb
266#endif
267
268        /* Enable FPU */
269        mov r0, #(1 << 30)
270        vmsr FPEXC, r0
271
272#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
273        bl bsp_start_init_registers_vfp
274#endif
275
276#endif /* ARM_MULTILIB_VFP */
277
278        /*
279         * Invoke the start hook 0.
280         *
281         * The previous code and parts of the start hook 0 may run with an
282         * address offset.  After the return from start hook 0 it is assumed
283         * that the code can run at its intended position.  Thus the link
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.
288         */
289
290        ldr     lr, =.Lstart_hook_0_done
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
297
298        mov     r0, r4          /* original CPSR value */
299        mov     r1, r5          /* machine type number or ~0 for DT boot */
300        mov     r2, r6          /* physical address of ATAGs or DTB */
301
302        bx      r7
303
304.Lstart_hook_0_done:
305
306        /*
307         * Initialize the exception vectors.  This includes the exceptions
308         * vectors and the pointers to the default exception handlers.
309         */
310
311        stmdb   sp!, {r4, r5, r6}
312
313        ldr     r0, =bsp_vector_table_begin
314        adr     r1, bsp_start_vector_table_begin
315        cmp     r0, r1
316        beq     .Lvector_table_copy_done
317        ldmia   r1!, {r2-r9}
318        stmia   r0!, {r2-r9}
319        ldmia   r1!, {r2-r9}
320        stmia   r0!, {r2-r9}
321
322.Lvector_table_copy_done:
323
324        ldmia   sp!, {r0, r1, r2}
325
326        SWITCH_FROM_ARM_TO_THUMB        r3
327
328        /* Branch to start hook 1 */
329        bl      bsp_start_hook_1
330
331        /* Branch to boot card */
332        mov     r0, #0
333        bl      boot_card
334
335#elif defined(ARM_MULTILIB_ARCH_V7M)
336
337#include <rtems/score/armv7m.h>
338
339        .syntax unified
340
341        .thumb
342
343bsp_start_vector_table_begin:
344
345        .word   _ISR_Stack_area_end
346        .word   _start /* Reset */
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 */
361        .rept   BSP_INTERRUPT_VECTOR_MAX + 1
362        .word   _ARMV7M_Exception_default /* IRQ */
363        .endr
364
365bsp_start_vector_table_end:
366
367        .thumb_func
368
369_start:
370
371#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
372        bl bsp_start_init_registers_core
373#endif
374
375#ifdef ARM_MULTILIB_VFP
376#ifdef ARM_MULTILIB_HAS_CPACR
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
387#endif
388
389#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
390        bl bsp_start_init_registers_vfp
391#endif
392
393#endif /* ARM_MULTILIB_VFP */
394
395        ldr     sp, =_ISR_Stack_area_end
396        ldr     lr, =.Lstart_hook_0_done + 1
397        b       bsp_start_hook_0
398
399.Lstart_hook_0_done:
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.