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

Last change on this file since e9f15be was 511dc4b, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 19, 2018 at 7:09:51 AM

Rework initialization and interrupt stack support

Statically initialize the interrupt stack area
(_Configuration_Interrupt_stack_area_begin,
_Configuration_Interrupt_stack_area_end, and
_Configuration_Interrupt_stack_size) via <rtems/confdefs.h>. Place the
interrupt stack area in a special section ".rtemsstack.interrupt". Let
BSPs define the optimal placement of this section in their linker
command files (e.g. in a fast on-chip memory).

This change makes makes the CPU_HAS_SOFTWARE_INTERRUPT_STACK and
CPU_HAS_HARDWARE_INTERRUPT_STACK CPU port defines superfluous, since the
low level initialization code has all information available via global
symbols.

This change makes the CPU_ALLOCATE_INTERRUPT_STACK CPU port define
superfluous, since the interrupt stacks are allocated by confdefs.h for
all architectures. There is no need for BSP-specific linker command
file magic (except the section placement), see previous ARM linker
command file as a bad example.

Remove _CPU_Install_interrupt_stack(). Initialize the hardware
interrupt stack in _CPU_Initialize() if necessary (e.g.
m68k_install_interrupt_stack()).

The optional _CPU_Interrupt_stack_setup() is still useful to customize
the registration of the interrupt stack area in the per-CPU information.

The initialization stack can reuse the interrupt stack, since

  • interrupts are disabled during the sequential system initialization, and
  • the boot_card() function does not return.

This stack resuse saves memory.

Changes per architecture:

arm:

  • Mostly replace the linker symbol based configuration of stacks with the standard <rtems/confdefs.h> configuration via CONFIGURE_INTERRUPT_STACK_SIZE. The size of the FIQ, ABT and UND mode stack is still defined via linker symbols. These modes are rarely used in applications and the default values provided by the BSP should be sufficient in most cases.
  • Remove the bsp_processor_count linker symbol hack used for the SMP support. This is possible since the interrupt stack area is now allocated by the linker and not allocated from the heap. This makes some configure.ac stuff obsolete. Remove the now superfluous BSP variants altcycv_devkit_smp and realview_pbx_a9_qemu_smp.

bfin:

  • Remove unused magic linker command file allocation of initialization stack. Maybe a previous linker command file copy and paste problem? In the start.S the initialization stack is set to a hard coded value.

lm32, m32c, mips, nios2, riscv, sh, v850:

  • Remove magic linker command file allocation of initialization stack. Reuse interrupt stack for initialization stack.

m68k:

  • Remove magic linker command file allocation of initialization stack. Reuse interrupt stack for initialization stack.

powerpc:

  • Remove magic linker command file allocation of initialization stack. Reuse interrupt stack for initialization stack.
  • Used dedicated memory region (REGION_RTEMSSTACK) for the interrupt stack on BSPs using the shared linkcmds.base (replacement for REGION_RWEXTRA).

sparc:

  • Remove the hard coded initialization stack. Use the interrupt stack for the initialization stack on the boot processor. This saves 16KiB of RAM.

Update #3459.

  • Property mode set to 100644
File size: 9.0 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, =_Configuration_Interrupt_stack_size
185#ifdef RTEMS_SMP
186        add     r7, #1
187        mul     r1, r1, r7
188#endif
189        ldr     r2, =_Configuration_Interrupt_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
340twiddle:
341
342        /* Branch to reset function */
343        bl      bsp_reset
344
345        b       twiddle
346
347#elif defined(ARM_MULTILIB_ARCH_V7M)
348
349#include <rtems/score/armv7m.h>
350
351        .syntax unified
352
353        .thumb
354
355bsp_start_vector_table_begin:
356
357        .word   _Configuration_Interrupt_stack_area_end
358        .word   _start /* Reset */
359        .word   _ARMV7M_Exception_default /* NMI */
360        .word   _ARMV7M_Exception_default /* Hard Fault */
361        .word   _ARMV7M_Exception_default /* MPU Fault */
362        .word   _ARMV7M_Exception_default /* Bus Fault */
363        .word   _ARMV7M_Exception_default /* Usage Fault */
364        .word   _ARMV7M_Exception_default /* Reserved */
365        .word   _ARMV7M_Exception_default /* Reserved */
366        .word   _ARMV7M_Exception_default /* Reserved */
367        .word   _ARMV7M_Exception_default /* Reserved */
368        .word   _ARMV7M_Exception_default /* SVC */
369        .word   _ARMV7M_Exception_default /* Debug Monitor */
370        .word   _ARMV7M_Exception_default /* Reserved */
371        .word   _ARMV7M_Exception_default /* PendSV */
372        .word   _ARMV7M_Exception_default /* SysTick */
373        .rept   BSP_INTERRUPT_VECTOR_MAX + 1
374        .word   _ARMV7M_Exception_default /* IRQ */
375        .endr
376
377bsp_start_vector_table_end:
378
379        .thumb_func
380
381_start:
382
383#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
384        bl bsp_start_init_registers_core
385#endif
386
387#ifdef ARM_MULTILIB_VFP
388#ifdef ARM_MULTILIB_HAS_CPACR
389        /*
390         * Enable CP10 and CP11 coprocessors for privileged and user mode in
391         * CPACR (bits 20-23).  Ensure that write to register completes.
392         */
393        ldr     r0, =ARMV7M_CPACR
394        ldr     r1, [r0]
395        orr     r1, r1, #(0xf << 20)
396        str     r1, [r0]
397        dsb
398        isb
399#endif
400
401#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
402        bl bsp_start_init_registers_vfp
403#endif
404
405#endif /* ARM_MULTILIB_VFP */
406
407        ldr     sp, =_Configuration_Interrupt_stack_area_end
408        ldr     lr, =bsp_start_hook_0_done + 1
409        b       bsp_start_hook_0
410
411bsp_start_hook_0_done:
412
413        bl      bsp_start_hook_1
414        movs    r0, #0
415        bl      boot_card
416
417twiddle:
418
419        bl      bsp_reset
420        b       twiddle
421
422#endif /* defined(ARM_MULTILIB_ARCH_V7M) */
423
424        .set    bsp_start_vector_table_size, bsp_start_vector_table_end - bsp_start_vector_table_begin
425        .set    bsp_vector_table_size, bsp_start_vector_table_size
Note: See TracBrowser for help on using the repository browser.