-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCstartup.S
400 lines (336 loc) · 11.5 KB
/
Cstartup.S
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
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
/*------------------------------------------------------------------------------
//*- File source : Cstartup.s
//*- Object : Generic CStartup for KEIL and GCC
//*- Compilation flag : None
//*-----------------------------------------------------------------------------*/
/* check configuration-options and map to "assembler symbols": */
#ifdef ROM
.set RAM_MODE, 0
#ifdef VECTORS_IN_RAM
.set REMAP, 1
.set VECTREMAPPED, 1
#else
.set REMAP, 0
.set VECTREMAPPED, 0
#endif
#endif
#ifdef RAM
.set RAM_MODE, 1
.set REMAP, 1
.set VECTREMAPPED, 0
#endif
.if (RAM_MODE)
.print "RAM_MODE enabled"
.else
.print "ROM_MODE enabled"
.endif
.if (REMAP)
.print "remapping enabled"
.endif
.if (VECTREMAPPED)
.print "Vectors at start of RAM"
.else
.print "Vectors at start of Code"
.endif
.equ AIC_IVR, (256)
.equ AIC_FVR, (260)
.equ AIC_EOICR, (304)
.equ AT91C_BASE_AIC, (0xFFFFF000)
/*------------------------------------------------------------------------------
//*- Exception vectors
//*--------------------
//*- These vectors can be read at address 0 or at RAM address
//*- They ABSOLUTELY requires to be in relative addresssing mode in order to
//*- guarantee a valid jump. For the moment, all are just looping.
//*- If an exception occurs before remap, this would result in an infinite loop.
//*- To ensure if a exeption occurs before start application to infinite loop.
//*------------------------------------------------------------------------------*/
.if (VECTREMAPPED)
.print "Vectors in section .vectmapped -> .data"
.section .vectmapped, "ax"
.else
.print "Vectors in section .vectorg -> .text"
.section .vectorg, "ax"
.endif
LDR PC,Reset_Addr /* 0x00 Reset handler */
LDR PC,Undef_Addr /* 0x04 Undefined Instruction */
LDR PC,SWI_Addr /* 0x08 Software Interrupt */
LDR PC,PAbt_Addr /* 0x0C Prefetch Abort */
LDR PC,DAbt_Addr /* 0x10 Data Abort */
NOP /* 0x14 reserved */
LDR PC,IRQ_Addr /* 0x18 IRQ */
fiqvec: /* 0x1c FIQ */
/*------------------------------------------------------------------------------
//*- Function : FIQ_Handler_Entry
//*- Treatments : FIQ Controller Interrupt Handler.
//*- Called Functions : AIC_FVR[interrupt]
//*------------------------------------------------------------------------------*/
FIQ_Handler_Entry:
/*- Switch in SVC/User Mode to allow User Stack access for C code */
/* because the FIQ is not yet acknowledged*/
/*- Save and r0 in FIQ_Register */
mov r9,r0
ldr r0 , [r8, #AIC_FVR]
msr CPSR_c,#I_BIT | F_BIT | ARM_MODE_SVC
/*- Save scratch/used registers and LR in User Stack */
stmfd sp!, { r1-r3, r12, lr}
/*- Branch to the routine pointed by the AIC_FVR */
mov r14, pc
bx r0
/*- Restore scratch/used registers and LR from User Stack */
ldmia sp!, { r1-r3, r12, lr}
/*- Leave Interrupts disabled and switch back in FIQ mode */
msr CPSR_c, #I_BIT | F_BIT | ARM_MODE_FIQ
/*- Restore the R0 ARM_MODE_SVC register */
mov r0,r9
/*- Restore the Program Counter using the LR_fiq directly in the PC */
subs pc,lr,#4
/* end of fiqhandler */
Reset_Addr: .word InitReset
Undef_Addr: .word Undef_Handler
SWI_Addr: .word SWI_Handler
/*SWI_Addr: .word SoftwareInterruptASM*/ /*in swi_handler.S */
PAbt_Addr: .word PAbt_Handler
DAbt_Addr: .word DAbt_Handler
IRQ_Addr: .word IRQ_Handler_Entry
Undef_Handler: B Undef_Handler
SWI_Handler: B SWI_Handler
PAbt_Handler: B PAbt_Handler
DAbt_Handler: B DAbt_Handler
.arm
.section .init, "ax"
.global _startup
.func _startup
_startup:
reset:
.if (VECTREMAPPED)
/* mthomas: Dummy used during startup */
LDR PC,=Reset_Addr_F
NOP
NOP
NOP
NOP
NOP /*.word 0xdeadbeef*/ /* Reserved Address */
NOP
NOP
Reset_Addr_F: .word InitReset
.endif
.RAM_TOP:
.word __TOP_STACK
InitReset:
/*------------------------------------------------------------------------------
/*- Remapping
/*------------------------------------------------------------------------------*/
.if (VECTREMAPPED)
.print "RCR setting for remapping enabled"
.equ MC_BASE,0xFFFFFF00 /* MC Base Address */
.equ MC_RCR, 0x00 /* MC_RCR Offset */
/* store first word in RAM into r4 */
ldr r0,=__FIRST_IN_RAM
ldr r4,[r0]
/* load value at address 0 into R2 */
ldr r1,=0x00000000
ldr r2,[r1]
/* xor value from address 0 (flip all bits), store in R3 */
ldr r3,=0xffffffff
eor r3, r2, r3
/* write xored value to first word in RAM
if already remapped this will also change
the value at 0 */
str r3,[r0]
/* load from address 0 again into R3 */
ldr r3,[r1]
/* restore first value in RAM */
str r4,[r0]
/* compare */
cmp r3, r2
bne already_remapped
/* if both values have been equal the change of the
RAM-value had no effect on the value at 0x00000000
so we are not remapping yet -> remap now: */
LDR R0, =MC_BASE
MOV R1, #1
STR R1, [R0, #MC_RCR]
already_remapped:
.endif
/*------------------------------------------------------------------------------
/*- Low level Init (PMC, AIC, ? ....) by C function AT91F_LowLevelInit
/*------------------------------------------------------------------------------*/
.extern AT91F_LowLevelInit
/*- minumum C initialization */
/*- call AT91F_LowLevelInit( void) */
ldr sp, .RAM_TOP /* temporary stack in internal RAM (**) */
/*--Call Low level init function in ABSOLUTE through the Interworking */
ldr r0,=AT91F_LowLevelInit
mov lr, pc
bx r0
/*------------------------------------------------------------------------------
//*- Stack Sizes Definition
//*------------------------
//*- Interrupt Stack requires 2 words x 8 priority level x 4 bytes when using
//*- the vectoring. This assume that the IRQ management.
//*- The Interrupt Stack must be adjusted depending on the interrupt handlers.
//*- Fast Interrupt not requires stack If in your application it required you must
//*- be definehere.
//*- The System stack size is not defined and is limited by the free internal
//*- SRAM.
//*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
//*- Top of Stack Definition
//*-------------------------
//*- Interrupt and Supervisor Stack are located at the top of internal memory in
//*- order to speed the exception handling context saving and restoring.
//*- ARM_MODE_SVC (Application, C) Stack is located at the top of the external memory.
//*------------------------------------------------------------------------------*/
.EQU IRQ_STACK_SIZE, (3*8*4)
.EQU FIQ_STACK_SIZE, (3*8*4)
.EQU ARM_MODE_FIQ, 0x11
.EQU ARM_MODE_IRQ, 0x12
.EQU ARM_MODE_SVC, 0x13
.EQU ARM_MODE_SYS, 0x1F
.EQU I_BIT, 0x80
.EQU F_BIT, 0x40
.global I_BIT
/*------------------------------------------------------------------------------
//*- Setup the stack for each mode
//*-------------------------------*/
mov r0, sp /* see (**) */
/*- Set up Fast Interrupt Mode and set FIQ Mode Stack*/
msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT
mov sp, r0
sub r0, r0, #FIQ_STACK_SIZE
/*- Init the FIQ register*/
ldr r8, =AT91C_BASE_AIC
/*- Set up Interrupt Mode and set IRQ Mode Stack*/
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT
mov sp, r0 /* Init stack IRQ */
sub r0, r0, #IRQ_STACK_SIZE
/*- Set up Supervisor Mode and set Supervisor Mode Stack*/
// /* start with INT and FIQ enabled */
msr CPSR_c, #ARM_MODE_SVC
/* start with INT and FIQ disabled */
//msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT
mov sp, r0 /* Init stack Sup */
/*- Enable interrupt & Set up Supervisor Mode and set Supervisor Mode Stack*/
/* Relocate .data section (Copy from ROM to RAM)
This will also copy the .vectmapped and .fastrun */
LDR R1, =_etext
LDR R2, =_data
LDR R3, =_edata
LoopRel:
CMP R2, R3
LDRLO R0, [R1], #4
STRLO R0, [R2], #4
BLO LoopRel
/* Clear .bss section (Zero init) */
MOV R0, #0
LDR R1, =__bss_start__
LDR R2, =__bss_end__
LoopZI:
CMP R1, R2
STRLO R0, [R1], #4
BLO LoopZI
/* call C++ constructors of global objects */
LDR r0, =__ctors_start__
LDR r1, =__ctors_end__
ctor_loop:
CMP r0, r1
BEQ ctor_end
LDR r2, [r0], #4
STMFD sp!, {r0-r1}
MOV lr, pc
/* MOV pc, r2 */
BX r2 /* mthomas 8/2006 */
LDMFD sp!, {r0-r1}
B ctor_loop
ctor_end:
/* call main() */
ldr lr,=exit
ldr r0,=main
bx r0
.size _startup, . - _startup
.endfunc
/* "exit" dummy added by mthomas to avoid sbrk write read etc. needed
by the newlib default "exit" */
.global exit
.func exit
exit:
b .
.size exit, . - exit
.endfunc
/*------------------------------------------------------------------------------
//*- Manage exception
//*---------------
//*- This module The exception must be ensure in ARM mode
//*------------------------------------------------------------------------------
//*------------------------------------------------------------------------------
//*- Function : IRQ_Handler_Entry
//*- Treatments : IRQ Controller Interrupt Handler.
//*- Called Functions : AIC_IVR[interrupt]
//*------------------------------------------------------------------------------*/
.if (VECTREMAPPED)
.print "IRQ_Handler_Entry in section .fastrun -> .data"
.section .fastrun, "ax"
.else
.print "IRQ_Handler_Entry in section .init -> .text"
.section .init, "ax"
.endif
.global IRQ_Handler_Entry
.func IRQ_Handler_Entry
IRQ_Handler_Entry:
/*---- Adjust and save return address on the stack */
sub lr, lr, #4
stmfd sp!, {lr}
/*---- Save r0 and SPSR on the stack */
mrs r14, SPSR
stmfd sp!, {r0, r14}
/*---- Write in the IVR to support Protect mode */
/*---- No effect in Normal Mode */
/*---- De-assert NIRQ and clear the source in Protect mode */
ldr r14, =AT91C_BASE_AIC
ldr r0, [r14, #AIC_IVR]
str r14, [r14, #AIC_IVR]
/*---- Enable nested interrupts and switch to Supervisor mode */
msr CPSR_c, #ARM_MODE_SVC
/*---- Save scratch/used registers and LR on the stack */
stmfd sp!, {r1-r3, r12, r14}
/*---- Branch to the routine pointed by AIC_IVR */
mov r14, pc
bx r0
/*---- Restore scratch/used registers and LR from the stack */
ldmia sp!, {r1-r3, r12, r14}
/*---- Disable nested interrupts and switch back to IRQ mode */
msr CPSR_c, #I_BIT | ARM_MODE_IRQ
/*---- Acknowledge interrupt by writing AIC_EOICR */
ldr r14, =AT91C_BASE_AIC
str r14, [r14, #AIC_EOICR]
/*---- Restore SPSR and r0 from the stack */
ldmia sp!, {r0, r14}
msr SPSR_cxsf, r14
/*---- Return from interrupt handler */
ldmia sp!, {pc}^
.size IRQ_Handler_Entry, . - IRQ_Handler_Entry
.endfunc
/*---------------------------------------------------------------
//* ?EXEPTION_VECTOR
//* This module is only linked if needed for closing files.
//*---------------------------------------------------------------*/
.global AT91F_Default_FIQ_handler
.func AT91F_Default_FIQ_handler
AT91F_Default_FIQ_handler:
b AT91F_Default_FIQ_handler
.size AT91F_Default_FIQ_handler, . - AT91F_Default_FIQ_handler
.endfunc
.global AT91F_Default_IRQ_handler
.func AT91F_Default_IRQ_handler
AT91F_Default_IRQ_handler:
b AT91F_Default_IRQ_handler
.size AT91F_Default_IRQ_handler, . - AT91F_Default_IRQ_handler
.endfunc
.global AT91F_Spurious_handler
.func AT91F_Spurious_handler
AT91F_Spurious_handler:
b AT91F_Spurious_handler
.size AT91F_Spurious_handler, . - AT91F_Spurious_handler
.endfunc
.end