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
401
402
403
404
405
|
@-----------------------------------------------------------------------------
@- File source : boot.S
@- Object : Bootfile fuer Praktikum
@-
@- 1.0 17/09/02 GR : Creation
@- letzte �nderung : 11/11/02
@------------------------------------------------------------------------------
#include "aic.inc"
#include "ebi.inc"
@------------------------------------------------------------------------------
@- Area Definition
@-----------------
@- Must be defined as function to put first in the code as it must be mapped
@- at SRAM.
@------------------------------------------------------------------------------
.text
.global _start
@------------------------------------------------------------------------------
@- Define the entry point
@------------------------
_start:
@------------------------------------------------------------------------------
@- Exception vectors
@------------------------------------------------------------------------------
Reset: B InitReset @ reset
undefvec: B undefvec @ Undefined Instruction
swivec: B swivec @ Software Interrupt
pabtvec: B pabtvec @ Prefetch Abort
dabtvec: B dabtvec @ Data Abort
rsvdvec: B rsvdvec @ reserved
irqvec: B irqvec @ reserved
fiqvec: B fiqvec @ reserved
@------------------------------------------------------------------------------
@- Exception vectors ( after cstartup execution )
@------------------------------------
@- These vectors are read at RAM address after the remap command is performed in
@- the EBI. As they will be relocated at address 0x0 to be effective, a
@- relative addressing is forbidden. The only possibility to get an absolute
@- addressing for an ARM vector is to read a PC relative value at a defined
@- offset. It is easy to reserve the locations 0x20 to 0x3C (the 8 next
@- vectors) for storing the absolute exception handler address.
@- The AIC vectoring access vectors are saved in the interrupt and fast
@- interrupt ARM vectors. So, only 5 offsets are required ( reserved vector
@- offset is never used).
@- The provisory handler addresses are defined on infinite loop and can be
@- modified at any time.
@- Note also that the reset is only accessible by a jump from the application
@- to 0. It is an actual software reset.
@- As the 13 first location are used by the vectors, the read/write link
@- address must be defined from 0x34 if internal data mapping is required.
@- (use for that the option -rw- base=0x34
@------------------------------------------------------------------------------
VectorTable:
ldr pc, [pc, #0x18] @ SoftReset
ldr pc, [pc, #0x18] @ UndefHandler
ldr pc, [pc, #0x18] @ SWIHandler
ldr pc, [pc, #0x18] @ PrefetchAbortHandler
ldr pc, [pc, #0x18] @ DataAbortHandler
nop @ Reserved
ldr pc, [pc,#-0xF20] @ IRQ : read the AIC
ldr pc, [pc,#-0xF20] @ FIQ : read the AIC
@- There are only 5 offsets as the vectoring is used.
.word _SoftReset
.word _UndefHandler
.word SWIHandler
.word _PrefetchAbortHandler
.word _DataAbortHandler
@- Vectoring Execution function run at absolut addresss
_SoftReset: b _SoftReset
_UndefHandler: b _UndefHandler
_SWIHandler: b _SWIHandler
_PrefetchAbortHandler: b _PrefetchAbortHandler
_DataAbortHandler: b _DataAbortHandler
InitTableEBI:
.word EBI_CSR_0
.word EBI_CSR_1
.word EBI_CSR_2
.word EBI_CSR_3
.word EBI_CSR_4
.word EBI_CSR_5
.word EBI_CSR_6
.word EBI_CSR_7
.word 0x00000001 @ REMAP command
.word 0x00000006 @ 6 memory regions, standard read
PtEBIBase:
.word EBI_BASE @ EBI Base Address
@------------------------------------------------------------------------------
@- The reset handler before Remap
@--------------------------------
@- From here, the code is executed from SRAM address
@------------------------------------------------------------------------------
InitReset:
@------------------------------------------------------------------------------
@- Speed up the Boot sequence
@----------------------------
@- After reset, the number os wait states on chip select 0 is 8. All AT91
@- Evaluation Boards fits fast flash memories, so that the number of wait
@- states can be optimized to fast up the boot sequence.
@- ICE note :For ICE debug no need to set the EBI value these values already set
@- by the boot function.
@------------------------------------------------------------------------------
@- Load System EBI Base address and CSR0 Init Value
ldr r0, PtEBIBase
ldr r1, InitTableEBI @ values (relative)
@- Speed up code execution by disabling wait state on Chip Select 0
str r1, [r0]
@------------------------------------------------------------------------------
@- low level init
@----------------
@ Call __low_level_init to perform initialization before initializing
@ AIC and calling main.
@----------------------------------------------------------------------
@ bl __low_level_init
@------------------------------------------------------------------------------
@- Reset the Interrupt Controller
@--------------------------------
@- Normally, the code is executed only if a reset has been actually performed.
@- So, the AIC initialization resumes at setting up the default vectors.
@------------------------------------------------------------------------------
@- Load the AIC Base Address and the default handler addresses
adr r0, AicData @ @ where to read values (relative)
ldmia r0, {r1-r4}
@- Setup the Spurious Vector
str r4, [r1, #AIC_SPU] @ r4 = spurious handler
@ - ICE note : For ICE debug
@ - Perform 8 End Of Interrupt Command to make sure AIC will not lock out nIRQ
mov r0, #8
LoopAic0:
str r1, [r1, #AIC_EOICR] @ any value written
subs r0, r0, #1
bhi LoopAic0
@- Reset Interrupts
mov r0, #0
sub r0, r0, #1 @ all bits set
str r0, [r1, #AIC_IDCR]
str r0, [r1, #AIC_ICCR]
@- Set up the default interrupt handler vectors
str r2, [r1, #AIC_SVR] @ SVR[0] for FIQ
add r1, r1, #AIC_SVR
mov r0, #31 @ counter
LoopAic1:
str r3, [r1, r0, LSL #2] @ SVRs for IRQs
subs r0, r0, #1 @ do not save FIQ
bhi LoopAic1
b EndInitAic
@- Default Interrupt Handlers
AicData:
.word AIC_BASE @ AIC Base Address
@------------------------------------------------------------------------------
@- Default Interrupt Handler
@---------------------------
@- These function are defined in the AT91 library. If you want to change this
@- you can redifine these function in your appication code
@------------------------------------------------------------------------------
PtDefaultHandler:
.word at91_default_fiq_handler
.word at91_default_irq_handler
.word at91_spurious_handler
at91_default_fiq_handler: B at91_default_fiq_handler
at91_default_irq_handler: B at91_default_irq_handler
at91_spurious_handler: B at91_spurious_handler
EndInitAic:
@------------------------------------------------------------------------------
@- Setup Exception Vectors in Internal RAM before Remap
@------------------------------------------------------
@- That's important to perform this operation before Remap in order to guarantee
@- that the core has valid vectors at any time during the remap operation.
@- Note: There are only 5 offsets as the vectoring is used.
@- ICE note : In this code only the start address value is changed if you use
@- without Semihosting.
@- Before Remap the internal RAM it's 0x300000
@- After Remap the internal RAM it's 0x000000
@- Remap it's already executed it's no possible to write to 0x300000.
@------------------------------------------------------------------------------
@- Copy the ARM exception vectors
mov r0, #0x28
adr r1, Init_Vector
str r1,[r0]
mov r0, #0x08
adr r1, VectorTable+8
ldr r1,[r1]
str r1,[r0]
swi 0
@ The RAM_BASE = 0 it's specific for ICE
RAM_BASE = 0
Init_Vector:
mov r8, #RAM_BASE @ @ of the hard vector after remap in internal RAM 0x0
adr r9, VectorTable @ where to read values (relative)
ldmia r9!, {r0-r7} @ read 8 vectors
stmia r8!, {r0-r7} @ store them
ldmia r9!, {r0-r4} @ read 5 absolute handler addresses
stmia r8!, {r0-r4} @ store them
@------------------------------------------------------------------------------
@- Initialise the Memory Controller
@----------------------------------
@- That's principaly the Remap Command. Actually, all the External Bus
@- Interface is configured with some instructions and the User Interface Image
@- as described above. The jump "mov pc, r12" could be unread as it is after
@- located after the Remap but actually it is thanks to the Arm core pipeline.
@- The IniTableEBI addressing must be relative .
@- The PtInitRemap must be absolute as the processor jumps at this address
@- immediatly after the Remap is performed.
@- Note also that the EBI base address is loaded in r11 by the "ldmia".
@- ICE note :For ICE debug these values already set by the boot function and the
@- Remap it's already executed it's no need to set still.
@------------------------------------------------------------------------------
@- Copy the Image of the Memory Controller
adr r10, InitTableEBI @ get the address of the chip select register image
ldr r12, PtInitRemap @ get the real jump address ( after remap )
@- Copy Chip Select Register Image to Memory Controller and command remap
ldmia r10!, {r0-r9,r11} @ load the complete image and the EBI base
stmia r11!, {r0-r9} @ store the complete image with the remap command
@- Jump to ROM at its new address
mov pc, r12 @ jump and break the pipeline
PtInitRemap:
.word InitRemap @ address where to jump after REMAP
@------------------------------------------------------------------------------
@- The Reset Handler after Remap
@-------------------------------
@- From here, the code is continous execute from its link address.
@------------------------------------------------------------------------------
InitRemap:
@--------------------------------
@- ARM Core Mode and Status Bits
@--------------------------------
ARM_MODE_USER = 0x10
ARM_MODE_FIQ = 0x11
ARM_MODE_IRQ = 0x12
ARM_MODE_SVC = 0x13
ARM_MODE_ABORT = 0x17
ARM_MODE_UNDEF = 0x1B
ARM_MODE_SYS = 0x1F
I_BIT = 0x80
F_BIT = 0x40
T_BIT = 0x20
@------------------------------------------------------------------------------
@- Stack Sizes Definition
@------------------------
@- Interrupt Stack requires 3 words x 8 priority level x 4 bytes when using
@- the vectoring. This assume that the IRQ_ENTRY/IRQ_EXIT macro are used.
@- The Interrupt Stack must be adjusted depending on the interrupt handlers.
@- Fast Interrupt is the same than Interrupt without priority level.
@- Other stacks are defined by default to save one word each.
@- The System stack size is not defined and is limited by the free internal
@- SRAM.
@- User stack size is not defined and is limited by the free external SRAM.
@------------------------------------------------------------------------------
IRQ_STACK_SIZE = (3*8*4) @ 3 words per interrupt priority level
FIQ_STACK_SIZE = (3*4) @ 3 words
ABT_STACK_SIZE = (1*4) @ 1 word
UND_STACK_SIZE = (1*4) @ 1 word
@------------------------------------------------------------------------------
@- Top of Stack Definition
@-------------------------
@- Fast Interrupt, Interrupt, Abort, Undefined and Supervisor Stack are located
@- at the top of internal memory in order to speed the exception handling
@- context saving and restoring.
@- User (Application, C) Stack is located at the top of the external memory.
@------------------------------------------------------------------------------
RAM_BASE = 0
RAM_SIZE = (2*1024)
RAM_LIMIT = (RAM_BASE+RAM_SIZE)
EXT_SRAM_BASE = 0x02000000
EXT_SRAM_SIZE = 0x00040000 @ 256Kbytes
EXT_SRAM_LIMIT = (EXT_SRAM_BASE+EXT_SRAM_SIZE)
TOP_EXCEPTION_STACK = RAM_LIMIT @ Defined in part
TOP_APPLICATION_STACK = EXT_SRAM_LIMIT @ Defined in Target
@------------------------------------------------------------------------------
@- Setup the stack for each mode
@-------------------------------
ldr r0, =TOP_EXCEPTION_STACK
@- Set up Fast Interrupt Mode and set FIQ Mode Stack
msr CPSR_c, #ARM_MODE_FIQ | I_BIT |F_BIT
mov r13, r0 @ Init stack FIQ
sub r0, r0, #FIQ_STACK_SIZE
@- Set up Interrupt Mode and set IRQ Mode Stack
msr CPSR_c, #ARM_MODE_IRQ | I_BIT |F_BIT
mov r13, r0 @ Init stack IRQ
sub r0, r0, #IRQ_STACK_SIZE
@- Set up Abort Mode and set Abort Mode Stack
msr CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT
mov r13, r0 @ Init stack Abort
sub r0, r0, #ABT_STACK_SIZE
@- Set up Undefined Instruction Mode and set Undef Mode Stack
msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT
mov r13, r0 @ Init stack Undef
sub r0, r0, #UND_STACK_SIZE
@- Set up Supervisor Mode and set Supervisor Mode Stack
msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT
mov sp, r0 @ Init stack Sup
@------------------------------------------------------------------------------
@- Setup Application Operating Mode and Enable the interrupts
@------------------------------------------------------------
@- System Mode is selected first and the stack is setup. This allows to prevent
@- any interrupt occurence while the User is not initialized. System Mode is
@- used as the interrupt enabling would be avoided from User Mode (CPSR cannot
@- be written while the core is in User Mode).
@------------------------------------------------------------------------------
msr CPSR_c, #ARM_MODE_USER @ set User mode
ldr sp, =TOP_APPLICATION_STACK @ Init stack User
@------------------------------------------------------------------------------
@- Initialise C variables
@------------------------
@- Following labels are automatically generated by the linker.
@- RO: Read-only = the code
@- RW: Read Write = the data pre-initialized and zero-initialized.
@- ZI: Zero-Initialized.
@- Pre-initialization values are located after the code area in the image.
@- Zero-initialized datas are mapped after the pre-initialized.
@- Note on the Data position :
@- If using the ARMSDT, when no -rw-base option is used for the linker, the
@- data area is mapped after the code. You can map the data either in internal
@- SRAM ( -rw-base=0x40 or 0x34) or in external SRAM ( -rw-base=0x2000000 ).
@- Note also that to improve the code density, the pre_initialized data must
@- be limited to a minimum.
@------------------------------------------------------------------------------
ldr r3, = __bss_start__ @ Zero init base => top of init
NoRW: ldr r1, = __bss_end__ @ Top of zero init segment
mov r2, #0
LoopZI: cmp r3, r1 @ Zero init
strcc r2, [r3], #4
bcc LoopZI
@------------------------------------------------------------------------------
@- Branch on C code Main function (with interworking)
@----------------------------------------------------
@- Branch must be performed by an interworking call as either an ARM or Thumb
@- main C function must be supported. This makes the code not position-
@- independant. A Branch with link would generate errors
@------------------------------------------------------------------------------
bl main
@------------------------------------------------------------------------------
@- Loop for ever
@---------------
@- End of application. Normally, never occur.
@- Could jump on Software Reset ( B 0x0 ).
@------------------------------------------------------------------------------
End:
b End
.END
|