1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
|
/**
* @file
*
* @brief Boot and system start code.
*/
/*
* Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Obere Lagerstr. 30
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <rtems/asm.h>
#include <rtems/system.h>
#include <rtems/score/cpu.h>
#include <bspopts.h>
#include <bsp/irq.h>
#include <bsp/linker-symbols.h>
/* External symbols */
.extern bsp_reset
.extern boot_card
.extern bsp_start_hook_0
.extern bsp_start_hook_1
.extern bsp_stack_irq_end
.extern bsp_stack_fiq_end
.extern bsp_stack_abt_end
.extern bsp_stack_und_end
.extern bsp_stack_svc_end
#ifdef RTEMS_SMP
.extern bsp_stack_all_size
#endif
.extern _ARMV4_Exception_undef_default
.extern _ARMV4_Exception_swi_default
.extern _ARMV4_Exception_data_abort_default
.extern _ARMV4_Exception_pref_abort_default
.extern _ARMV4_Exception_reserved_default
.extern _ARMV4_Exception_interrupt
.extern _ARMV4_Exception_fiq_default
.extern _ARMV7M_Exception_default
/* Global symbols */
.globl _start
.globl bsp_start_vector_table_begin
.globl bsp_start_vector_table_end
.globl bsp_start_vector_table_size
.globl bsp_vector_table_size
.section ".bsp_start_text", "ax"
#if defined(ARM_MULTILIB_ARCH_V4)
.arm
/*
* This is the exception vector table and the pointers to the default
* exceptions handlers.
*/
bsp_start_vector_table_begin:
ldr pc, handler_addr_reset
ldr pc, handler_addr_undef
ldr pc, handler_addr_swi
ldr pc, handler_addr_prefetch
ldr pc, handler_addr_abort
/* Program signature checked by boot loader */
.word 0xb8a06f58
ldr pc, handler_addr_irq
ldr pc, handler_addr_fiq
handler_addr_reset:
#ifdef BSP_START_RESET_VECTOR
.word BSP_START_RESET_VECTOR
#else
.word _start
#endif
handler_addr_undef:
.word _ARMV4_Exception_undef_default
handler_addr_swi:
.word _ARMV4_Exception_swi_default
handler_addr_prefetch:
.word _ARMV4_Exception_pref_abort_default
handler_addr_abort:
.word _ARMV4_Exception_data_abort_default
handler_addr_reserved:
.word _ARMV4_Exception_reserved_default
handler_addr_irq:
.word _ARMV4_Exception_interrupt
handler_addr_fiq:
.word _ARMV4_Exception_fiq_default
bsp_start_vector_table_end:
/* Start entry */
_start:
/*
* We do not save the context since we do not return to the boot
* loader.
*/
#ifdef RTEMS_SMP
/* Read MPIDR */
mrc p15, 0, r0, c0, c0, 5
/* Calculate stack offset */
and r0, #0xff
ldr r1, =bsp_stack_all_size
mul r1, r0
#endif
/*
* Set SVC mode, disable interrupts and enable ARM instructions.
*/
mov r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F)
msr cpsr, r0
/* Initialize stack pointer registers for the various modes */
/* Enter IRQ mode and set up the IRQ stack pointer */
mov r0, #(ARM_PSR_M_IRQ | ARM_PSR_I | ARM_PSR_F)
msr cpsr, r0
ldr sp, =bsp_stack_irq_end
#ifdef RTEMS_SMP
add sp, r1
#endif
/* Enter FIQ mode and set up the FIQ stack pointer */
mov r0, #(ARM_PSR_M_FIQ | ARM_PSR_I | ARM_PSR_F)
msr cpsr, r0
ldr sp, =bsp_stack_fiq_end
#ifdef RTEMS_SMP
add sp, r1
#endif
/* Enter ABT mode and set up the ABT stack pointer */
mov r0, #(ARM_PSR_M_ABT | ARM_PSR_I | ARM_PSR_F)
msr cpsr, r0
ldr sp, =bsp_stack_abt_end
#ifdef RTEMS_SMP
add sp, r1
#endif
/* Enter UND mode and set up the UND stack pointer */
mov r0, #(ARM_PSR_M_UND | ARM_PSR_I | ARM_PSR_F)
msr cpsr, r0
ldr sp, =bsp_stack_und_end
#ifdef RTEMS_SMP
add sp, r1
#endif
/* Enter SVC mode and set up the SVC stack pointer */
mov r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F)
msr cpsr, r0
ldr sp, =bsp_stack_svc_end
#ifdef RTEMS_SMP
add sp, r1
#endif
/* Stay in SVC mode */
#ifdef ARM_MULTILIB_VFP_D32
/* Read CPACR */
mrc p15, 0, r0, c1, c0, 2
/* Enable CP10 and CP11 */
orr r0, r0, #(1 << 20)
orr r0, r0, #(1 << 22)
/* Clear ASEDIS and D32DIS */
bic r0, r0, #(3 << 30)
/* Write CPACR */
mcr p15, 0, r0, c1, c0, 2
isb
/* Enable FPU */
mov r0, #(1 << 30)
vmsr FPEXC, r0
#endif
/*
* Branch to start hook 0.
*
* The previous code and parts of the start hook 0 may run with an
* address offset. This implies that only branches relative to the
* program counter are allowed. After the start hook 0 it is assumed
* that the code can run at its intended position. Thus the link
* register will be loaded with the absolute address. In THUMB mode
* the start hook 0 must be within a 2kByte range due to the branch
* instruction limitation.
*/
ldr lr, =bsp_start_hook_0_done
#ifdef __thumb__
orr lr, #1
#endif
SWITCH_FROM_ARM_TO_THUMB r0
b bsp_start_hook_0
bsp_start_hook_0_done:
SWITCH_FROM_THUMB_TO_ARM
/*
* Initialize the exception vectors. This includes the exceptions
* vectors and the pointers to the default exception handlers.
*/
ldr r0, =bsp_vector_table_begin
adr r1, bsp_start_vector_table_begin
cmp r0, r1
beq bsp_vector_table_copy_done
ldmia r1!, {r2-r9}
stmia r0!, {r2-r9}
ldmia r1!, {r2-r9}
stmia r0!, {r2-r9}
bsp_vector_table_copy_done:
SWITCH_FROM_ARM_TO_THUMB r0
/* Branch to start hook 1 */
bl bsp_start_hook_1
/* Branch to boot card */
mov r0, #0
bl boot_card
twiddle:
/* Branch to reset function */
bl bsp_reset
b twiddle
#elif defined(ARM_MULTILIB_ARCH_V7M)
.syntax unified
.extern bsp_stack_main_end
.thumb
bsp_start_vector_table_begin:
.word bsp_stack_main_end
.word _start /* Reset */
.word _ARMV7M_Exception_default /* NMI */
.word _ARMV7M_Exception_default /* Hard Fault */
.word _ARMV7M_Exception_default /* MPU Fault */
.word _ARMV7M_Exception_default /* Bus Fault */
.word _ARMV7M_Exception_default /* Usage Fault */
.word _ARMV7M_Exception_default /* Reserved */
.word _ARMV7M_Exception_default /* Reserved */
.word _ARMV7M_Exception_default /* Reserved */
.word _ARMV7M_Exception_default /* Reserved */
.word _ARMV7M_Exception_default /* SVC */
.word _ARMV7M_Exception_default /* Debug Monitor */
.word _ARMV7M_Exception_default /* Reserved */
.word _ARMV7M_Exception_default /* PendSV */
.word _ARMV7M_Exception_default /* SysTick */
.rept BSP_INTERRUPT_VECTOR_MAX + 1
.word _ARMV7M_Exception_default /* IRQ */
.endr
bsp_start_vector_table_end:
.thumb_func
_start:
ldr sp, =bsp_stack_main_end
ldr lr, =bsp_start_hook_0_done + 1
b bsp_start_hook_0
bsp_start_hook_0_done:
bl bsp_start_hook_1
movs r0, #0
bl boot_card
twiddle:
bl bsp_reset
b twiddle
#endif /* defined(ARM_MULTILIB_ARCH_V7M) */
.set bsp_start_vector_table_size, bsp_start_vector_table_end - bsp_start_vector_table_begin
.set bsp_vector_table_size, bsp_start_vector_table_size
|