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

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

bsps/arm: Simplify start.S

The boot_card() function does not return.

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