source: rtems/c/src/lib/libbsp/arm/shared/start/start.S @ 8e6a407a

5
Last change on this file since 8e6a407a was 8e6a407a, checked in by Sebastian Huber <sebastian.huber@…>, on Sep 22, 2017 at 11:48:03 AM

bsps/arm: Copy FDT only on boot processor

Update #3090.

  • Property mode set to 100755
File size: 9.9 KB
Line 
1/**
2 * @file
3 *
4 * @brief Boot and system start code.
5 */
6
7/*
8 * Copyright (c) 2008, 2016 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/system.h>       
23#include <rtems/score/percpu.h>
24       
25#include <bspopts.h>
26#include <bsp/irq.h>
27#include <bsp/linker-symbols.h>
28
29        /* External symbols */
30        .extern bsp_reset
31        .extern boot_card
32        .extern bsp_start_hook_0
33        .extern bsp_start_hook_1
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
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
47        .extern _ARMV4_Exception_interrupt
48        .extern _ARMV4_Exception_fiq_default
49        .extern _ARMV7M_Exception_default
50
51#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
52        .extern bsp_start_init_registers_core
53        .extern bsp_start_init_registers_banked_fiq
54        .extern bsp_start_init_registers_vfp
55#endif
56
57#ifdef BSP_START_IN_HYP_SUPPORT
58        .extern bsp_start_arm_drop_hyp_mode
59        .globl  bsp_start_hyp_vector_table_begin
60#endif
61
62        /* Global symbols */
63        .globl  _start
64        .globl  bsp_start_vector_table_begin
65        .globl  bsp_start_vector_table_end
66        .globl  bsp_start_vector_table_size
67        .globl  bsp_vector_table_size
68        .globl  bsp_start_hook_0_done
69
70        .section        ".bsp_start_text", "ax"
71
72#if defined(ARM_MULTILIB_ARCH_V4)
73
74        .arm
75
76/*
77 * This is the exception vector table and the pointers to the default
78 * exceptions handlers.
79 */
80
81bsp_start_vector_table_begin:
82
83        ldr     pc, handler_addr_reset
84        ldr     pc, handler_addr_undef
85        ldr     pc, handler_addr_swi
86        ldr     pc, handler_addr_prefetch
87        ldr     pc, handler_addr_abort
88
89        /* Program signature checked by boot loader */
90        .word   0xb8a06f58
91
92        ldr     pc, handler_addr_irq
93        ldr     pc, handler_addr_fiq
94
95handler_addr_reset:
96
97#ifdef BSP_START_RESET_VECTOR
98        .word   BSP_START_RESET_VECTOR
99#else
100        .word   _start
101#endif
102
103handler_addr_undef:
104
105        .word   _ARMV4_Exception_undef_default
106
107handler_addr_swi:
108
109        .word   _ARMV4_Exception_swi_default
110
111handler_addr_prefetch:
112
113        .word   _ARMV4_Exception_pref_abort_default
114
115handler_addr_abort:
116
117        .word   _ARMV4_Exception_data_abort_default
118
119handler_addr_reserved:
120
121        .word   _ARMV4_Exception_reserved_default
122
123handler_addr_irq:
124
125        .word   _ARMV4_Exception_interrupt
126
127handler_addr_fiq:
128
129        .word   _ARMV4_Exception_fiq_default
130
131bsp_start_vector_table_end:
132
133#ifdef BSP_START_IN_HYP_SUPPORT
134bsp_start_hyp_vector_table_begin:
135        ldr     pc, handler_addr_hyp_reset
136        ldr     pc, handler_addr_hyp_undef
137        ldr     pc, handler_addr_hyp_swi
138        ldr     pc, handler_addr_hyp_prefetch
139        ldr     pc, handler_addr_hyp_abort
140        ldr     pc, handler_addr_hyp_hyp
141        ldr     pc, handler_addr_hyp_irq
142        ldr     pc, handler_addr_hyp_fiq
143
144handler_addr_hyp_reset:
145        .word   _ARMV4_Exception_reserved_default
146
147handler_addr_hyp_undef:
148        .word   _ARMV4_Exception_reserved_default
149
150handler_addr_hyp_swi:
151        .word   _ARMV4_Exception_reserved_default
152
153handler_addr_hyp_prefetch:
154        .word   _ARMV4_Exception_reserved_default
155
156handler_addr_hyp_abort:
157        .word   _ARMV4_Exception_reserved_default
158
159handler_addr_hyp_hyp:
160        .word   _ARMV4_Exception_reserved_default
161
162handler_addr_hyp_irq:
163        .word   _ARMV4_Exception_reserved_default
164
165handler_addr_hyp_fiq:
166        .word   _ARMV4_Exception_reserved_default
167
168bsp_start_hyp_vector_table_end:
169#endif
170
171/* Start entry */
172
173_start:
174
175        /*
176         * We do not save the context since we do not return to the boot
177         * loader but preserve r1 and r2 to allow access to bootloader parameters
178         */
179#ifndef BSP_START_NEEDS_REGISTER_INITIALIZATION
180        mov     r5, r1          /* machine type number or ~0 for DT boot */
181        mov     r6, r2          /* physical address of ATAGs or DTB */
182#else /* BSP_START_NEEDS_REGISTER_INITIALIZATION */
183        bl bsp_start_init_registers_core
184#endif
185
186#ifdef RTEMS_SMP
187        /* Read MPIDR and get current processor index */
188        mrc     p15, 0, r7, c0, c0, 5
189        and     r7, #0xff
190#endif
191
192#ifdef BSP_START_COPY_FDT_FROM_U_BOOT
193#ifdef RTEMS_SMP
194        cmp     r7, #0
195        bne     1f
196#endif
197        mov     r0, r6
198        bl      bsp_fdt_copy
1991:
200#endif
201
202#ifdef RTEMS_SMP
203        /*
204         * Get current per-CPU control and store it in PL1 only Thread ID
205         * Register (TPIDRPRW).
206         */
207        ldr     r1, =_Per_CPU_Information
208        add     r1, r1, r7, asl #PER_CPU_CONTROL_SIZE_LOG2
209        mcr     p15, 0, r1, c13, c0, 4
210
211        /* Calculate stack offset */
212        ldr     r1, =bsp_stack_all_size
213        mul     r1, r7
214#endif
215
216        mrs     r4, cpsr        /* save original procesor status value  */
217#ifdef BSP_START_IN_HYP_SUPPORT
218        orr     r0, r4, #(ARM_PSR_I | ARM_PSR_F)
219        msr     cpsr, r4
220
221        and     r0, r4, #ARM_PSR_M_MASK
222        cmp     r0, #ARM_PSR_M_HYP
223        bne     bsp_start_skip_hyp_svc_switch
224
225        /* Boot loader stats kernel in HYP mode, switch to SVC necessary */
226        ldr     sp, =bsp_stack_hyp_end
227#ifdef RTEMS_SMP
228        add     sp, r1
229#endif
230        bl      bsp_start_arm_drop_hyp_mode
231
232bsp_start_skip_hyp_svc_switch:
233#endif
234        /*
235         * Set SVC mode, disable interrupts and enable ARM instructions.
236         */
237        mov     r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F)
238        msr     cpsr, r0
239
240        /* Initialize stack pointer registers for the various modes */
241
242        /* Enter IRQ mode and set up the IRQ stack pointer */
243        mov     r0, #(ARM_PSR_M_IRQ | ARM_PSR_I | ARM_PSR_F)
244        msr     cpsr, r0
245        ldr     sp, =bsp_stack_irq_end
246#ifdef RTEMS_SMP
247        add     sp, r1
248#endif
249
250        /* Enter FIQ mode and set up the FIQ stack pointer */
251        mov     r0, #(ARM_PSR_M_FIQ | ARM_PSR_I | ARM_PSR_F)
252        msr     cpsr, r0
253        ldr     sp, =bsp_stack_fiq_end
254#ifdef RTEMS_SMP
255        add     sp, r1
256#endif
257
258#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
259        bl bsp_start_init_registers_banked_fiq
260#endif
261
262        /* Enter ABT mode and set up the ABT stack pointer */
263        mov     r0, #(ARM_PSR_M_ABT | ARM_PSR_I | ARM_PSR_F)
264        msr     cpsr, r0
265        ldr     sp, =bsp_stack_abt_end
266#ifdef RTEMS_SMP
267        add     sp, r1
268#endif
269
270        /* Enter UND mode and set up the UND stack pointer */
271        mov     r0, #(ARM_PSR_M_UND | ARM_PSR_I | ARM_PSR_F)
272        msr     cpsr, r0
273        ldr     sp, =bsp_stack_und_end
274#ifdef RTEMS_SMP
275        add     sp, r1
276#endif
277
278        /* Enter SVC mode and set up the SVC stack pointer */
279        mov     r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F)
280        msr     cpsr, r0
281        ldr     sp, =bsp_stack_svc_end
282#ifdef RTEMS_SMP
283        add     sp, r1
284#endif
285
286        /* Stay in SVC mode */
287
288#ifdef ARM_MULTILIB_VFP
289#ifdef ARM_MULTILIB_HAS_CPACR
290        /* Read CPACR */
291        mrc p15, 0, r0, c1, c0, 2
292
293        /* Enable CP10 and CP11 */
294        orr r0, r0, #(1 << 20)
295        orr r0, r0, #(1 << 22)
296
297        /*
298         * Clear ASEDIS and D32DIS.  Writes to D32DIS are ignored for VFP-D16.
299         */
300        bic r0, r0, #(3 << 30)
301
302        /* Write CPACR */
303        mcr p15, 0, r0, c1, c0, 2
304        isb
305#endif
306
307        /* Enable FPU */
308        mov r0, #(1 << 30)
309        vmsr FPEXC, r0
310
311#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
312        bl bsp_start_init_registers_vfp
313#endif
314
315#endif /* ARM_MULTILIB_VFP */
316
317        /*
318         * Branch to start hook 0.
319         *
320         * The previous code and parts of the start hook 0 may run with an
321         * address offset.  This implies that only branches relative to the
322         * program counter are allowed.  After the start hook 0 it is assumed
323         * that the code can run at its intended position.  Thus the link
324         * register will be loaded with the absolute address.  In THUMB mode
325         * the start hook 0 must be within a 2kByte range due to the branch
326         * instruction limitation.
327         */
328
329        ldr     lr, =bsp_start_hook_0_done
330#ifdef __thumb__
331        orr     lr, #1
332#endif
333
334        SWITCH_FROM_ARM_TO_THUMB        r0
335
336        mov     r0, r4          /* original cpsr value */
337        mov     r1, r5          /* machine type number or ~0 for DT boot */
338        mov     r2, r6          /* physical address of ATAGs or DTB */
339
340        b       bsp_start_hook_0
341
342bsp_start_hook_0_done:
343
344        SWITCH_FROM_THUMB_TO_ARM
345
346        /*
347         * Initialize the exception vectors.  This includes the exceptions
348         * vectors and the pointers to the default exception handlers.
349         */
350
351        stmdb   sp!, {r4, r5, r6}
352
353        ldr     r0, =bsp_vector_table_begin
354        adr     r1, bsp_start_vector_table_begin
355        cmp     r0, r1
356        beq     bsp_vector_table_copy_done
357        ldmia   r1!, {r2-r9}
358        stmia   r0!, {r2-r9}
359        ldmia   r1!, {r2-r9}
360        stmia   r0!, {r2-r9}
361
362bsp_vector_table_copy_done:
363
364        ldmia   sp!, {r0, r1, r2}
365
366        SWITCH_FROM_ARM_TO_THUMB        r3
367
368        /* Branch to start hook 1 */
369        bl      bsp_start_hook_1
370
371        /* Branch to boot card */
372        mov     r0, #0
373        bl      boot_card
374
375twiddle:
376
377        /* Branch to reset function */
378        bl      bsp_reset
379
380        b       twiddle
381
382#elif defined(ARM_MULTILIB_ARCH_V7M)
383
384#include <rtems/score/armv7m.h>
385
386        .syntax unified
387
388        .extern bsp_stack_main_end
389
390        .thumb
391
392bsp_start_vector_table_begin:
393
394        .word   bsp_stack_main_end
395        .word   _start /* Reset */
396        .word   _ARMV7M_Exception_default /* NMI */
397        .word   _ARMV7M_Exception_default /* Hard Fault */
398        .word   _ARMV7M_Exception_default /* MPU Fault */
399        .word   _ARMV7M_Exception_default /* Bus Fault */
400        .word   _ARMV7M_Exception_default /* Usage Fault */
401        .word   _ARMV7M_Exception_default /* Reserved */
402        .word   _ARMV7M_Exception_default /* Reserved */
403        .word   _ARMV7M_Exception_default /* Reserved */
404        .word   _ARMV7M_Exception_default /* Reserved */
405        .word   _ARMV7M_Exception_default /* SVC */
406        .word   _ARMV7M_Exception_default /* Debug Monitor */
407        .word   _ARMV7M_Exception_default /* Reserved */
408        .word   _ARMV7M_Exception_default /* PendSV */
409        .word   _ARMV7M_Exception_default /* SysTick */
410        .rept   BSP_INTERRUPT_VECTOR_MAX + 1
411        .word   _ARMV7M_Exception_default /* IRQ */
412        .endr
413
414bsp_start_vector_table_end:
415
416        .thumb_func
417
418_start:
419
420#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
421        bl bsp_start_init_registers_core
422#endif
423
424#ifdef ARM_MULTILIB_VFP
425#ifdef ARM_MULTILIB_HAS_CPACR
426        /*
427         * Enable CP10 and CP11 coprocessors for privileged and user mode in
428         * CPACR (bits 20-23).  Ensure that write to register completes.
429         */
430        ldr     r0, =ARMV7M_CPACR
431        ldr     r1, [r0]
432        orr     r1, r1, #(0xf << 20)
433        str     r1, [r0]
434        dsb
435        isb
436#endif
437
438#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
439        bl bsp_start_init_registers_vfp
440#endif
441
442#endif /* ARM_MULTILIB_VFP */
443
444        ldr     sp, =bsp_stack_main_end
445        ldr     lr, =bsp_start_hook_0_done + 1
446        b       bsp_start_hook_0
447
448bsp_start_hook_0_done:
449
450        bl      bsp_start_hook_1
451        movs    r0, #0
452        bl      boot_card
453
454twiddle:
455
456        bl      bsp_reset
457        b       twiddle
458
459#endif /* defined(ARM_MULTILIB_ARCH_V7M) */
460
461        .set    bsp_start_vector_table_size, bsp_start_vector_table_end - bsp_start_vector_table_begin
462        .set    bsp_vector_table_size, bsp_start_vector_table_size
Note: See TracBrowser for help on using the repository browser.